From 3e6fc0049b18c0f523d2dc1c9204846e5d05ccd0 Mon Sep 17 00:00:00 2001 From: Francis Russell Date: Wed, 20 Jun 2012 18:24:38 +0100 Subject: [PATCH] Add generated code used for initial ACM TOMS submission. --- mass_matrix_2d/mass_matrix_f1_p1_q1_excafe.h | 54 + .../mass_matrix_f1_p1_q1_quadrature.h | 1439 +++ mass_matrix_2d/mass_matrix_f1_p1_q1_tensor.h | 1402 +++ mass_matrix_2d/mass_matrix_f1_p1_q2_excafe.h | 99 + .../mass_matrix_f1_p1_q2_quadrature.h | 3357 +++++++ mass_matrix_2d/mass_matrix_f1_p1_q2_tensor.h | 3337 +++++++ mass_matrix_2d/mass_matrix_f1_p1_q3_excafe.h | 182 + .../mass_matrix_f1_p1_q3_quadrature.h | 4575 +++++++++ mass_matrix_2d/mass_matrix_f1_p1_q3_tensor.h | 4601 +++++++++ mass_matrix_2d/mass_matrix_f1_p1_q4_excafe.h | 399 + .../mass_matrix_f1_p1_q4_quadrature.h | 6446 ++++++++++++ mass_matrix_2d/mass_matrix_f1_p1_q4_tensor.h | 6579 +++++++++++++ mass_matrix_2d/mass_matrix_f1_p2_q1_excafe.h | 60 + .../mass_matrix_f1_p2_q1_quadrature.h | 3355 +++++++ mass_matrix_2d/mass_matrix_f1_p2_q1_tensor.h | 3313 +++++++ mass_matrix_2d/mass_matrix_f1_p2_q2_excafe.h | 108 + .../mass_matrix_f1_p2_q2_quadrature.h | 2209 +++++ mass_matrix_2d/mass_matrix_f1_p2_q2_tensor.h | 2196 +++++ mass_matrix_2d/mass_matrix_f1_p2_q3_excafe.h | 245 + .../mass_matrix_f1_p2_q3_quadrature.h | 5357 ++++++++++ mass_matrix_2d/mass_matrix_f1_p2_q3_tensor.h | 5368 ++++++++++ mass_matrix_2d/mass_matrix_f1_p2_q4_excafe.h | 500 + .../mass_matrix_f1_p2_q4_quadrature.h | 7232 ++++++++++++++ mass_matrix_2d/mass_matrix_f1_p2_q4_tensor.h | 7346 ++++++++++++++ mass_matrix_2d/mass_matrix_f1_p3_q1_excafe.h | 68 + .../mass_matrix_f1_p3_q1_quadrature.h | 4557 +++++++++ mass_matrix_2d/mass_matrix_f1_p3_q1_tensor.h | 4517 +++++++++ mass_matrix_2d/mass_matrix_f1_p3_q2_excafe.h | 137 + .../mass_matrix_f1_p3_q2_quadrature.h | 5339 ++++++++++ mass_matrix_2d/mass_matrix_f1_p3_q2_tensor.h | 5308 ++++++++++ mass_matrix_2d/mass_matrix_f1_p3_q3_excafe.h | 319 + .../mass_matrix_f1_p3_q3_quadrature.h | 3422 +++++++ mass_matrix_2d/mass_matrix_f1_p3_q3_tensor.h | 3464 +++++++ mass_matrix_2d/mass_matrix_f1_p3_q4_excafe.h | 578 ++ .../mass_matrix_f1_p3_q4_quadrature.h | 8432 ++++++++++++++++ mass_matrix_2d/mass_matrix_f1_p3_q4_tensor.h | 8550 ++++++++++++++++ mass_matrix_2d/mass_matrix_f2_p1_q1_excafe.h | 69 + .../mass_matrix_f2_p1_q1_quadrature.h | 1451 +++ mass_matrix_2d/mass_matrix_f2_p1_q1_tensor.h | 1418 +++ mass_matrix_2d/mass_matrix_f2_p1_q2_excafe.h | 123 + .../mass_matrix_f2_p1_q2_quadrature.h | 3379 +++++++ mass_matrix_2d/mass_matrix_f2_p1_q2_tensor.h | 3353 +++++++ mass_matrix_2d/mass_matrix_f2_p1_q3_excafe.h | 238 + .../mass_matrix_f2_p1_q3_quadrature.h | 4605 +++++++++ mass_matrix_2d/mass_matrix_f2_p1_q3_tensor.h | 4617 +++++++++ mass_matrix_2d/mass_matrix_f2_p1_q4_excafe.h | 535 + .../mass_matrix_f2_p1_q4_quadrature.h | 6480 ++++++++++++ mass_matrix_2d/mass_matrix_f2_p1_q4_tensor.h | 6595 +++++++++++++ mass_matrix_2d/mass_matrix_f2_p2_q1_excafe.h | 111 + .../mass_matrix_f2_p2_q1_quadrature.h | 3379 +++++++ mass_matrix_2d/mass_matrix_f2_p2_q1_tensor.h | 3353 +++++++ mass_matrix_2d/mass_matrix_f2_p2_q2_excafe.h | 219 + .../mass_matrix_f2_p2_q2_quadrature.h | 2234 +++++ mass_matrix_2d/mass_matrix_f2_p2_q2_tensor.h | 2236 +++++ mass_matrix_2d/mass_matrix_f2_p2_q3_excafe.h | 403 + .../mass_matrix_f2_p2_q3_quadrature.h | 5391 ++++++++++ mass_matrix_2d/mass_matrix_f2_p2_q3_tensor.h | 5408 +++++++++++ mass_matrix_2d/mass_matrix_f2_p2_q4_excafe.h | 631 ++ .../mass_matrix_f2_p2_q4_quadrature.h | 7270 ++++++++++++++ mass_matrix_2d/mass_matrix_f2_p2_q4_tensor.h | 7386 ++++++++++++++ mass_matrix_2d/mass_matrix_f2_p3_q1_excafe.h | 207 + .../mass_matrix_f2_p3_q1_quadrature.h | 4605 +++++++++ mass_matrix_2d/mass_matrix_f2_p3_q1_tensor.h | 4617 +++++++++ mass_matrix_2d/mass_matrix_f2_p3_q2_excafe.h | 350 + .../mass_matrix_f2_p3_q2_quadrature.h | 5391 ++++++++++ mass_matrix_2d/mass_matrix_f2_p3_q2_tensor.h | 5408 +++++++++++ mass_matrix_2d/mass_matrix_f2_p3_q3_excafe.h | 626 ++ .../mass_matrix_f2_p3_q3_quadrature.h | 3458 +++++++ mass_matrix_2d/mass_matrix_f2_p3_q3_tensor.h | 3564 +++++++ mass_matrix_2d/mass_matrix_f2_p3_q4_excafe.h | 1105 +++ .../mass_matrix_f2_p3_q4_quadrature.h | 8500 ++++++++++++++++ mass_matrix_2d/mass_matrix_f2_p3_q4_tensor.h | 8650 +++++++++++++++++ mass_matrix_2d/mass_matrix_f3_p1_q1_excafe.h | 87 + .../mass_matrix_f3_p1_q1_quadrature.h | 1464 +++ mass_matrix_2d/mass_matrix_f3_p1_q1_tensor.h | 1446 +++ mass_matrix_2d/mass_matrix_f3_p1_q2_excafe.h | 157 + .../mass_matrix_f3_p1_q2_quadrature.h | 3399 +++++++ mass_matrix_2d/mass_matrix_f3_p1_q2_tensor.h | 3381 +++++++ mass_matrix_2d/mass_matrix_f3_p1_q3_excafe.h | 328 + .../mass_matrix_f3_p1_q3_quadrature.h | 4617 +++++++++ mass_matrix_2d/mass_matrix_f3_p1_q3_tensor.h | 4645 +++++++++ mass_matrix_2d/mass_matrix_f3_p1_q4_excafe.h | 619 ++ .../mass_matrix_f3_p1_q4_quadrature.h | 6492 +++++++++++++ mass_matrix_2d/mass_matrix_f3_p1_q4_tensor.h | 6623 +++++++++++++ mass_matrix_2d/mass_matrix_f3_p2_q1_excafe.h | 262 + .../mass_matrix_f3_p2_q1_quadrature.h | 3417 +++++++ mass_matrix_2d/mass_matrix_f3_p2_q1_tensor.h | 3543 +++++++ mass_matrix_2d/mass_matrix_f3_p2_q2_excafe.h | 607 ++ .../mass_matrix_f3_p2_q2_quadrature.h | 2257 +++++ mass_matrix_2d/mass_matrix_f3_p2_q2_tensor.h | 2426 +++++ mass_matrix_2d/mass_matrix_f3_p2_q3_excafe.h | 644 ++ .../mass_matrix_f3_p2_q3_quadrature.h | 5429 +++++++++++ mass_matrix_2d/mass_matrix_f3_p2_q3_tensor.h | 5598 +++++++++++ mass_matrix_2d/mass_matrix_f4_p1_q1_excafe.h | 106 + .../mass_matrix_f4_p1_q1_quadrature.h | 1481 +++ mass_matrix_2d/mass_matrix_f4_p1_q1_tensor.h | 1510 +++ mass_matrix_2d/mass_matrix_f4_p1_q2_excafe.h | 175 + .../mass_matrix_f4_p1_q2_quadrature.h | 3429 +++++++ mass_matrix_2d/mass_matrix_f4_p1_q2_tensor.h | 3445 +++++++ mass_matrix_2d/mass_matrix_f4_p1_q3_excafe.h | 367 + .../mass_matrix_f4_p1_q3_quadrature.h | 4651 +++++++++ mass_matrix_2d/mass_matrix_f4_p1_q3_tensor.h | 4709 +++++++++ mass_matrix_2d/mass_matrix_f4_p1_q4_excafe.h | 639 ++ .../mass_matrix_f4_p1_q4_quadrature.h | 6530 +++++++++++++ mass_matrix_2d/mass_matrix_f4_p1_q4_tensor.h | 6687 +++++++++++++ mass_matrix_2d/mass_matrix_f4_p2_q1_excafe.h | 569 ++ .../mass_matrix_f4_p2_q1_quadrature.h | 3451 +++++++ mass_matrix_2d/mass_matrix_f4_p2_q1_tensor.h | 4633 +++++++++ 108 files changed, 331638 insertions(+) create mode 100644 mass_matrix_2d/mass_matrix_f1_p1_q1_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p1_q1_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p1_q1_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p1_q2_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p1_q2_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p1_q2_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p1_q3_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p1_q3_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p1_q3_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p1_q4_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p1_q4_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p1_q4_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p2_q1_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p2_q1_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p2_q1_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p2_q2_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p2_q2_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p2_q2_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p2_q3_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p2_q3_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p2_q3_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p2_q4_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p2_q4_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p2_q4_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p3_q1_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p3_q1_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p3_q1_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p3_q2_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p3_q2_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p3_q2_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p3_q3_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p3_q3_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p3_q3_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p3_q4_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p3_q4_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f1_p3_q4_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p1_q1_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p1_q1_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p1_q1_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p1_q2_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p1_q2_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p1_q2_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p1_q3_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p1_q3_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p1_q3_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p1_q4_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p1_q4_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p1_q4_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p2_q1_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p2_q1_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p2_q1_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p2_q2_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p2_q2_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p2_q2_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p2_q3_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p2_q3_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p2_q3_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p2_q4_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p2_q4_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p2_q4_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p3_q1_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p3_q1_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p3_q1_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p3_q2_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p3_q2_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p3_q2_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p3_q3_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p3_q3_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p3_q3_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p3_q4_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p3_q4_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f2_p3_q4_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f3_p1_q1_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f3_p1_q1_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f3_p1_q1_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f3_p1_q2_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f3_p1_q2_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f3_p1_q2_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f3_p1_q3_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f3_p1_q3_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f3_p1_q3_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f3_p1_q4_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f3_p1_q4_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f3_p1_q4_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f3_p2_q1_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f3_p2_q1_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f3_p2_q1_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f3_p2_q2_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f3_p2_q2_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f3_p2_q2_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f3_p2_q3_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f3_p2_q3_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f3_p2_q3_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f4_p1_q1_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f4_p1_q1_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f4_p1_q1_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f4_p1_q2_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f4_p1_q2_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f4_p1_q2_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f4_p1_q3_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f4_p1_q3_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f4_p1_q3_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f4_p1_q4_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f4_p1_q4_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f4_p1_q4_tensor.h create mode 100644 mass_matrix_2d/mass_matrix_f4_p2_q1_excafe.h create mode 100644 mass_matrix_2d/mass_matrix_f4_p2_q1_quadrature.h create mode 100644 mass_matrix_2d/mass_matrix_f4_p2_q1_tensor.h diff --git a/mass_matrix_2d/mass_matrix_f1_p1_q1_excafe.h b/mass_matrix_2d/mass_matrix_f1_p1_q1_excafe.h new file mode 100644 index 0000000..40ef240 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p1_q1_excafe.h @@ -0,0 +1,54 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 0.01 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 = -1.0000000000000000000000000*x[0][1]; + const double var_1 = x[2][1] + var_0; + const double var_2 = -1.0000000000000000000000000*x[0][0]; + const double var_3 = x[1][0] + var_2; + const double var_4 = var_0 + x[1][1]; + const double var_5 = var_2 + x[2][0]; + const double var_6 = var_1*var_3 + -1.0000000000000000000000000*var_4*var_5; + const double var_7 = std::abs(var_6); + const double var_8 = 0.0166666666666666664353702*var_7*w[0][0]; + const double var_9 = 0.0166666666666666664353702*var_7*w[0][1]; + const double var_10 = 0.0166666666666666664353702*var_7*w[0][2]; + const double var_11 = var_9 + var_10; + A[5] = 0.0083333333333333332176851*var_7*w[0][0] + var_11; + const double var_12 = var_9 + var_8; + A[1] = 0.0083333333333333332176851*var_7*w[0][2] + var_12; + A[3] = A[1]; + const double var_13 = var_10 + var_8; + A[2] = 0.0083333333333333332176851*var_7*w[0][1] + var_13; + A[6] = A[2]; + A[7] = A[5]; + A[4] = 0.0500000000000000027755576*var_7*w[0][1] + var_13; + A[8] = 0.0500000000000000027755576*var_7*w[0][2] + var_12; + A[0] = 0.0500000000000000027755576*var_7*w[0][0] + var_11; + } + + 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/mass_matrix_2d/mass_matrix_f1_p1_q1_quadrature.h b/mass_matrix_2d/mass_matrix_f1_p1_q1_quadrature.h new file mode 100644 index 0000000..24052db --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p1_q1_quadrature.h @@ -0,0 +1,1439 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P1_Q1_QUADRATURE_H +#define __MASS_MATRIX_F1_P1_Q1_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p1_q1_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p1_q1_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p1_q1_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p1_q1_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p1_q1_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p1_q1_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class mass_matrix_f1_p1_q1_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p1_q1_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // 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[6][3] = \ + {{0.109039009072877, 0.659027622374092, 0.231933368553031}, + {0.231933368553031, 0.659027622374092, 0.109039009072877}, + {0.109039009072877, 0.231933368553031, 0.659027622374092}, + {0.659027622374092, 0.231933368553031, 0.109039009072877}, + {0.231933368553031, 0.109039009072877, 0.659027622374092}, + {0.659027622374092, 0.109039009072877, 0.231933368553031}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 9; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 210 + for (unsigned int ip = 0; ip < 6; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + + // Total number of operations to compute function values = 6 + for (unsigned int r = 0; r < 3; r++) + { + F0 += FE0[ip][r]*w[0][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 2 + double I[1]; + // Number of operations: 2 + I[0] = F0*W6[ip]*det; + + + // Number of operations for primary indices: 27 + for (unsigned int j = 0; j < 3; j++) + { + for (unsigned int k = 0; k < 3; k++) + { + // Number of operations to compute entry: 3 + A[j*3 + k] += FE0[ip][j]*FE0[ip][k]*I[0]; + }// 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 mass_matrix_f1_p1_q1_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p1_q1_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p1_q1_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1))), 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 mass_matrix_f1_p1_q1_quadrature_finite_element_0(); + break; + } + case 1: + { + return new mass_matrix_f1_p1_q1_quadrature_finite_element_0(); + break; + } + case 2: + { + return new mass_matrix_f1_p1_q1_quadrature_finite_element_0(); + 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 mass_matrix_f1_p1_q1_quadrature_dofmap_0(); + break; + } + case 1: + { + return new mass_matrix_f1_p1_q1_quadrature_dofmap_0(); + break; + } + case 2: + { + return new mass_matrix_f1_p1_q1_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f1_p1_q1_tensor.h b/mass_matrix_2d/mass_matrix_f1_p1_q1_tensor.h new file mode 100644 index 0000000..909424c --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p1_q1_tensor.h @@ -0,0 +1,1402 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P1_Q1_TENSOR_H +#define __MASS_MATRIX_F1_P1_Q1_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p1_q1_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p1_q1_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p1_q1_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p1_q1_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p1_q1_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p1_q1_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class mass_matrix_f1_p1_q1_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p1_q1_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 3 + // Number of operations (multiply-add pairs) for tensor contraction: 9 + // Total number of operations (multiply-add pairs): 21 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0 = det*w[0][0]*(1.0); + const double G0_1 = det*w[0][1]*(1.0); + const double G0_2 = det*w[0][2]*(1.0); + + // Compute element tensor + A[1] = 0.0166666666666667*G0_0 + 0.0166666666666667*G0_1 + 0.00833333333333332*G0_2; + A[5] = A[1] - 0.00833333333333334*G0_0 + 0.00833333333333334*G0_2; + A[0] = A[5] + 0.0416666666666666*G0_0; + A[7] = A[5]; + A[8] = A[1] + 0.0416666666666666*G0_2; + A[3] = A[1]; + A[4] = A[1] + 0.0333333333333333*G0_1 + 0.00833333333333334*G0_2; + A[6] = A[4] - 0.0416666666666666*G0_1; + A[2] = A[6]; + } + + /// 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 mass_matrix_f1_p1_q1_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p1_q1_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p1_q1_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1))), 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 mass_matrix_f1_p1_q1_tensor_finite_element_0(); + break; + } + case 1: + { + return new mass_matrix_f1_p1_q1_tensor_finite_element_0(); + break; + } + case 2: + { + return new mass_matrix_f1_p1_q1_tensor_finite_element_0(); + 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 mass_matrix_f1_p1_q1_tensor_dofmap_0(); + break; + } + case 1: + { + return new mass_matrix_f1_p1_q1_tensor_dofmap_0(); + break; + } + case 2: + { + return new mass_matrix_f1_p1_q1_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f1_p1_q2_excafe.h b/mass_matrix_2d/mass_matrix_f1_p1_q2_excafe.h new file mode 100644 index 0000000..f4c9cba --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p1_q2_excafe.h @@ -0,0 +1,99 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 0.07 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 = -1.0000000000000000000000000*x[0][1]; + const double var_1 = x[2][1] + var_0; + const double var_2 = -1.0000000000000000000000000*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 = var_2 + x[2][0]; + const double var_6 = -1.0000000000000000000000000*var_4*var_5 + var_1*var_3; + const double var_7 = std::abs(var_6); + const double var_8 = w[0][1] + w[0][2]; + const double var_9 = 0.3333333333333333148296163*w[0][0] + var_8; + A[21] = 0.0380952380952380986744998*var_7*var_9; + const double var_10 = w[0][0] + 0.6666666666666666296592325*var_8; + A[29] = 0.0190476190476190493372499*var_10*var_7; + const double var_11 = -0.0015873015873015873002105*var_7*w[0][2]; + const double var_12 = 0.0047619047619047623343125*var_7*w[0][1]; + const double var_13 = -0.0031746031746031746004211*var_7*w[0][0]; + A[11] = var_12 + var_13 + var_11; + A[31] = A[11]; + const double var_14 = -0.0015873015873015873002105*var_7*w[0][0]; + const double var_15 = -0.0031746031746031746004211*var_7*w[0][2]; + A[9] = var_12 + var_14 + var_15; + const double var_16 = w[0][0] + w[0][1]; + const double var_17 = -1.0000000000000000000000000*var_16 + 0.2500000000000000000000000*w[0][2]; + A[1] = 0.0015873015873015873002105*var_17*var_7; + const double var_18 = 0.0047619047619047623343125*var_7*w[0][2]; + const double var_19 = 0.2500000000000000000000000*w[0][0] + -1.0000000000000000000000000*var_8; + A[8] = 0.0015873015873015873002105*var_19*var_7; + const double var_20 = -0.0015873015873015873002105*var_7*w[0][1]; + A[6] = A[1]; + const double var_21 = var_16 + 0.3333333333333333148296163*w[0][2]; + A[35] = 0.0380952380952380986744998*var_21*var_7; + const double var_22 = 0.2000000000000000111022302*var_16 + w[0][2]; + const double var_23 = w[0][0] + w[0][2]; + A[10] = -0.0047619047619047623343125*var_23*var_7 + var_20; + A[3] = var_14 + -0.0047619047619047623343125*var_7*var_8; + const double var_24 = 0.6666666666666666296592325*var_23 + w[0][1]; + A[23] = 0.0190476190476190493372499*var_24*var_7; + A[33] = A[23]; + A[14] = 0.0119047619047619041010577*var_22*var_7; + A[25] = A[10]; + const double var_25 = -0.0031746031746031746004211*var_7*w[0][1]; + const double var_26 = 0.0047619047619047623343125*var_7*w[0][0]; + A[4] = var_20 + var_26 + var_15; + A[24] = A[4]; + const double var_27 = var_23 + 0.3333333333333333148296163*w[0][1]; + const double var_28 = -1.0000000000000000000000000*var_23 + 0.2500000000000000000000000*w[0][1]; + A[2] = 0.0015873015873015873002105*var_28*var_7; + A[12] = A[2]; + const double var_29 = 0.6666666666666666296592325*var_16 + w[0][2]; + A[15] = var_14 + var_18 + var_25; + A[20] = A[15]; + const double var_30 = w[0][0] + 0.2000000000000000111022302*var_8; + A[0] = 0.0119047619047619041010577*var_30*var_7; + A[16] = var_20 + var_13 + var_18; + A[26] = A[16]; + A[18] = A[3]; + const double var_31 = 0.2000000000000000111022302*var_23 + w[0][1]; + A[7] = 0.0119047619047619041010577*var_31*var_7; + A[22] = 0.0190476190476190493372499*var_29*var_7; + A[27] = A[22]; + A[17] = -0.0047619047619047623343125*var_16*var_7 + var_11; + A[32] = A[17]; + A[34] = A[29]; + A[13] = A[8]; + A[5] = var_26 + var_11 + var_25; + A[19] = A[9]; + A[30] = A[5]; + A[28] = 0.0380952380952380986744998*var_27*var_7; + } + + 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/mass_matrix_2d/mass_matrix_f1_p1_q2_quadrature.h b/mass_matrix_2d/mass_matrix_f1_p1_q2_quadrature.h new file mode 100644 index 0000000..8769e84 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p1_q2_quadrature.h @@ -0,0 +1,3357 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P1_Q2_QUADRATURE_H +#define __MASS_MATRIX_F1_P1_Q2_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p1_q2_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p1_q2_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p1_q2_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p1_q2_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p1_q2_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p1_q2_quadrature_finite_element_1() + { + // 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p1_q2_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p1_q2_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p1_q2_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p1_q2_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p1_q2_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p1_q2_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f1_p1_q2_quadrature_dofmap_1() + { + // 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 mass_matrix_f1_p1_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 mass_matrix_f1_p1_q2_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p1_q2_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // 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[7][3] = \ + {{0.333333333333333, 0.333333333333333, 0.333333333333333}, + {0.101286507323456, 0.797426985353087, 0.101286507323456}, + {0.101286507323456, 0.101286507323456, 0.797426985353087}, + {0.797426985353087, 0.101286507323456, 0.101286507323456}, + {0.470142064105115, 0.0597158717897698, 0.470142064105115}, + {0.470142064105115, 0.470142064105115, 0.0597158717897697}, + {0.0597158717897699, 0.470142064105115, 0.470142064105115}}; + + static const double FE1[7][6] = \ + {{-0.111111111111111, -0.111111111111111, -0.111111111111111, 0.444444444444444, 0.444444444444445, 0.444444444444445}, + {-0.0807685941918873, 0.474352608585538, -0.0807685941918872, 0.323074376767549, 0.0410358262631383, 0.323074376767549}, + {-0.0807685941918872, -0.0807685941918872, 0.474352608585538, 0.323074376767549, 0.323074376767549, 0.0410358262631384}, + {0.474352608585539, -0.0807685941918872, -0.0807685941918872, 0.0410358262631384, 0.323074376767549, 0.323074376767549}, + {-0.0280749432230787, -0.0525839011025453, -0.0280749432230789, 0.112299772892315, 0.884134241764073, 0.112299772892315}, + {-0.0280749432230787, -0.0280749432230788, -0.0525839011025453, 0.112299772892315, 0.112299772892315, 0.884134241764073}, + {-0.0525839011025454, -0.0280749432230788, -0.0280749432230788, 0.884134241764072, 0.112299772892315, 0.112299772892315}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 36; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 812 + for (unsigned int ip = 0; ip < 7; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + + // Total number of operations to compute function values = 6 + for (unsigned int r = 0; r < 3; r++) + { + F0 += FE0[ip][r]*w[0][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 2 + double I[1]; + // Number of operations: 2 + I[0] = F0*W7[ip]*det; + + + // Number of operations for primary indices: 108 + for (unsigned int j = 0; j < 6; j++) + { + for (unsigned int k = 0; k < 6; k++) + { + // Number of operations to compute entry: 3 + A[j*6 + k] += FE1[ip][j]*FE1[ip][k]*I[0]; + }// 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 mass_matrix_f1_p1_q2_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p1_q2_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p1_q2_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1))), 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 mass_matrix_f1_p1_q2_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p1_q2_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p1_q2_quadrature_finite_element_0(); + 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 mass_matrix_f1_p1_q2_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p1_q2_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p1_q2_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f1_p1_q2_tensor.h b/mass_matrix_2d/mass_matrix_f1_p1_q2_tensor.h new file mode 100644 index 0000000..f38c539 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p1_q2_tensor.h @@ -0,0 +1,3337 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P1_Q2_TENSOR_H +#define __MASS_MATRIX_F1_P1_Q2_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p1_q2_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p1_q2_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p1_q2_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p1_q2_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p1_q2_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p1_q2_tensor_finite_element_1() + { + // 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p1_q2_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p1_q2_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p1_q2_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p1_q2_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p1_q2_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p1_q2_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f1_p1_q2_tensor_dofmap_1() + { + // 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 mass_matrix_f1_p1_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 mass_matrix_f1_p1_q2_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p1_q2_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 3 + // Number of operations (multiply-add pairs) for tensor contraction: 38 + // Total number of operations (multiply-add pairs): 50 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0 = det*w[0][0]*(1.0); + const double G0_1 = det*w[0][1]*(1.0); + const double G0_2 = det*w[0][2]*(1.0); + + // Compute element tensor + A[9] = -0.00158730158730159*G0_0 + 0.00476190476190476*G0_1 - 0.00317460317460318*G0_2; + A[18] = A[9] - 0.00952380952380952*G0_1 - 0.00158730158730159*G0_2; + A[20] = A[9] - 0.00793650793650793*G0_1 + 0.00793650793650793*G0_2; + A[31] = A[9] - 0.00158730158730158*G0_0 + 0.00158730158730159*G0_2; + A[13] = A[31] + 0.00357142857142857*G0_0 - 0.00634920634920635*G0_1; + A[3] = A[18]; + A[17] = -A[9] - 0.00634920634920635*G0_0 - 0.00476190476190476*G0_2; + A[24] = A[9] + 0.00634920634920635*G0_0 - 0.00634920634920635*G0_1; + A[8] = A[13]; + A[21] = -8*A[18]; + A[28] = A[21] + 0.0253968253968254*G0_0 - 0.0253968253968254*G0_1; + A[11] = A[31]; + A[30] = A[31] + 0.00793650793650793*G0_0 - 0.00793650793650794*G0_1; + A[4] = A[24]; + A[25] = -0.125*A[28]; + A[14] = 0.00238095238095238*G0_0 + 0.00238095238095238*G0_1 + 0.0119047619047619*G0_2; + A[7] = A[14] + 0.00952380952380952*G0_1 - 0.00952380952380951*G0_2; + A[0] = A[14] + 0.00952380952380953*G0_0 - 0.00952380952380951*G0_2; + A[10] = A[25]; + A[5] = A[30]; + A[26] = -A[18] - 0.00476190476190476*G0_0 - 0.00634920634920635*G0_1; + A[6] = A[9] - 0.00634920634920635*G0_1 + 0.00357142857142857*G0_2; + A[1] = A[6]; + A[35] = -8*A[17]; + A[34] = A[35] - 0.0190476190476191*G0_0 - 0.0253968253968254*G0_1; + A[29] = A[34]; + A[23] = A[21] - 0.019047619047619*G0_1 - 0.0253968253968254*G0_2; + A[33] = A[23]; + A[19] = A[9]; + A[16] = A[26]; + A[27] = A[21] - 0.0253968253968254*G0_1 - 0.019047619047619*G0_2; + A[22] = A[27]; + A[15] = A[20]; + A[32] = A[17]; + A[2] = A[9] - 0.00436507936507936*G0_1 + 0.00158730158730159*G0_2; + A[12] = A[2]; + } + + /// 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 mass_matrix_f1_p1_q2_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p1_q2_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p1_q2_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1))), 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 mass_matrix_f1_p1_q2_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p1_q2_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p1_q2_tensor_finite_element_0(); + 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 mass_matrix_f1_p1_q2_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p1_q2_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p1_q2_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f1_p1_q3_excafe.h b/mass_matrix_2d/mass_matrix_f1_p1_q3_excafe.h new file mode 100644 index 0000000..bd21306 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p1_q3_excafe.h @@ -0,0 +1,182 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 0.34 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 = -1.0000000000000000000000000*x[0][1]; + const double var_1 = x[2][1] + var_0; + const double var_2 = -1.0000000000000000000000000*x[0][0]; + const double var_3 = x[1][0] + var_2; + const double var_4 = var_0 + x[1][1]; + const double var_5 = var_2 + x[2][0]; + const double var_6 = -1.0000000000000000000000000*var_4*var_5 + var_1*var_3; + const double var_7 = std::abs(var_6); + const double var_8 = w[0][0] + w[0][1]; + const double var_9 = 0.1428571428571428492126927*var_8 + w[0][2]; + A[4] = 0.0015625000000000000867362*var_7*var_9; + A[40] = A[4]; + const double var_10 = -0.0008928571428571428292634*var_7*w[0][1]; + const double var_11 = -0.0004464285714285714146317*var_7*w[0][0]; + const double var_12 = 0.0026785714285714285962103*var_7*w[0][2]; + A[24] = var_11 + var_12 + var_10; + A[42] = A[24]; + const double var_13 = w[0][1] + w[0][2]; + const double var_14 = w[0][0] + 0.1428571428571428492126927*var_13; + A[15] = 0.0015625000000000000867362*var_14*var_7; + A[61] = A[4]; + const double var_15 = -0.0008928571428571428292634*var_7*w[0][0]; + const double var_16 = 0.0120535714285714273819039*var_7*w[0][0]; + A[57] = 0.0040178571428571424606346*var_13*var_7 + var_16; + const double var_17 = -0.0004464285714285714146317*var_7*w[0][1]; + A[26] = var_12 + var_15 + var_17; + const double var_18 = 0.0120535714285714273819039*var_7*w[0][1]; + const double var_19 = 0.0040178571428571424606346*var_7*w[0][2]; + const double var_20 = 0.0241071428571428547638078*var_7*w[0][0]; + A[77] = var_20 + var_19 + var_18; + const double var_21 = -0.0020089285714285712303173*var_7*var_8; + A[36] = var_21 + -0.0060267857142857136909520*var_7*w[0][2]; + A[54] = A[36]; + const double var_22 = 0.0002232142857142857073158*var_7*w[0][0]; + const double var_23 = 0.0011160714285714285094742*var_7*w[0][2]; + const double var_24 = -0.0013392857142857142981052*var_7*w[0][1]; + A[14] = var_24 + var_22 + var_23; + const double var_25 = 0.2000000000000000111022302*w[0][0] + var_13; + A[12] = 0.0003720238095238095031581*var_25*var_7; + const double var_26 = 0.0241071428571428547638078*var_7*w[0][1]; + A[88] = var_26 + var_16 + var_19; + const double var_27 = w[0][0] + w[0][2]; + const double var_28 = 0.2000000000000000111022302*w[0][1] + var_27; + A[39] = var_18; + A[89] = A[39]; + A[19] = 0.0013392857142857142981052*var_27*var_7; + const double var_29 = -0.0020089285714285712303173*var_27*var_7; + A[37] = var_29 + -0.0060267857142857136909520*var_7*w[0][1]; + A[62] = A[26]; + const double var_30 = -0.0008928571428571428292634*var_7*w[0][2]; + const double var_31 = 0.0026785714285714285962103*var_7*w[0][1]; + A[13] = var_11 + var_31 + var_30; + const double var_32 = w[0][0] + 3.0000000000000000000000000*var_13; + A[34] = -0.0020089285714285712303173*var_32*var_7; + A[43] = A[34]; + const double var_33 = w[0][1] + 3.0000000000000000000000000*var_27; + A[16] = A[4]; + A[56] = -0.0020089285714285712303173*var_33*var_7; + A[9] = 0.0013392857142857142981052*var_13*var_7; + const double var_34 = var_8 + 0.2000000000000000111022302*w[0][2]; + A[1] = 0.0003720238095238095031581*var_34*var_7; + A[10] = A[1]; + const double var_35 = -0.0020089285714285712303173*var_13*var_7; + A[58] = -0.0060267857142857136909520*var_7*w[0][0] + var_35; + A[67] = A[58]; + const double var_36 = 0.0120535714285714273819039*var_7*w[0][2]; + A[49] = var_36; + const double var_37 = w[0][1] + 0.1428571428571428492126927*var_27; + const double var_38 = 0.0011160714285714285094742*var_7*w[0][1]; + const double var_39 = -0.0013392857142857142981052*var_7*w[0][2]; + A[23] = var_39 + var_22 + var_38; + A[32] = A[23]; + A[21] = A[12]; + A[59] = var_16; + A[95] = A[59]; + A[29] = 0.0013392857142857142981052*var_7*var_8; + A[98] = A[39]; + A[22] = 0.0044642857142857140378966*var_7*w[0][2] + 0.0005952380952380952917891*var_7*var_8; + const double var_40 = 0.0002232142857142857073158*var_7*w[0][1]; + const double var_41 = 0.0011160714285714285094742*var_7*w[0][0]; + A[25] = var_39 + var_41 + var_40; + A[52] = A[25]; + const double var_42 = 3.0000000000000000000000000*var_8 + w[0][2]; + A[84] = A[37]; + const double var_43 = -0.0013392857142857142981052*var_7*w[0][0]; + A[6] = var_40 + var_43 + var_23; + const double var_44 = 0.0040178571428571424606346*var_7*w[0][0]; + const double var_45 = 0.0241071428571428547638078*var_7*w[0][2]; + A[44] = var_45 + var_44 + var_18; + const double var_46 = w[0][1] + var_27; + A[3] = 0.0015625000000000000867362*var_37*var_7; + A[30] = A[3]; + A[51] = A[15]; + A[94] = A[49]; + A[60] = A[6]; + A[46] = var_36 + 0.0040178571428571424606346*var_7*var_8; + A[64] = A[46]; + A[97] = A[59]; + A[68] = var_35; + A[38] = var_18 + 0.0040178571428571424606346*var_27*var_7; + A[83] = A[38]; + const double var_47 = -0.0004464285714285714146317*var_7*w[0][2]; + A[18] = var_31 + var_15 + var_47; + A[81] = A[18]; + A[28] = A[3]; + const double var_48 = 0.0026785714285714285962103*var_7*w[0][0]; + A[7] = var_47 + var_48 + var_10; + A[48] = A[37]; + A[78] = -0.0020089285714285712303173*var_42*var_7; + A[72] = A[15]; + const double var_49 = 0.0040178571428571424606346*var_7*w[0][1]; + A[66] = var_49 + var_16 + var_45; + A[31] = A[13]; + A[96] = A[49]; + A[45] = A[36]; + A[86] = A[68]; + A[2] = 0.0003720238095238095031581*var_28*var_7; + A[93] = A[39]; + A[35] = var_21; + A[53] = A[35]; + A[47] = var_29; + A[74] = A[47]; + A[27] = A[15]; + A[41] = A[14]; + A[55] = var_49 + var_20 + var_36; + A[90] = A[9]; + const double var_50 = 0.0002232142857142857073158*var_7*w[0][2]; + A[17] = var_41 + var_24 + var_50; + A[73] = A[37]; + A[79] = A[59]; + A[11] = 0.0044642857142857140378966*var_7*w[0][1] + 0.0005952380952380952917891*var_27*var_7; + A[0] = 0.0005952380952380952917891*var_13*var_7 + 0.0044642857142857140378966*var_7*w[0][0]; + A[69] = A[49]; + A[85] = A[58]; + A[8] = var_38 + var_50 + var_43; + A[76] = A[58]; + A[80] = A[8]; + A[75] = A[57]; + A[92] = A[29]; + A[5] = var_17 + var_30 + var_48; + A[50] = A[5]; + A[99] = 0.0482142857142857095276156*var_46*var_7; + A[70] = A[7]; + A[71] = A[17]; + A[63] = A[36]; + A[65] = A[56]; + A[33] = var_26 + var_36 + var_44; + A[91] = A[19]; + A[82] = A[3]; + A[87] = A[78]; + A[20] = 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/mass_matrix_2d/mass_matrix_f1_p1_q3_quadrature.h b/mass_matrix_2d/mass_matrix_f1_p1_q3_quadrature.h new file mode 100644 index 0000000..86883c0 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p1_q3_quadrature.h @@ -0,0 +1,4575 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P1_Q3_QUADRATURE_H +#define __MASS_MATRIX_F1_P1_Q3_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p1_q3_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p1_q3_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p1_q3_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p1_q3_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p1_q3_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p1_q3_quadrature_finite_element_1() + { + // 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p1_q3_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p1_q3_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p1_q3_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p1_q3_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p1_q3_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p1_q3_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f1_p1_q3_quadrature_dofmap_1() + { + // 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.0*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 mass_matrix_f1_p1_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 mass_matrix_f1_p1_q3_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p1_q3_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Array of quadrature weights. + static const double W16[16] = {0.0235683681933823, 0.0353880678980859, 0.0225840492823699, 0.00542322591052525, 0.0441850885223617, 0.0663442161070497, 0.0423397245217463, 0.0101672595644788, 0.0441850885223617, 0.0663442161070497, 0.0423397245217463, 0.0101672595644788, 0.0235683681933823, 0.0353880678980859, 0.0225840492823699, 0.00542322591052525}; + // Quadrature points on the UFC reference element: (0.0654669945550145, 0.0571041961145177), (0.0502101232113698, 0.276843013638124), (0.028912084224389, 0.583590432368917), (0.00970378512694614, 0.860240135656219), (0.311164552244357, 0.0571041961145177), (0.238648659731443, 0.276843013638124), (0.137419104134574, 0.583590432368917), (0.0461220799064521, 0.860240135656219), (0.631731251641125, 0.0571041961145177), (0.484508326630433, 0.276843013638124), (0.278990463496509, 0.583590432368917), (0.0936377844373285, 0.860240135656219), (0.877428809330468, 0.0571041961145177), (0.672946863150506, 0.276843013638124), (0.387497483406694, 0.583590432368917), (0.130056079216834, 0.860240135656219) + + // Value of basis functions at quadrature points. + static const double FE0[16][3] = \ + {{0.877428809330468, 0.0654669945550145, 0.0571041961145176}, + {0.672946863150506, 0.0502101232113698, 0.276843013638124}, + {0.387497483406694, 0.028912084224389, 0.583590432368917}, + {0.130056079216834, 0.0097037851269462, 0.860240135656219}, + {0.631731251641125, 0.311164552244357, 0.0571041961145176}, + {0.484508326630433, 0.238648659731443, 0.276843013638124}, + {0.278990463496509, 0.137419104134574, 0.583590432368917}, + {0.0936377844373285, 0.0461220799064521, 0.860240135656219}, + {0.311164552244357, 0.631731251641125, 0.0571041961145176}, + {0.238648659731443, 0.484508326630433, 0.276843013638124}, + {0.137419104134574, 0.278990463496509, 0.583590432368917}, + {0.046122079906452, 0.0936377844373286, 0.860240135656219}, + {0.0654669945550144, 0.877428809330468, 0.0571041961145176}, + {0.0502101232113698, 0.672946863150506, 0.276843013638124}, + {0.0289120842243889, 0.387497483406694, 0.583590432368917}, + {0.00970378512694603, 0.130056079216835, 0.860240135656219}}; + + static const double FE1[16][10] = \ + {{0.452785096544088, 0.0474429618915808, 0.0432681417093322, -0.0135189305273306, -0.0139409921109051, 0.368034723276116, -0.186845725726384, 0.421932692589788, -0.207723773787635, 0.0885658061413495}, + {0.00645879502307897, 0.0394349905858879, 0.0274339473899979, -0.0531293004470149, -0.01060065392075, 0.854147931483282, -0.142076464805357, 0.1549140515302, -0.129146101999649, 0.252562805160324}, + {-0.0263670054419039, 0.0252592508316564, -0.0545988990428341, -0.0693419891600489, 0.0570043158923523, 0.165357063338021, 0.764006800069202, 0.00819207628699473, -0.0460423009076122, 0.176530688134173}, + {0.0638397523745609, 0.00928416145919281, 0.394831554211582, -0.0364705915852906, 0.0593783938998503, -0.307024415063853, 0.795825649453315, -0.00346333404943191, -0.00551383497665217, 0.0293126642767273}, + {-0.0296351119176843, 0.0110353632465608, 0.0432681417093322, -0.00531782108849545, -0.0662615199844949, 0.145321523295419, -0.134525197852795, 0.791866619346228, -0.0588298934372821, 0.303077896683211}, + {-0.0600402894008985, 0.0435224405021434, 0.0274339473899979, -0.0844512384591529, -0.0503848962850379, 0.273746477720596, -0.102292222441069, 0.235979334120451, -0.147799750082178, 0.864286196935148}, + {0.0264492636219917, 0.0641186652464314, -0.0545988990428341, -0.212107011291982, 0.270941449981089, -0.119446618596469, 0.550069665980465, -0.0281263132652844, -0.101399594834004, 0.604099392200595}, + {0.0578762154363197, 0.0369909803572857, 0.394831554211582, -0.153838064046657, 0.282225440107984, -0.260654104682365, 0.572978603245181, -0.0139750622480945, -0.0167453887378413, 0.100309826356606}, + {0.0110353632465609, -0.0296351119176843, 0.0432681417093322, 0.145321523295419, -0.134525197852795, -0.00531782108849545, -0.0662615199844949, -0.0588298934372824, 0.791866619346228, 0.303077896683211}, + {0.0435224405021434, -0.0600402894008985, 0.0274339473899979, 0.273746477720596, -0.102292222441069, -0.0844512384591529, -0.050384896285038, -0.147799750082179, 0.235979334120451, 0.864286196935148}, + {0.0641186652464314, 0.0264492636219917, -0.0545988990428341, -0.119446618596469, 0.550069665980465, -0.212107011291982, 0.270941449981089, -0.101399594834004, -0.0281263132652843, 0.604099392200595}, + {0.0369909803572857, 0.0578762154363197, 0.394831554211582, -0.260654104682365, 0.572978603245181, -0.153838064046657, 0.282225440107983, -0.0167453887378415, -0.0139750622480942, 0.100309826356606}, + {0.0474429618915808, 0.452785096544089, 0.0432681417093322, 0.368034723276116, -0.186845725726384, -0.0135189305273307, -0.0139409921109051, -0.207723773787635, 0.421932692589788, 0.0885658061413495}, + {0.039434990585888, 0.00645879502307895, 0.0274339473899979, 0.854147931483282, -0.142076464805357, -0.0531293004470149, -0.0106006539207499, -0.129146101999649, 0.1549140515302, 0.252562805160324}, + {0.0252592508316564, -0.0263670054419039, -0.0545988990428341, 0.165357063338021, 0.764006800069202, -0.0693419891600489, 0.0570043158923523, -0.0460423009076123, 0.00819207628699494, 0.176530688134173}, + {0.00928416145919272, 0.063839752374561, 0.394831554211582, -0.307024415063853, 0.795825649453315, -0.0364705915852904, 0.0593783938998497, -0.00551383497665229, -0.00346333404943161, 0.0293126642767269}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 100; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 4928 + for (unsigned int ip = 0; ip < 16; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + + // Total number of operations to compute function values = 6 + for (unsigned int r = 0; r < 3; r++) + { + F0 += FE0[ip][r]*w[0][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 2 + double I[1]; + // Number of operations: 2 + I[0] = F0*W16[ip]*det; + + + // Number of operations for primary indices: 300 + for (unsigned int j = 0; j < 10; j++) + { + for (unsigned int k = 0; k < 10; k++) + { + // Number of operations to compute entry: 3 + A[j*10 + k] += FE1[ip][j]*FE1[ip][k]*I[0]; + }// 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 mass_matrix_f1_p1_q3_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p1_q3_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p1_q3_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1))), 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 mass_matrix_f1_p1_q3_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p1_q3_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p1_q3_quadrature_finite_element_0(); + 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 mass_matrix_f1_p1_q3_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p1_q3_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p1_q3_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f1_p1_q3_tensor.h b/mass_matrix_2d/mass_matrix_f1_p1_q3_tensor.h new file mode 100644 index 0000000..4cdbb02 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p1_q3_tensor.h @@ -0,0 +1,4601 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P1_Q3_TENSOR_H +#define __MASS_MATRIX_F1_P1_Q3_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p1_q3_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p1_q3_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p1_q3_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p1_q3_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p1_q3_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p1_q3_tensor_finite_element_1() + { + // 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p1_q3_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p1_q3_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p1_q3_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p1_q3_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p1_q3_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p1_q3_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f1_p1_q3_tensor_dofmap_1() + { + // 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.0*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 mass_matrix_f1_p1_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 mass_matrix_f1_p1_q3_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p1_q3_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 3 + // Number of operations (multiply-add pairs) for tensor contraction: 67 + // Total number of operations (multiply-add pairs): 79 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0 = det*w[0][0]*(1.0); + const double G0_1 = det*w[0][1]*(1.0); + const double G0_2 = det*w[0][2]*(1.0); + + // Compute element tensor + A[73] = -0.00200892857142857*G0_0 - 0.00602678571428571*G0_1 - 0.00200892857142857*G0_2; + A[69] = 0.0120535714285714*G0_2; + A[7] = 0.00267857142857142*G0_0 - 0.000892857142857144*G0_1 - 0.000446428571428572*G0_2; + A[37] = A[73]; + A[11] = 0.000595238095238095*G0_0 + 0.00446428571428571*G0_1 + 0.000595238095238094*G0_2; + A[93] = 0.0120535714285714*G0_1; + A[1] = 0.00037202380952381*G0_0 + 0.00037202380952381*G0_1 + 7.44047619047619e-05*G0_2; + A[99] = 0.0482142857142857*G0_0 + 0.0482142857142857*G0_1 + 0.0482142857142857*G0_2; + A[78] = A[73] - 0.00401785714285713*G0_0; + A[85] = A[78] + 0.00401785714285714*G0_1; + A[58] = A[85]; + A[67] = A[85]; + A[76] = A[85]; + A[75] = -2.0*A[85]; + A[21] = A[1] - 0.000297619047619048*G0_0 + 0.000297619047619048*G0_2; + A[89] = A[93]; + A[94] = A[69]; + A[22] = A[11] - 0.00386904761904761*G0_1 + 0.00386904761904762*G0_2; + A[86] = A[85] + 0.00602678571428571*G0_0; + A[90] = -0.666666666666668*A[86]; + A[25] = -A[90] + 0.00111607142857143*G0_0 + 0.0015625*G0_1; + A[16] = A[25] - 0.000892857142857143*G0_0 + 0.00290178571428571*G0_2; + A[40] = A[16]; + A[4] = A[16]; + A[32] = -A[90] + 0.000223214285714285*G0_0 + 0.00245535714285714*G0_1; + A[82] = A[16] + 0.00133928571428571*G0_1 - 0.00133928571428571*G0_2; + A[51] = A[25] + 0.000446428571428571*G0_0 + 0.0015625*G0_2; + A[72] = A[51]; + A[15] = A[51]; + A[41] = -A[90] + 0.000223214285714286*G0_0 + 0.00245535714285714*G0_2; + A[97] = 0.0120535714285714*G0_0; + A[71] = -A[90] + 0.00111607142857143*G0_0 + 0.0015625*G0_2; + A[5] = A[7] + 0.000446428571428572*G0_1 - 0.000446428571428571*G0_2; + A[26] = A[5] - 0.00357142857142857*G0_0 + 0.00357142857142857*G0_2; + A[31] = A[5] - 0.003125*G0_0 + 0.003125*G0_1; + A[10] = A[1]; + A[27] = A[51]; + A[83] = -2*A[73]; + A[61] = A[16]; + A[57] = A[75]; + A[74] = A[73] + 0.00602678571428571*G0_1; + A[2] = A[1] - 0.000297619047619048*G0_1 + 0.000297619047619047*G0_2; + A[13] = A[31]; + A[48] = A[73]; + A[30] = A[82]; + A[28] = A[82]; + A[98] = A[93]; + A[62] = A[26]; + A[50] = A[5]; + A[14] = A[41]; + A[39] = A[93]; + A[23] = A[32]; + A[19] = -0.666666666666666*A[74]; + A[60] = -A[19] + 0.000223214285714284*G0_1 + 0.00245535714285714*G0_2; + A[8] = -A[19] + 0.00111607142857143*G0_1 + 0.0015625*G0_2; + A[80] = A[8]; + A[87] = A[78]; + A[42] = A[7] - 0.00312499999999999*G0_0 + 0.003125*G0_2; + A[96] = A[69]; + A[65] = A[85] - 0.00401785714285715*G0_2; + A[45] = A[65] + 0.00401785714285714*G0_0; + A[36] = A[45]; + A[64] = -2.0*A[45]; + A[55] = A[64] + 0.0200892857142857*G0_0; + A[54] = A[45]; + A[35] = A[45] + 0.00602678571428572*G0_2; + A[46] = A[64]; + A[92] = -0.666666666666666*A[35]; + A[53] = A[35]; + A[70] = A[7]; + A[68] = A[86]; + A[6] = A[60]; + A[17] = A[71]; + A[9] = A[90]; + A[34] = A[73] - 0.00401785714285715*G0_2; + A[24] = A[42]; + A[84] = A[73]; + A[59] = A[97]; + A[47] = A[74]; + A[91] = A[19]; + A[66] = A[75] + 0.0200892857142857*G0_2; + A[56] = A[65]; + A[77] = A[83] + 0.0200892857142857*G0_0; + A[3] = A[82]; + A[12] = A[21]; + A[49] = A[69]; + A[33] = A[64] + 0.0200892857142857*G0_1; + A[29] = A[92]; + A[81] = A[7] - 0.00357142857142857*G0_0 + 0.00357142857142857*G0_1; + A[44] = A[83] + 0.0200892857142857*G0_2; + A[63] = A[45]; + A[0] = A[11] + 0.00386904761904761*G0_0 - 0.00386904761904761*G0_1; + A[79] = A[97]; + A[38] = A[83]; + A[20] = A[2]; + A[18] = A[81]; + A[88] = A[75] + 0.0200892857142857*G0_1; + A[43] = A[34]; + A[95] = A[97]; + A[52] = A[25]; + } + + /// 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 mass_matrix_f1_p1_q3_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p1_q3_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p1_q3_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1))), 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 mass_matrix_f1_p1_q3_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p1_q3_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p1_q3_tensor_finite_element_0(); + 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 mass_matrix_f1_p1_q3_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p1_q3_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p1_q3_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f1_p1_q4_excafe.h b/mass_matrix_2d/mass_matrix_f1_p1_q4_excafe.h new file mode 100644 index 0000000..8c6d70c --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p1_q4_excafe.h @@ -0,0 +1,399 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 0.81 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][0] + w[0][2]; + const double var_1 = 0.4444444444444444197728217*w[0][1] + var_0; + const double var_2 = -1.0000000000000000000000000*x[0][1]; + const double var_3 = x[2][1] + var_2; + const double var_4 = -1.0000000000000000000000000*x[0][0]; + const double var_5 = x[1][0] + var_4; + const double var_6 = var_2 + x[1][1]; + const double var_7 = var_4 + x[2][0]; + const double var_8 = -1.0000000000000000000000000*var_6*var_7 + var_3*var_5; + const double var_9 = std::abs(var_8); + const double var_10 = -0.0000684089572978461906913*var_9*w[0][0]; + const double var_11 = 0.0005772005772005772000766*var_9*w[0][1]; + const double var_12 = -0.0005087916199027310093853*var_9*w[0][2]; + A[20] = var_12 + var_10 + var_11; + A[76] = A[20]; + const double var_13 = -0.0003719737053070386822128*var_9*w[0][0]; + const double var_14 = -0.0009106942440275774203542*var_9*w[0][1]; + const double var_15 = -0.0001282667949334615939937*var_9*w[0][2]; + A[43] = var_15 + var_13 + var_14; + const double var_16 = 0.0006840895729784619069130*var_9*w[0][1]; + const double var_17 = 0.0007182940516273849480486*var_9*w[0][0]; + const double var_18 = 0.0031126075570520011885634*var_9*w[0][2]; + A[53] = var_16 + var_18 + var_17; + A[123] = A[53]; + const double var_19 = w[0][1] + w[0][2]; + const double var_20 = var_19 + 0.4444444444444444197728217*w[0][0]; + A[12] = 0.0005772005772005772000766*var_20*var_9; + A[180] = A[12]; + const double var_21 = 0.0002308802308802308800306*var_9*w[0][2]; + A[17] = 0.0000163005718561274130492*var_9*w[0][0] + -0.0001271979049756827523463*var_19*var_9; + const double var_22 = w[0][0] + w[0][1]; + A[32] = 0.0002004168670835337711083*var_22*var_9 + 0.0021564854898188231743794*var_9*w[0][2]; + const double var_23 = -0.0001539201539201539290554*var_9*w[0][0]; + const double var_24 = 0.0056180856180856183698658*var_9*w[0][2]; + const double var_25 = -1.0000000000000000000000000*w[0][1]; + const double var_26 = 0.0020779220779220779202756*var_25*var_9; + A[73] = var_23 + var_24 + var_26; + const double var_27 = 0.0006840895729784619069130*var_9*w[0][2]; + A[146] = 0.0030441985997541553231327*var_22*var_9 + var_27; + A[174] = A[146]; + const double var_28 = 0.0018598685265351930315930*var_9*w[0][0]; + const double var_29 = -0.0002992891881780770707219*var_9*w[0][2]; + const double var_30 = -0.0001496445940890385353610*var_9*w[0][1]; + A[6] = var_29 + var_30 + var_28; + const double var_31 = var_22 + 1.1428571428571427937015414*w[0][2]; + A[51] = 0.0007182940516273849480486*var_31*var_9; + const double var_32 = 0.0007182940516273849480486*var_9*w[0][2]; + const double var_33 = 0.0031126075570520011885634*var_9*w[0][0]; + A[101] = var_33 + var_16 + var_32; + A[171] = A[101]; + const double var_34 = 0.0002052268718935385720739*var_9*w[0][1]; + const double var_35 = -0.0000684089572978461906913*var_9*w[0][2]; + const double var_36 = -0.0006755384533162311737342*var_9*w[0][1]; + const double var_37 = -0.0002437069103735770611140*var_9*w[0][0]; + A[41] = var_35 + var_36 + var_37; + A[167] = A[41]; + const double var_38 = 0.0006840895729784619069130*var_9*w[0][0]; + A[50] = var_38 + 0.0030441985997541553231327*var_19*var_9; + const double var_39 = 0.0017102239324461546588624*var_9*w[0][2]; + const double var_40 = 0.0051306717973384641934276*var_9*w[0][0]; + const double var_41 = 0.0157340601785046253768829*var_9*w[0][1]; + A[176] = var_40 + var_41 + var_39; + const double var_42 = -0.0012570145903479236319800*var_9*w[0][2]; + const double var_43 = -0.0064133397466730806754653*var_9*w[0][1]; + const double var_44 = -0.0036171236171236172650401*var_9*w[0][0]; + A[161] = var_42 + var_44 + var_43; + A[175] = A[161]; + A[0] = 0.0021564854898188231743794*var_9*w[0][0] + 0.0002004168670835337711083*var_19*var_9; + const double var_45 = 0.0005130671797338463759747*var_9*w[0][2]; + const double var_46 = 0.0001122334455667789015207*var_9*w[0][1]; + const double var_47 = -0.0013307679974346640038030*var_9*w[0][0]; + A[7] = var_47 + var_45 + var_46; + A[105] = A[7]; + A[193] = -0.0036940836940836940804900*var_22*var_9 + -0.0061568061568061565116960*var_9*w[0][2]; + A[207] = A[193]; + const double var_48 = -0.0005087916199027310093853*var_9*w[0][0]; + const double var_49 = 0.0006669873336540003321352*var_9*w[0][0]; + const double var_50 = 0.0002308802308802308800306*var_9*w[0][1]; + const double var_51 = -1.0000000000000000000000000*w[0][2]; + const double var_52 = 0.0003334936668270001660676*var_51*var_9; + A[52] = var_49 + var_52 + var_50; + A[108] = A[52]; + const double var_53 = 0.0020779220779220779202756*var_51*var_9; + const double var_54 = -0.0002437069103735770611140*var_9*w[0][2]; + const double var_55 = 0.0005130671797338463759747*var_9*w[0][1]; + const double var_56 = 0.0017102239324461546588624*var_9*w[0][0]; + const double var_57 = 0.0051306717973384641934276*var_9*w[0][2]; + A[48] = var_56 + var_41 + var_57; + const double var_58 = -0.0019496552829886164889123*var_9*w[0][0]; + const double var_59 = -0.0006755384533162311737342*var_9*w[0][0]; + const double var_60 = -0.0002437069103735770611140*var_9*w[0][1]; + A[39] = var_35 + var_59 + var_60; + A[137] = A[39]; + const double var_61 = -0.0001496445940890385353610*var_9*w[0][2]; + const double var_62 = -0.0002992891881780770707219*var_9*w[0][1]; + A[9] = var_61 + var_62 + var_28; + A[135] = A[9]; + const double var_63 = -0.0001539201539201539290554*var_9*w[0][2]; + A[70] = -0.0005002405002405002762064*var_0*var_9 + 0.0014237614237614239047491*var_9*w[0][1]; + A[154] = A[70]; + A[98] = 0.0030441985997541553231327*var_0*var_9 + var_16; + const double var_64 = -0.0002992891881780770707219*var_9*w[0][0]; + const double var_65 = 0.0018598685265351930315930*var_9*w[0][1]; + A[26] = var_64 + var_61 + var_65; + const double var_66 = -0.0012570145903479236319800*var_9*w[0][0]; + const double var_67 = -0.0013083213083213084647338*var_9*w[0][2]; + const double var_68 = -0.0059002725669392332152885*var_9*w[0][1]; + A[55] = var_66 + var_67 + var_68; + const double var_69 = var_19 + 0.2000000000000000111022302*w[0][0]; + A[4] = -0.0000481000481000480977476*var_69*var_9; + A[60] = A[4]; + const double var_70 = 0.0010261343594676927519493*var_9*w[0][0]; + const double var_71 = 0.0031810165143498479213557*var_9*w[0][2]; + const double var_72 = -0.0019496552829886164889123*var_9*w[0][1]; + A[59] = var_72 + var_70 + var_71; + A[213] = A[59]; + const double var_73 = -0.0013307679974346640038030*var_9*w[0][2]; + const double var_74 = 0.0005130671797338463759747*var_9*w[0][0]; + A[37] = var_74 + var_46 + var_73; + A[107] = A[37]; + const double var_75 = var_19 + 1.1428571428571427937015414*w[0][0]; + A[131] = 0.0007182940516273849480486*var_75*var_9; + A[173] = A[131]; + const double var_76 = -1.0000000000000000000000000*w[0][0]; + const double var_77 = 0.0003334936668270001660676*var_76*var_9; + const double var_78 = -0.0064133397466730806754653*var_9*w[0][0]; + const double var_79 = -0.0036171236171236172650401*var_9*w[0][1]; + A[145] = var_79 + var_42 + var_78; + A[28] = 0.0005772005772005772000766*var_1*var_9; + A[196] = A[28]; + A[31] = A[17]; + A[209] = -0.0061568061568061565116960*var_9*w[0][0] + -0.0036940836940836940804900*var_19*var_9; + A[223] = A[209]; + A[1] = -0.0001271979049756827523463*var_22*var_9 + 0.0000163005718561274130492*var_9*w[0][2]; + const double var_80 = -0.0005087916199027310093853*var_9*w[0][1]; + A[164] = -0.0026936026936026937449176*var_22*var_9 + -0.0013852813852813852801837*var_9*w[0][2]; + A[220] = A[164]; + const double var_81 = -0.0001282667949334615939937*var_9*w[0][1]; + const double var_82 = -0.0009106942440275774203542*var_9*w[0][2]; + A[29] = var_82 + var_81 + var_13; + const double var_83 = -0.0064133397466730806754653*var_9*w[0][2]; + A[65] = var_66 + var_83 + var_79; + const double var_84 = -0.0013083213083213084647338*var_9*w[0][1]; + const double var_85 = -0.0059002725669392332152885*var_9*w[0][2]; + A[82] = var_66 + var_85 + var_84; + const double var_86 = 0.0001122334455667789015207*var_9*w[0][0]; + const double var_87 = -0.0001026134359467692860370*var_9*w[0][2]; + const double var_88 = -0.0031810165143498479213557*var_9*w[0][1]; + A[57] = var_70 + var_87 + var_88; + const double var_89 = 0.0003078403078403078581109*var_9*w[0][2]; + const double var_90 = 0.0107744107744107749796703*var_9*w[0][0]; + A[102] = var_90 + var_34 + var_89; + const double var_91 = 0.0006669873336540003321352*var_9*w[0][1]; + A[130] = var_77 + var_91 + var_21; + A[158] = A[130]; + A[67] = -0.0005002405002405002762064*var_22*var_9 + 0.0014237614237614239047491*var_9*w[0][2]; + A[109] = A[67]; + const double var_92 = 0.0002052268718935385720739*var_9*w[0][0]; + const double var_93 = 0.0107744107744107749796703*var_9*w[0][1]; + A[58] = var_92 + var_93 + var_89; + A[194] = -0.0036940836940836940804900*var_0*var_9 + -0.0061568061568061565116960*var_9*w[0][1]; + A[222] = A[194]; + const double var_94 = var_22 + 4.6000000000000005329070518*w[0][2]; + A[83] = 0.0017102239324461546588624*var_9*var_94; + A[125] = A[83]; + const double var_95 = -0.0001026134359467692860370*var_9*w[0][1]; + const double var_96 = -0.0031810165143498479213557*var_9*w[0][2]; + A[87] = var_95 + var_70 + var_96; + A[185] = A[87]; + const double var_97 = 0.0002308802308802308800306*var_9*w[0][0]; + const double var_98 = 0.0006669873336540003321352*var_9*w[0][2]; + const double var_99 = 0.0003334936668270001660676*var_25*var_9; + A[69] = var_99 + var_97 + var_98; + A[3] = var_54 + var_10 + var_36; + A[166] = A[26]; + const double var_100 = -0.0001496445940890385353610*var_9*w[0][0]; + const double var_101 = 0.0018598685265351930315930*var_9*w[0][2]; + A[35] = var_101 + var_62 + var_100; + A[18] = var_29 + var_100 + var_65; + const double var_102 = 0.0010261343594676927519493*var_9*w[0][1]; + A[104] = var_102 + var_58 + var_71; + A[192] = 0.0480230880230880230463697*var_9*w[0][0] + 0.0233958633958633969995855*var_19*var_9; + const double var_103 = 0.0157340601785046253768829*var_9*w[0][0]; + const double var_104 = 0.0017102239324461546588624*var_9*w[0][1]; + A[96] = var_104 + var_57 + var_103; + const double var_105 = 0.0001122334455667789015207*var_9*w[0][2]; + const double var_106 = 1.1428571428571427937015414*w[0][1] + var_0; + A[84] = 0.0007182940516273849480486*var_106*var_9; + A[140] = A[84]; + const double var_107 = var_22 + 0.4444444444444444197728217*w[0][2]; + A[44] = 0.0005772005772005772000766*var_107*var_9; + const double var_108 = 0.0056180856180856183698658*var_9*w[0][1]; + A[74] = var_108 + var_53 + var_23; + const double var_109 = -0.0001282667949334615939937*var_9*w[0][0]; + const double var_110 = -0.0003719737053070386822128*var_9*w[0][2]; + A[13] = var_109 + var_14 + var_110; + A[38] = var_101 + var_64 + var_30; + const double var_111 = 0.0005772005772005772000766*var_9*w[0][2]; + const double var_112 = -0.0009106942440275774203542*var_9*w[0][0]; + const double var_113 = -0.0003719737053070386822128*var_9*w[0][1]; + A[42] = var_15 + var_112 + var_113; + const double var_114 = 0.0010261343594676927519493*var_9*w[0][2]; + const double var_115 = -0.0001026134359467692860370*var_9*w[0][0]; + A[179] = var_114 + var_115 + var_88; + A[197] = A[43]; + const double var_116 = 0.0007182940516273849480486*var_9*w[0][1]; + A[129] = var_33 + var_27 + var_116; + A[143] = A[129]; + A[112] = 0.0127753727753727765181768*var_0*var_9 + 0.0023857623857623860494370*var_9*w[0][1]; + A[182] = A[42]; + const double var_117 = -0.0013307679974346640038030*var_9*w[0][1]; + A[19] = var_117 + var_45 + var_86; + const double var_118 = 4.6000000000000005329070518*w[0][1] + var_0; + A[72] = -0.0013852813852813852801837*var_9*w[0][0] + -0.0026936026936026937449176*var_19*var_9; + A[184] = A[72]; + A[153] = A[55]; + const double var_119 = 0.0031126075570520011885634*var_9*w[0][1]; + A[86] = var_27 + var_17 + var_119; + const double var_120 = 0.0056180856180856183698658*var_9*w[0][0]; + const double var_121 = var_22 + 0.2000000000000000111022302*w[0][2]; + const double var_122 = 0.0157340601785046253768829*var_9*w[0][2]; + const double var_123 = 0.0005772005772005772000766*var_9*w[0][0]; + const double var_124 = -0.0012570145903479236319800*var_9*w[0][1]; + const double var_125 = -0.0013083213083213084647338*var_9*w[0][0]; + A[68] = var_85 + var_124 + var_125; + A[124] = A[68]; + A[214] = A[74]; + A[85] = var_49 + var_99 + var_21; + const double var_126 = -0.0000684089572978461906913*var_9*w[0][1]; + A[8] = var_12 + var_123 + var_126; + A[120] = A[8]; + A[24] = var_48 + var_35 + var_11; + A[198] = A[58]; + A[34] = var_55 + var_86 + var_73; + A[62] = A[34]; + const double var_127 = -0.0006755384533162311737342*var_9*w[0][2]; + A[64] = 0.0023857623857623860494370*var_9*w[0][0] + 0.0127753727753727765181768*var_19*var_9; + const double var_128 = -0.0031810165143498479213557*var_9*w[0][0]; + A[103] = var_87 + var_128 + var_102; + A[79] = A[65]; + A[14] = var_82 + var_109 + var_113; + A[210] = A[14]; + const double var_129 = 0.0031810165143498479213557*var_9*w[0][1]; + A[148] = var_114 + var_129 + var_58; + const double var_130 = 0.0003078403078403078581109*var_9*w[0][1]; + const double var_131 = -0.0019496552829886164889123*var_9*w[0][2]; + A[88] = var_70 + var_129 + var_131; + A[200] = A[88]; + A[66] = var_91 + var_52 + var_97; + A[118] = -0.0026936026936026937449176*var_0*var_9 + -0.0013852813852813852801837*var_9*w[0][1]; + A[202] = A[118]; + A[149] = var_114 + var_95 + var_128; + const double var_132 = -0.0036171236171236172650401*var_9*w[0][2]; + A[49] = var_66 + var_132 + var_43; + A[33] = var_80 + var_10 + var_111; + A[47] = A[33]; + A[61] = A[19]; + A[78] = A[50]; + A[97] = var_132 + var_124 + var_78; + const double var_133 = 0.0031810165143498479213557*var_9*w[0][0]; + A[132] = var_133 + var_131 + var_102; + A[186] = A[102]; + A[208] = 0.0233958633958633969995855*var_0*var_9 + 0.0480230880230880230463697*var_9*w[0][1]; + A[183] = A[57]; + A[5] = var_10 + var_60 + var_127; + A[75] = A[5]; + const double var_134 = var_19 + 4.6000000000000005329070518*w[0][0]; + A[99] = 0.0017102239324461546588624*var_134*var_9; + A[141] = A[99]; + A[201] = A[103]; + const double var_135 = 0.0002052268718935385720739*var_9*w[0][2]; + const double var_136 = 0.2000000000000000111022302*w[0][1] + var_0; + const double var_137 = 0.0107744107744107749796703*var_9*w[0][2]; + A[89] = var_92 + var_130 + var_137; + A[215] = A[89]; + const double var_138 = -0.0059002725669392332152885*var_9*w[0][0]; + A[114] = var_84 + var_42 + var_138; + const double var_139 = 0.0020779220779220779202756*var_76*var_9; + A[162] = var_108 + var_63 + var_139; + A[190] = A[162]; + A[25] = var_117 + var_105 + var_74; + A[151] = A[25]; + A[40] = -0.0000481000481000480977476*var_121*var_9; + A[152] = A[40]; + A[122] = A[38]; + A[110] = A[82]; + A[133] = var_115 + var_96 + var_102; + A[203] = A[133]; + A[11] = var_35 + var_80 + var_123; + A[126] = A[98]; + A[100] = var_67 + var_124 + var_138; + A[188] = A[132]; + A[116] = var_77 + var_50 + var_98; + A[172] = A[116]; + const double var_140 = 0.0051306717973384641934276*var_9*w[0][1]; + A[23] = var_37 + var_127 + var_126; + A[113] = var_83 + var_124 + var_44; + A[212] = A[44]; + A[163] = var_26 + var_63 + var_120; + A[205] = A[163]; + A[94] = A[66]; + A[77] = A[35]; + A[21] = var_54 + var_59 + var_126; + A[15] = A[1]; + A[177] = var_72 + var_114 + var_133; + A[144] = var_140 + var_39 + var_103; + A[80] = var_56 + var_140 + var_122; + A[127] = A[113]; + A[155] = A[85]; + A[54] = var_38 + var_32 + var_119; + A[27] = var_81 + var_112 + var_110; + A[199] = A[73]; + A[195] = A[13]; + A[56] = 0.0017102239324461546588624*var_118*var_9; + A[121] = A[23]; + A[181] = A[27]; + const double var_141 = 0.0003078403078403078581109*var_9*w[0][0]; + A[134] = var_141 + var_34 + var_137; + A[147] = var_90 + var_135 + var_130; + A[170] = A[86]; + A[16] = 0.0002004168670835337711083*var_0*var_9 + 0.0021564854898188231743794*var_9*w[0][1]; + const double var_142 = -0.0001539201539201539290554*var_9*w[0][1]; + A[117] = var_142 + var_24 + var_139; + A[178] = var_135 + var_141 + var_93; + A[119] = var_53 + var_142 + var_120; + A[217] = A[119]; + A[138] = A[54]; + A[10] = var_47 + var_55 + var_105; + A[150] = A[10]; + A[160] = 0.0127753727753727765181768*var_22*var_9 + 0.0023857623857623860494370*var_9*w[0][2]; + A[139] = A[69]; + A[206] = A[178]; + A[168] = A[56]; + A[63] = A[49]; + A[128] = var_104 + var_40 + var_122; + A[71] = var_42 + var_125 + var_68; + A[169] = A[71]; + A[90] = A[6]; + A[81] = var_38 + var_116 + var_18; + A[115] = 0.0014237614237614239047491*var_9*w[0][0] + -0.0005002405002405002762064*var_19*var_9; + A[204] = A[148]; + A[159] = A[145]; + A[22] = -0.0000481000481000480977476*var_136*var_9; + A[157] = A[115]; + A[93] = A[51]; + A[187] = A[117]; + A[221] = A[179]; + A[189] = A[147]; + A[36] = var_48 + var_111 + var_126; + A[111] = A[97]; + A[211] = A[29]; + A[95] = A[81]; + A[2] = -0.0001271979049756827523463*var_0*var_9 + 0.0000163005718561274130492*var_9*w[0][1]; + A[219] = A[149]; + A[142] = A[114]; + A[46] = A[18]; + A[165] = A[11]; + A[136] = A[24]; + A[92] = A[36]; + A[216] = A[104]; + A[91] = A[21]; + A[218] = A[134]; + A[30] = A[2]; + A[224] = 0.0233958633958633969995855*var_22*var_9 + 0.0480230880230880230463697*var_9*w[0][2]; + A[156] = A[100]; + A[106] = A[22]; + A[191] = A[177]; + A[45] = A[3]; + } + + 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/mass_matrix_2d/mass_matrix_f1_p1_q4_quadrature.h b/mass_matrix_2d/mass_matrix_f1_p1_q4_quadrature.h new file mode 100644 index 0000000..9c473ad --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p1_q4_quadrature.h @@ -0,0 +1,6446 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P1_Q4_QUADRATURE_H +#define __MASS_MATRIX_F1_P1_Q4_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p1_q4_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p1_q4_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p1_q4_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p1_q4_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p1_q4_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p1_q4_quadrature_finite_element_1() + { + // 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.0224478343233824, 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.0412393049421162, -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.0388807895679869, 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.0439885919382571, 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.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 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.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.00927360943924092, 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.0535412090610519}; + + // 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.0622092633087791, -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.251415744421884, 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.0224478343233824, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0412393049421162, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0388807895679869, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0439885919382571, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.00927360943924092, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0622092633087791, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.251415744421884, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p1_q4_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p1_q4_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p1_q4_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p1_q4_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p1_q4_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p1_q4_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f1_p1_q4_quadrature_dofmap_1() + { + // 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.0*m.num_entities[1] + 3.0*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 mass_matrix_f1_p1_q4_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 mass_matrix_f1_p1_q4_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p1_q4_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // 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[25][3] = \ + {{0.915147549378728, 0.0450425935698037, 0.0398098570514687}, + {0.764365329781281, 0.0376212523451112, 0.198013417873608}, + {0.535660544808143, 0.026364644944471, 0.437974810247386}, + {0.290249932250793, 0.0142857943955714, 0.695464273353636}, + {0.09391279733378, 0.00462228846504648, 0.901464914201173}, + {0.738611533396152, 0.221578609552379, 0.0398098570514687}, + {0.616915871859002, 0.185070710267389, 0.198013417873608}, + {0.43232925297036, 0.129695936782254, 0.437974810247386}, + {0.234259434638082, 0.0702762920082818, 0.695464273353636}, + {0.0757966027350624, 0.0227384830637641, 0.901464914201173}, + {0.480095071474266, 0.480095071474266, 0.0398098570514687}, + {0.400993291063196, 0.400993291063196, 0.198013417873608}, + {0.281012594876307, 0.281012594876307, 0.437974810247386}, + {0.152267863323182, 0.152267863323182, 0.695464273353636}, + {0.0492675428994132, 0.0492675428994133, 0.901464914201173}, + {0.221578609552379, 0.738611533396152, 0.0398098570514687}, + {0.185070710267389, 0.616915871859002, 0.198013417873608}, + {0.129695936782254, 0.43232925297036, 0.437974810247386}, + {0.0702762920082818, 0.234259434638082, 0.695464273353636}, + {0.022738483063764, 0.0757966027350624, 0.901464914201173}, + {0.0450425935698037, 0.915147549378728, 0.0398098570514687}, + {0.0376212523451112, 0.764365329781281, 0.198013417873608}, + {0.0263646449444709, 0.535660544808143, 0.437974810247386}, + {0.0142857943955715, 0.290249932250793, 0.695464273353636}, + {0.00462228846504642, 0.0939127973337801, 0.901464914201173}}; + + static const double FE1[25][15] = \ + {{0.445156226392546, -0.0315827066853605, -0.0291704843038615, 0.00713406527528782, 0.00494390302967954, 0.00740035204250015, 0.429230849744386, -0.325980824651526, 0.150355774379167, 0.485650342518488, -0.359646713982119, 0.163997633685216, 0.139711801803413, -0.0430505510725602, -0.0441496681752572}, + {0.015926541983722, -0.0280725488715023, -0.0183033581130483, 0.0312122806513762, 0.00526393070506935, 0.00498994197780162, 0.878133411796469, -0.259023118319191, 0.101382553947527, 0.166839596188151, -0.2010466984854, 0.120484689621101, 0.374895740359004, -0.154792485474193, -0.0378904779668863}, + {-0.0124755223559809, -0.0215553463039365, 0.0169955517944373, 0.0521848394572087, -0.031066415935976, -0.00574417327076651, 0.10196843192882, 0.806248057040336, -0.116706558733174, 0.00613816466255062, -0.0577407317141719, 0.0638241261377217, 0.226162683532578, -0.177056205175583, 0.148823098935937}, + {0.0120168299638107, -0.0128353827169193, -0.035226128971713, 0.0485327049359034, -0.0667663799679945, 0.0369103533986063, -0.0727114709060112, 0.231635414227961, 0.749921724802327, -0.00149359379534171, -0.00251771986590465, 0.0202549790971517, 0.0148568408302708, -0.0870055733827927, 0.164427402350646}, + {-0.0416583119739728, -0.00446718301487104, 0.380915129245166, 0.0216105670502481, -0.0426296719091545, 0.0464978867840786, 0.228954361412766, -0.550949644932602, 0.944715296551356, 0.00117397037545055, 0.00106405531464627, 0.00225134530660744, -0.00781822054597092, -0.012290674911692, 0.0326310952479456}, + {-0.0104608074149253, -0.00988291055472088, -0.0291704843038615, 0.00297820840373324, 0.00337253209481225, 0.0364046469312236, 0.146268417801009, -0.193269238973082, 0.121351479490444, 0.814118789622188, -0.145456430759666, 0.0552561410358951, 0.407481803286924, -0.0237022637411396, -0.175289882918835}, + {-0.0375682445666015, -0.0228041670217817, -0.0183033581130483, 0.0319723628129167, 0.00791670028481502, 0.0245470857150986, 0.223588390713669, -0.149127693933143, 0.08182541021023, 0.208974031766544, -0.174080754470082, 0.0996107147279931, 1.06178044825661, -0.187892254450544, -0.150438671932679}, + {0.0180749828439264, -0.0382294890062686, 0.0169955517944373, 0.107969972703516, -0.0822120406470857, -0.0282573854099214, -0.099680405014501, 0.415336154256794, -0.0941933465940192, -0.0295180069828396, -0.0787150209063744, 0.106578224477739, 0.573134363428599, -0.378164181374591, 0.590880626430588}, + {-0.00539057742418073, -0.0393518056736197, -0.035226128971713, 0.161052348865788, -0.250427424267609, 0.181573575941528, 0.0290762779820009, -0.0731113992256325, 0.605258502259406, 0.00293814230330424, 0.00298065424432665, 0.0542486992329663, -0.0230680588700581, -0.263388066500361, 0.652835260103854}, + {-0.0402809925511414, -0.0191321218464864, 0.380915129245166, 0.0948596133698159, -0.194225935966402, 0.228737652168572, 0.215435885617666, -0.496279337853032, 0.762475531166862, 0.00543413854413311, 0.00436690480348772, 0.00797594705786747, -0.0346438897097151, -0.045195576272416, 0.129557052225623}, + {0.00633045207143156, 0.00633045207143156, -0.0291704843038615, -0.00373486165534533, -0.0591585474081252, 0.0788780632108338, -0.00373486165534527, -0.0591585474081251, 0.0788780632108337, -0.0450413240884349, 0.780996525962778, -0.0450413240884348, 0.270247944530608, 0.270247944530609, -0.246869494980853}, + {0.0223162840810259, 0.022316284081026, -0.0183033581130483, -0.0506457162222919, -0.0398896859719982, 0.0531862479626644, -0.0506457162222918, -0.0398896859719981, 0.0531862479626644, -0.10256169831477, 0.23462240890356, -0.10256169831477, 0.615370189888619, 0.615370189888619, -0.211870293637011}, + {0.00954713210350602, 0.00954713210350604, 0.0169955517944373, -0.0356632466096778, 0.0459190245014777, -0.0612253660019703, -0.0356632466096778, 0.0459190245014779, -0.0612253660019703, -0.0228821869135316, 0.00486080004623412, -0.0228821869135315, 0.137293121481189, 0.13729312148119, 0.832166691037341}, + {-0.0329933038013481, -0.0329933038013481, -0.035226128971713, 0.153551483320339, -0.29506202932535, 0.393416039100467, 0.153551483320339, -0.29506202932535, 0.393416039100467, 0.0336192054302757, 0.0141733094249416, 0.0336192054302758, -0.201715232581654, -0.201715232581654, 0.919420495261312}, + {-0.0333179517004775, -0.0333179517004775, 0.380915129245166, 0.17144896981256, -0.371704943750788, 0.495606591667717, 0.17144896981256, -0.371704943750788, 0.495606591667717, 0.00937015888498062, 0.00625946163885422, 0.00937015888498074, -0.0562209533098842, -0.056220953309884, 0.182461665907764}, + {-0.00988291055472087, -0.0104608074149253, -0.0291704843038615, 0.146268417801009, -0.193269238973081, 0.121351479490444, 0.00297820840373326, 0.00337253209481234, 0.0364046469312236, 0.055256141035895, -0.145456430759665, 0.814118789622188, -0.0237022637411396, 0.407481803286924, -0.175289882918835}, + {-0.0228041670217816, -0.0375682445666014, -0.0183033581130483, 0.223588390713669, -0.149127693933143, 0.0818254102102301, 0.0319723628129166, 0.00791670028481525, 0.0245470857150987, 0.099610714727993, -0.174080754470082, 0.208974031766544, -0.187892254450544, 1.06178044825661, -0.150438671932679}, + {-0.0382294890062686, 0.0180749828439264, 0.0169955517944373, -0.0996804050145011, 0.415336154256794, -0.0941933465940191, 0.107969972703516, -0.0822120406470855, -0.0282573854099214, 0.106578224477739, -0.0787150209063744, -0.0295180069828396, -0.378164181374591, 0.573134363428599, 0.590880626430589}, + {-0.0393518056736197, -0.00539057742418073, -0.035226128971713, 0.0290762779820011, -0.0731113992256331, 0.605258502259406, 0.161052348865789, -0.250427424267609, 0.181573575941528, 0.0542486992329661, 0.00298065424432674, 0.00293814230330428, -0.263388066500361, -0.023068058870058, 0.652835260103854}, + {-0.0191321218464864, -0.0402809925511414, 0.380915129245166, 0.215435885617666, -0.496279337853032, 0.762475531166862, 0.0948596133698158, -0.194225935966402, 0.228737652168572, 0.00797594705786734, 0.00436690480348782, 0.00543413854413317, -0.0451955762724162, -0.0346438897097148, 0.129557052225622}, + {-0.0315827066853606, 0.445156226392546, -0.0291704843038615, 0.429230849744386, -0.325980824651526, 0.150355774379167, 0.00713406527528781, 0.00494390302967976, 0.00740035204250012, 0.163997633685216, -0.359646713982119, 0.485650342518488, -0.0430505510725604, 0.139711801803414, -0.0441496681752572}, + {-0.0280725488715023, 0.0159265419837221, -0.0183033581130483, 0.878133411796469, -0.259023118319191, 0.101382553947527, 0.0312122806513761, 0.00526393070506977, 0.0049899419778016, 0.120484689621101, -0.2010466984854, 0.166839596188151, -0.154792485474193, 0.374895740359004, -0.0378904779668862}, + {-0.0215553463039365, -0.0124755223559809, 0.0169955517944373, 0.101968431928819, 0.806248057040335, -0.116706558733174, 0.0521848394572089, -0.0310664159359758, -0.00574417327076651, 0.0638241261377219, -0.057740731714172, 0.00613816466255059, -0.177056205175583, 0.226162683532578, 0.148823098935937}, + {-0.0128353827169194, 0.0120168299638107, -0.035226128971713, -0.072711470906011, 0.23163541422796, 0.749921724802327, 0.0485327049359037, -0.0667663799679949, 0.0369103533986067, 0.0202549790971517, -0.00251771986590455, -0.00149359379534173, -0.0870055733827935, 0.0148568408302712, 0.164427402350647}, + {-0.00446718301487104, -0.0416583119739727, 0.380915129245166, 0.228954361412766, -0.550949644932603, 0.944715296551356, 0.021610567050248, -0.0426296719091541, 0.0464978867840787, 0.00225134530660727, 0.00106405531464645, 0.0011739703754506, -0.0122906749116922, -0.00781822054597063, 0.0326310952479452}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 225; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 17075 + for (unsigned int ip = 0; ip < 25; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + + // Total number of operations to compute function values = 6 + for (unsigned int r = 0; r < 3; r++) + { + F0 += FE0[ip][r]*w[0][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 2 + double I[1]; + // Number of operations: 2 + I[0] = F0*W25[ip]*det; + + + // Number of operations for primary indices: 675 + for (unsigned int j = 0; j < 15; j++) + { + for (unsigned int k = 0; k < 15; k++) + { + // Number of operations to compute entry: 3 + A[j*15 + k] += FE1[ip][j]*FE1[ip][k]*I[0]; + }// 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 mass_matrix_f1_p1_q4_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p1_q4_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p1_q4_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 1))), 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 mass_matrix_f1_p1_q4_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p1_q4_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p1_q4_quadrature_finite_element_0(); + 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 mass_matrix_f1_p1_q4_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p1_q4_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p1_q4_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f1_p1_q4_tensor.h b/mass_matrix_2d/mass_matrix_f1_p1_q4_tensor.h new file mode 100644 index 0000000..f1a36dd --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p1_q4_tensor.h @@ -0,0 +1,6579 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P1_Q4_TENSOR_H +#define __MASS_MATRIX_F1_P1_Q4_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p1_q4_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p1_q4_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p1_q4_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p1_q4_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p1_q4_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p1_q4_tensor_finite_element_1() + { + // 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.0224478343233824, 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.0412393049421162, -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.0388807895679869, 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.0439885919382571, 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.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 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.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.00927360943924092, 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.0535412090610519}; + + // 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.0622092633087791, -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.251415744421884, 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.0224478343233824, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0412393049421162, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0388807895679869, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0439885919382571, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.00927360943924092, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0622092633087791, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.251415744421884, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p1_q4_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p1_q4_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p1_q4_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p1_q4_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p1_q4_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p1_q4_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f1_p1_q4_tensor_dofmap_1() + { + // 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.0*m.num_entities[1] + 3.0*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 mass_matrix_f1_p1_q4_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 mass_matrix_f1_p1_q4_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p1_q4_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 3 + // Number of operations (multiply-add pairs) for tensor contraction: 280 + // Total number of operations (multiply-add pairs): 292 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0 = det*w[0][0]*(1.0); + const double G0_1 = det*w[0][1]*(1.0); + const double G0_2 = det*w[0][2]*(1.0); + + // Compute element tensor + A[108] = 0.000666987333654*G0_0 + 0.000230880230880238*G0_1 - 0.000333493666826992*G0_2; + A[99] = 0.00786703008925227*G0_0 + 0.00171022393244615*G0_1 + 0.00171022393244615*G0_2; + A[181] = -0.000910694244027576*G0_0 - 0.000128266794933462*G0_1 - 0.000371973705307038*G0_2; + A[176] = A[99] - 0.00273635829191384*G0_0 + 0.0140238362460584*G0_1; + A[117] = -0.00207792207792206*G0_0 - 0.000153920153920149*G0_1 + 0.00561808561808559*G0_2; + A[199] = A[117] + 0.00192400192400191*G0_0 - 0.0019240019240019*G0_1; + A[214] = A[199] + 0.00769600769600764*G0_1 - 0.00769600769600765*G0_2; + A[192] = 0.0480230880230879*G0_0 + 0.0233958633958633*G0_1 + 0.0233958633958633*G0_2; + A[21] = -A[108] - 8.5511196622303e-06*G0_0 + 0.000162471273582391*G0_1 - 0.000577200577200568*G0_2; + A[52] = A[108]; + A[35] = A[199] + 4.27555983111079e-06*G0_0 + 0.00177863288974398*G0_1 - 0.00375821709155041*G0_2; + A[125] = A[99] - 0.00615680615680613*G0_0 + 0.00615680615680611*G0_2; + A[83] = A[125]; + A[60] = -9.62000962000948e-06*G0_0 - 4.81000481000482e-05*G0_1 - 4.81000481000487e-05*G0_2; + A[135] = A[35] + 0.00200951312062422*G0_0 - 0.00200951312062422*G0_2; + A[26] = A[135] - 0.00215915771471326*G0_0 + 0.00215915771471326*G0_1; + A[97] = -0.00641333974667304*G0_0 - 0.00125701459034792*G0_1 - 0.00361712361712359*G0_2; + A[80] = A[125] + 0.00342044786489229*G0_1 + 0.00786703008925227*G0_2; + A[111] = A[97]; + A[100] = A[97] + 0.000513067179733832*G0_0 + 0.00230880230880229*G0_2; + A[211] = A[181] + 0.000538720538720539*G0_0 - 0.000538720538720534*G0_2; + A[202] = -0.00269360269360268*G0_0 - 0.00138528138528136*G0_1 - 0.00269360269360268*G0_2; + A[4] = A[60]; + A[36] = A[21] + 0.000166746833413502*G0_0 + 0.000820907487574149*G0_2; + A[70] = A[36] + 8.55111966223138e-06*G0_0 + 0.00149217038105926*G0_1 - 0.00107744107744107*G0_2; + A[157] = A[70] + 0.00192400192400191*G0_0 - 0.00192400192400191*G0_1; + A[47] = A[36] + 0.000440382662604883*G0_0 - 0.000440382662604882*G0_1; + A[10] = -A[47] - 0.0013991769547325*G0_0 + 4.27555983111678e-06*G0_1 + 0.000689434022767352*G0_2; + A[7] = A[10] - 0.000400833734167067*G0_1 + 0.000400833734167066*G0_2; + A[149] = -A[7] - 0.00451178451178448*G0_0 + 9.62000962001468e-06*G0_1 + 0.00153920153920153*G0_2; + A[122] = A[117] + 0.00177863288974398*G0_0 + 4.27555983111146e-06*G0_1 - 0.00375821709155042*G0_2; + A[163] = A[199] + 0.00577200577200575*G0_0 - 0.00577200577200575*G0_2; + A[138] = -A[21] + 8.5511196622277e-06*G0_0 + 0.00304419859975414*G0_1 + 0.000474587141253806*G0_2; + A[170] = A[138] + 3.4204478648922e-05*G0_0 - 3.42044786489234e-05*G0_2; + A[86] = A[170]; + A[90] = A[117] + 0.00393779060445724*G0_0 + 4.27555983111084e-06*G0_1 - 0.00591737480626367*G0_2; + A[186] = -A[90] + 0.0126342793009459*G0_0 + 5.55822778044973e-05*G0_1 + 8.55111966223306e-06*G0_2; + A[165] = A[157] - 0.000846560846560844*G0_0 - 8.55111966223138e-06*G0_1 + 0.000431831542942654*G0_2; + A[191] = A[149] + 0.00636203302869966*G0_0 - 0.00184704184704184*G0_1; + A[212] = A[165] + 0.0010859921971033*G0_1 + 0.000324942547164765*G0_2; + A[205] = A[163]; + A[1] = A[181] + 0.000783496339051894*G0_0 + 1.06888995777987e-06*G0_1 + 0.000388274277163166*G0_2; + A[57] = -A[10] - 0.000304633637966972*G0_0 - 0.002667949334616*G0_1 + 9.62000962000715e-06*G0_2; + A[27] = A[181]; + A[132] = -A[149] + 0.000923520923520921*G0_1 - 0.000923520923520921*G0_2; + A[46] = A[199] + 4.27555983111033e-06*G0_0 + 0.00393779060445723*G0_1 - 0.00591737480626367*G0_2; + A[41] = A[165] - 0.000820907487574149*G0_0 - 0.000166746833413497*G0_1; + A[158] = -A[41] - 0.000577200577200574*G0_0 - 8.5511196622303e-06*G0_1 + 0.000162471273582385*G0_2; + A[144] = A[99] + 0.00786703008925227*G0_0 + 0.00342044786489229*G0_1; + A[89] = -A[35] + 5.55822778045029e-05*G0_0 + 8.55111966223653e-06*G0_1 + 0.0126342793009459*G0_2; + A[16] = A[89] - 4.810004810008e-06*G0_0 + 0.0018486451819785*G0_1 - 0.0105739939073272*G0_2; + A[164] = A[202] - 0.00130832130832132*G0_1 + 0.00130832130832131*G0_2; + A[103] = -A[10] - 0.00451178451178449*G0_0 + 0.00153920153920153*G0_1 + 9.62000962000978e-06*G0_2; + A[113] = A[97] + 0.00279621612954945*G0_0 - 0.00279621612954943*G0_2; + A[65] = A[113] + 0.00236010902677568*G0_0 - 0.00236010902677568*G0_1; + A[110] = A[65] + 0.00230880230880229*G0_1 + 0.00051306717973385*G0_2; + A[218] = -A[26] + 8.55111966223241e-06*G0_0 + 0.00206509539842872*G0_1 + 0.0106247661803217*G0_2; + A[195] = A[181] + 0.000782427449094116*G0_0 - 0.000782427449094113*G0_1; + A[188] = A[132]; + A[208] = A[192] - 0.0246272246272245*G0_0 + 0.0246272246272245*G0_1; + A[14] = A[211] + 0.000243706910373576*G0_0 - 0.000243706910373578*G0_1; + A[56] = A[99] - 0.00615680615680613*G0_0 + 0.00615680615680612*G0_1; + A[31] = A[181] + 0.000926994815883704*G0_0 + 1.06888995778031e-06*G0_1 + 0.000244775800331356*G0_2; + A[129] = A[170] + 0.0023943135054246*G0_0 - 0.0023943135054246*G0_1; + A[72] = A[202] + 0.0013083213083213*G0_0 - 0.00130832130832132*G0_1; + A[42] = A[181] - 0.000243706910373574*G0_1 + 0.000243706910373578*G0_2; + A[76] = A[70] + 0.000431831542942651*G0_0 - 0.000846560846560839*G0_1 - 8.55111966222867e-06*G0_2; + A[153] = A[100] + 0.00464325797659129*G0_0 - 0.00464325797659129*G0_1; + A[107] = -A[36] + 4.27555983111493e-06*G0_0 + 4.38244882689322e-05*G0_1 - 0.000753567420234081*G0_2; + A[104] = A[132] - 0.00513067179733843*G0_0 + 0.00513067179733844*G0_2; + A[182] = A[42]; + A[175] = A[113] - 0.00515632515632513*G0_1 + 0.00515632515632511*G0_2; + A[215] = A[89]; + A[198] = -A[90] + 0.00206509539842871*G0_0 + 0.0106247661803217*G0_1 + 8.55111966223171e-06*G0_2; + A[193] = -0.00369408369408369*G0_0 - 0.00369408369408369*G0_1 - 0.00615680615680613*G0_2; + A[20] = A[76]; + A[11] = A[165]; + A[51] = A[170] - 0.0023943135054246*G0_1 + 0.00013681791459569*G0_2; + A[32] = A[186] - 0.0105739939073272*G0_0 - 4.81000481000288e-06*G0_1 + 0.0018486451819785*G0_2; + A[25] = -A[36] + 4.27555983111699e-06*G0_0 - 0.0013991769547325*G0_1 + 0.000689434022767351*G0_2; + A[126] = -A[41] + 0.00280049168938056*G0_0 + 8.55111966223052e-06*G0_1 + 0.00297578964245629*G0_2; + A[61] = A[7] + 0.00144300144300143*G0_0 - 0.00144300144300143*G0_1; + A[159] = A[97] - 0.00236010902677569*G0_1 + 0.00236010902677568*G0_2; + A[142] = A[100] - 5.13067179733794e-05*G0_1 + 5.13067179733887e-05*G0_2; + A[94] = A[108] - 0.00043610710277377*G0_0 + 0.000436107102773762*G0_1; + A[139] = A[94] - 0.00100048100048099*G0_1 + 0.00100048100048099*G0_2; + A[79] = A[65]; + A[169] = A[153] - 5.13067179733811e-05*G0_0 + 5.13067179733866e-05*G0_2; + A[154] = A[70]; + A[106] = -4.81000481000481e-05*G0_0 - 9.62000962000866e-06*G0_1 - 4.81000481000495e-05*G0_2; + A[101] = A[138] + 0.00242851798407353*G0_0 - 0.00242851798407353*G0_1; + A[187] = A[117]; + A[174] = A[170] + 0.00232590454812676*G0_0 - 6.84089572978415e-05*G0_1; + A[216] = A[104]; + A[201] = A[103]; + A[5] = A[47] + 0.000265084709529152*G0_1 - 0.0012527390305168*G0_2; + A[15] = A[1]; + A[8] = A[21] + 0.0012527390305168*G0_0 - 0.000265084709529152*G0_2; + A[71] = A[169]; + A[50] = -A[21] + 8.55111966222748e-06*G0_0 + 0.00297578964245629*G0_1 + 0.00280049168938056*G0_2; + A[37] = A[107]; + A[148] = A[149] + 0.00123136123136122*G0_0 + 0.0032836299502966*G0_1; + A[123] = A[170] - 0.00242851798407352*G0_1 + 0.00242851798407352*G0_2; + A[85] = A[108] - 0.000564373897707234*G0_1 + 0.000564373897707224*G0_2; + A[66] = A[94]; + A[160] = 0.0127753727753727*G0_0 + 0.0127753727753727*G0_1 + 0.00238576238576238*G0_2; + A[137] = -A[108] - 8.5511196622277e-06*G0_0 - 1.28266794933379e-05*G0_1 - 0.000401902624124838*G0_2; + A[91] = A[21]; + A[82] = A[110]; + A[168] = A[56]; + A[109] = A[36] + 8.55111966222661e-06*G0_0 - 0.000431831542942656*G0_1 + 0.000846560846560833*G0_2; + A[222] = A[193] - 0.00246272246272244*G0_1 + 0.00246272246272245*G0_2; + A[184] = A[72]; + A[213] = A[191] - 0.00215488215488215*G0_0 + 0.00215488215488214*G0_2; + A[204] = A[148]; + A[2] = A[1] + 0.00014349847683181*G0_1 - 0.000143498476831809*G0_2; + A[18] = A[46]; + A[133] = A[132] - 0.00328362995029659*G0_0 - 0.00123136123136122*G0_2; + A[68] = A[97] + 0.00510501843835174*G0_0 - 0.0022831489498156*G0_2; + A[45] = A[21] + 0.000607129496018384*G0_0 - 0.000607129496018384*G0_1; + A[38] = A[122]; + A[143] = A[129]; + A[120] = A[8]; + A[88] = A[57] + 0.00636203302869967*G0_1 - 0.00184704184704183*G0_2; + A[92] = A[36]; + A[179] = A[149] + 0.00307840307840306*G0_0 - 0.00307840307840306*G0_1; + A[116] = A[108] - 0.00100048100048099*G0_0 + 0.00100048100048099*G0_2; + A[219] = A[149]; + A[189] = -A[35] + 0.0106247661803217*G0_0 + 8.55111966222575e-06*G0_1 + 0.00206509539842872*G0_2; + A[207] = A[193]; + A[55] = A[153]; + A[29] = A[211]; + A[130] = A[158]; + A[73] = A[199]; + A[43] = A[211] - 0.000782427449094113*G0_1 + 0.000782427449094113*G0_2; + A[146] = A[174]; + A[75] = A[5]; + A[150] = A[10]; + A[183] = A[57]; + A[178] = -A[26] + 8.55111966222336e-06*G0_0 + 0.0126342793009459*G0_1 + 5.55822778044976e-05*G0_2; + A[119] = A[117] + 0.00769600769600765*G0_0 - 0.00769600769600764*G0_2; + A[220] = A[164]; + A[197] = A[43]; + A[194] = A[222]; + A[19] = A[61]; + A[12] = A[36] + 0.000765325209769647*G0_0 + 0.000645609534498421*G0_1; + A[54] = A[138]; + A[33] = A[47]; + A[24] = A[36] + 0.00064560953449842*G0_1 - 0.000645609534498419*G0_2; + A[127] = A[113]; + A[62] = -A[47] + 4.38244882689325e-05*G0_0 + 4.27555983111482e-06*G0_1 - 0.000753567420234081*G0_2; + A[44] = A[212]; + A[141] = A[99]; + A[95] = -A[21] + 8.55111966222748e-06*G0_0 + 0.000649885094329535*G0_1 + 0.00286890064667841*G0_2; + A[78] = A[50]; + A[172] = A[116]; + A[155] = A[85]; + A[105] = A[7]; + A[98] = A[126]; + A[180] = A[12]; + A[173] = A[138] + 0.000136817914595691*G0_0 - 0.00239431350542461*G0_1; + A[118] = A[202]; + A[217] = A[119]; + A[200] = A[88]; + A[6] = A[90]; + A[22] = A[106]; + A[9] = A[135]; + A[49] = A[97] + 0.00515632515632513*G0_0 - 0.00515632515632512*G0_1; + A[34] = A[62]; + A[147] = A[189]; + A[124] = A[68]; + A[84] = A[138] + 3.4204478648921e-05*G0_0 - 0.00229170006947784*G0_1; + A[67] = A[109]; + A[161] = A[175]; + A[136] = A[24]; + A[96] = A[99] + 0.00786703008925227*G0_0 + 0.00342044786489229*G0_2; + A[81] = A[95]; + A[167] = A[41]; + A[156] = A[100]; + A[112] = A[160] - 0.0103896103896103*G0_1 + 0.0103896103896103*G0_2; + A[223] = A[193] - 0.00246272246272244*G0_0 + 0.00246272246272246*G0_2; + A[185] = -A[7] - 0.000304633637966972*G0_0 + 9.62000962000522e-06*G0_1 - 0.00266794933461599*G0_2; + A[210] = A[14]; + A[203] = A[133]; + A[3] = A[45]; + A[59] = A[213]; + A[17] = A[31]; + A[134] = A[218]; + A[69] = A[139]; + A[48] = A[176] - 0.00342044786489229*G0_0 + 0.00342044786489229*G0_2; + A[39] = A[137]; + A[121] = A[21] + 0.000431831542942654*G0_0 - 0.000431831542942651*G0_2; + A[87] = A[185]; + A[64] = A[160] - 0.0103896103896103*G0_0 + 0.0103896103896103*G0_2; + A[162] = A[117] + 0.00577200577200574*G0_1 - 0.00577200577200575*G0_2; + A[93] = A[51]; + A[166] = A[26]; + A[115] = A[157]; + A[224] = A[192] - 0.0246272246272246*G0_0 + 0.0246272246272245*G0_2; + A[190] = A[162]; + A[206] = A[178]; + A[0] = A[186] - 0.00861792528459192*G0_0 - 4.81000481000266e-06*G0_1 - 0.000107423440756777*G0_2; + A[58] = A[198]; + A[28] = A[36] + 0.0010859921971033*G0_0 + 0.000324942547164768*G0_1; + A[131] = A[173]; + A[74] = A[214]; + A[40] = -4.81000481000476e-05*G0_0 - 4.8100048100048e-05*G0_1 - 9.62000962000942e-06*G0_2; + A[145] = A[159]; + A[151] = A[25]; + A[102] = A[186]; + A[177] = A[191]; + A[114] = A[142]; + A[221] = A[179]; + A[196] = A[28]; + A[209] = A[223]; + A[13] = A[195]; + A[53] = A[123]; + A[30] = A[2]; + A[23] = A[121]; + A[128] = A[99] - 0.00273635829191384*G0_0 + 0.0140238362460584*G0_2; + A[63] = A[49]; + A[140] = A[84]; + A[77] = A[35]; + A[171] = A[101]; + A[152] = A[40]; + } + + /// 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 mass_matrix_f1_p1_q4_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p1_q4_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p1_q4_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 1))), 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 mass_matrix_f1_p1_q4_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p1_q4_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p1_q4_tensor_finite_element_0(); + 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 mass_matrix_f1_p1_q4_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p1_q4_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p1_q4_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f1_p2_q1_excafe.h b/mass_matrix_2d/mass_matrix_f1_p2_q1_excafe.h new file mode 100644 index 0000000..3e51066 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p2_q1_excafe.h @@ -0,0 +1,60 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 0.05 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 = -1.0000000000000000000000000*x[0][0]; + const double var_1 = x[1][0] + var_0; + const double var_2 = w[0][3] + w[0][4] + -0.2500000000000000000000000*w[0][2]; + const double var_3 = -1.0000000000000000000000000*x[0][1]; + const double var_4 = var_3 + x[1][1]; + const double var_5 = x[2][0] + var_0; + const double var_6 = var_3 + x[2][1]; + const double var_7 = var_1*var_6 + -1.0000000000000000000000000*var_4*var_5; + const double var_8 = std::abs(var_7); + const double var_9 = w[0][3] + w[0][5] + -0.2500000000000000000000000*w[0][1]; + const double var_10 = w[0][4] + 0.5000000000000000000000000*var_9; + A[2] = 0.0222222222222222230703093*var_10*var_8; + A[6] = A[2]; + const double var_11 = w[0][4] + -0.1666666666666666574148081*w[0][1]; + const double var_12 = -0.1666666666666666574148081*w[0][0] + w[0][3]; + const double var_13 = var_12 + 0.3333333333333333148296163*w[0][5] + var_11 + 0.5000000000000000000000000*w[0][2]; + const double var_14 = w[0][4] + -0.2500000000000000000000000*w[0][0] + w[0][5]; + const double var_15 = w[0][3] + 0.5000000000000000000000000*var_14; + const double var_16 = w[0][5] + -0.1666666666666666574148081*w[0][2]; + const double var_17 = 0.5000000000000000000000000*w[0][0] + 0.3333333333333333148296163*w[0][3] + var_11 + var_16; + A[0] = 0.0333333333333333328707404*var_17*var_8; + const double var_18 = w[0][5] + 0.5000000000000000000000000*var_2; + A[8] = 0.0333333333333333328707404*var_13*var_8; + A[1] = 0.0222222222222222230703093*var_18*var_8; + A[3] = A[1]; + const double var_19 = var_12 + 0.3333333333333333148296163*w[0][4] + 0.5000000000000000000000000*w[0][1] + var_16; + A[4] = 0.0333333333333333328707404*var_19*var_8; + A[5] = 0.0222222222222222230703093*var_15*var_8; + A[7] = A[5]; + } + + 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/mass_matrix_2d/mass_matrix_f1_p2_q1_quadrature.h b/mass_matrix_2d/mass_matrix_f1_p2_q1_quadrature.h new file mode 100644 index 0000000..65eb606 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p2_q1_quadrature.h @@ -0,0 +1,3355 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P2_Q1_QUADRATURE_H +#define __MASS_MATRIX_F1_P2_Q1_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p2_q1_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p2_q1_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p2_q1_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p2_q1_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p2_q1_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p2_q1_quadrature_finite_element_1() + { + // 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 mass_matrix_f1_p2_q1_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p2_q1_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p2_q1_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p2_q1_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p2_q1_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p2_q1_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f1_p2_q1_quadrature_dofmap_1() + { + // 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 mass_matrix_f1_p2_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 mass_matrix_f1_p2_q1_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p2_q1_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // 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[6][3] = \ + {{0.09157621350977, 0.816847572980459, 0.091576213509771}, + {0.09157621350977, 0.0915762135097711, 0.816847572980459}, + {0.816847572980458, 0.091576213509771, 0.091576213509771}, + {0.445948490915965, 0.10810301816807, 0.445948490915965}, + {0.445948490915965, 0.445948490915965, 0.10810301816807}, + {0.10810301816807, 0.445948490915965, 0.445948490915965}}; + + static const double FE1[6][6] = \ + {{-0.0748038077481961, 0.517632341987674, -0.0748038077481967, 0.299215230992787, 0.0335448115231483, 0.299215230992784}, + {-0.074803807748196, -0.0748038077481966, 0.517632341987673, 0.299215230992787, 0.299215230992784, 0.0335448115231483}, + {0.517632341987671, -0.0748038077481967, -0.0748038077481967, 0.0335448115231487, 0.299215230992787, 0.299215230992787}, + {-0.048208377815512, -0.0847304930939778, -0.048208377815512, 0.192833511262048, 0.795480226200906, 0.192833511262048}, + {-0.048208377815512, -0.0482083778155119, -0.0847304930939778, 0.192833511262048, 0.192833511262048, 0.795480226200906}, + {-0.0847304930939778, -0.048208377815512, -0.048208377815512, 0.795480226200906, 0.192833511262048, 0.192833511262048}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 9; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 246 + for (unsigned int ip = 0; ip < 6; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + + // Total number of operations to compute function values = 12 + for (unsigned int r = 0; r < 6; r++) + { + F0 += FE1[ip][r]*w[0][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 2 + double I[1]; + // Number of operations: 2 + I[0] = F0*W6[ip]*det; + + + // Number of operations for primary indices: 27 + for (unsigned int j = 0; j < 3; j++) + { + for (unsigned int k = 0; k < 3; k++) + { + // Number of operations to compute entry: 3 + A[j*3 + k] += FE0[ip][j]*FE0[ip][k]*I[0]; + }// 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 mass_matrix_f1_p2_q1_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p2_q1_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p2_q1_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1))), 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 mass_matrix_f1_p2_q1_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p2_q1_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p2_q1_quadrature_finite_element_0(); + 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 mass_matrix_f1_p2_q1_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p2_q1_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p2_q1_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f1_p2_q1_tensor.h b/mass_matrix_2d/mass_matrix_f1_p2_q1_tensor.h new file mode 100644 index 0000000..2dc7f38 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p2_q1_tensor.h @@ -0,0 +1,3313 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P2_Q1_TENSOR_H +#define __MASS_MATRIX_F1_P2_Q1_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p2_q1_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p2_q1_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p2_q1_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p2_q1_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p2_q1_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p2_q1_tensor_finite_element_1() + { + // 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 mass_matrix_f1_p2_q1_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p2_q1_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p2_q1_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p2_q1_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p2_q1_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p2_q1_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f1_p2_q1_tensor_dofmap_1() + { + // 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 mass_matrix_f1_p2_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 mass_matrix_f1_p2_q1_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p2_q1_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 6 + // Number of operations (multiply-add pairs) for tensor contraction: 23 + // Total number of operations (multiply-add pairs): 38 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0 = det*w[0][0]*(1.0); + const double G0_1 = det*w[0][1]*(1.0); + const double G0_2 = det*w[0][2]*(1.0); + const double G0_3 = det*w[0][3]*(1.0); + const double G0_4 = det*w[0][4]*(1.0); + const double G0_5 = det*w[0][5]*(1.0); + + // Compute element tensor + A[1] = -0.00277777777777777*G0_2 + 0.0111111111111111*G0_3 + 0.0111111111111111*G0_4 + 0.0222222222222222*G0_5; + A[5] = -0.00277777777777777*G0_0 + 0.0222222222222222*G0_3 + 0.0111111111111111*G0_4 + 0.0111111111111111*G0_5; + A[0] = A[1] + 0.0166666666666666*G0_0 - 0.00555555555555555*G0_1 - 0.00277777777777779*G0_2 + 0.0222222222222223*G0_4 + 0.0111111111111111*G0_5; + A[7] = A[5]; + A[6] = -0.00277777777777777*G0_1 + 0.0111111111111111*G0_3 + 0.0222222222222222*G0_4 + 0.0111111111111111*G0_5; + A[2] = A[6]; + A[8] = A[0] - 0.0222222222222222*G0_0 + 0.0222222222222223*G0_2 + 0.0222222222222223*G0_3 - 0.0222222222222223*G0_5; + A[3] = A[1]; + A[4] = A[0] - 0.0222222222222222*G0_0 + 0.0222222222222223*G0_1 + 0.0222222222222223*G0_3 - 0.0222222222222223*G0_4; + } + + /// 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 mass_matrix_f1_p2_q1_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p2_q1_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p2_q1_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1))), 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 mass_matrix_f1_p2_q1_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p2_q1_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p2_q1_tensor_finite_element_0(); + 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 mass_matrix_f1_p2_q1_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p2_q1_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p2_q1_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f1_p2_q2_excafe.h b/mass_matrix_2d/mass_matrix_f1_p2_q2_excafe.h new file mode 100644 index 0000000..c751e9e --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p2_q2_excafe.h @@ -0,0 +1,108 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 0.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 = -1.0000000000000000000000000*x[0][1]; + const double var_1 = x[1][1] + var_0; + const double var_2 = -1.0000000000000000000000000*x[0][0]; + const double var_3 = x[2][0] + var_2; + const double var_4 = var_0 + x[2][1]; + const double var_5 = x[1][0] + var_2; + const double var_6 = var_4*var_5 + -1.0000000000000000000000000*var_1*var_3; + const double var_7 = std::abs(var_6); + const double var_8 = w[0][3] + w[0][5]; + const double var_9 = 0.0190476190476190493372499*var_7*var_8; + const double var_10 = w[0][0] + w[0][2]; + const double var_11 = 4.0000000000000000000000000*w[0][4] + -1.0000000000000000000000000*var_10; + A[23] = var_9 + 0.0031746031746031746004211*var_11*var_7; + A[33] = A[23]; + const double var_12 = w[0][4] + w[0][5]; + const double var_13 = 0.5000000000000000000000000*w[0][0] + -2.0000000000000000000000000*w[0][3] + -1.0000000000000000000000000*var_12; + A[3] = 0.0031746031746031746004211*var_13*var_7; + A[18] = A[3]; + const double var_14 = w[0][0] + w[0][1]; + const double var_15 = -1.0000000000000000000000000*var_14 + 4.0000000000000000000000000*w[0][5]; + const double var_16 = 0.0047619047619047623343125*var_7*w[0][2] + -0.0031746031746031746004211*var_7*w[0][5]; + const double var_17 = -0.0015873015873015873002105*var_7*w[0][0]; + A[16] = var_16 + var_17; + A[26] = A[16]; + const double var_18 = w[0][4] + -0.1111111111111111049432054*w[0][1]; + A[28] = 0.0571428571428571410728559*var_18*var_7 + var_9; + const double var_19 = -0.0007936507936507936501053*var_14*var_7; + const double var_20 = -1.0000000000000000000000000*w[0][5] + 0.2500000000000000000000000*w[0][2]; + A[1] = 0.0015873015873015873002105*var_20*var_7 + var_19; + A[6] = A[1]; + const double var_21 = 0.2500000000000000000000000*w[0][0] + -1.0000000000000000000000000*w[0][3]; + const double var_22 = -2.0000000000000000000000000*w[0][4] + 0.5000000000000000000000000*w[0][1] + -1.0000000000000000000000000*var_8; + const double var_23 = w[0][1] + w[0][2]; + const double var_24 = -0.0031746031746031746004211*var_7*w[0][3] + 0.0047619047619047623343125*var_7*w[0][0]; + const double var_25 = -0.0015873015873015873002105*var_7*w[0][1]; + A[5] = var_25 + var_24; + const double var_26 = w[0][4] + w[0][3]; + const double var_27 = -2.0000000000000000000000000*w[0][5] + -1.0000000000000000000000000*var_26 + 0.5000000000000000000000000*w[0][2]; + A[17] = 0.0031746031746031746004211*var_27*var_7; + A[32] = A[17]; + const double var_28 = 0.0190476190476190493372499*var_26*var_7; + const double var_29 = -0.0007936507936507936501053*var_10*var_7; + const double var_30 = 0.3333333333333333148296163*w[0][4] + var_8; + A[7] = var_29 + 0.0071428571428571426341070*var_7*w[0][1] + 0.0047619047619047623343125*var_30*var_7; + const double var_31 = w[0][5] + -0.1111111111111111049432054*w[0][2]; + A[35] = var_28 + 0.0571428571428571410728559*var_31*var_7; + const double var_32 = -0.0007936507936507936501053*var_23*var_7; + const double var_33 = 0.3333333333333333148296163*w[0][3] + var_12; + A[0] = 0.0047619047619047623343125*var_33*var_7 + var_32 + 0.0071428571428571426341070*var_7*w[0][0]; + A[30] = A[5]; + const double var_34 = -0.0031746031746031746004211*var_7*w[0][4] + 0.0047619047619047623343125*var_7*w[0][1]; + A[11] = var_34 + var_17; + A[22] = var_28 + 0.0031746031746031746004211*var_15*var_7; + A[15] = var_16 + var_25; + A[20] = A[15]; + const double var_35 = 0.0190476190476190493372499*var_12*var_7; + const double var_36 = -0.1111111111111111049432054*w[0][0] + w[0][3]; + A[21] = var_35 + 0.0571428571428571410728559*var_36*var_7; + const double var_37 = 4.0000000000000000000000000*w[0][3] + -1.0000000000000000000000000*var_23; + A[29] = 0.0031746031746031746004211*var_37*var_7 + var_35; + A[34] = A[29]; + const double var_38 = -0.0015873015873015873002105*var_7*w[0][2]; + A[9] = var_34 + var_38; + A[4] = var_38 + var_24; + A[8] = var_32 + 0.0015873015873015873002105*var_21*var_7; + A[24] = A[4]; + const double var_39 = 0.3333333333333333148296163*w[0][5] + var_26; + const double var_40 = -1.0000000000000000000000000*w[0][4] + 0.2500000000000000000000000*w[0][1]; + A[31] = A[11]; + A[10] = 0.0031746031746031746004211*var_22*var_7; + A[2] = 0.0015873015873015873002105*var_40*var_7 + var_29; + A[13] = A[8]; + A[19] = A[9]; + A[14] = 0.0047619047619047623343125*var_39*var_7 + var_19 + 0.0071428571428571426341070*var_7*w[0][2]; + A[27] = A[22]; + A[12] = A[2]; + A[25] = A[10]; + } + + 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/mass_matrix_2d/mass_matrix_f1_p2_q2_quadrature.h b/mass_matrix_2d/mass_matrix_f1_p2_q2_quadrature.h new file mode 100644 index 0000000..210e49f --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p2_q2_quadrature.h @@ -0,0 +1,2209 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P2_Q2_QUADRATURE_H +#define __MASS_MATRIX_F1_P2_Q2_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p2_q2_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p2_q2_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p2_q2_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p2_q2_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p2_q2_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p2_q2_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class mass_matrix_f1_p2_q2_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p2_q2_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // 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[12][6] = \ + {{-0.0551285669924842, 0.65330770304706, -0.0551285669924841, 0.220514267969936, 0.0159208949980358, 0.220514267969937}, + {-0.0551285669924841, -0.055128566992484, 0.65330770304706, 0.220514267969936, 0.220514267969936, 0.0159208949980359}, + {0.653307703047059, -0.0551285669924842, -0.0551285669924842, 0.0159208949980359, 0.220514267969937, 0.220514267969937}, + {-0.124998982535098, 0.00143057951778881, -0.124998982535098, 0.499995930140389, 0.248575525271626, 0.499995930140391}, + {-0.124998982535098, -0.124998982535098, 0.00143057951778877, 0.499995930140389, 0.499995930140391, 0.248575525271626}, + {0.00143057951778977, -0.124998982535098, -0.124998982535098, 0.248575525271625, 0.49999593014039, 0.49999593014039}, + {-0.0474962571988001, 0.173768363654174, -0.117715163308429, 0.790160442765823, 0.0659747859186054, 0.135307828168627}, + {-0.117715163308429, 0.173768363654174, -0.0474962571988, 0.135307828168627, 0.0659747859186052, 0.790160442765823}, + {-0.0474962571988, -0.117715163308429, 0.173768363654174, 0.790160442765823, 0.135307828168627, 0.0659747859186053}, + {0.173768363654174, -0.117715163308429, -0.0474962571988, 0.0659747859186053, 0.135307828168627, 0.790160442765823}, + {-0.117715163308429, -0.0474962571988, 0.173768363654174, 0.135307828168627, 0.790160442765823, 0.0659747859186053}, + {0.173768363654174, -0.0474962571988001, -0.117715163308429, 0.0659747859186055, 0.790160442765823, 0.135307828168627}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 36; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 1464 + for (unsigned int ip = 0; ip < 12; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + + // Total number of operations to compute function values = 12 + for (unsigned int r = 0; r < 6; r++) + { + F0 += FE0[ip][r]*w[0][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 2 + double I[1]; + // Number of operations: 2 + I[0] = F0*W12[ip]*det; + + + // Number of operations for primary indices: 108 + for (unsigned int j = 0; j < 6; j++) + { + for (unsigned int k = 0; k < 6; k++) + { + // Number of operations to compute entry: 3 + A[j*6 + k] += FE0[ip][j]*FE0[ip][k]*I[0]; + }// 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 mass_matrix_f1_p2_q2_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p2_q2_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p2_q2_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1))), 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 mass_matrix_f1_p2_q2_quadrature_finite_element_0(); + break; + } + case 1: + { + return new mass_matrix_f1_p2_q2_quadrature_finite_element_0(); + break; + } + case 2: + { + return new mass_matrix_f1_p2_q2_quadrature_finite_element_0(); + 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 mass_matrix_f1_p2_q2_quadrature_dofmap_0(); + break; + } + case 1: + { + return new mass_matrix_f1_p2_q2_quadrature_dofmap_0(); + break; + } + case 2: + { + return new mass_matrix_f1_p2_q2_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f1_p2_q2_tensor.h b/mass_matrix_2d/mass_matrix_f1_p2_q2_tensor.h new file mode 100644 index 0000000..e01f18e --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p2_q2_tensor.h @@ -0,0 +1,2196 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P2_Q2_TENSOR_H +#define __MASS_MATRIX_F1_P2_Q2_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p2_q2_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p2_q2_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p2_q2_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p2_q2_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p2_q2_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p2_q2_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class mass_matrix_f1_p2_q2_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p2_q2_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 6 + // Number of operations (multiply-add pairs) for tensor contraction: 69 + // Total number of operations (multiply-add pairs): 84 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0 = det*w[0][0]*(1.0); + const double G0_1 = det*w[0][1]*(1.0); + const double G0_2 = det*w[0][2]*(1.0); + const double G0_3 = det*w[0][3]*(1.0); + const double G0_4 = det*w[0][4]*(1.0); + const double G0_5 = det*w[0][5]*(1.0); + + // Compute element tensor + A[9] = 0.00476190476190478*G0_1 - 0.0015873015873016*G0_2 - 0.00317460317460315*G0_4; + A[18] = 0.00158730158730158*G0_0 - 0.0063492063492063*G0_3 - 0.00317460317460315*G0_4 - 0.00317460317460315*G0_5; + A[20] = -0.0015873015873016*G0_1 + 0.00476190476190478*G0_2 - 0.00317460317460315*G0_5; + A[13] = 0.000396825396825395*G0_0 - 0.000793650793650797*G0_1 - 0.000793650793650795*G0_2 - 0.0015873015873016*G0_3; + A[31] = A[9] - 0.0015873015873016*G0_0 + 0.0015873015873016*G0_2; + A[3] = A[18]; + A[17] = 0.00158730158730158*G0_2 - 0.00317460317460315*G0_3 - 0.00317460317460316*G0_4 - 0.00634920634920633*G0_5; + A[24] = 0.00476190476190478*G0_0 - 0.0015873015873016*G0_2 - 0.00317460317460315*G0_3; + A[8] = A[13]; + A[21] = -0.0063492063492063*G0_0 + 0.0571428571428575*G0_3 + 0.0190476190476189*G0_4 + 0.0190476190476189*G0_5; + A[28] = -0.00634920634920633*G0_1 + 0.019047619047619*G0_3 + 0.0571428571428576*G0_4 + 0.019047619047619*G0_5; + A[11] = A[31]; + A[30] = A[24] - 0.0015873015873016*G0_1 + 0.0015873015873016*G0_2; + A[4] = A[24]; + A[25] = 0.00158730158730158*G0_1 - 0.00317460317460315*G0_3 - 0.00634920634920633*G0_4 - 0.00317460317460316*G0_5; + A[34] = A[21] + 0.00634920634920631*G0_0 - 0.0031746031746032*G0_1 - 0.00317460317460321*G0_2 - 0.0444444444444449*G0_3; + A[0] = A[13] + 0.00674603174603181*G0_0 + 0.00317460317460318*G0_3 + 0.00476190476190478*G0_4 + 0.00476190476190479*G0_5; + A[7] = A[0] - 0.007936507936508*G0_0 + 0.00793650793650801*G0_1 + 0.0031746031746032*G0_3 - 0.0031746031746032*G0_4; + A[29] = A[34]; + A[14] = A[0] - 0.007936507936508*G0_0 + 0.00793650793650801*G0_2 + 0.0031746031746032*G0_3 - 0.00317460317460321*G0_5; + A[10] = A[25]; + A[5] = A[30]; + A[26] = A[20] - 0.0015873015873016*G0_0 + 0.0015873015873016*G0_1; + A[6] = -0.000793650793650797*G0_0 - 0.000793650793650796*G0_1 + 0.000396825396825395*G0_2 - 0.0015873015873016*G0_5; + A[1] = A[6]; + A[35] = -0.00634920634920633*G0_2 + 0.019047619047619*G0_3 + 0.019047619047619*G0_4 + 0.0571428571428577*G0_5; + A[23] = A[21] + 0.00317460317460316*G0_0 - 0.0031746031746032*G0_2 - 0.0380952380952386*G0_3 - 0.0063492063492063*G0_4; + A[33] = A[23]; + A[19] = A[9]; + A[16] = A[26]; + A[27] = A[21] + 0.00317460317460316*G0_0 - 0.0031746031746032*G0_1 - 0.0380952380952386*G0_3 - 0.0063492063492063*G0_5; + A[22] = A[27]; + A[15] = A[20]; + A[32] = A[17]; + A[2] = -0.000793650793650797*G0_0 + 0.000396825396825395*G0_1 - 0.000793650793650795*G0_2 - 0.0015873015873016*G0_4; + A[12] = A[2]; + } + + /// 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 mass_matrix_f1_p2_q2_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p2_q2_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p2_q2_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1))), 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 mass_matrix_f1_p2_q2_tensor_finite_element_0(); + break; + } + case 1: + { + return new mass_matrix_f1_p2_q2_tensor_finite_element_0(); + break; + } + case 2: + { + return new mass_matrix_f1_p2_q2_tensor_finite_element_0(); + 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 mass_matrix_f1_p2_q2_tensor_dofmap_0(); + break; + } + case 1: + { + return new mass_matrix_f1_p2_q2_tensor_dofmap_0(); + break; + } + case 2: + { + return new mass_matrix_f1_p2_q2_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f1_p2_q3_excafe.h b/mass_matrix_2d/mass_matrix_f1_p2_q3_excafe.h new file mode 100644 index 0000000..a2f56ce --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p2_q3_excafe.h @@ -0,0 +1,245 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 0.68 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 = -1.0000000000000000000000000*x[0][1]; + const double var_1 = var_0 + x[1][1]; + const double var_2 = -1.0000000000000000000000000*x[0][0]; + const double var_3 = x[2][0] + var_2; + const double var_4 = var_0 + x[2][1]; + const double var_5 = var_2 + x[1][0]; + const double var_6 = -1.0000000000000000000000000*var_1*var_3 + var_4*var_5; + const double var_7 = std::abs(var_6); + const double var_8 = -1.0000000000000000000000000*w[0][4]; + const double var_9 = 0.0016071428571428571143581*var_7*var_8 + -0.0020089285714285712303173*var_7*w[0][1]; + const double var_10 = -1.0000000000000000000000000*w[0][3]; + const double var_11 = 0.0048214285714285711262339*var_10*var_7; + const double var_12 = 0.0004017857142857142785895*var_7*w[0][0] + var_11; + const double var_13 = -1.0000000000000000000000000*w[0][5]; + const double var_14 = 0.0032142857142857142287162*var_13*var_7; + const double var_15 = 0.0012053571428571427815585*var_7*w[0][2]; + const double var_16 = var_14 + var_15; + A[37] = var_9 + var_12 + var_16; + A[73] = A[37]; + const double var_17 = w[0][5] + 3.2500000000000000000000000*w[0][2]; + const double var_18 = 0.0001785714285714285712737*var_17*var_7; + const double var_19 = 0.0012500000000000000260209*var_7*w[0][3] + -0.0002232142857142857073158*var_7*w[0][0]; + const double var_20 = 0.0007142857142857142850947*var_7*w[0][4]; + const double var_21 = var_20 + -0.0004910714285714286048840*var_7*w[0][1]; + A[4] = var_19 + var_21 + var_18; + A[40] = A[4]; + const double var_22 = -0.0004464285714285714146317*var_7*w[0][2]; + const double var_23 = var_20 + -0.0013392857142857142981052*var_7*w[0][1]; + const double var_24 = -0.0001339285714285714352315*var_7*w[0][0]; + const double var_25 = 0.0007589285714285714211369*var_7*w[0][2]; + A[14] = var_25 + var_24 + var_23; + const double var_26 = w[0][0] + w[0][1]; + const double var_27 = w[0][5] + 0.1250000000000000000000000*var_26; + A[29] = 0.0021428571428571429637044*var_27*var_7; + const double var_28 = 3.0000000000000000000000000*w[0][0] + var_10; + const double var_29 = 0.0008928571428571428292634*var_28*var_7; + const double var_30 = -0.0004464285714285714146317*var_7*w[0][1]; + A[7] = var_29 + var_30; + A[70] = A[7]; + const double var_31 = -0.0001339285714285714352315*var_7*w[0][2]; + const double var_32 = w[0][4] + 3.2500000000000000000000000*w[0][1]; + const double var_33 = 0.0001785714285714285712737*var_32*var_7; + const double var_34 = 0.0007142857142857142850947*var_7*w[0][5]; + const double var_35 = -0.0004910714285714286048840*var_7*w[0][2] + var_34; + A[3] = var_35 + var_19 + var_33; + const double var_36 = 0.0048214285714285711262339*var_13*var_7; + const double var_37 = 0.0004017857142857142785895*var_7*w[0][2] + var_36; + const double var_38 = 0.0032142857142857142287162*var_10*var_7; + const double var_39 = 0.0012053571428571427815585*var_7*w[0][0]; + const double var_40 = var_38 + var_39; + A[48] = var_9 + var_37 + var_40; + const double var_41 = 0.0080357142857142849212693*var_7*w[0][4]; + const double var_42 = w[0][4] + w[0][5]; + const double var_43 = var_10 + -1.0000000000000000000000000*var_42; + const double var_44 = 0.0016071428571428571143581*var_43*var_7; + const double var_45 = w[0][0] + w[0][2]; + const double var_46 = w[0][1] + -0.2500000000000000000000000*var_45; + A[47] = var_44 + 0.0016071428571428571143581*var_46*var_7; + const double var_47 = 0.0241071428571428547638078*var_7*w[0][5]; + const double var_48 = -0.0020089285714285712303173*var_7*w[0][2] + 0.0016071428571428571143581*var_13*var_7; + const double var_49 = 0.0032142857142857142287162*var_7*var_8; + const double var_50 = 0.0012053571428571427815585*var_7*w[0][1]; + const double var_51 = var_50 + var_49; + A[45] = var_51 + var_12 + var_48; + const double var_52 = 0.0096428571428571422524678*var_7*w[0][3] + -0.0016071428571428571143581*var_7*w[0][0]; + const double var_53 = -0.5000000000000000000000000*w[0][0] + w[0][3]; + const double var_54 = 0.0064285714285714284574325*var_53*var_7; + const double var_55 = 0.0040178571428571424606346*var_7*w[0][0]; + const double var_56 = w[0][5] + -0.5000000000000000000000000*w[0][2]; + const double var_57 = 0.0064285714285714284574325*var_56*var_7; + const double var_58 = 0.0096428571428571422524678*var_7*w[0][4] + -0.0016071428571428571143581*var_7*w[0][1]; + const double var_59 = var_38 + var_55; + A[59] = var_57 + var_59 + var_58; + A[95] = A[59]; + const double var_60 = -0.0013392857142857142981052*var_7*w[0][2] + var_34; + const double var_61 = 0.0007589285714285714211369*var_7*w[0][1]; + A[23] = var_61 + var_24 + var_60; + const double var_62 = -0.0001339285714285714352315*var_7*w[0][1]; + const double var_63 = 0.0007589285714285714211369*var_7*w[0][0]; + A[25] = var_63 + var_62 + var_60; + A[52] = A[25]; + const double var_64 = w[0][1] + w[0][2]; + const double var_65 = w[0][3] + -0.5000000000000000000000000*var_64; + A[57] = 0.0080357142857142849212693*var_42*var_7 + var_55 + 0.0032142857142857142287162*var_65*var_7; + const double var_66 = 0.0241071428571428547638078*var_7*w[0][4]; + const double var_67 = 3.0000000000000000000000000*w[0][1] + var_8; + const double var_68 = 0.0008928571428571428292634*var_67*var_7; + const double var_69 = -0.0002232142857142857073158*var_7*w[0][2] + 0.0012500000000000000260209*var_7*w[0][5]; + const double var_70 = 0.0007142857142857142850947*var_7*w[0][3]; + const double var_71 = var_70 + -0.0004910714285714286048840*var_7*w[0][0]; + A[28] = var_69 + var_33 + var_71; + const double var_72 = var_13 + 3.0000000000000000000000000*w[0][2]; + const double var_73 = 0.0008928571428571428292634*var_7*var_72; + const double var_74 = -0.0004464285714285714146317*var_7*w[0][0]; + A[26] = var_73 + var_74; + A[62] = A[26]; + const double var_75 = w[0][4] + -0.5000000000000000000000000*w[0][1]; + const double var_76 = 0.0064285714285714284574325*var_7*var_75; + const double var_77 = -0.0016071428571428571143581*var_7*w[0][2] + 0.0096428571428571422524678*var_7*w[0][5]; + A[79] = var_76 + var_77 + var_59; + A[54] = A[45]; + const double var_78 = w[0][3] + var_42; + const double var_79 = w[0][1] + var_45; + A[99] = -0.0096428571428571422524678*var_7*var_79 + 0.0578571428571428569842539*var_7*var_78; + const double var_80 = var_70 + -0.0013392857142857142981052*var_7*w[0][0]; + const double var_81 = w[0][0] + 0.6000000000000000888178420*var_65; + const double var_82 = 0.0080357142857142849212693*var_7*var_81; + const double var_83 = 0.0080357142857142849212693*var_7*w[0][5]; + A[55] = var_66 + var_83 + var_82; + const double var_84 = w[0][5] + -0.5000000000000000000000000*var_26; + const double var_85 = w[0][4] + w[0][3]; + const double var_86 = 0.3333333333333333148296163*var_84 + var_85 + 2.7500000000000000000000000*w[0][2]; + const double var_87 = 0.6000000000000000888178420*var_84 + w[0][2]; + const double var_88 = 0.0080357142857142849212693*var_7*var_87; + const double var_89 = 0.0080357142857142849212693*var_7*w[0][3]; + A[66] = var_66 + var_89 + var_88; + const double var_90 = 2.7500000000000000000000000*w[0][0] + 0.3333333333333333148296163*var_65 + var_42; + A[0] = 0.0011904761904761905835781*var_7*var_90; + A[32] = A[23]; + const double var_91 = 0.0012500000000000000260209*var_7*w[0][4] + -0.0002232142857142857073158*var_7*w[0][1]; + const double var_92 = 3.2500000000000000000000000*w[0][0] + w[0][3]; + const double var_93 = 0.0001785714285714285712737*var_7*var_92; + A[15] = var_35 + var_91 + var_93; + const double var_94 = 0.0040178571428571424606346*var_7*w[0][1]; + const double var_95 = var_94 + var_49; + A[39] = var_57 + var_52 + var_95; + A[93] = A[39]; + A[41] = A[14]; + A[17] = var_63 + var_23 + var_31; + A[71] = A[17]; + const double var_96 = 0.0206349206349206344690561*w[0][5] + 0.0031746031746031746004211*var_85 + 0.0178571428571428561515866*var_26 + 0.0027777777777777778837887*w[0][2]; + A[1] = 0.0125000000000000006938894*var_7*var_96; + A[10] = A[1]; + const double var_97 = w[0][2] + -0.2500000000000000000000000*var_26; + A[35] = var_44 + 0.0016071428571428571143581*var_7*var_97; + A[16] = var_91 + var_71 + var_18; + const double var_98 = w[0][4] + -0.5000000000000000000000000*var_45; + const double var_99 = w[0][3] + w[0][5]; + A[38] = 0.0032142857142857142287162*var_7*var_98 + var_94 + 0.0080357142857142849212693*var_7*var_99; + A[83] = A[38]; + A[82] = A[28]; + const double var_100 = 0.0040178571428571424606346*var_7*w[0][2]; + A[46] = var_100 + 0.0032142857142857142287162*var_7*var_84 + 0.0080357142857142849212693*var_7*var_85; + A[64] = A[46]; + const double var_101 = 0.0027777777777777778837887*w[0][0] + 0.0206349206349206344690561*w[0][3] + 0.0031746031746031746004211*var_42 + 0.0178571428571428561515866*var_64; + A[12] = 0.0125000000000000006938894*var_101*var_7; + A[21] = A[12]; + A[61] = A[16]; + const double var_102 = 0.0016071428571428571143581*var_10*var_7 + -0.0020089285714285712303173*var_7*w[0][0]; + A[67] = var_37 + var_51 + var_102; + A[76] = A[67]; + const double var_103 = 0.0048214285714285711262339*var_7*var_8; + const double var_104 = 0.0004017857142857142785895*var_7*w[0][1] + var_103; + A[36] = var_104 + var_40 + var_48; + A[63] = A[36]; + A[8] = var_80 + var_61 + var_31; + A[80] = A[8]; + const double var_105 = 0.0241071428571428547638078*var_7*w[0][3]; + A[44] = var_41 + var_105 + var_88; + A[58] = var_16 + var_102 + var_104; + const double var_106 = var_14 + var_100; + A[69] = var_106 + var_54 + var_58; + A[75] = A[57]; + A[49] = var_76 + var_52 + var_106; + A[94] = A[49]; + const double var_107 = 2.7500000000000000000000000*w[0][1] + 0.3333333333333333148296163*var_98 + var_99; + A[27] = var_21 + var_69 + var_93; + A[72] = A[27]; + const double var_108 = w[0][4] + 0.1250000000000000000000000*var_45; + A[96] = A[69]; + A[13] = var_22 + var_68; + A[31] = A[13]; + A[22] = 0.0011904761904761905835781*var_7*var_86; + A[11] = 0.0011904761904761905835781*var_107*var_7; + const double var_109 = w[0][1] + 0.6000000000000000888178420*var_98; + A[97] = A[79]; + const double var_110 = 0.0206349206349206344690561*w[0][4] + 0.0027777777777777778837887*w[0][1] + 0.0178571428571428561515866*var_45 + 0.0031746031746031746004211*var_99; + A[2] = 0.0125000000000000006938894*var_110*var_7; + A[20] = A[2]; + A[85] = A[58]; + A[18] = var_68 + var_74; + A[81] = A[18]; + A[19] = 0.0021428571428571429637044*var_108*var_7; + A[91] = A[19]; + A[74] = A[47]; + A[77] = var_47 + var_41 + var_82; + const double var_111 = w[0][0] + -0.2500000000000000000000000*var_64; + A[68] = 0.0016071428571428571143581*var_111*var_7 + var_44; + A[86] = A[68]; + A[51] = A[15]; + A[6] = var_25 + var_80 + var_62; + A[24] = var_73 + var_30; + A[53] = A[35]; + A[5] = var_22 + var_29; + const double var_112 = 0.0080357142857142849212693*var_109*var_7; + A[30] = A[3]; + A[60] = A[6]; + A[56] = var_50 + -0.0020089285714285712303173*var_45*var_7 + var_38 + var_14 + var_103; + A[50] = A[5]; + A[89] = var_77 + var_95 + var_54; + A[98] = A[89]; + A[78] = var_15 + var_36 + var_49 + -0.0020089285714285712303173*var_26*var_7 + var_38; + A[87] = A[78]; + A[34] = -0.0032142857142857142287162*var_42*var_7 + -0.0020089285714285712303173*var_64*var_7 + var_39 + var_11; + A[65] = A[56]; + const double var_113 = w[0][3] + 0.1250000000000000000000000*var_64; + A[9] = 0.0021428571428571429637044*var_113*var_7; + A[90] = A[9]; + A[33] = var_112 + var_83 + var_105; + A[92] = A[29]; + A[43] = A[34]; + A[88] = var_89 + var_47 + var_112; + A[84] = A[48]; + A[42] = A[24]; + } + + 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/mass_matrix_2d/mass_matrix_f1_p2_q3_quadrature.h b/mass_matrix_2d/mass_matrix_f1_p2_q3_quadrature.h new file mode 100644 index 0000000..3bf5925 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p2_q3_quadrature.h @@ -0,0 +1,5357 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P2_Q3_QUADRATURE_H +#define __MASS_MATRIX_F1_P2_Q3_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p2_q3_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p2_q3_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p2_q3_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p2_q3_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p2_q3_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p2_q3_quadrature_finite_element_1() + { + // 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p2_q3_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p2_q3_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p2_q3_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p2_q3_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p2_q3_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p2_q3_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f1_p2_q3_quadrature_dofmap_1() + { + // 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.0*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 mass_matrix_f1_p2_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 mass_matrix_f1_p2_q3_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p2_q3_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // 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[25][6] = \ + {{0.759842524889053, -0.0409849230988147, -0.036640207614552, 0.00717255684496526, 0.145727572487076, 0.164882476492272}, + {0.404143384962011, -0.0347905350890822, -0.119594790557632, 0.0297980510461641, 0.605418365816316, 0.115025523822223}, + {0.03820389372017, -0.0249744559383749, -0.0543309414249184, 0.0461882014671776, 0.938423301877432, 0.0564900002985143}, + {-0.121759885907613, -0.0138776265525463, 0.271876837668966, 0.0397410384743821, 0.807433832894958, 0.0165858034218534}, + {-0.0762735703276687, -0.00457955736373819, 0.723813068870285, 0.0166673234982246, 0.338636367163553, 0.00173636815934475}, + {0.352482461135478, -0.123384449130048, -0.036640207614552, 0.0352840510877738, 0.117616078244268, 0.65464206627708}, + {0.144254514044104, -0.116568374669637, -0.119594790557632, 0.146585935553368, 0.488630481309112, 0.456692234320686}, + {-0.0585120870225412, -0.0960538647466012, -0.0543309414249184, 0.227214213208259, 0.75739729013635, 0.224285389849452}, + {-0.124504469204174, -0.0603987775714151, 0.271876837668966, 0.19549860142211, 0.65167626994723, 0.0658515377372835}, + {-0.0643063527627087, -0.0217044058396818, 0.723813068870285, 0.0819917787365635, 0.273311911925214, 0.00689399907032831}, + {-0.0191125161665053, -0.0191125161665052, -0.036640207614552, 0.0764500646660208, 0.0764500646660208, 0.921965110615521}, + {-0.0794020521078101, -0.07940205210781, -0.119594790557632, 0.31760820843124, 0.31760820843124, 0.643182477910772}, + {-0.123076437918076, -0.123076437918076, -0.0543309414249183, 0.492305751672305, 0.492305751672305, 0.315872313916462}, + {-0.105896858921168, -0.105896858921168, 0.271876837668966, 0.42358743568467, 0.42358743568467, 0.092742008804029}, + {-0.0444129613327222, -0.0444129613327222, 0.723813068870285, 0.177651845330889, 0.177651845330889, 0.00970916313338213}, + {-0.123384449130048, 0.352482461135478, -0.036640207614552, 0.117616078244268, 0.0352840510877737, 0.65464206627708}, + {-0.116568374669637, 0.144254514044104, -0.119594790557632, 0.488630481309112, 0.146585935553368, 0.456692234320686}, + {-0.0960538647466012, -0.0585120870225412, -0.0543309414249183, 0.75739729013635, 0.227214213208259, 0.224285389849452}, + {-0.0603987775714152, -0.124504469204174, 0.271876837668966, 0.65167626994723, 0.195498601422111, 0.0658515377372835}, + {-0.0217044058396819, -0.0643063527627086, 0.723813068870285, 0.273311911925214, 0.0819917787365634, 0.00689399907032831}, + {-0.0409849230988147, 0.759842524889054, -0.036640207614552, 0.145727572487076, 0.00717255684496518, 0.164882476492272}, + {-0.0347905350890822, 0.404143384962011, -0.119594790557632, 0.605418365816316, 0.0297980510461639, 0.115025523822223}, + {-0.024974455938375, 0.03820389372017, -0.0543309414249183, 0.938423301877431, 0.0461882014671776, 0.0564900002985144}, + {-0.0138776265525464, -0.121759885907613, 0.271876837668966, 0.807433832894958, 0.0397410384743823, 0.0165858034218536}, + {-0.00457955736373822, -0.0762735703276687, 0.723813068870285, 0.338636367163553, 0.0166673234982245, 0.00173636815934475}}; + + static const double FE1[25][10] = \ + {{0.595361771100889, 0.0363240630142744, 0.0329620582231266, -0.00697876330105453, -0.00710543413900173, 0.286154010031837, -0.144363814874519, 0.323767019699913, -0.160427557536749, 0.0443066477812842}, + {0.144847707077251, 0.031491752557511, 0.056509372357196, -0.0297392974343587, -0.0136089104009562, 0.880722068301204, -0.276497422020097, 0.167331423967527, -0.114798724929776, 0.153742030524499}, + {-0.0638922318573471, 0.0233191863197456, -0.0471646056404562, -0.0478518692290425, 0.0163120554591614, 0.640806423249974, 0.331418250941681, 0.038574441798557, -0.0585247318831845, 0.167003080840912}, + {0.0211818331847306, 0.0133805365030047, 0.0326369349932555, -0.0427925717552784, 0.0485711762178746, -0.117406110387015, 0.98683910857276, -0.0024116832712123, -0.0178593517002863, 0.0778601276421673}, + {0.0579517721596659, 0.00452658789692546, 0.541134376806172, -0.0184907249626245, 0.0319586608616019, -0.273633189306433, 0.649316299328904, -0.0014030624094848, -0.00192632644777788, 0.010565606073051}, + {0.0969129145557495, 0.0495966310503562, 0.0329620582231266, -0.0133081629182569, -0.0349538534974921, 0.160876909651335, -0.116515395516028, 0.895428534283356, -0.246912783611135, 0.175913147778989}, + {-0.0391667888544834, 0.0594654509565622, 0.056509372357196, -0.0733496016702976, -0.0669464878724995, 0.467663868980969, -0.223159844548554, 0.437096058075966, -0.228522561505531, 0.610410534080673}, + {-0.0451321541833679, 0.0638185648099453, -0.0471646056404562, -0.15615892407532, 0.0802441041051714, 0.253054939278284, 0.267486202295671, 0.074936267198872, -0.154146013447678, 0.663061619658879}, + {0.045160818752146, 0.0496137334753148, 0.0326369349932555, -0.17356708239734, 0.238936811531546, -0.217903867034122, 0.796473473259088, -0.0220190689531468, -0.0584641485580772, 0.309132394931336}, + {0.0519031146003489, 0.0204647143413336, 0.541134376806172, -0.0859485068100627, 0.157214651192224, -0.23755901477889, 0.524060308998282, -0.00599217068695466, -0.00722668705539908, 0.0419492133929461}, + {-0.0591559090807405, -0.0591559090807405, 0.0329620582231266, 0.03786731225338, -0.0757346245067602, 0.03786731225338, -0.0757346245067601, 0.456668557219904, 0.456668557219904, 0.247747270005307}, + {-0.032436155693348, -0.032436155693348, 0.056509372357196, 0.0725265831052634, -0.145053166210527, 0.0725265831052632, -0.145053166210527, 0.146872235029605, 0.146872235029605, 0.859671635180817}, + {0.025515852626442, 0.0255158526264419, -0.0471646056404562, -0.0869325766002105, 0.173865153200421, -0.0869325766002107, 0.173865153200421, -0.0557775204375565, -0.0557775204375563, 0.933822788062264}, + {0.0638199343796498, 0.0638199343796498, 0.0326369349932555, -0.258852571197659, 0.517705142395317, -0.258852571197659, 0.517705142395317, -0.0566742670215316, -0.0566742670215314, 0.435366587895191}, + {0.0388828743119486, 0.0388828743119486, 0.541134376806172, -0.170318740047627, 0.340637480095253, -0.170318740047627, 0.340637480095253, -0.0093083887122843, -0.00930838871228411, 0.0590791718992466}, + {0.0495966310503563, 0.0969129145557494, 0.0329620582231266, 0.160876909651335, -0.116515395516028, -0.013308162918257, -0.034953853497492, -0.246912783611135, 0.895428534283356, 0.175913147778989}, + {0.0594654509565623, -0.0391667888544834, 0.056509372357196, 0.467663868980969, -0.223159844548554, -0.0733496016702976, -0.0669464878724995, -0.228522561505532, 0.437096058075966, 0.610410534080673}, + {0.0638185648099453, -0.0451321541833679, -0.0471646056404562, 0.253054939278284, 0.267486202295671, -0.15615892407532, 0.0802441041051715, -0.154146013447678, 0.0749362671988722, 0.663061619658879}, + {0.0496137334753148, 0.045160818752146, 0.0326369349932555, -0.217903867034122, 0.796473473259088, -0.17356708239734, 0.238936811531547, -0.0584641485580774, -0.0220190689531466, 0.309132394931336}, + {0.0204647143413336, 0.0519031146003489, 0.541134376806172, -0.23755901477889, 0.524060308998282, -0.0859485068100628, 0.157214651192223, -0.00722668705539924, -0.00599217068695446, 0.041949213392946}, + {0.0363240630142745, 0.595361771100889, 0.0329620582231266, 0.286154010031837, -0.144363814874519, -0.00697876330105458, -0.00710543413900171, -0.160427557536749, 0.323767019699913, 0.0443066477812842}, + {0.031491752557511, 0.144847707077251, 0.056509372357196, 0.880722068301204, -0.276497422020097, -0.0297392974343586, -0.0136089104009562, -0.114798724929776, 0.167331423967527, 0.153742030524498}, + {0.0233191863197457, -0.0638922318573471, -0.0471646056404562, 0.640806423249974, 0.331418250941681, -0.0478518692290426, 0.0163120554591614, -0.0585247318831847, 0.0385744417985573, 0.167003080840912}, + {0.0133805365030048, 0.0211818331847307, 0.0326369349932554, -0.117406110387015, 0.986839108572759, -0.0427925717552788, 0.0485711762178751, -0.0178593517002866, -0.00241168327121213, 0.0778601276421677}, + {0.00452658789692547, 0.057951772159666, 0.541134376806172, -0.273633189306433, 0.649316299328904, -0.0184907249626247, 0.0319586608616018, -0.00192632644777806, -0.0014030624094846, 0.0105656060730509}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 100; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 7850 + for (unsigned int ip = 0; ip < 25; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + + // Total number of operations to compute function values = 12 + for (unsigned int r = 0; r < 6; r++) + { + F0 += FE0[ip][r]*w[0][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 2 + double I[1]; + // Number of operations: 2 + I[0] = F0*W25[ip]*det; + + + // Number of operations for primary indices: 300 + for (unsigned int j = 0; j < 10; j++) + { + for (unsigned int k = 0; k < 10; k++) + { + // Number of operations to compute entry: 3 + A[j*10 + k] += FE1[ip][j]*FE1[ip][k]*I[0]; + }// 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 mass_matrix_f1_p2_q3_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p2_q3_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p2_q3_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1))), 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 mass_matrix_f1_p2_q3_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p2_q3_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p2_q3_quadrature_finite_element_0(); + 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 mass_matrix_f1_p2_q3_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p2_q3_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p2_q3_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f1_p2_q3_tensor.h b/mass_matrix_2d/mass_matrix_f1_p2_q3_tensor.h new file mode 100644 index 0000000..901aff1 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p2_q3_tensor.h @@ -0,0 +1,5368 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P2_Q3_TENSOR_H +#define __MASS_MATRIX_F1_P2_Q3_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p2_q3_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p2_q3_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p2_q3_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p2_q3_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p2_q3_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p2_q3_tensor_finite_element_1() + { + // 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p2_q3_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p2_q3_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p2_q3_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p2_q3_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p2_q3_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p2_q3_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f1_p2_q3_tensor_dofmap_1() + { + // 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.0*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 mass_matrix_f1_p2_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 mass_matrix_f1_p2_q3_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p2_q3_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 6 + // Number of operations (multiply-add pairs) for tensor contraction: 191 + // Total number of operations (multiply-add pairs): 206 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0 = det*w[0][0]*(1.0); + const double G0_1 = det*w[0][1]*(1.0); + const double G0_2 = det*w[0][2]*(1.0); + const double G0_3 = det*w[0][3]*(1.0); + const double G0_4 = det*w[0][4]*(1.0); + const double G0_5 = det*w[0][5]*(1.0); + + // Compute element tensor + A[73] = 0.000401785714285713*G0_0 - 0.00200892857142856*G0_1 + 0.00120535714285714*G0_2 - 0.00482142857142856*G0_3 - 0.00160714285714285*G0_4 - 0.00321428571428571*G0_5; + A[69] = A[73] - 0.00361607142857142*G0_0 + 0.000401785714285714*G0_1 + 0.00281249999999999*G0_2 + 0.01125*G0_3 + 0.01125*G0_4; + A[7] = 0.00267857142857141*G0_0 - 0.000446428571428569*G0_1 - 0.00089285714285714*G0_3; + A[37] = A[73]; + A[25] = 0.000758928571428568*G0_0 - 0.000133928571428571*G0_1 - 0.00133928571428571*G0_2 + 0.000714285714285711*G0_5; + A[85] = A[73] - 0.00241071428571427*G0_0 + 0.00241071428571428*G0_1 + 0.0032142857142857*G0_3 - 0.0032142857142857*G0_4; + A[58] = A[85]; + A[90] = 0.000267857142857142*G0_1 + 0.000267857142857142*G0_2 + 0.00214285714285714*G0_3; + A[55] = -A[73] + 0.00843749999999995*G0_0 - 0.00441964285714284*G0_1 - 0.00120535714285713*G0_2 + 0.0224999999999999*G0_4 + 0.00482142857142855*G0_5; + A[11] = -0.000198412698412698*G0_0 + 0.00327380952380951*G0_1 - 0.000198412698412698*G0_2 + 0.00119047619047618*G0_3 + 0.000396825396825396*G0_4 + 0.00119047619047618*G0_5; + A[32] = A[25] - 0.000892857142857139*G0_0 + 0.000892857142857139*G0_1; + A[26] = -0.000446428571428569*G0_0 + 0.00267857142857141*G0_2 - 0.000892857142857139*G0_5; + A[60] = -0.00133928571428571*G0_0 - 0.000133928571428571*G0_1 + 0.000758928571428568*G0_2 + 0.000714285714285712*G0_3; + A[16] = A[60] + 0.00084821428571428*G0_0 - 8.92857142857138e-05*G0_1 - 0.000178571428571427*G0_2 + 0.00124999999999999*G0_4 + 0.000178571428571428*G0_5; + A[40] = A[16] + 0.000267857142857141*G0_0 - 0.000267857142857142*G0_1 + 0.000535714285714285*G0_3 - 0.000535714285714284*G0_4; + A[4] = A[40]; + A[82] = A[16] + 0.000803571428571425*G0_1 - 0.000803571428571424*G0_2 - 0.00107142857142857*G0_4 + 0.00107142857142856*G0_5; + A[1] = -A[16] - 0.000267857142857143*G0_0 + 0.000615079365079362*G0_2 + 0.000753968253968252*G0_3 + 0.00128968253968253*G0_4 + 0.000436507936507935*G0_5; + A[31] = 0.00267857142857141*G0_1 - 0.000446428571428569*G0_2 - 0.00089285714285714*G0_4; + A[99] = -0.00964285714285711*G0_0 - 0.00964285714285711*G0_1 - 0.00964285714285711*G0_2 + 0.0578571428571427*G0_3 + 0.0578571428571427*G0_4 + 0.0578571428571427*G0_5; + A[21] = A[1] - 0.000188492063492062*G0_0 + 0.000188492063492062*G0_2 + 0.000218253968253967*G0_3 - 0.000218253968253967*G0_5; + A[89] = A[69] + 0.00562499999999998*G0_1 - 0.00562499999999998*G0_2 - 0.0128571428571428*G0_4 + 0.0128571428571428*G0_5; + A[93] = A[89] + 0.00160714285714285*G0_0 - 0.00160714285714285*G0_2 + 0.00321428571428569*G0_3 - 0.00321428571428571*G0_5; + A[94] = A[69] + 0.00160714285714285*G0_0 - 0.00160714285714285*G0_1 + 0.00321428571428571*G0_3 - 0.0032142857142857*G0_4; + A[51] = A[16] + 0.00107142857142857*G0_0 - 0.00107142857142857*G0_2 - 0.000535714285714284*G0_3 + 0.000535714285714282*G0_5; + A[72] = A[40] + 0.000803571428571425*G0_0 - 0.000803571428571426*G0_2 - 0.00107142857142857*G0_3 + 0.00107142857142856*G0_5; + A[15] = A[51]; + A[22] = A[11] - 0.0034722222222222*G0_1 + 0.0034722222222222*G0_2 + 0.000793650793650789*G0_4 - 0.00079365079365079*G0_5; + A[86] = A[73] + 0.00120535714285714*G0_0 + 0.00160714285714285*G0_1 - 0.00160714285714285*G0_2 + 0.00321428571428571*G0_3 + 0.00160714285714286*G0_5; + A[41] = -0.000133928571428571*G0_0 - 0.00133928571428571*G0_1 + 0.000758928571428568*G0_2 + 0.000714285714285712*G0_4; + A[97] = A[89] + 0.00723214285714283*G0_0 - 0.00723214285714283*G0_1 - 0.00964285714285712*G0_3 + 0.0096428571428571*G0_4; + A[75] = A[97] + 0.00160714285714285*G0_1 + 0.00642857142857141*G0_3 + 0.00160714285714286*G0_4 - 0.00160714285714285*G0_5; + A[64] = A[69] + 0.00160714285714285*G0_0 + 0.00160714285714286*G0_3 - 0.00160714285714285*G0_4 + 0.00642857142857141*G0_5; + A[71] = A[41] + 0.000892857142857138*G0_0 - 0.000892857142857138*G0_2; + A[5] = A[7] + 0.000446428571428569*G0_1 - 0.000446428571428569*G0_2; + A[10] = A[1]; + A[8] = A[60] + 0.000892857142857139*G0_1 - 0.000892857142857139*G0_2; + A[35] = A[86] - 0.00200892857142856*G0_0 + 0.00200892857142856*G0_2; + A[27] = A[72]; + A[83] = A[89] + 0.00160714285714285*G0_0 + 0.00160714285714284*G0_3 + 0.0064285714285714*G0_4 - 0.00160714285714286*G0_5; + A[46] = A[64]; + A[92] = 0.000267857142857142*G0_0 + 0.000267857142857142*G0_1 + 0.00214285714285713*G0_5; + A[61] = A[16]; + A[57] = A[75]; + A[74] = A[86] - 0.00200892857142856*G0_0 + 0.00200892857142856*G0_1; + A[2] = A[1] - 0.000188492063492062*G0_1 + 0.000188492063492062*G0_2 + 0.000218253968253967*G0_4 - 0.000218253968253967*G0_5; + A[13] = A[31]; + A[30] = A[40] + 0.00107142857142857*G0_1 - 0.00107142857142857*G0_2 - 0.000535714285714284*G0_4 + 0.000535714285714283*G0_5; + A[28] = A[82]; + A[98] = A[89]; + A[80] = A[8]; + A[62] = A[26]; + A[50] = A[5]; + A[14] = A[41]; + A[39] = A[93]; + A[23] = A[32]; + A[19] = 0.000267857142857142*G0_0 + 0.000267857142857142*G0_2 + 0.00214285714285713*G0_4; + A[42] = A[26] + 0.000446428571428569*G0_0 - 0.000446428571428569*G0_1; + A[96] = A[69]; + A[65] = A[85] + 0.000803571428571428*G0_1 - 0.0032142857142857*G0_2 - 0.00160714285714285*G0_3; + A[36] = A[65] + 0.0032142857142857*G0_0 - 0.000803571428571426*G0_1 + 0.00160714285714285*G0_5; + A[53] = A[35]; + A[70] = A[7]; + A[68] = A[86]; + A[6] = A[60]; + A[17] = A[71]; + A[9] = A[90]; + A[34] = A[73] + 0.000803571428571427*G0_0 - 0.0032142857142857*G0_2 - 0.00160714285714285*G0_4; + A[45] = A[34] - 0.000803571428571426*G0_0 + 0.0032142857142857*G0_1 + 0.00160714285714285*G0_5; + A[67] = A[45] - 0.00241071428571427*G0_0 + 0.00241071428571428*G0_2 + 0.0032142857142857*G0_3 - 0.0032142857142857*G0_5; + A[76] = A[67]; + A[78] = A[67] - 0.0032142857142857*G0_1 + 0.000803571428571428*G0_2 - 0.00160714285714285*G0_3; + A[54] = A[45]; + A[48] = A[78] + 0.0032142857142857*G0_0 - 0.000803571428571426*G0_2 + 0.00160714285714285*G0_4; + A[87] = A[78]; + A[24] = A[42]; + A[84] = A[48]; + A[59] = A[69] + 0.00723214285714283*G0_0 - 0.00723214285714283*G0_2 - 0.00964285714285711*G0_3 + 0.0096428571428571*G0_5; + A[47] = A[74]; + A[91] = A[19]; + A[66] = A[55] - 0.0104464285714285*G0_0 + 0.0104464285714285*G0_2 + 0.0032142857142857*G0_3 - 0.0032142857142857*G0_5; + A[56] = A[65]; + A[77] = A[55] - 0.0160714285714285*G0_4 + 0.0160714285714285*G0_5; + A[3] = A[30]; + A[12] = A[21]; + A[49] = A[94]; + A[33] = A[55] - 0.0104464285714285*G0_0 + 0.0104464285714285*G0_1 + 0.0192857142857142*G0_3 - 0.0192857142857142*G0_4; + A[29] = A[92]; + A[81] = A[31] - 0.000446428571428569*G0_0 + 0.000446428571428569*G0_2; + A[44] = A[66] + 0.0160714285714285*G0_3 - 0.0160714285714285*G0_4; + A[63] = A[36]; + A[0] = A[11] + 0.0034722222222222*G0_0 - 0.0034722222222222*G0_1 - 0.000793650793650789*G0_3 + 0.000793650793650788*G0_4; + A[79] = A[97]; + A[38] = A[83]; + A[20] = A[2]; + A[18] = A[81]; + A[88] = A[33] - 0.0160714285714285*G0_3 + 0.0160714285714285*G0_5; + A[43] = A[34]; + A[95] = A[59]; + A[52] = A[25]; + } + + /// 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 mass_matrix_f1_p2_q3_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p2_q3_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p2_q3_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1))), 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 mass_matrix_f1_p2_q3_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p2_q3_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p2_q3_tensor_finite_element_0(); + 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 mass_matrix_f1_p2_q3_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p2_q3_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p2_q3_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f1_p2_q4_excafe.h b/mass_matrix_2d/mass_matrix_f1_p2_q4_excafe.h new file mode 100644 index 0000000..f56da61 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p2_q4_excafe.h @@ -0,0 +1,500 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 3.47 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 = -1.0000000000000000000000000*x[0][1]; + const double var_1 = x[1][1] + var_0; + const double var_2 = -1.0000000000000000000000000*x[0][0]; + const double var_3 = x[2][0] + var_2; + const double var_4 = x[2][1] + var_0; + const double var_5 = x[1][0] + var_2; + const double var_6 = -1.0000000000000000000000000*var_1*var_3 + var_4*var_5; + const double var_7 = std::abs(var_6); + const double var_8 = w[0][3] + w[0][5]; + const double var_9 = w[0][0] + w[0][2]; + const double var_10 = -0.0571428571428571410728559*w[0][4] + 0.0030303030303030303004019*w[0][1] + 0.0242424242424242424032155*var_9 + -0.0043290043290043290005742*var_8; + A[22] = 0.0074074074074074076901031*var_10*var_7; + const double var_11 = 0.3333333333333333148296163*w[0][4] + -0.1666666666666666574148081*var_9 + var_8; + const double var_12 = -1.0000000000000000000000000*w[0][0]; + const double var_13 = 38.0000000000000000000000000*w[0][3] + var_12; + const double var_14 = 0.0001539201539201539290554*var_13*var_7; + const double var_15 = -1.0000000000000000000000000*w[0][2]; + const double var_16 = var_15 + 0.8888888888888888395456433*w[0][5]; + const double var_17 = 0.0034632034632034632004594*var_16*var_7; + const double var_18 = -1.0000000000000000000000000*w[0][4]; + const double var_19 = w[0][1] + 2.6666666666666665186369300*var_18; + const double var_20 = 0.0011544011544011544001531*var_19*var_7; + A[74] = var_14 + var_17 + var_20; + const double var_21 = 0.0037624926513815403796015*var_7*w[0][3] + -0.0014365881032547698960972*var_7*w[0][0]; + const double var_22 = -0.0033349366682700015522556*var_7*w[0][4] + 0.0003591470258136924740243*var_7*w[0][1]; + const double var_23 = w[0][4] + w[0][3]; + const double var_24 = w[0][0] + w[0][1]; + const double var_25 = var_23 + 0.3333333333333333148296163*w[0][5] + -0.1666666666666666574148081*var_24; + A[32] = 0.0004008337341670675422166*var_25*var_7 + 0.0017556517556517555779527*var_7*w[0][2]; + const double var_26 = -4.0000000000000000000000000*var_23 + -11.3333333333333321490954404*w[0][5] + w[0][2]; + const double var_27 = 0.0032836299502966171531826*var_7*w[0][4] + -0.0013339746673080006642703*var_7*w[0][1]; + const double var_28 = -1.0000000000000000000000000*w[0][5]; + const double var_29 = var_15 + 2.0000000000000000000000000*var_28; + const double var_30 = 0.0002052268718935385720739*var_29*var_7; + const double var_31 = -1.0000000000000000000000000*w[0][3]; + const double var_32 = 0.0008209074875741542882956*var_31*var_7; + const double var_33 = var_32 + 0.0017444284110950778084181*var_7*w[0][0]; + A[177] = var_30 + var_27 + var_33; + A[191] = A[177]; + const double var_34 = 3.8000000000000002664535259*w[0][4] + -13.1666666666666660745477202*w[0][1] + -0.6666666666666666296592325*var_8; + const double var_35 = 0.0000962000962000961954953*var_34*var_7; + const double var_36 = -0.0000384800384800384822639*var_7*w[0][2]; + const double var_37 = 0.0003623536956870290260714*var_7*w[0][0]; + A[25] = var_35 + var_36 + var_37; + A[151] = A[25]; + const double var_38 = 0.0016076104964993854270355*var_7*w[0][1]; + A[164] = 0.0004617604617604617600612*var_26*var_7 + 0.0008465608465608465962524*var_24*var_7; + A[220] = A[164]; + const double var_39 = w[0][4] + w[0][5]; + const double var_40 = w[0][1] + w[0][2]; + const double var_41 = -1.0000000000000000000000000*var_40; + const double var_42 = 2.0000000000000000000000000*w[0][3] + w[0][0] + var_41; + A[209] = 0.0012313612313612314324435*var_42*var_7 + -0.0073881673881673881609800*var_39*var_7; + const double var_43 = 0.0037624926513815403796015*var_7*w[0][4] + -0.0014365881032547698960972*var_7*w[0][1]; + const double var_44 = -0.3961038961038961248029011*w[0][4] + -0.5616883116883116811024479*var_9 + 0.1250000000000000000000000*w[0][1] + -0.0259740259740259757381686*var_8; + A[2] = 0.0001646090534979423997391*var_44*var_7; + const double var_45 = 2.4285714285714283811046243*var_23 + var_15 + 4.1428571428571423496123316*w[0][5]; + const double var_46 = 0.0000812356367911923582222*var_7*w[0][2] + -0.0004361071027737694521045*var_7*w[0][5]; + const double var_47 = 0.0030784030784030782558480*var_15*var_7 + 0.0009235209235209235201225*var_28*var_7; + const double var_48 = -1.0000000000000000000000000*w[0][1]; + const double var_49 = 38.0000000000000000000000000*w[0][4] + var_48; + const double var_50 = -1.0000000000000000000000000*var_9; + const double var_51 = 0.0571428571428571410728559*w[0][4] + 0.0158730158730158721347436*w[0][1] + 0.0222222222222222230703093*var_50 + 0.1079365079365079416184869*var_8; + const double var_52 = 4.0000000000000000000000000*w[0][3]; + const double var_53 = var_15 + var_52; + const double var_54 = 23.0000000000000000000000000*w[0][4] + w[0][1]; + const double var_55 = 0.0000513067179733846430185*var_54*var_7; + const double var_56 = 0.0000513067179733846430185*var_7*w[0][5]; + const double var_57 = -0.0009491742825076159364994*var_7*w[0][0]; + A[116] = var_56 + 0.0000769600769600769645277*var_53*var_7 + var_55 + var_57; + const double var_58 = -0.0019496552829886164889123*var_7*w[0][1]; + A[106] = A[22]; + const double var_59 = 4.0000000000000000000000000*w[0][5]; + const double var_60 = var_48 + var_59; + const double var_61 = w[0][0] + 23.0000000000000000000000000*w[0][3]; + const double var_62 = 0.0000513067179733846430185*var_61*var_7; + const double var_63 = -0.0009491742825076159364994*var_7*w[0][2]; + const double var_64 = 0.0000513067179733846430185*var_7*w[0][4]; + A[66] = 0.0000769600769600769645277*var_60*var_7 + var_62 + var_64 + var_63; + A[94] = A[66]; + const double var_65 = 0.0001539201539201539290554*var_49*var_7; + const double var_66 = w[0][5] + -0.0969696969696969696128619*w[0][2]; + const double var_67 = 0.0112874779541446215724854*var_66*var_7; + const double var_68 = 0.0032836299502966171531826*var_7*w[0][3] + -0.0013339746673080006642703*var_7*w[0][0]; + const double var_69 = var_48 + 2.0000000000000000000000000*var_18; + const double var_70 = 0.0002052268718935385720739*var_69*var_7; + const double var_71 = 0.0008209074875741542882956*var_28*var_7; + const double var_72 = var_71 + 0.0017444284110950778084181*var_7*w[0][2]; + A[104] = var_72 + var_68 + var_70; + A[216] = A[104]; + const double var_73 = 0.0061568061568061565116960*var_7*w[0][5]; + const double var_74 = 0.8888888888888888395456433*w[0][4] + var_48; + const double var_75 = 0.0034632034632034632004594*var_7*var_74; + const double var_76 = 2.6666666666666665186369300*var_28 + w[0][2]; + const double var_77 = 0.0011544011544011544001531*var_7*var_76; + A[73] = var_14 + var_75 + var_77; + const double var_78 = -0.0002223291112180001197467*var_7*w[0][3]; + const double var_79 = var_78 + 0.0005772005772005772000766*var_7*w[0][0]; + const double var_80 = 0.0002137779915557693323578*var_48*var_7; + const double var_81 = -0.0495238095238095255012922*var_23 + -0.0228571428571428571230317*w[0][5] + 0.1904761904761904656169236*w[0][2] + -0.0133333333333333341891302*var_24; + const double var_82 = var_12 + 2.0000000000000000000000000*var_31; + const double var_83 = 0.0002052268718935385720739*var_7*var_82; + A[59] = var_72 + var_83 + var_27; + const double var_84 = 0.0018470418470418470402450*var_7*w[0][4]; + const double var_85 = var_84 + 0.0082090748757415420155947*var_7*w[0][1]; + const double var_86 = 4.1200000000000001065814104*var_23 + 18.4400000000000012789769244*w[0][5] + 2.0000000000000000000000000*var_24 + -1.6400000000000001243449788*w[0][2]; + const double var_87 = 4.1428571428571423496123316*w[0][3] + var_12 + 2.4285714285714283811046243*var_39; + const double var_88 = -0.0014365881032547698960972*var_7*w[0][2] + 0.0037624926513815403796015*var_7*w[0][5]; + const double var_89 = w[0][4] + -0.0969696969696969696128619*w[0][1]; + const double var_90 = 0.0112874779541446215724854*var_7*var_89; + const double var_91 = 0.0018470418470418470402450*var_7*w[0][3]; + const double var_92 = 0.0082090748757415420155947*var_7*w[0][0] + var_91; + A[96] = var_90 + var_92 + var_88; + const double var_93 = -0.0001795735129068462370121*var_7*w[0][4] + 0.0001539201539201539290554*var_7*w[0][1]; + const double var_94 = -4.3333333333333330372738601*w[0][0] + var_31; + const double var_95 = 0.0000769600769600769645277*var_7*var_94; + const double var_96 = -0.0009748276414943082444561*var_7*w[0][5]; + A[42] = var_96 + var_93 + var_95; + A[182] = A[42]; + const double var_97 = var_48 + var_52; + const double var_98 = 0.0004104537437870771441478*var_15*var_7 + 0.0011629522740633853501724*var_7*w[0][5]; + const double var_99 = 0.0016076104964993854270355*var_7*w[0][0]; + A[101] = var_84 + 0.0001026134359467692860370*var_7*var_97 + var_99 + var_98; + A[171] = A[101]; + const double var_100 = var_23 + 6.8000000000000007105427358*w[0][5] + w[0][2]; + A[44] = 0.0000769600769600769645277*var_24*var_7 + 0.0001282667949334615939937*var_100*var_7; + const double var_101 = -0.6666666666666666296592325*var_23 + 3.8000000000000002664535259*w[0][5] + -13.1666666666666660745477202*w[0][2]; + const double var_102 = 0.0000962000962000961954953*var_101*var_7; + const double var_103 = -0.0000384800384800384822639*var_7*w[0][1]; + A[37] = var_103 + var_102 + var_37; + A[107] = A[37]; + const double var_104 = var_28 + -4.3333333333333330372738601*w[0][2]; + const double var_105 = 0.0000769600769600769645277*var_104*var_7; + const double var_106 = 4.0000000000000000000000000*w[0][4]; + const double var_107 = var_106 + var_15; + const double var_108 = -0.0009491742825076159364994*var_7*w[0][1]; + A[69] = var_108 + var_62 + var_56 + 0.0000769600769600769645277*var_107*var_7; + const double var_109 = var_12 + var_59; + const double var_110 = -0.2909090909090908949607979*w[0][4] + w[0][1]; + const double var_111 = 0.0056437389770723107862427*var_110*var_7; + const double var_112 = -0.0019496552829886164889123*var_7*w[0][2]; + const double var_113 = 0.0061568061568061565116960*var_7*w[0][3]; + A[58] = 0.0010261343594676927519493*var_109*var_7 + var_113 + var_112 + var_111; + A[198] = A[58]; + const double var_114 = -0.0017444284110950778084181*var_7*w[0][2] + 0.0016418149751483085765913*var_7*w[0][5]; + const double var_115 = 0.0020522687189353855038987*var_31*var_7 + 0.0006156806156806157162217*var_7*w[0][0]; + const double var_116 = 0.0008209074875741542882956*var_18*var_7; + const double var_117 = var_116 + 0.0001026134359467692860370*var_7*w[0][1]; + A[87] = var_115 + var_117 + var_114; + A[185] = A[87]; + const double var_118 = 0.0181818181818181809350499*var_106 + 0.2424242424242424309710486*w[0][1] + -0.0464646464646464654735247*var_9 + 0.2222222222222222098864108*var_8; + const double var_119 = 0.0020522687189353855038987*var_18*var_7 + 0.0006156806156806157162217*var_7*w[0][1]; + const double var_120 = var_32 + 0.0001026134359467692860370*var_7*w[0][0]; + A[133] = var_119 + var_120 + var_114; + const double var_121 = -0.0002223291112180001197467*var_7*w[0][4]; + const double var_122 = 0.0005772005772005772000766*var_7*w[0][1] + var_121; + const double var_123 = -0.0004361071027737694521045*var_7*w[0][3] + 0.0000812356367911923582222*var_7*w[0][0]; + const double var_124 = 4.1428571428571423496123316*w[0][4] + var_48 + 2.4285714285714283811046243*var_8; + const double var_125 = 0.0011629522740633853501724*var_7*w[0][3] + 0.0004104537437870771441478*var_12*var_7; + const double var_126 = 0.0016076104964993854270355*var_7*w[0][2]; + A[53] = var_84 + 0.0001026134359467692860370*var_60*var_7 + var_126 + var_125; + const double var_127 = -1.0000000000000000000000000*var_24; + const double var_128 = 2.0000000000000000000000000*w[0][5] + w[0][2] + var_127; + const double var_129 = 0.3555555555555555691249481*w[0][0] + var_31; + const double var_130 = 0.0023088023088023088003062*var_129*var_7; + A[68] = var_22 + var_47 + var_130; + A[124] = A[68]; + const double var_131 = -0.2909090909090908949607979*w[0][5] + w[0][2]; + const double var_132 = 0.0056437389770723107862427*var_131*var_7; + const double var_133 = 0.0061568061568061565116960*var_7*w[0][4]; + const double var_134 = -0.0019496552829886164889123*var_7*w[0][0]; + A[134] = var_133 + 0.0010261343594676927519493*var_7*var_97 + var_134 + var_132; + A[218] = A[134]; + const double var_135 = 0.0158730158730158721347436*w[0][0] + 0.0571428571428571410728559*w[0][3] + 0.0222222222222222230703093*var_41 + 0.1079365079365079416184869*var_39; + const double var_136 = 0.0666666666666666657414808*w[0][3] + var_12; + const double var_137 = 0.0003848003848003847819810*var_136*var_7; + const double var_138 = 0.0000256533589866923215092*var_18*var_7 + 0.0000299289188178077050393*var_7*w[0][1]; + const double var_139 = -0.0002223291112180001197467*var_7*w[0][5]; + const double var_140 = var_139 + 0.0005772005772005772000766*var_7*w[0][2]; + A[36] = var_140 + var_138 + var_137; + const double var_141 = 0.0030303030303030303004019*w[0][0] + -0.0571428571428571410728559*w[0][3] + 0.0242424242424242424032155*var_40 + -0.0043290043290043290005742*var_39; + A[4] = 0.0074074074074074076901031*var_141*var_7; + const double var_142 = -0.2222222222222222098864108*w[0][4] + var_48; + const double var_143 = 0.0003463203463203463200459*var_142*var_7; + const double var_144 = var_139 + 0.0000128266794933461607546*var_7*w[0][2]; + A[3] = var_143 + var_123 + var_144; + A[45] = A[3]; + const double var_145 = w[0][0] + var_40; + const double var_146 = 0.0002052268718935385720739*var_145*var_7; + const double var_147 = 0.6666666666666666296592325*w[0][3] + var_39; + A[131] = var_146 + 0.0006156806156806157162217*var_147*var_7; + const double var_148 = -0.0009748276414943082444561*var_7*w[0][3]; + const double var_149 = 1.8571428571428569842538536*w[0][0] + w[0][3]; + const double var_150 = -0.0017957351290684624243316*var_149*var_7; + A[193] = 0.0012313612313612314324435*var_128*var_7 + -0.0073881673881673881609800*var_23*var_7; + A[207] = A[193]; + const double var_151 = var_28 + 0.3555555555555555691249481*w[0][2]; + const double var_152 = 0.0023088023088023088003062*var_151*var_7; + const double var_153 = 0.3333333333333333148296163*w[0][3] + -0.1666666666666666574148081*var_40 + var_39; + A[0] = 0.0004008337341670675422166*var_153*var_7 + 0.0017556517556517555779527*var_7*w[0][0]; + const double var_154 = 0.0000513067179733846430185*var_7*w[0][3]; + A[52] = 0.0000769600769600769645277*var_109*var_7 + var_63 + var_154 + var_55; + const double var_155 = -0.0033349366682700015522556*var_7*w[0][3] + 0.0003591470258136924740243*var_7*w[0][0]; + const double var_156 = 0.3555555555555555691249481*w[0][1] + var_18; + const double var_157 = 0.0023088023088023088003062*var_156*var_7; + A[82] = var_157 + var_155 + var_47; + A[110] = A[82]; + const double var_158 = var_106 + var_12; + A[89] = var_113 + var_58 + 0.0010261343594676927519493*var_158*var_7 + var_132; + const double var_159 = 0.8888888888888888395456433*w[0][3] + var_12; + const double var_160 = 0.0034632034632034632004594*var_159*var_7; + const double var_161 = var_15 + 38.0000000000000000000000000*w[0][5]; + const double var_162 = 0.0001539201539201539290554*var_161*var_7; + A[162] = var_160 + var_20 + var_162; + A[190] = A[162]; + const double var_163 = 0.0001539201539201539290554*var_7*w[0][2] + -0.0001795735129068462370121*var_7*w[0][5]; + const double var_164 = -0.3961038961038961248029011*w[0][3] + -0.5616883116883116811024479*var_40 + 0.1250000000000000000000000*w[0][0] + -0.0259740259740259757381686*var_39; + A[17] = 0.0001646090534979423997391*var_164*var_7; + const double var_165 = -13.1666666666666660745477202*w[0][0] + 3.8000000000000002664535259*w[0][3] + -0.6666666666666666296592325*var_39; + A[98] = 0.0014707925819036930456529*var_7*var_9 + 0.0004788627010849232806290*var_124*var_7; + const double var_166 = -11.3333333333333321490954404*w[0][3] + w[0][0] + -4.0000000000000000000000000*var_39; + A[72] = 0.0004617604617604617600612*var_166*var_7 + 0.0008465608465608465962524*var_40*var_7; + A[184] = A[72]; + const double var_167 = 0.0001710223932446154767283*var_7*w[0][3]; + const double var_168 = 0.0007952541285874619803389*var_7*w[0][2] + -0.0038480038480038481450707*var_7*w[0][5]; + const double var_169 = -0.0023088023088023088003062*var_7*w[0][4] + 0.0007952541285874619803389*var_48*var_7; + A[145] = var_150 + var_169 + var_168; + A[159] = A[145]; + const double var_170 = 0.0016418149751483085765913*var_7*w[0][4] + -0.0017444284110950778084181*var_7*w[0][1]; + const double var_171 = var_71 + 0.0001026134359467692860370*var_7*w[0][2]; + A[57] = var_115 + var_170 + var_171; + const double var_172 = 0.0666666666666666657414808*w[0][4] + var_48; + const double var_173 = 0.0003848003848003847819810*var_172*var_7; + const double var_174 = 0.0000256533589866923215092*var_31*var_7 + 0.0000299289188178077050393*var_7*w[0][0]; + A[33] = var_140 + var_174 + var_173; + const double var_175 = 0.0003591470258136924740243*var_7*w[0][2] + -0.0033349366682700015522556*var_7*w[0][5]; + const double var_176 = 0.0030784030784030782558480*var_12*var_7 + 0.0009235209235209235201225*var_31*var_7; + A[114] = var_157 + var_176 + var_175; + const double var_177 = 0.0000962000962000961954953*var_165*var_7; + const double var_178 = 0.0003623536956870290260714*var_7*w[0][1]; + A[10] = var_177 + var_178 + var_36; + const double var_179 = 0.0000128266794933461607546*var_7*w[0][1] + var_121; + const double var_180 = var_15 + -0.2222222222222222098864108*w[0][5]; + const double var_181 = 0.0003463203463203463200459*var_180*var_7; + A[173] = A[131]; + A[14] = var_148 + var_93 + var_105; + const double var_182 = -0.0000384800384800384822639*var_7*w[0][0]; + A[34] = var_178 + var_182 + var_102; + A[62] = A[34]; + const double var_183 = 0.0009235209235209235201225*var_18*var_7 + 0.0030784030784030782558480*var_48*var_7; + A[55] = var_155 + var_183 + var_152; + A[153] = A[55]; + A[117] = var_160 + var_77 + var_65; + A[187] = A[117]; + const double var_184 = -0.1975308641975308532323652*w[0][5] + w[0][2]; + const double var_185 = 0.0017316017316017316002297*var_184*var_7; + const double var_186 = 0.0001710223932446154767283*var_7*w[0][4]; + const double var_187 = 0.0002137779915557693323578*var_12*var_7; + A[38] = 0.0000213777991555769345910*var_7*var_97 + var_185 + var_187 + var_186; + A[122] = A[38]; + const double var_188 = 0.0006156806156806157162217*var_7*w[0][2] + 0.0020522687189353855038987*var_28*var_7; + A[50] = 0.0004788627010849232806290*var_7*var_87 + 0.0014707925819036930456529*var_40*var_7; + A[78] = A[50]; + const double var_189 = -0.0038480038480038481450707*var_7*w[0][3] + 0.0007952541285874619803389*var_7*w[0][0]; + const double var_190 = w[0][5] + 1.8571428571428569842538536*w[0][2]; + const double var_191 = -0.0017957351290684624243316*var_190*var_7; + A[65] = var_191 + var_169 + var_189; + A[79] = A[65]; + const double var_192 = -0.0023088023088023088003062*var_7*w[0][3] + 0.0007952541285874619803389*var_12*var_7; + const double var_193 = -0.0013339746673080006642703*var_7*w[0][2] + 0.0032836299502966171531826*var_7*w[0][5]; + const double var_194 = var_116 + 0.0017444284110950778084181*var_7*w[0][1]; + A[88] = var_193 + var_194 + var_83; + A[200] = A[88]; + const double var_195 = 0.0016418149751483085765913*var_7*w[0][3] + -0.0017444284110950778084181*var_7*w[0][0]; + A[149] = var_117 + var_195 + var_188; + A[219] = A[149]; + const double var_196 = 0.1904761904761904656169236*w[0][0] + -0.0228571428571428571230317*w[0][3] + -0.0133333333333333341891302*var_40 + -0.0495238095238095255012922*var_39; + A[115] = 0.0101010101010101018687015*var_196*var_7; + A[157] = A[115]; + A[179] = var_170 + var_120 + var_188; + A[221] = A[179]; + const double var_197 = 0.0002137779915557693323578*var_15*var_7; + const double var_198 = 0.0003623536956870290260714*var_7*w[0][2]; + A[7] = var_103 + var_177 + var_198; + A[105] = A[7]; + const double var_199 = -0.0004361071027737694521045*var_7*w[0][4] + 0.0000812356367911923582222*var_7*w[0][1]; + const double var_200 = var_78 + 0.0000128266794933461607546*var_7*w[0][0]; + A[23] = var_200 + var_199 + var_181; + const double var_201 = 0.6666666666666666296592325*w[0][4] + var_8; + A[84] = var_146 + 0.0006156806156806157162217*var_201*var_7; + const double var_202 = -0.0228571428571428571230317*w[0][4] + -0.0133333333333333341891302*var_9 + 0.1904761904761904656169236*w[0][1] + -0.0495238095238095255012922*var_8; + const double var_203 = 0.0018470418470418470402450*var_7*w[0][5]; + const double var_204 = 0.0011629522740633853501724*var_7*w[0][4] + 0.0004104537437870771441478*var_48*var_7; + A[129] = 0.0001026134359467692860370*var_53*var_7 + var_99 + var_204 + var_203; + const double var_205 = -0.2222222222222222098864108*w[0][3] + var_12; + const double var_206 = 0.0003463203463203463200459*var_205*var_7; + A[21] = var_206 + var_199 + var_144; + A[91] = A[21]; + const double var_207 = -0.0001795735129068462370121*var_7*w[0][3] + 0.0001539201539201539290554*var_7*w[0][0]; + A[121] = A[23]; + const double var_208 = w[0][0] + -0.1975308641975308532323652*w[0][3]; + const double var_209 = 0.0017316017316017316002297*var_208*var_7; + const double var_210 = -0.0038480038480038481450707*var_7*w[0][4] + 0.0007952541285874619803389*var_7*w[0][1]; + const double var_211 = 0.0007952541285874619803389*var_15*var_7 + -0.0023088023088023088003062*var_7*w[0][5]; + A[97] = var_211 + var_150 + var_210; + A[111] = A[97]; + const double var_212 = 18.4400000000000012789769244*w[0][4] + -1.6400000000000001243449788*w[0][1] + 2.0000000000000000000000000*var_9 + 4.1200000000000001065814104*var_8; + A[112] = 0.0009620009620009620362677*var_212*var_7; + A[103] = var_119 + var_195 + var_171; + A[201] = A[103]; + A[81] = var_126 + 0.0001026134359467692860370*var_109*var_7 + var_204 + var_91; + A[95] = A[81]; + const double var_213 = 23.0000000000000000000000000*w[0][5] + w[0][2]; + A[16] = 0.0004008337341670675422166*var_11*var_7 + 0.0017556517556517555779527*var_7*w[0][1]; + const double var_214 = -0.0259740259740259757381686*var_23 + -0.3961038961038961248029011*w[0][5] + 0.1250000000000000000000000*w[0][2] + -0.5616883116883116811024479*var_24; + A[199] = A[73]; + A[1] = 0.0001646090534979423997391*var_214*var_7; + A[15] = A[1]; + A[100] = var_22 + var_176 + var_152; + const double var_215 = 2.0000000000000000000000000*w[0][4] + w[0][1] + var_50; + const double var_216 = -0.1975308641975308532323652*w[0][4] + w[0][1]; + const double var_217 = 0.0017316017316017316002297*var_216*var_7; + const double var_218 = 0.0001710223932446154767283*var_7*w[0][5]; + A[26] = var_217 + 0.0000213777991555769345910*var_53*var_7 + var_218 + var_187; + A[166] = A[26]; + A[160] = 0.0009620009620009620362677*var_7*var_86; + A[215] = A[89]; + const double var_219 = -0.0043290043290043290005742*var_23 + -0.0571428571428571410728559*w[0][5] + 0.0242424242424242424032155*var_24 + 0.0030303030303030303004019*w[0][2]; + A[40] = 0.0074074074074074076901031*var_219*var_7; + A[148] = var_68 + var_194 + var_30; + const double var_220 = 0.0082090748757415420155947*var_7*w[0][2] + var_203; + A[150] = A[10]; + const double var_221 = w[0][0] + 2.6666666666666665186369300*var_31; + const double var_222 = 0.0011544011544011544001531*var_221*var_7; + A[163] = var_75 + var_222 + var_162; + A[205] = A[163]; + const double var_223 = -4.3333333333333330372738601*w[0][1] + var_18; + const double var_224 = 6.8000000000000007105427358*w[0][3] + w[0][0] + var_39; + A[12] = 0.0001282667949334615939937*var_224*var_7 + 0.0000769600769600769645277*var_40*var_7; + A[210] = A[14]; + A[132] = var_193 + var_70 + var_33; + A[188] = A[132]; + A[47] = A[33]; + const double var_225 = 0.0000769600769600769645277*var_223*var_7; + A[43] = var_96 + var_225 + var_207; + A[197] = A[43]; + const double var_226 = 0.0000513067179733846430185*var_213*var_7; + A[85] = var_108 + var_226 + 0.0000769600769600769645277*var_158*var_7 + var_154; + A[56] = 0.0169312169312169323587280*var_118*var_7; + const double var_227 = w[0][4] + 1.8571428571428569842538536*w[0][1]; + const double var_228 = -0.0017957351290684624243316*var_227*var_7; + A[223] = A[209]; + A[67] = 0.0101010101010101018687015*var_7*var_81; + A[109] = A[67]; + const double var_229 = -11.3333333333333321490954404*w[0][4] + w[0][1] + -4.0000000000000000000000000*var_8; + A[35] = var_80 + var_167 + var_185 + 0.0000213777991555769345910*var_158*var_7; + A[77] = A[35]; + A[118] = 0.0008465608465608465962524*var_7*var_9 + 0.0004617604617604617600612*var_229*var_7; + A[202] = A[118]; + A[13] = var_148 + var_163 + var_225; + A[195] = A[13]; + const double var_230 = -0.0009748276414943082444561*var_7*w[0][4]; + A[29] = var_105 + var_230 + var_207; + A[39] = var_206 + var_179 + var_46; + A[137] = A[39]; + A[119] = var_17 + var_65 + var_222; + A[217] = A[119]; + A[168] = A[56]; + A[108] = A[52]; + const double var_231 = -0.0969696969696969696128619*w[0][0] + w[0][3]; + A[113] = var_192 + var_191 + var_210; + A[127] = A[113]; + A[27] = var_163 + var_95 + var_230; + A[181] = A[27]; + const double var_232 = w[0][0] + -0.2909090909090908949607979*w[0][3]; + const double var_233 = 0.0056437389770723107862427*var_232*var_7; + A[102] = 0.0010261343594676927519493*var_60*var_7 + var_133 + var_233 + var_112; + A[186] = A[102]; + const double var_234 = -1.6400000000000001243449788*w[0][0] + 2.0000000000000000000000000*var_40 + 18.4400000000000012789769244*w[0][3] + 4.1200000000000001065814104*var_39; + A[64] = 0.0009620009620009620362677*var_234*var_7; + A[6] = 0.0000213777991555769345910*var_60*var_7 + var_209 + var_197 + var_186; + A[90] = A[6]; + A[60] = A[4]; + const double var_235 = 6.8000000000000007105427358*w[0][4] + w[0][1] + var_8; + A[28] = 0.0000769600769600769645277*var_7*var_9 + 0.0001282667949334615939937*var_235*var_7; + A[128] = var_220 + var_90 + var_21; + const double var_236 = var_15 + 0.0666666666666666657414808*w[0][5]; + const double var_237 = 0.0003848003848003847819810*var_236*var_7; + A[19] = var_35 + var_198 + var_182; + A[61] = A[19]; + A[9] = var_80 + var_209 + var_218 + 0.0000213777991555769345910*var_107*var_7; + A[135] = A[9]; + const double var_238 = 0.0000299289188178077050393*var_7*w[0][2] + 0.0000256533589866923215092*var_28*var_7; + A[11] = var_79 + var_238 + var_173; + const double var_239 = 0.2424242424242424309710486*w[0][0] + -0.0464646464646464654735247*var_40 + 0.2222222222222222098864108*var_39 + 0.0181818181818181809350499*var_52; + A[99] = 0.0169312169312169323587280*var_239*var_7; + A[208] = 0.3878787878787878784514476*var_51*var_7; + A[123] = A[53]; + A[152] = A[40]; + A[139] = A[69]; + A[147] = var_58 + var_73 + var_233 + 0.0010261343594676927519493*var_107*var_7; + A[176] = var_67 + var_85 + var_21; + A[156] = A[100]; + A[71] = var_183 + var_175 + var_130; + A[169] = A[71]; + const double var_240 = 0.2222222222222222098864108*var_23 + 0.0181818181818181809350499*var_59 + -0.0464646464646464654735247*var_24 + 0.2424242424242424309710486*w[0][2]; + A[83] = 0.0169312169312169323587280*var_240*var_7; + A[155] = A[85]; + A[130] = var_64 + 0.0000769600769600769645277*var_7*var_97 + var_226 + var_57; + A[158] = A[130]; + A[204] = A[148]; + A[146] = 0.0014707925819036930456529*var_24*var_7 + 0.0004788627010849232806290*var_45*var_7; + A[41] = var_143 + var_200 + var_46; + A[167] = A[41]; + A[142] = A[114]; + const double var_241 = var_23 + 0.6666666666666666296592325*w[0][5]; + A[214] = A[74]; + A[178] = var_73 + 0.0010261343594676927519493*var_53*var_7 + var_134 + var_111; + A[206] = A[178]; + A[212] = A[44]; + A[54] = var_38 + var_98 + 0.0001026134359467692860370*var_158*var_7 + var_91; + A[140] = A[84]; + A[31] = A[17]; + A[5] = var_179 + var_123 + var_181; + A[75] = A[5]; + const double var_242 = 0.0112874779541446215724854*var_231*var_7; + A[48] = var_85 + var_88 + var_242; + A[143] = A[129]; + const double var_243 = 0.1079365079365079416184869*var_23 + 0.0571428571428571410728559*w[0][5] + 0.0158730158730158721347436*w[0][2] + 0.0222222222222222230703093*var_127; + A[224] = 0.3878787878787878784514476*var_243*var_7; + A[80] = var_43 + var_220 + var_242; + A[180] = A[12]; + A[196] = A[28]; + A[161] = var_228 + var_192 + var_168; + A[175] = A[161]; + A[138] = A[54]; + A[51] = var_146 + 0.0006156806156806157162217*var_241*var_7; + A[93] = A[51]; + A[192] = 0.3878787878787878784514476*var_135*var_7; + A[49] = var_211 + var_228 + var_189; + A[63] = A[49]; + A[70] = 0.0101010101010101018687015*var_202*var_7; + A[154] = A[70]; + A[213] = A[59]; + A[211] = A[29]; + A[174] = A[146]; + A[141] = A[99]; + A[20] = var_174 + var_122 + var_237; + A[76] = A[20]; + A[194] = 0.0012313612313612314324435*var_215*var_7 + -0.0073881673881673881609800*var_7*var_8; + A[24] = var_238 + var_122 + var_137; + A[136] = A[24]; + A[86] = var_38 + var_125 + var_203 + 0.0001026134359467692860370*var_107*var_7; + A[8] = var_79 + var_138 + var_237; + A[120] = A[8]; + A[222] = A[194]; + A[183] = A[57]; + A[172] = A[116]; + A[203] = A[133]; + A[18] = 0.0000213777991555769345910*var_109*var_7 + var_217 + var_167 + var_197; + A[46] = A[18]; + A[125] = A[83]; + A[30] = A[2]; + A[165] = A[11]; + A[189] = A[147]; + A[170] = A[86]; + A[126] = A[98]; + A[144] = var_67 + var_43 + var_92; + A[92] = A[36]; + } + + 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/mass_matrix_2d/mass_matrix_f1_p2_q4_quadrature.h b/mass_matrix_2d/mass_matrix_f1_p2_q4_quadrature.h new file mode 100644 index 0000000..42b05c7 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p2_q4_quadrature.h @@ -0,0 +1,7232 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P2_Q4_QUADRATURE_H +#define __MASS_MATRIX_F1_P2_Q4_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p2_q4_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p2_q4_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p2_q4_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p2_q4_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p2_q4_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p2_q4_quadrature_finite_element_1() + { + // 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.0224478343233824, 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.0412393049421162, -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.0388807895679869, 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.0439885919382571, 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.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 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.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.00927360943924092, 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.0535412090610519}; + + // 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.0622092633087791, -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.251415744421884, 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.0224478343233824, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0412393049421162, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0388807895679869, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0439885919382571, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.00927360943924092, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0622092633087791, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.251415744421884, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p2_q4_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p2_q4_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p2_q4_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p2_q4_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p2_q4_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p2_q4_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f1_p2_q4_quadrature_dofmap_1() + { + // 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.0*m.num_entities[1] + 3.0*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 mass_matrix_f1_p2_q4_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 mass_matrix_f1_p2_q4_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p2_q4_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Array of quadrature weights. + static const double W36[36] = {0.00619426535265906, 0.0116108747669979, 0.0120606064042655, 0.0084515357969434, 0.0037652982126918, 0.000748542561236343, 0.0130433943300833, 0.0244492622580587, 0.0253962715890485, 0.0177965759970269, 0.00792866733379675, 0.00157622175402364, 0.0169175056800133, 0.0317111115907051, 0.0329393989007878, 0.023082463651359, 0.0102836172287667, 0.00204438659154493, 0.0169175056800133, 0.0317111115907051, 0.0329393989007878, 0.023082463651359, 0.0102836172287667, 0.00204438659154493, 0.0130433943300833, 0.0244492622580587, 0.0253962715890485, 0.0177965759970269, 0.00792866733379675, 0.00157622175402364, 0.00619426535265908, 0.0116108747669979, 0.0120606064042655, 0.00845153579694342, 0.00376529821269181, 0.000748542561236345}; + // Quadrature points on the UFC reference element: (0.0327753666144599, 0.0293164271597849), (0.0287653330125591, 0.148078599668484), (0.0223868729780306, 0.336984690281154), (0.0149015633666711, 0.55867151877155), (0.00779187470128645, 0.769233862030055), (0.00246669715267023, 0.926945671319741), (0.164429241594827, 0.0293164271597849), (0.144311486950417, 0.148078599668484), (0.112311681780954, 0.336984690281154), (0.0747589734626491, 0.55867151877155), (0.0390907007328242, 0.769233862030055), (0.01237506041744, 0.926945671319741), (0.369529924372377, 0.0293164271597849), (0.324318304588776, 0.148078599668484), (0.252403568076518, 0.336984690281154), (0.168009519121192, 0.55867151877155), (0.0878504549759972, 0.769233862030055), (0.0278110821153606, 0.926945671319741), (0.601153648467838, 0.0293164271597849), (0.52760309574274, 0.148078599668484), (0.410611741642328, 0.336984690281154), (0.273318962107258, 0.55867151877155), (0.142915682993948, 0.769233862030055), (0.0452432465648983, 0.926945671319741), (0.806254331245388, 0.0293164271597849), (0.707609913381099, 0.148078599668484), (0.550703627937892, 0.336984690281154), (0.366569507765801, 0.55867151877155), (0.191675437237121, 0.769233862030055), (0.0606792682628189, 0.926945671319741), (0.937908206225755, 0.0293164271597849), (0.823156067318956, 0.148078599668484), (0.640628436740815, 0.336984690281154), (0.426426917861779, 0.55867151877155), (0.222974263268659, 0.769233862030055), (0.0705876315275886, 0.926945671319741) + + // Value of basis functions at quadrature points. + static const double FE0[36][6] = \ + {{0.821435400385472, -0.0306269173010354, -0.027597521356955, 0.00384342659195225, 0.109984470441528, 0.122961141239038}, + {0.532015755009065, -0.0271104442459123, -0.104224056308926, 0.0170381209259896, 0.487567191028831, 0.0947134335909535}, + {0.180181151181146, -0.0213845288145617, -0.109867327313383, 0.0301761338274608, 0.863527901361615, 0.0573666697577237}, + {-0.0627470853075864, -0.0144574501851293, 0.0655562130014708, 0.0333003161525148, 0.952930295387644, 0.0254177109510863}, + {-0.123539219108257, -0.00767044807856534, 0.414207606957291, 0.0239750954756995, 0.686077414669827, 0.00694955008400423}, + {-0.0606224040782395, -0.0024545279629842, 0.79151088383707, 0.00914597699249764, 0.261723597972845, 0.00069647323881139}, + {0.493837762058507, -0.110355290611927, -0.027597521356955, 0.0192819115366138, 0.0945459854968659, 0.530287152876896}, + {0.293813665649314, -0.102659876418736, -0.104224056308926, 0.0854777716147778, 0.419127540340042, 0.408464955123528}, + {0.0558453437100203, -0.0870838540520213, -0.109867327313383, 0.151389269199641, 0.742314765989434, 0.247401802466309}, + {-0.0978230997184779, -0.0635811652362709, 0.0655562130014709, 0.167062836984721, 0.819167774555438, 0.109617440413119}, + {-0.118196490757038, -0.0360345349652578, 0.414207606957291, 0.120279562776686, 0.58977294736884, 0.0299709086194782}, + {-0.0533153210689967, -0.0120687761767694, 0.79151088383707, 0.0458840347450652, 0.224985540220277, 0.00300363844335377}, + {0.121617769664549, -0.0964251943590678, -0.027597521356955, 0.0433331884448944, 0.0704947085885853, 0.888577049017995}, + {0.0291269575319054, -0.1139535792061, -0.104224056308926, 0.192098401561452, 0.312506910393369, 0.6844453660283}, + {-0.0734077368932363, -0.124988445721003, -0.109867327313383, 0.340224552856495, 0.553479482332581, 0.414559474738547}, + {-0.123912452012481, -0.111555122090524, 0.0655562130014709, 0.375448532862056, 0.610782078678102, 0.183680749561375}, + {-0.102065898102695, -0.0724150500970178, 0.414207606957291, 0.270310179049135, 0.439742331096391, 0.050220831096895}, + {-0.041149343845434, -0.0262641695385059, 0.79151088383707, 0.103117448726206, 0.167752126239137, 0.00503305458152761}, + {-0.0964251943590678, 0.121617769664549, -0.027597521356955, 0.0704947085885853, 0.0433331884448943, 0.888577049017995}, + {-0.1139535792061, 0.0291269575319054, -0.104224056308926, 0.312506910393369, 0.192098401561452, 0.6844453660283}, + {-0.124988445721003, -0.0734077368932363, -0.109867327313383, 0.553479482332581, 0.340224552856495, 0.414559474738547}, + {-0.111555122090524, -0.123912452012481, 0.0655562130014709, 0.610782078678102, 0.375448532862056, 0.183680749561375}, + {-0.0724150500970178, -0.102065898102695, 0.414207606957291, 0.439742331096391, 0.270310179049135, 0.050220831096895}, + {-0.026264169538506, -0.0411493438454339, 0.79151088383707, 0.167752126239137, 0.103117448726206, 0.00503305458152761}, + {-0.110355290611927, 0.493837762058507, -0.027597521356955, 0.094545985496866, 0.0192819115366137, 0.530287152876895}, + {-0.102659876418736, 0.293813665649314, -0.104224056308926, 0.419127540340043, 0.0854777716147777, 0.408464955123527}, + {-0.0870838540520213, 0.0558453437100204, -0.109867327313383, 0.742314765989434, 0.151389269199641, 0.247401802466309}, + {-0.0635811652362708, -0.0978230997184778, 0.0655562130014709, 0.819167774555438, 0.16706283698472, 0.109617440413119}, + {-0.0360345349652578, -0.118196490757038, 0.414207606957291, 0.58977294736884, 0.120279562776686, 0.0299709086194782}, + {-0.0120687761767695, -0.0533153210689966, 0.79151088383707, 0.224985540220277, 0.0458840347450654, 0.00300363844335377}, + {-0.0306269173010354, 0.821435400385472, -0.027597521356955, 0.109984470441527, 0.00384342659195216, 0.122961141239039}, + {-0.0271104442459124, 0.532015755009064, -0.104224056308926, 0.487567191028831, 0.0170381209259896, 0.0947134335909537}, + {-0.0213845288145617, 0.180181151181146, -0.109867327313383, 0.863527901361614, 0.0301761338274608, 0.0573666697577238}, + {-0.0144574501851293, -0.0627470853075864, 0.0655562130014709, 0.952930295387644, 0.0333003161525146, 0.0254177109510863}, + {-0.00767044807856535, -0.123539219108256, 0.414207606957291, 0.686077414669827, 0.0239750954756995, 0.00694955008400424}, + {-0.00245452796298434, -0.0606224040782394, 0.79151088383707, 0.261723597972845, 0.00914597699249803, 0.000696473238811418}}; + + static const double FE1[36][15] = \ + {{0.56630237132032, -0.025448739951231, -0.02340903093109, 0.00416085056960128, 0.00294793329848728, 0.00425839910756952, 0.353405794301071, -0.267147951008896, 0.121859429227921, 0.395102868735011, -0.293986529335415, 0.133116353941705, 0.0793522773075458, -0.0250575137648273, -0.0254565128177721}, + {0.118972466830072, -0.0230709318617449, -0.0341013730463095, 0.018947016495499, 0.00614695794455526, 0.00651870726857255, 0.963270822664205, -0.455714379551745, 0.186540981008593, 0.18712228544335, -0.192157632298739, 0.105324818176152, 0.257233041221556, -0.099290349448832, -0.045742430845185}, + {-0.0410559740731875, -0.0188884466735285, 0.0210511710271628, 0.0349917675522029, -0.00955924750821981, -0.00456418811345946, 0.505990196901837, 0.469464799398205, -0.130609964999847, 0.0336144002765209, -0.0816095123137331, 0.0665214829999042, 0.241648244025793, -0.140804681095384, 0.0538099525957325}, + {0.0191042291114048, -0.0133255662493701, -0.0206485123834592, 0.0405094826163528, -0.0386646995111557, 0.00643281363514752, -0.131939141811172, 0.830314310030356, 0.184083027003091, -0.00351924058446104, -0.0168682880103284, 0.0309203767076776, 0.080169244991654, -0.106829866961562, 0.140261831415824}, + {-0.00938453904605184, -0.00735417356108037, 0.0220620722354296, 0.0304878329277379, -0.0482427486128633, 0.0357504701324324, 0.0547897737103965, -0.154040051327386, 1.02304452328671, 0.000554987335758502, 0.000727851735427045, 0.00883736717957267, -0.00462319916590223, -0.0414337049897014, 0.0888235381595224}, + {-0.039411023284595, -0.00242231653722821, 0.505649261589883, 0.0120147467421047, -0.0245209639812787, 0.0281958543435565, 0.215079260438399, -0.508591455559504, 0.806859721248732, 0.000572347890212842, 0.000494891999080295, 0.000914932279387579, -0.00370647497562177, -0.0051137834055052, 0.0139850012123767}, + {0.0824161637725179, -0.0294914855256902, -0.02340903093109, 0.00590593006797314, 0.00582593260452294, 0.0213637682196615, 0.171801701915994, -0.185697684231962, 0.104754060115829, 0.963597078074327, -0.40385910184121, 0.162423670230445, 0.276723174191905, -0.0425693977624813, -0.109784778900741}, + {-0.0303969806920391, -0.0350490773722188, -0.0341013730463095, 0.0342751641157549, 0.0147321571899481, 0.0327034051200263, 0.424735375088394, -0.312771366460782, 0.160356283157139, 0.413930126815579, -0.316080712840952, 0.163787650378721, 0.885711947101502, -0.204561955373223, -0.19727064318154}, + {-0.0178494055445301, -0.0407795027424123, 0.0210511710271628, 0.0861992776649916, -0.0290104851672837, -0.0228978671335801, 0.120724252767667, 0.310663028371925, -0.112276285979726, 0.040235489181343, -0.163892320828179, 0.140867690149755, 0.802235130592271, -0.36733313364048, 0.232062961281076}, + {0.0233190985494116, -0.0401256259898051, -0.0206485123834592, 0.132794326958115, -0.144587977270839, 0.032272489268862, -0.135906939764466, 0.47160061549191, 0.158243351369376, -0.0181864708721552, -0.0358278205906738, 0.0871323298781454, 0.228439462369848, -0.343417130728224, 0.604898803713954}, + {-0.0205277588289655, -0.0288155938118291, 0.0220620722354296, 0.124718754065599, -0.21075144429941, 0.179354902713459, 0.113128801818687, -0.285771773170361, 0.879440090705682, 0.00574894626256647, 0.0058988467391181, 0.031077053282736, -0.0430288533926338, -0.155598000009121, 0.383063955689044}, + {-0.0371082327213856, -0.0112820903294173, 0.505649261589883, 0.0567111236787091, -0.118093887044145, 0.141454495394839, 0.199601225425082, -0.461345808814886, 0.69360108019745, 0.00266474864758105, 0.00216201065863758, 0.00371239609144181, -0.0168674754837758, -0.0211711248206387, 0.0603122775306251}, + {-0.0339024544799458, 0.023387640004351, -0.02340903093109, -0.00720836763307398, -0.0182888871179095, 0.0480118473937476, 0.0267093906452789, -0.0874064926762268, 0.0781059809417426, 0.336668552801051, 0.596745158445697, -0.147812572060763, 0.292720606365088, 0.0996397790360984, -0.183961150734045}, + {-0.0095906246236551, 0.0192268203241027, -0.0341013730463094, -0.0267531412354512, -0.0232811757502806, 0.0734959712974962, 0.0255429142588088, -0.141471609601455, 0.119563716979669, 0.0559434966647409, 0.225932583629769, -0.0953212697058672, 0.900337562556068, 0.241033195353002, -0.330557067100639}, + {0.0213409951908707, 0.000797264231187582, 0.0210511710271628, -0.00215970873408773, 0.00113811168767276, -0.0514595033589619, -0.0847594279128907, 0.123720487246374, -0.0837146497543445, -0.0634853233702957, 0.00256059295790888, -0.00263157879369526, 0.717999738211763, 0.0107449258196653, 0.388856905551671}, + {0.00734599742741782, -0.02839014160368, -0.0206485123834592, 0.109010467002261, -0.152030381966887, 0.0725275529045928, -0.0344381186867421, 0.0703415678092674, 0.117988287733645, -0.0103565898127769, -0.00561896434021046, 0.0533312093041724, 0.0765736536295873, -0.269236283109832, 1.01360025609264}, + {-0.0353878578540361, -0.0414666912205211, 0.0220620722354296, 0.192691111987477, -0.364133910121009, 0.403073096930251, 0.179359194783873, -0.391207466820726, 0.65572189648889, 0.0204837405679316, 0.0139522896496609, 0.0358000125005907, -0.132378708183015, -0.200450896105804, 0.641882115161008}, + {-0.031669348089454, -0.0224768586657739, 0.505649261589883, 0.115398208580281, -0.248158040619958, 0.317897646905111, 0.166615019902697, -0.372031802654953, 0.517157928687178, 0.00499893806458903, 0.00366363544055174, 0.00563246559694469, -0.0305685004026728, -0.0331709792809288, 0.101062424946505}, + {0.023387640004351, -0.0339024544799458, -0.02340903093109, 0.0267093906452788, -0.0874064926762267, 0.0781059809417426, -0.00720836763307393, -0.0182888871179095, 0.0480118473937476, -0.147812572060763, 0.596745158445697, 0.336668552801051, 0.0996397790360983, 0.292720606365088, -0.183961150734045}, + {0.0192268203241027, -0.00959062462365504, -0.0341013730463094, 0.0255429142588087, -0.141471609601455, 0.119563716979669, -0.0267531412354512, -0.0232811757502805, 0.0734959712974963, -0.0953212697058673, 0.22593258362977, 0.0559434966647408, 0.241033195353002, 0.900337562556068, -0.330557067100639}, + {0.000797264231187593, 0.0213409951908707, 0.0210511710271628, -0.0847594279128908, 0.123720487246374, -0.0837146497543445, -0.00215970873408771, 0.00113811168767294, -0.0514595033589619, -0.00263157879369533, 0.00256059295790887, -0.0634853233702957, 0.0107449258196652, 0.717999738211763, 0.388856905551671}, + {-0.0283901416036801, 0.00734599742741785, -0.0206485123834592, -0.0344381186867421, 0.0703415678092673, 0.117988287733645, 0.109010467002261, -0.152030381966887, 0.0725275529045927, 0.0533312093041724, -0.00561896434021046, -0.0103565898127769, -0.269236283109833, 0.0765736536295877, 1.01360025609264}, + {-0.0414666912205212, -0.035387857854036, 0.0220620722354296, 0.179359194783873, -0.391207466820727, 0.65572189648889, 0.192691111987477, -0.364133910121008, 0.403073096930251, 0.0358000125005907, 0.0139522896496609, 0.0204837405679316, -0.200450896105804, -0.132378708183015, 0.641882115161008}, + {-0.0224768586657739, -0.031669348089454, 0.505649261589883, 0.166615019902697, -0.372031802654953, 0.517157928687178, 0.115398208580281, -0.248158040619958, 0.317897646905111, 0.00563246559694458, 0.00366363544055176, 0.00499893806458915, -0.0331709792809289, -0.0305685004026726, 0.101062424946505}, + {-0.0294914855256903, 0.0824161637725182, -0.02340903093109, 0.171801701915994, -0.185697684231962, 0.104754060115829, 0.00590593006797323, 0.00582593260452294, 0.0213637682196615, 0.162423670230446, -0.40385910184121, 0.963597078074327, -0.0425693977624813, 0.276723174191904, -0.109784778900741}, + {-0.0350490773722189, -0.030396980692039, -0.0341013730463095, 0.424735375088395, -0.312771366460783, 0.160356283157139, 0.034275164115755, 0.0147321571899484, 0.0327034051200263, 0.163787650378721, -0.316080712840952, 0.41393012681558, -0.204561955373223, 0.885711947101502, -0.19727064318154}, + {-0.0407795027424123, -0.0178494055445301, 0.0210511710271628, 0.120724252767667, 0.310663028371925, -0.112276285979726, 0.0861992776649916, -0.0290104851672834, -0.0228978671335801, 0.140867690149755, -0.163892320828179, 0.040235489181343, -0.36733313364048, 0.802235130592271, 0.232062961281076}, + {-0.0401256259898051, 0.0233190985494116, -0.0206485123834592, -0.135906939764466, 0.471600615491911, 0.158243351369376, 0.132794326958115, -0.144587977270839, 0.0322724892688619, 0.0871323298781453, -0.0358278205906738, -0.0181864708721552, -0.343417130728224, 0.228439462369848, 0.604898803713953}, + {-0.0288155938118291, -0.0205277588289655, 0.0220620722354296, 0.113128801818687, -0.285771773170361, 0.879440090705682, 0.124718754065599, -0.21075144429941, 0.179354902713459, 0.0310770532827359, 0.00589884673911823, 0.00574894626256647, -0.155598000009122, -0.0430288533926335, 0.383063955689044}, + {-0.0112820903294174, -0.0371082327213855, 0.505649261589883, 0.199601225425082, -0.461345808814886, 0.693601080197449, 0.0567111236787092, -0.118093887044145, 0.141454495394839, 0.0037123960914417, 0.00216201065863769, 0.00266474864758115, -0.021171124820639, -0.0168674754837758, 0.0603122775306252}, + {-0.0254487399512311, 0.566302371320319, -0.02340903093109, 0.35340579430107, -0.267147951008896, 0.121859429227921, 0.00416085056960128, 0.00294793329848743, 0.00425839910756955, 0.133116353941706, -0.293986529335416, 0.395102868735012, -0.0250575137648273, 0.0793522773075462, -0.0254565128177724}, + {-0.0230709318617449, 0.118972466830072, -0.0341013730463095, 0.963270822664205, -0.455714379551745, 0.186540981008593, 0.018947016495499, 0.00614695794455568, 0.00651870726857255, 0.105324818176152, -0.192157632298739, 0.18712228544335, -0.0992903494488324, 0.257233041221557, -0.045742430845185}, + {-0.0188884466735285, -0.0410559740731874, 0.0210511710271628, 0.505990196901837, 0.469464799398205, -0.130609964999847, 0.034991767552203, -0.00955924750821949, -0.00456418811345951, 0.0665214829999044, -0.0816095123137332, 0.0336144002765209, -0.140804681095384, 0.241648244025794, 0.0538099525957328}, + {-0.0133255662493701, 0.0191042291114048, -0.0206485123834592, -0.131939141811172, 0.830314310030356, 0.184083027003091, 0.0405094826163529, -0.0386646995111555, 0.00643281363514756, 0.0309203767076776, -0.0168682880103284, -0.00351924058446107, -0.106829866961562, 0.0801692449916541, 0.140261831415824}, + {-0.00735417356108038, -0.00938453904605184, 0.0220620722354296, 0.0547897737103965, -0.154040051327387, 1.02304452328671, 0.0304878329277378, -0.0482427486128629, 0.0357504701324325, 0.00883736717957254, 0.000727851735427243, 0.000554987335758443, -0.0414337049897016, -0.00462319916590201, 0.0888235381595222}, + {-0.00242231653722834, -0.0394110232845949, 0.505649261589883, 0.215079260438399, -0.508591455559504, 0.806859721248731, 0.0120147467421051, -0.0245209639812793, 0.0281958543435579, 0.000914932279387486, 0.000494891999080461, 0.000572347890212904, -0.00511378340550558, -0.00370647497562168, 0.0139850012123772}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 225; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 24804 + for (unsigned int ip = 0; ip < 36; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + + // Total number of operations to compute function values = 12 + for (unsigned int r = 0; r < 6; r++) + { + F0 += FE0[ip][r]*w[0][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 2 + double I[1]; + // Number of operations: 2 + I[0] = F0*W36[ip]*det; + + + // Number of operations for primary indices: 675 + for (unsigned int j = 0; j < 15; j++) + { + for (unsigned int k = 0; k < 15; k++) + { + // Number of operations to compute entry: 3 + A[j*15 + k] += FE1[ip][j]*FE1[ip][k]*I[0]; + }// 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 mass_matrix_f1_p2_q4_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p2_q4_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p2_q4_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 1))), 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 mass_matrix_f1_p2_q4_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p2_q4_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p2_q4_quadrature_finite_element_0(); + 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 mass_matrix_f1_p2_q4_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p2_q4_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p2_q4_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f1_p2_q4_tensor.h b/mass_matrix_2d/mass_matrix_f1_p2_q4_tensor.h new file mode 100644 index 0000000..b76cec9 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p2_q4_tensor.h @@ -0,0 +1,7346 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P2_Q4_TENSOR_H +#define __MASS_MATRIX_F1_P2_Q4_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p2_q4_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p2_q4_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p2_q4_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p2_q4_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p2_q4_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p2_q4_tensor_finite_element_1() + { + // 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.0224478343233824, 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.0412393049421162, -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.0388807895679869, 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.0439885919382571, 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.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 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.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.00927360943924092, 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.0535412090610519}; + + // 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.0622092633087791, -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.251415744421884, 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.0224478343233824, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0412393049421162, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0388807895679869, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0439885919382571, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.00927360943924092, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0622092633087791, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.251415744421884, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p2_q4_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p2_q4_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p2_q4_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f1_p2_q4_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p2_q4_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p2_q4_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f1_p2_q4_tensor_dofmap_1() + { + // 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.0*m.num_entities[1] + 3.0*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 mass_matrix_f1_p2_q4_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 mass_matrix_f1_p2_q4_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p2_q4_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 6 + // Number of operations (multiply-add pairs) for tensor contraction: 516 + // Total number of operations (multiply-add pairs): 531 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0 = det*w[0][0]*(1.0); + const double G0_1 = det*w[0][1]*(1.0); + const double G0_2 = det*w[0][2]*(1.0); + const double G0_3 = det*w[0][3]*(1.0); + const double G0_4 = det*w[0][4]*(1.0); + const double G0_5 = det*w[0][5]*(1.0); + + // Compute element tensor + A[108] = -7.69600769600799e-05*G0_0 + 5.1306717973389e-05*G0_1 - 0.000949174282507648*G0_2 + 5.13067179733899e-05*G0_3 + 0.00118005451338788*G0_4 + 0.00030784030784032*G0_5; + A[192] = 0.00615680615680638*G0_0 - 0.00861952861952892*G0_1 - 0.00861952861952892*G0_2 + 0.0221645021645029*G0_3 + 0.0418662818662833*G0_4 + 0.0418662818662833*G0_5; + A[52] = A[108]; + A[212] = -A[108] + 0.000128266794933469*G0_1 - 0.000820907487574183*G0_2 + 0.000179573512906856*G0_3 + 0.00130832130832135*G0_4 + 0.00118005451338789*G0_5; + A[1] = -9.24589813478734e-05*G0_0 - 9.24589813478739e-05*G0_1 + 2.05761316872436e-05*G0_2 - 4.27555983111572e-06*G0_3 - 4.27555983111555e-06*G0_4 - 6.52022874245122e-05*G0_5; + A[208] = A[192] - 0.0147763347763353*G0_0 + 0.0147763347763353*G0_1 + 0.0197017797017804*G0_3 - 0.0197017797017804*G0_4; + A[31] = 2.05761316872435e-05*G0_0 - 9.24589813478735e-05*G0_1 - 9.24589813478733e-05*G0_2 - 6.52022874245119e-05*G0_3 - 4.27555983111554e-06*G0_4 - 4.27555983111566e-06*G0_5; + A[193] = -0.00123136123136127*G0_0 - 0.00123136123136128*G0_1 + 0.00123136123136127*G0_2 - 0.00738816738816765*G0_3 - 0.00738816738816764*G0_4 + 0.00246272246272255*G0_5; + A[94] = A[108] + 0.000128266794933465*G0_0 - 0.000128266794933469*G0_1 + 0.0011287477954145*G0_3 - 0.0011287477954145*G0_4; + A[21] = -A[94] - 0.000295013628346973*G0_0 + 4.27555983111579e-06*G0_1 - 0.0009363476030143*G0_2 + 0.00110309443642781*G0_3 - 0.000384800384800401*G0_4 + 8.55111966223099e-05*G0_5; + A[26] = -A[21] - 0.000560098337876136*G0_0 + 0.00181283736839299*G0_1 - 8.5511196622314e-06*G0_2 + 8.55111966223266e-06*G0_3 - 0.000778151889263028*G0_4 - 5.13067179733832e-05*G0_5; + A[181] = -A[26] - 0.000547271658382789*G0_0 + 0.0017316017316018*G0_1 + 0.000132542354764582*G0_2 + 8.55111966223118e-06*G0_3 - 0.00131687242798359*G0_4 - 8.55111966222924e-06*G0_5; + A[158] = A[94] - 0.00100048100048103*G0_0 + 0.00100048100048103*G0_2 - 0.000872214205547569*G0_3 + 0.000872214205547569*G0_5; + A[135] = A[26] + 0.00194537972315757*G0_0 - 0.00194537972315758*G0_1 - 0.000427555983111555*G0_3 + 0.000427555983111553*G0_4; + A[35] = A[135] - 0.00175297953075737*G0_0 + 0.00175297953075737*G0_2 + 0.000513067179733864*G0_3 - 0.000513067179733863*G0_5; + A[60] = -A[35] + 1.06888995777846e-06*G0_0 - 3.42044786489235e-05*G0_1 + 0.00191117524450864*G0_2 - 0.000252258030035817*G0_3 + 5.34444978889444e-05*G0_4 - 0.000374111485222609*G0_5; + A[211] = A[181] + 0.000487413820747171*G0_0 - 0.000487413820747171*G0_2 - 0.000102613435946772*G0_3 + 0.000102613435946774*G0_5; + A[4] = A[60]; + A[47] = A[21] + 0.000376249265138167*G0_0 - 0.000466036021591594*G0_1 + 0.00056437389770725*G0_2 + 5.13067179733861e-05*G0_3 + 0.000461760461760478*G0_4; + A[36] = A[47] - 0.000414729303618207*G0_0 + 0.000414729303618207*G0_1 + 5.13067179733866e-05*G0_3 - 5.13067179733864e-05*G0_4; + A[7] = -A[36] - 0.00165143498476837*G0_0 - 8.55111966223121e-06*G0_1 + 0.000939554272887638*G0_2 + 0.000391213724547071*G0_3 - 8.97867564534251e-05*G0_4 - 0.00028646250868474*G0_5; + A[10] = A[7] + 0.000400833734167083*G0_1 - 0.000400833734167081*G0_2; + A[100] = A[10] - 0.00181176847843521*G0_0 - 3.20666987333834e-06*G0_1 + 0.000859387526054223*G0_2 - 0.00128908128908133*G0_3 - 0.00327080327080338*G0_4 - 0.00224466891133566*G0_5; + A[97] = A[100] - 0.000256533589866928*G0_0 + 0.000436107102773784*G0_1 - 0.00161616161616167*G0_2 - 0.000872214205547565*G0_3 - 0.000513067179733857*G0_4; + A[99] = A[97] + 0.00743947410614102*G0_0 - 0.00158195713751275*G0_1 + 8.55111966222965e-06*G0_2 + 0.0030270963604298*G0_3 + 0.00761049649938564*G0_4 + 0.00607129496018406*G0_5; + A[125] = A[99] - 0.00489124044679617*G0_0 + 0.00489124044679617*G0_2 + 0.00253113142002039*G0_3 - 0.0025311314200204*G0_5; + A[176] = A[125] - 0.000649885094329563*G0_0 + 0.0089957778846671*G0_1 - 0.00519908075463649*G0_2 - 0.00191545080433976*G0_4 + 0.0100561167227837*G0_5; + A[83] = A[125]; + A[111] = A[97]; + A[122] = A[26] - 0.00175297953075738*G0_1 + 0.00175297953075737*G0_2 + 0.000513067179733864*G0_4 - 0.000513067179733867*G0_5; + A[90] = A[135] + 0.0001924001924002*G0_1 - 0.000192400192400199*G0_2 + 8.55111966223098e-05*G0_4 - 8.55111966223103e-05*G0_5; + A[165] = A[47] + 0.000547271658382789*G0_0 - 0.000547271658382788*G0_2 - 0.000196675752231315*G0_3 + 0.000196675752231314*G0_5; + A[191] = A[90] + 1.28266794933477e-05*G0_0 - 0.00131259686815247*G0_1 + 8.55111966223079e-06*G0_2 - 0.000478862701084942*G0_3 + 0.00311260755705211*G0_4 - 0.000495964940409399*G0_5; + A[27] = A[181]; + A[132] = A[191] + 0.0011287477954145*G0_1 - 0.0011287477954145*G0_2 - 0.00369408369408383*G0_4 + 0.00369408369408381*G0_5; + A[46] = A[26] + 0.0001924001924002*G0_0 - 0.000192400192400199*G0_2 + 8.55111966223087e-05*G0_3 - 8.55111966223123e-05*G0_5; + A[41] = -A[35] - 8.551119662231e-06*G0_0 - 0.000560098337876135*G0_1 + 0.00181283736839298*G0_2 - 5.13067179733873e-05*G0_3 + 8.55111966223119e-06*G0_4 - 0.000778151889263027*G0_5; + A[157] = A[41] + 0.00191117524450864*G0_0 + 0.000211640211640219*G0_1 - 0.000215915771471335*G0_2 - 8.55111966223263e-06*G0_3 - 0.000423280423280438*G0_4 - 6.41333974667289e-05*G0_5; + A[70] = A[157] - 0.00205868205868213*G0_0 + 0.00205868205868213*G0_1 - 0.000269360269360276*G0_3 + 0.00026936026936028*G0_4; + A[144] = A[176] + 0.00964566297899665*G0_0 - 0.00964566297899666*G0_1 - 0.00191545080433976*G0_3 + 0.00191545080433976*G0_4; + A[80] = A[144] - 0.00930361819250741*G0_0 + 0.0093036181925074*G0_2 + 0.00944043610710309*G0_3 - 0.00944043610710311*G0_5; + A[170] = A[80] + 0.000684089572978485*G0_0 + 0.00304419859975426*G0_1 - 0.00831168831168859*G0_2 - 0.0101245256800816*G0_3 - 0.00335203890759458*G0_4; + A[202] = -A[144] + 0.00905563572230271*G0_0 - 0.000974827641494338*G0_1 - 0.000247982470204706*G0_2 - 0.00147079258190373*G0_4 + 0.00944043610710312*G0_5; + A[86] = A[170]; + A[138] = A[170] + 0.000307840307840317*G0_0 - 0.000307840307840319*G0_2 + 0.000684089572978489*G0_3 - 0.000684089572978485*G0_5; + A[164] = A[202] + 0.000384800384800396*G0_1 - 0.000384800384800393*G0_2 + 0.0033862433862435*G0_4 - 0.00338624338624351*G0_5; + A[113] = A[97] + 0.00253968253968262*G0_0 - 0.00253968253968262*G0_2 - 0.000513067179733863*G0_3 + 0.000513067179733866*G0_5; + A[65] = A[113] + 0.00159050825717498*G0_0 - 0.00159050825717498*G0_1 - 0.00153920153920159*G0_3 + 0.00153920153920159*G0_4; + A[195] = A[181] + 0.000333493666827012*G0_0 - 0.000333493666827012*G0_1 - 0.000897867564534263*G0_3 + 0.000897867564534263*G0_4; + A[188] = A[132]; + A[14] = A[211] - 0.000153920153920159*G0_0 + 0.00015392015392016*G0_1 - 0.000795254128587489*G0_3 + 0.000795254128587489*G0_4; + A[117] = -A[14] - 0.00346320346320358*G0_0 + 0.000820907487574181*G0_2 + 0.00210357543690884*G0_3 + 0.00566939233605919*G0_4 - 0.00315536315536326*G0_5; + A[199] = A[117] + 0.00330928330928342*G0_0 - 0.00330928330928343*G0_1 + 0.00277056277056287*G0_3 - 0.00277056277056286*G0_4; + A[214] = A[199] + 0.00461760461760478*G0_1 - 0.00461760461760477*G0_2 - 0.00615680615680637*G0_4 + 0.00615680615680636*G0_5; + A[163] = A[199] + 0.00130832130832135*G0_0 - 0.00130832130832135*G0_2 - 0.00892736892736924*G0_3 + 0.00892736892736922*G0_5; + A[205] = A[163]; + A[56] = A[99] - 0.00489124044679617*G0_0 + 0.00489124044679618*G0_1 + 0.0025311314200204*G0_3 - 0.0025311314200204*G0_4; + A[129] = A[170] + 0.00201806424028653*G0_0 - 0.00201806424028653*G0_1 - 0.000752498530276335*G0_3 + 0.000752498530276333*G0_4; + A[16] = A[129] - 0.00167441611886062*G0_0 + 0.00216610549943891*G0_1 + 3.58078135855928e-05*G0_2 - 9.62000962000987e-06*G0_3 - 0.00102934102934106*G0_4 - 0.00144620811287483*G0_5; + A[72] = A[202] - 0.000384800384800397*G0_0 + 0.000384800384800397*G0_1 - 0.00338624338624351*G0_3 + 0.0033862433862435*G0_4; + A[42] = A[181] + 0.00015392015392016*G0_1 - 0.00015392015392016*G0_2 + 0.000795254128587491*G0_4 - 0.000795254128587487*G0_5; + A[139] = A[94] - 0.000872214205547571*G0_1 + 0.000872214205547568*G0_2 + 0.000256533589866933*G0_4 - 0.000256533589866933*G0_5; + A[76] = A[47] + 0.000962000962000996*G0_1 - 0.000962000962000995*G0_2 - 0.000247982470204701*G0_4 + 0.000247982470204702*G0_5; + A[153] = A[100] + 0.00343755010421689*G0_0 - 0.0034375501042169*G0_1 - 0.00241141574474917*G0_3 + 0.00241141574474916*G0_4; + A[110] = A[153] + 0.00389931056597737*G0_1 - 0.00389931056597736*G0_2 - 0.00138528138528143*G0_4 + 0.00138528138528144*G0_5; + A[107] = A[7] + 0.00162898829565502*G0_0 - 0.00162898829565502*G0_2 - 0.00042969376302711*G0_3 + 0.00042969376302711*G0_5; + A[104] = A[132] - 0.00307840307840318*G0_0 + 0.00307840307840318*G0_2 + 0.00410453743787091*G0_3 - 0.00410453743787091*G0_5; + A[182] = A[42]; + A[175] = A[113] - 0.00413019079685762*G0_1 + 0.0041301907968576*G0_2 + 0.00205226871893545*G0_4 - 0.00205226871893546*G0_5; + A[20] = A[76]; + A[11] = A[165]; + A[51] = -A[191] + 0.00194965528298868*G0_0 - 0.0011287477954145*G0_1 - 0.000205226871893547*G0_3 + 0.00389931056597737*G0_4; + A[32] = A[16] - 0.001822457378013*G0_1 + 0.00182245737801299*G0_2 + 0.000267222489444721*G0_4 - 0.000267222489444722*G0_5; + A[25] = A[10] + 0.00162898829565502*G0_0 - 0.00162898829565502*G0_1 - 0.000429693763027113*G0_3 + 0.000429693763027111*G0_4; + A[126] = A[170] + 0.00188124632569083*G0_0 - 0.00208647319758438*G0_1 + 0.00157340601785052*G0_2 + 0.00157340601785051*G0_4 - 0.000684089572978486*G0_5; + A[61] = A[25] - 0.000400833734167082*G0_0 + 0.000400833734167081*G0_2; + A[159] = A[97] - 0.00159050825717498*G0_1 + 0.00159050825717498*G0_2 + 0.00153920153920158*G0_4 - 0.00153920153920159*G0_5; + A[142] = A[100] + 0.000461760461760478*G0_1 - 0.000461760461760478*G0_2 + 0.00102613435946773*G0_4 - 0.00102613435946772*G0_5; + A[79] = A[65]; + A[169] = A[153] + 0.000461760461760476*G0_0 - 0.000461760461760479*G0_2 + 0.00102613435946773*G0_3 - 0.00102613435946772*G0_5; + A[154] = A[70]; + A[106] = A[60] + 0.000157126823793496*G0_0 - 0.000157126823793496*G0_1 + 0.000391213724547071*G0_3 - 0.000391213724547071*G0_4; + A[101] = A[138] + 0.00171022393244621*G0_0 - 0.00171022393244622*G0_1 - 0.00143658810325482*G0_3 + 0.00143658810325482*G0_4; + A[149] = -A[101] - 0.000136817914595698*G0_0 + 0.000205226871893546*G0_2 + 0.00205226871893545*G0_3 + 0.00102613435946773*G0_4 - 0.000889316444872033*G0_5; + A[186] = -A[149] + 0.00389931056597737*G0_0 - 0.000923520923520956*G0_1 - 0.00133397466730805*G0_2 + 0.00533589866923219*G0_4 + 0.00205226871893546*G0_5; + A[103] = A[149] + 0.000513067179733865*G0_1 - 0.000513067179733863*G0_2 - 0.00123136123136127*G0_4 + 0.00123136123136127*G0_5; + A[57] = A[103] + 0.00236010902677577*G0_0 - 0.00236010902677578*G0_1 - 0.00369408369408383*G0_3 + 0.00369408369408381*G0_4; + A[218] = A[186] - 0.00759339426006119*G0_0 + 0.00759339426006119*G0_2 + 0.00574635241301927*G0_3 - 0.00574635241301928*G0_5; + A[89] = A[218] + 0.000923520923520955*G0_0 - 0.000923520923520956*G0_1 + 0.00205226871893546*G0_3 - 0.00205226871893545*G0_4; + A[215] = A[89]; + A[198] = A[186] - 0.00666987333654024*G0_0 + 0.00666987333654025*G0_1 + 0.00779862113195475*G0_3 - 0.00779862113195473*G0_4; + A[187] = A[117]; + A[174] = A[126] + 0.00194965528298869*G0_1 - 0.00194965528298868*G0_2 - 0.000820907487574178*G0_4 + 0.000820907487574186*G0_5; + A[216] = A[104]; + A[201] = A[103]; + A[5] = -A[90] + 0.00181283736839298*G0_0 - 8.55111966223131e-06*G0_1 - 0.000560098337876135*G0_2 - 0.000778151889263028*G0_3 - 5.13067179733878e-05*G0_4 + 8.55111966223045e-06*G0_5; + A[15] = A[1]; + A[8] = A[36] + 0.000962000962000994*G0_0 - 0.000962000962000995*G0_2 - 0.000247982470204701*G0_3 + 0.0002479824702047*G0_5; + A[71] = A[169]; + A[50] = A[126] - 0.00194965528298868*G0_0 + 0.00194965528298868*G0_1 + 0.00082090748757418*G0_3 - 0.000820907487574179*G0_4; + A[37] = A[107]; + A[148] = A[191] - 0.00307840307840318*G0_0 + 0.00307840307840319*G0_1 + 0.00410453743787092*G0_3 - 0.00410453743787091*G0_4; + A[123] = A[170] - 0.00171022393244622*G0_1 + 0.00171022393244621*G0_2 + 0.00143658810325482*G0_4 - 0.00143658810325482*G0_5; + A[85] = A[108] - 0.00100048100048104*G0_1 + 0.00100048100048104*G0_2 - 0.000872214205547565*G0_4 + 0.000872214205547565*G0_5; + A[66] = A[94]; + A[160] = A[157] + 0.00205868205868214*G0_1 - 0.00144300144300149*G0_2 + 0.00419432419432434*G0_3 + 0.00446368446368462*G0_4 + 0.0182395382395389*G0_5; + A[137] = A[21] - 6.8408957297849e-05*G0_1 + 6.84089572978483e-05*G0_2 + 0.000213777991555777*G0_4 - 0.000213777991555777*G0_5; + A[91] = A[21]; + A[82] = A[110]; + A[168] = A[56]; + A[109] = A[157] - 0.00205868205868213*G0_0 + 0.00205868205868213*G0_2 - 0.000269360269360274*G0_3 + 0.000269360269360274*G0_5; + A[222] = A[193] + 0.00246272246272255*G0_1 - 0.00246272246272255*G0_2 + 0.00985088985089018*G0_4 - 0.0098508898508902*G0_5; + A[184] = A[72]; + A[213] = A[191] - 0.00194965528298868*G0_0 + 0.00194965528298868*G0_2 + 0.000410453743787094*G0_3 - 0.000410453743787092*G0_5; + A[204] = A[148]; + A[2] = -9.24589813478733e-05*G0_0 + 2.05761316872436e-05*G0_1 - 9.24589813478736e-05*G0_2 - 4.2755598311155e-06*G0_3 - 6.52022874245119e-05*G0_4 - 4.27555983111542e-06*G0_5; + A[18] = A[46]; + A[133] = A[103] + 0.00184704184704191*G0_0 - 0.00184704184704191*G0_2 - 0.00246272246272254*G0_3 + 0.00246272246272255*G0_5; + A[68] = A[100] + 0.00389931056597737*G0_0 - 0.00389931056597737*G0_2 - 0.00138528138528143*G0_3 + 0.00138528138528144*G0_5; + A[45] = A[21] + 0.000427555983111554*G0_0 - 0.000427555983111555*G0_1 - 0.000359147025813707*G0_3 + 0.000359147025813705*G0_4; + A[38] = A[122]; + A[143] = A[129]; + A[120] = A[8]; + A[88] = A[132] - 0.00194965528298868*G0_0 + 0.00194965528298868*G0_1 + 0.000410453743787098*G0_3 - 0.000410453743787084*G0_4; + A[92] = A[36]; + A[179] = A[149] + 0.00184704184704191*G0_0 - 0.00184704184704191*G0_1 - 0.00246272246272254*G0_3 + 0.00246272246272255*G0_4; + A[116] = A[108] - 0.000872214205547568*G0_0 + 0.000872214205547568*G0_2 + 0.00025653358986693*G0_3 - 0.000256533589866932*G0_5; + A[219] = A[149]; + A[189] = A[186] - 0.000923520923520958*G0_1 + 0.000923520923520955*G0_2 - 0.00205226871893545*G0_4 + 0.00205226871893547*G0_5; + A[207] = A[193]; + A[55] = A[153]; + A[29] = A[211]; + A[130] = A[158]; + A[73] = A[199]; + A[43] = -A[35] + 0.000132542354764581*G0_0 - 0.000547271658382789*G0_1 + 0.00173160173160179*G0_2 - 8.55111966223179e-06*G0_3 + 8.55111966223155e-06*G0_4 - 0.00131687242798358*G0_5; + A[146] = A[174]; + A[75] = A[5]; + A[150] = A[10]; + A[183] = A[57]; + A[178] = A[218] + 0.00666987333654024*G0_1 - 0.00666987333654023*G0_2 - 0.00779862113195473*G0_4 + 0.00779862113195473*G0_5; + A[119] = A[117] + 0.00461760461760477*G0_0 - 0.00461760461760477*G0_2 - 0.00615680615680634*G0_3 + 0.00615680615680637*G0_5; + A[220] = A[164]; + A[197] = A[43]; + A[194] = A[222]; + A[19] = A[61]; + A[12] = A[212] + 5.13067179733865e-05*G0_0 - 5.13067179733857e-05*G0_2 + 0.000743947410614103*G0_3 - 0.000743947410614104*G0_5; + A[54] = A[138]; + A[33] = A[47]; + A[24] = A[36] + 0.000547271658382791*G0_1 - 0.000547271658382788*G0_2 - 0.000196675752231315*G0_4 + 0.000196675752231316*G0_5; + A[127] = A[113]; + A[62] = A[107] - 0.000400833734167081*G0_0 + 0.000400833734167081*G0_1; + A[44] = A[212]; + A[141] = A[99]; + A[95] = A[138] - 0.00201806424028654*G0_1 + 0.00201806424028653*G0_2 + 0.000752498530276333*G0_4 - 0.000752498530276335*G0_5; + A[78] = A[50]; + A[172] = A[116]; + A[155] = A[85]; + A[105] = A[7]; + A[98] = A[126]; + A[180] = A[12]; + A[173] = A[51] - 0.000205226871893546*G0_3 + 0.000205226871893545*G0_5; + A[118] = A[202]; + A[217] = A[119]; + A[200] = A[88]; + A[6] = A[90]; + A[22] = A[106]; + A[9] = A[135]; + A[49] = A[97] + 0.0041301907968576*G0_0 - 0.0041301907968576*G0_1 - 0.00205226871893545*G0_3 + 0.00205226871893545*G0_4; + A[34] = A[62]; + A[147] = A[189]; + A[124] = A[68]; + A[84] = A[51] - 0.000205226871893546*G0_4 + 0.000205226871893546*G0_5; + A[67] = A[109]; + A[161] = A[175]; + A[136] = A[24]; + A[96] = A[144] + 0.00034204478648924*G0_1 - 0.000342044786489242*G0_2 + 0.00752498530276333*G0_4 - 0.00752498530276335*G0_5; + A[81] = A[95]; + A[167] = A[41]; + A[156] = A[100]; + A[112] = A[160] - 0.00350168350168363*G0_1 + 0.00350168350168362*G0_2 + 0.0137758537758542*G0_4 - 0.0137758537758543*G0_5; + A[223] = A[193] + 0.00246272246272255*G0_0 - 0.00246272246272255*G0_2 + 0.00985088985089019*G0_3 - 0.00985088985089019*G0_5; + A[185] = A[149] + 0.00236010902677577*G0_0 - 0.00236010902677577*G0_2 - 0.00369408369408382*G0_3 + 0.00369408369408382*G0_5; + A[210] = A[14]; + A[203] = A[133]; + A[3] = A[45]; + A[59] = A[213]; + A[17] = A[31]; + A[134] = A[218]; + A[69] = A[139]; + A[48] = A[176] + 0.000342044786489242*G0_0 - 0.000342044786489243*G0_2 + 0.00752498530276334*G0_3 - 0.00752498530276334*G0_5; + A[39] = A[137]; + A[121] = A[21] + 0.000359147025813705*G0_0 - 0.000359147025813705*G0_2 - 0.000145369034257928*G0_3 + 0.000145369034257928*G0_5; + A[87] = A[185]; + A[64] = A[160] - 0.00350168350168362*G0_0 + 0.00350168350168362*G0_2 + 0.0137758537758543*G0_3 - 0.0137758537758543*G0_5; + A[162] = A[117] + 0.00130832130832136*G0_1 - 0.00130832130832135*G0_2 - 0.00892736892736923*G0_4 + 0.00892736892736923*G0_5; + A[93] = A[51]; + A[166] = A[26]; + A[115] = A[157]; + A[224] = A[192] - 0.0147763347763353*G0_0 + 0.0147763347763353*G0_2 + 0.0197017797017803*G0_3 - 0.0197017797017804*G0_5; + A[190] = A[162]; + A[206] = A[178]; + A[0] = A[16] + 0.001822457378013*G0_0 - 0.001822457378013*G0_1 - 0.000267222489444721*G0_3 + 0.000267222489444721*G0_4; + A[58] = A[198]; + A[28] = A[212] + 5.13067179733898e-05*G0_1 - 5.13067179733866e-05*G0_2 + 0.000743947410614103*G0_4 - 0.0007439474106141*G0_5; + A[131] = A[173]; + A[74] = A[214]; + A[40] = A[60] + 0.000157126823793496*G0_0 - 0.000157126823793496*G0_2 + 0.000391213724547072*G0_3 - 0.000391213724547071*G0_5; + A[145] = A[159]; + A[151] = A[25]; + A[102] = A[186]; + A[177] = A[191]; + A[114] = A[142]; + A[221] = A[179]; + A[196] = A[28]; + A[209] = A[223]; + A[13] = A[195]; + A[53] = A[123]; + A[30] = A[2]; + A[23] = A[121]; + A[128] = A[176] - 0.00930361819250742*G0_1 + 0.0093036181925074*G0_2 + 0.00944043610710309*G0_4 - 0.00944043610710311*G0_5; + A[63] = A[49]; + A[140] = A[84]; + A[77] = A[35]; + A[171] = A[101]; + A[152] = A[40]; + } + + /// 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 mass_matrix_f1_p2_q4_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p2_q4_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p2_q4_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 1))), 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 mass_matrix_f1_p2_q4_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p2_q4_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p2_q4_tensor_finite_element_0(); + 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 mass_matrix_f1_p2_q4_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p2_q4_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p2_q4_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f1_p3_q1_excafe.h b/mass_matrix_2d/mass_matrix_f1_p3_q1_excafe.h new file mode 100644 index 0000000..d227480 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p3_q1_excafe.h @@ -0,0 +1,68 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 0.18 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][8] + w[0][7]; + const double var_1 = -1.0000000000000000000000000*x[0][1]; + const double var_2 = var_1 + x[1][1]; + const double var_3 = -1.0000000000000000000000000*x[0][0]; + const double var_4 = var_3 + x[2][0]; + const double var_5 = var_1 + x[2][1]; + const double var_6 = x[1][0] + var_3; + const double var_7 = -1.0000000000000000000000000*var_2*var_4 + var_5*var_6; + const double var_8 = std::abs(var_7); + const double var_9 = w[0][4] + w[0][6]; + const double var_10 = w[0][3] + w[0][5]; + const double var_11 = w[0][0] + w[0][1]; + const double var_12 = 0.9000000000000000222044605*w[0][9]; + const double var_13 = -0.1500000000000000222044605*var_10 + 0.7500000000000000000000000*var_9 + -0.0500000000000000027755576*var_0 + var_12 + 0.0666666666666666657414808*var_11 + 0.2000000000000000111022302*w[0][2]; + A[8] = 0.0357142857142857123031732*var_13*var_8; + const double var_14 = w[0][8] + w[0][6]; + const double var_15 = 3.0000000000000000000000000*w[0][9]; + const double var_16 = 0.5000000000000000000000000*var_10 + -0.2500000000000000000000000*var_9 + var_15 + var_0 + 0.1666666666666666574148081*w[0][2] + 0.0833333333333333287074041*var_11; + const double var_17 = w[0][0] + w[0][2]; + const double var_18 = w[0][8] + w[0][3]; + const double var_19 = w[0][4] + w[0][7]; + const double var_20 = w[0][5] + w[0][6]; + const double var_21 = var_15 + 0.5000000000000000000000000*var_19 + -0.2500000000000000000000000*var_18 + var_20 + 0.1666666666666666574148081*w[0][1] + 0.0833333333333333287074041*var_17; + A[2] = 0.0071428571428571426341070*var_21*var_8; + const double var_22 = w[0][4] + w[0][3]; + const double var_23 = w[0][1] + w[0][2]; + const double var_24 = w[0][5] + w[0][7]; + const double var_25 = var_15 + 0.1666666666666666574148081*w[0][0] + -0.2500000000000000000000000*var_24 + var_22 + 0.5000000000000000000000000*var_14 + 0.0833333333333333287074041*var_23; + A[5] = 0.0071428571428571426341070*var_25*var_8; + A[7] = A[5]; + const double var_26 = -0.1500000000000000222044605*var_19 + 0.7500000000000000000000000*var_18 + -0.0500000000000000027755576*var_20 + var_12 + 0.2000000000000000111022302*w[0][1] + 0.0666666666666666657414808*var_17; + A[4] = 0.0357142857142857123031732*var_26*var_8; + const double var_27 = 0.2000000000000000111022302*w[0][0] + var_12 + 0.7500000000000000000000000*var_24 + -0.0500000000000000027755576*var_22 + -0.1500000000000000222044605*var_14 + 0.0666666666666666657414808*var_23; + A[0] = 0.0357142857142857123031732*var_27*var_8; + A[1] = 0.0071428571428571426341070*var_16*var_8; + A[3] = A[1]; + A[6] = 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/mass_matrix_2d/mass_matrix_f1_p3_q1_quadrature.h b/mass_matrix_2d/mass_matrix_f1_p3_q1_quadrature.h new file mode 100644 index 0000000..15d80db --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p3_q1_quadrature.h @@ -0,0 +1,4557 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P3_Q1_QUADRATURE_H +#define __MASS_MATRIX_F1_P3_Q1_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p3_q1_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p3_q1_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p3_q1_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p3_q1_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p3_q1_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p3_q1_quadrature_finite_element_1() + { + // 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 mass_matrix_f1_p3_q1_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p3_q1_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p3_q1_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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.0*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 mass_matrix_f1_p3_q1_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p3_q1_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p3_q1_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f1_p3_q1_quadrature_dofmap_1() + { + // 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 mass_matrix_f1_p3_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 mass_matrix_f1_p3_q1_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p3_q1_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // 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[7][3] = \ + {{0.333333333333333, 0.333333333333333, 0.333333333333333}, + {0.101286507323456, 0.797426985353087, 0.101286507323456}, + {0.101286507323456, 0.101286507323456, 0.797426985353087}, + {0.797426985353087, 0.101286507323456, 0.101286507323456}, + {0.470142064105115, 0.0597158717897698, 0.470142064105115}, + {0.470142064105115, 0.470142064105115, 0.0597158717897697}, + {0.0597158717897699, 0.470142064105115, 0.470142064105115}}; + + static const double FE1[7][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}, + {0.0597971252344169, 0.217763476154296, 0.0597971252344169, 0.506036589934694, -0.253018294967347, -0.0321375371750573, -0.0321375371750573, -0.253018294967347, 0.506036589934695, 0.22088075779229}, + {0.0597971252344169, 0.0597971252344169, 0.217763476154296, -0.253018294967347, 0.506036589934694, -0.253018294967348, 0.506036589934695, -0.0321375371750574, -0.0321375371750572, 0.22088075779229}, + {0.217763476154296, 0.0597971252344168, 0.0597971252344169, -0.0321375371750572, -0.0321375371750573, 0.506036589934694, -0.253018294967347, 0.506036589934694, -0.253018294967347, 0.22088075779229}, + {-0.0568816733393732, 0.0446271943996398, -0.0568816733393731, -0.10370422841866, 0.0518521142093298, 0.408230831635699, 0.408230831635699, 0.0518521142093297, -0.10370422841866, 0.356378717426369}, + {-0.0568816733393731, -0.0568816733393731, 0.0446271943996398, 0.0518521142093297, -0.10370422841866, 0.0518521142093298, -0.10370422841866, 0.408230831635699, 0.408230831635699, 0.356378717426369}, + {0.0446271943996399, -0.0568816733393731, -0.0568816733393731, 0.408230831635698, 0.408230831635699, -0.10370422841866, 0.05185211420933, -0.10370422841866, 0.0518521142093299, 0.356378717426369}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 9; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 343 + for (unsigned int ip = 0; ip < 7; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + + // Total number of operations to compute function values = 20 + for (unsigned int r = 0; r < 10; r++) + { + F0 += FE1[ip][r]*w[0][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 2 + double I[1]; + // Number of operations: 2 + I[0] = F0*W7[ip]*det; + + + // Number of operations for primary indices: 27 + for (unsigned int j = 0; j < 3; j++) + { + for (unsigned int k = 0; k < 3; k++) + { + // Number of operations to compute entry: 3 + A[j*3 + k] += FE0[ip][j]*FE0[ip][k]*I[0]; + }// 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 mass_matrix_f1_p3_q1_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p3_q1_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p3_q1_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1))), 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 mass_matrix_f1_p3_q1_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p3_q1_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p3_q1_quadrature_finite_element_0(); + 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 mass_matrix_f1_p3_q1_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p3_q1_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p3_q1_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f1_p3_q1_tensor.h b/mass_matrix_2d/mass_matrix_f1_p3_q1_tensor.h new file mode 100644 index 0000000..8f10202 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p3_q1_tensor.h @@ -0,0 +1,4517 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P3_Q1_TENSOR_H +#define __MASS_MATRIX_F1_P3_Q1_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p3_q1_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p3_q1_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p3_q1_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p3_q1_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p3_q1_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p3_q1_tensor_finite_element_1() + { + // 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 mass_matrix_f1_p3_q1_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p3_q1_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p3_q1_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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.0*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 mass_matrix_f1_p3_q1_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p3_q1_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p3_q1_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f1_p3_q1_tensor_dofmap_1() + { + // 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 mass_matrix_f1_p3_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 mass_matrix_f1_p3_q1_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p3_q1_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 10 + // Number of operations (multiply-add pairs) for tensor contraction: 50 + // Total number of operations (multiply-add pairs): 69 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0 = det*w[0][0]*(1.0); + const double G0_1 = det*w[0][1]*(1.0); + const double G0_2 = det*w[0][2]*(1.0); + const double G0_3 = det*w[0][3]*(1.0); + const double G0_4 = det*w[0][4]*(1.0); + const double G0_5 = det*w[0][5]*(1.0); + const double G0_6 = det*w[0][6]*(1.0); + const double G0_7 = det*w[0][7]*(1.0); + const double G0_8 = det*w[0][8]*(1.0); + const double G0_9 = det*w[0][9]*(1.0); + + // Compute element tensor + A[1] = 0.000595238095238096*G0_0 + 0.000595238095238095*G0_1 + 0.00119047619047619*G0_2 + 0.00357142857142857*G0_3 - 0.00178571428571429*G0_4 + 0.00357142857142857*G0_5 - 0.00178571428571429*G0_6 + 0.00714285714285714*G0_7 + 0.00714285714285715*G0_8 + 0.0214285714285714*G0_9; + A[5] = A[1] + 0.000595238095238096*G0_0 - 0.000595238095238096*G0_2 + 0.00357142857142856*G0_3 + 0.00892857142857143*G0_4 - 0.00535714285714286*G0_5 + 0.00535714285714286*G0_6 - 0.00892857142857144*G0_7 - 0.00357142857142858*G0_8; + A[0] = A[1] + 0.00654761904761905*G0_0 + 0.00178571428571429*G0_1 + 0.00119047619047619*G0_2 - 0.00535714285714286*G0_3 + 0.0232142857142857*G0_5 - 0.00357142857142857*G0_6 + 0.0196428571428571*G0_7 - 0.0125*G0_8 + 0.0107142857142857*G0_9; + A[7] = A[5]; + A[6] = A[1] + 0.000595238095238096*G0_1 - 0.000595238095238096*G0_2 - 0.00535714285714286*G0_3 + 0.00535714285714286*G0_4 + 0.00357142857142857*G0_5 + 0.00892857142857144*G0_6 - 0.00357142857142858*G0_7 - 0.00892857142857143*G0_8; + A[2] = A[6]; + A[8] = A[0] - 0.00476190476190476*G0_0 + 0.00476190476190475*G0_2 - 0.00357142857142858*G0_3 + 0.0285714285714286*G0_4 - 0.0321428571428572*G0_5 + 0.0321428571428572*G0_6 - 0.0285714285714286*G0_7 + 0.00357142857142856*G0_8; + A[3] = A[1]; + A[4] = A[0] - 0.00476190476190476*G0_0 + 0.00476190476190475*G0_1 + 0.0285714285714285*G0_3 - 0.00357142857142857*G0_4 - 0.0285714285714286*G0_5 + 0.00357142857142857*G0_6 - 0.0321428571428571*G0_7 + 0.0321428571428571*G0_8; + } + + /// 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 mass_matrix_f1_p3_q1_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p3_q1_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p3_q1_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1))), 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 mass_matrix_f1_p3_q1_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p3_q1_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p3_q1_tensor_finite_element_0(); + 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 mass_matrix_f1_p3_q1_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p3_q1_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p3_q1_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f1_p3_q2_excafe.h b/mass_matrix_2d/mass_matrix_f1_p3_q2_excafe.h new file mode 100644 index 0000000..1b65e1b --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p3_q2_excafe.h @@ -0,0 +1,137 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 0.68 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 = -1.0000000000000000000000000*x[0][1]; + const double var_1 = x[1][1] + var_0; + const double var_2 = -1.0000000000000000000000000*x[0][0]; + const double var_3 = x[2][0] + var_2; + const double var_4 = var_0 + x[2][1]; + const double var_5 = x[1][0] + var_2; + const double var_6 = var_4*var_5 + -1.0000000000000000000000000*var_1*var_3; + const double var_7 = std::abs(var_6); + const double var_8 = 0.0285714285714285705364279*var_7*w[0][9]; + const double var_9 = w[0][8] + w[0][3]; + const double var_10 = w[0][0] + w[0][2]; + const double var_11 = var_9 + 0.1111111111111111049432054*var_10; + A[23] = 0.0071428571428571426341070*var_11*var_7 + var_8; + A[33] = A[23]; + const double var_12 = w[0][4] + w[0][6]; + const double var_13 = -1.0000000000000000000000000*var_12; + const double var_14 = w[0][8] + w[0][7]; + const double var_15 = w[0][3] + w[0][5] + var_13 + 3.0000000000000000000000000*var_14; + const double var_16 = 0.0428571428571428575393654*var_7*w[0][9]; + A[35] = 0.0071428571428571426341070*var_15*var_7 + 0.0031746031746031746004211*var_7*w[0][2] + var_16; + const double var_17 = w[0][1] + w[0][2]; + const double var_18 = w[0][5] + w[0][7]; + const double var_19 = -1.0000000000000000000000000*var_9; + const double var_20 = var_18 + var_13 + var_19; + const double var_21 = -0.1111111111111111049432054*w[0][0] + 0.5000000000000000000000000*var_20; + A[8] = 0.0017857142857142856585267*var_21*var_7 + -0.0003968253968253968250526*var_17*var_7; + const double var_22 = 0.0555555555555555524716027*w[0][1]; + const double var_23 = var_22 + w[0][7]; + const double var_24 = 0.0555555555555555524716027*w[0][2]; + const double var_25 = var_24 + w[0][5]; + const double var_26 = 0.1666666666666666574148081*w[0][0]; + const double var_27 = -1.0000000000000000000000000*w[0][6]; + const double var_28 = 0.2500000000000000000000000*var_27; + const double var_29 = -1.0000000000000000000000000*w[0][3]; + const double var_30 = 0.2500000000000000000000000*var_29; + const double var_31 = var_30 + -0.7500000000000000000000000*w[0][8] + var_26 + 0.5000000000000000000000000*var_25 + var_28 + var_23; + const double var_32 = -1.0000000000000000000000000*w[0][4]; + const double var_33 = 0.2500000000000000000000000*var_32; + const double var_34 = -1.0000000000000000000000000*w[0][8]; + const double var_35 = 0.2500000000000000000000000*var_34; + const double var_36 = -0.7500000000000000000000000*w[0][6] + var_35 + var_33 + var_26 + var_25 + 0.5000000000000000000000000*var_23; + const double var_37 = -0.0035714285714285713170535*var_7*w[0][9]; + const double var_38 = w[0][3] + var_24; + const double var_39 = 0.0555555555555555524716027*w[0][0]; + const double var_40 = w[0][8] + var_39; + const double var_41 = 0.1666666666666666574148081*w[0][1]; + const double var_42 = -1.0000000000000000000000000*w[0][7]; + const double var_43 = 0.2500000000000000000000000*var_42; + const double var_44 = var_43 + var_41 + var_38 + 0.5000000000000000000000000*var_40 + var_28 + -0.7500000000000000000000000*w[0][4]; + A[9] = 0.0071428571428571426341070*var_44*var_7 + var_37; + A[19] = A[9]; + const double var_45 = 0.0035714285714285713170535*var_7*w[0][9]; + const double var_46 = var_32 + 3.0000000000000000000000000*var_9 + 0.3333333333333333148296163*var_10 + var_42; + A[7] = 0.0047619047619047623343125*var_7*w[0][1] + var_45 + 0.0017857142857142856585267*var_46*var_7; + A[5] = 0.0071428571428571426341070*var_31*var_7 + var_37; + const double var_47 = var_39 + w[0][6]; + const double var_48 = w[0][4] + var_22; + const double var_49 = -1.0000000000000000000000000*var_18; + const double var_50 = var_49 + var_9 + var_13; + const double var_51 = 0.5000000000000000000000000*var_50 + -0.1111111111111111049432054*w[0][1]; + A[2] = -0.0003968253968253968250526*var_10*var_7 + 0.0017857142857142856585267*var_51*var_7; + A[12] = A[2]; + const double var_52 = 0.1111111111111111049432054*var_17 + var_18; + A[30] = A[5]; + const double var_53 = 0.1666666666666666574148081*w[0][2]; + const double var_54 = -1.0000000000000000000000000*w[0][5]; + const double var_55 = 0.2500000000000000000000000*var_54; + const double var_56 = var_35 + var_53 + var_48 + -0.7500000000000000000000000*w[0][3] + 0.5000000000000000000000000*var_47 + var_55; + const double var_57 = -0.0071428571428571426341070*var_7*w[0][9]; + const double var_58 = var_49 + var_12 + var_19; + const double var_59 = -0.1111111111111111049432054*w[0][2] + 0.5000000000000000000000000*var_58; + A[17] = var_57 + 0.0035714285714285713170535*var_59*var_7; + const double var_60 = w[0][0] + w[0][1]; + A[1] = -0.0003968253968253968250526*var_60*var_7 + 0.0017857142857142856585267*var_59*var_7; + A[6] = A[1]; + A[3] = 0.0035714285714285713170535*var_21*var_7 + var_57; + A[10] = var_57 + 0.0035714285714285713170535*var_51*var_7; + A[25] = A[10]; + const double var_61 = var_29 + 0.3333333333333333148296163*var_60 + 3.0000000000000000000000000*var_12 + var_54; + A[14] = 0.0017857142857142856585267*var_61*var_7 + var_45 + 0.0047619047619047623343125*var_7*w[0][2]; + const double var_62 = w[0][4] + w[0][3]; + const double var_63 = 0.1111111111111111049432054*var_60 + var_12; + A[22] = 0.0071428571428571426341070*var_63*var_7 + var_8; + A[15] = 0.0071428571428571426341070*var_56*var_7 + var_37; + const double var_64 = var_43 + var_30 + var_53 + 0.5000000000000000000000000*var_48 + var_47 + -0.7500000000000000000000000*w[0][5]; + const double var_65 = w[0][8] + var_49 + 3.0000000000000000000000000*var_62 + w[0][6]; + A[21] = 0.0071428571428571426341070*var_65*var_7 + 0.0031746031746031746004211*var_7*w[0][0] + var_16; + const double var_66 = 0.3333333333333333148296163*var_17 + var_27 + var_34 + 3.0000000000000000000000000*var_18; + A[0] = var_45 + 0.0047619047619047623343125*var_7*w[0][0] + 0.0017857142857142856585267*var_66*var_7; + A[4] = 0.0071428571428571426341070*var_36*var_7 + var_37; + A[24] = A[4]; + A[20] = A[15]; + A[29] = 0.0071428571428571426341070*var_52*var_7 + var_8; + A[34] = A[29]; + const double var_67 = w[0][5] + w[0][6]; + const double var_68 = w[0][4] + 3.0000000000000000000000000*var_67 + var_19 + w[0][7]; + A[28] = 0.0031746031746031746004211*var_7*w[0][1] + 0.0071428571428571426341070*var_68*var_7 + var_16; + const double var_69 = var_41 + -0.7500000000000000000000000*w[0][7] + var_33 + 0.5000000000000000000000000*var_38 + var_40 + var_55; + A[18] = A[3]; + A[11] = 0.0071428571428571426341070*var_69*var_7 + var_37; + A[31] = A[11]; + A[27] = A[22]; + A[32] = A[17]; + A[16] = 0.0071428571428571426341070*var_64*var_7 + var_37; + A[26] = A[16]; + A[13] = A[8]; + } + + 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/mass_matrix_2d/mass_matrix_f1_p3_q2_quadrature.h b/mass_matrix_2d/mass_matrix_f1_p3_q2_quadrature.h new file mode 100644 index 0000000..77ea9a9 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p3_q2_quadrature.h @@ -0,0 +1,5339 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P3_Q2_QUADRATURE_H +#define __MASS_MATRIX_F1_P3_Q2_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p3_q2_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p3_q2_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p3_q2_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p3_q2_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p3_q2_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p3_q2_quadrature_finite_element_1() + { + // 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p3_q2_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p3_q2_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p3_q2_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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.0*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 mass_matrix_f1_p3_q2_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p3_q2_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p3_q2_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f1_p3_q2_quadrature_dofmap_1() + { + // 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 mass_matrix_f1_p3_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 mass_matrix_f1_p3_q2_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p3_q2_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Array of quadrature weights. + static const double W16[16] = {0.0235683681933823, 0.0353880678980859, 0.0225840492823699, 0.00542322591052525, 0.0441850885223617, 0.0663442161070497, 0.0423397245217463, 0.0101672595644788, 0.0441850885223617, 0.0663442161070497, 0.0423397245217463, 0.0101672595644788, 0.0235683681933823, 0.0353880678980859, 0.0225840492823699, 0.00542322591052525}; + // Quadrature points on the UFC reference element: (0.0654669945550145, 0.0571041961145177), (0.0502101232113698, 0.276843013638124), (0.028912084224389, 0.583590432368917), (0.00970378512694614, 0.860240135656219), (0.311164552244357, 0.0571041961145177), (0.238648659731443, 0.276843013638124), (0.137419104134574, 0.583590432368917), (0.0461220799064521, 0.860240135656219), (0.631731251641125, 0.0571041961145177), (0.484508326630433, 0.276843013638124), (0.278990463496509, 0.583590432368917), (0.0936377844373285, 0.860240135656219), (0.877428809330468, 0.0571041961145177), (0.672946863150506, 0.276843013638124), (0.387497483406694, 0.583590432368917), (0.130056079216834, 0.860240135656219) + + // Value of basis functions at quadrature points. + static const double FE0[16][6] = \ + {{0.662333821555697, -0.0568951398028819, -0.0505824176867471, 0.0149537603843904, 0.200419467218139, 0.229770508331402}, + {0.232768098097706, -0.0451680102655679, -0.123558905237647, 0.0556012872999085, 0.745202550451633, 0.135154979653967}, + {-0.0871888841136517, -0.0272402669959927, 0.0975651531361617, 0.067491262932791, 0.904559295532719, 0.0448134395079725}, + {-0.0962269117343234, -0.00951545823536622, 0.619786046331442, 0.0333903417359319, 0.447517836913623, 0.00504814498869303}, + {0.166437496959, -0.117517795097495, -0.0505824176867471, 0.0710752064609914, 0.144298021141538, 0.786289488222712}, + {-0.015011689481988, -0.124742294148215, -0.123558905237647, 0.264272856643007, 0.536530981108534, 0.462509051116308}, + {-0.123319106052515, -0.0996510837722764, 0.0975651531361617, 0.320785897590582, 0.651264660874928, 0.15335447822312}, + {-0.0761017150886653, -0.0418675873966577, 0.619786046331442, 0.158704257101893, 0.322203921547661, 0.0172750775043264}, + {-0.117517795097495, 0.166437496959, -0.0505824176867471, 0.144298021141538, 0.0710752064609913, 0.786289488222712}, + {-0.124742294148215, -0.0150116894819881, -0.123558905237647, 0.536530981108534, 0.264272856643007, 0.462509051116308}, + {-0.0996510837722764, -0.123319106052515, 0.0975651531361617, 0.651264660874928, 0.320785897590582, 0.15335447822312}, + {-0.0418675873966577, -0.0761017150886653, 0.619786046331442, 0.322203921547661, 0.158704257101893, 0.0172750775043264}, + {-0.0568951398028819, 0.662333821555697, -0.0505824176867471, 0.200419467218139, 0.0149537603843903, 0.229770508331402}, + {-0.0451680102655679, 0.232768098097706, -0.123558905237647, 0.745202550451633, 0.0556012872999085, 0.135154979653967}, + {-0.0272402669959926, -0.0871888841136517, 0.0975651531361618, 0.904559295532719, 0.0674912629327909, 0.0448134395079725}, + {-0.00951545823536613, -0.0962269117343234, 0.619786046331442, 0.447517836913623, 0.0333903417359314, 0.00504814498869298}}; + + static const double FE1[16][10] = \ + {{0.452785096544088, 0.0474429618915808, 0.0432681417093322, -0.0135189305273306, -0.0139409921109051, 0.368034723276116, -0.186845725726384, 0.421932692589788, -0.207723773787635, 0.0885658061413495}, + {0.00645879502307897, 0.0394349905858879, 0.0274339473899979, -0.0531293004470149, -0.01060065392075, 0.854147931483282, -0.142076464805357, 0.1549140515302, -0.129146101999649, 0.252562805160324}, + {-0.0263670054419039, 0.0252592508316564, -0.0545988990428341, -0.0693419891600489, 0.0570043158923523, 0.165357063338021, 0.764006800069202, 0.00819207628699473, -0.0460423009076122, 0.176530688134173}, + {0.0638397523745609, 0.00928416145919281, 0.394831554211582, -0.0364705915852906, 0.0593783938998503, -0.307024415063853, 0.795825649453315, -0.00346333404943191, -0.00551383497665217, 0.0293126642767273}, + {-0.0296351119176843, 0.0110353632465608, 0.0432681417093322, -0.00531782108849545, -0.0662615199844949, 0.145321523295419, -0.134525197852795, 0.791866619346228, -0.0588298934372821, 0.303077896683211}, + {-0.0600402894008985, 0.0435224405021434, 0.0274339473899979, -0.0844512384591529, -0.0503848962850379, 0.273746477720596, -0.102292222441069, 0.235979334120451, -0.147799750082178, 0.864286196935148}, + {0.0264492636219917, 0.0641186652464314, -0.0545988990428341, -0.212107011291982, 0.270941449981089, -0.119446618596469, 0.550069665980465, -0.0281263132652844, -0.101399594834004, 0.604099392200595}, + {0.0578762154363197, 0.0369909803572857, 0.394831554211582, -0.153838064046657, 0.282225440107984, -0.260654104682365, 0.572978603245181, -0.0139750622480945, -0.0167453887378413, 0.100309826356606}, + {0.0110353632465609, -0.0296351119176843, 0.0432681417093322, 0.145321523295419, -0.134525197852795, -0.00531782108849545, -0.0662615199844949, -0.0588298934372824, 0.791866619346228, 0.303077896683211}, + {0.0435224405021434, -0.0600402894008985, 0.0274339473899979, 0.273746477720596, -0.102292222441069, -0.0844512384591529, -0.050384896285038, -0.147799750082179, 0.235979334120451, 0.864286196935148}, + {0.0641186652464314, 0.0264492636219917, -0.0545988990428341, -0.119446618596469, 0.550069665980465, -0.212107011291982, 0.270941449981089, -0.101399594834004, -0.0281263132652843, 0.604099392200595}, + {0.0369909803572857, 0.0578762154363197, 0.394831554211582, -0.260654104682365, 0.572978603245181, -0.153838064046657, 0.282225440107983, -0.0167453887378415, -0.0139750622480942, 0.100309826356606}, + {0.0474429618915808, 0.452785096544089, 0.0432681417093322, 0.368034723276116, -0.186845725726384, -0.0135189305273307, -0.0139409921109051, -0.207723773787635, 0.421932692589788, 0.0885658061413495}, + {0.039434990585888, 0.00645879502307895, 0.0274339473899979, 0.854147931483282, -0.142076464805357, -0.0531293004470149, -0.0106006539207499, -0.129146101999649, 0.1549140515302, 0.252562805160324}, + {0.0252592508316564, -0.0263670054419039, -0.0545988990428341, 0.165357063338021, 0.764006800069202, -0.0693419891600489, 0.0570043158923523, -0.0460423009076123, 0.00819207628699494, 0.176530688134173}, + {0.00928416145919272, 0.063839752374561, 0.394831554211582, -0.307024415063853, 0.795825649453315, -0.0364705915852904, 0.0593783938998497, -0.00551383497665229, -0.00346333404943161, 0.0293126642767269}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 36; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 2080 + for (unsigned int ip = 0; ip < 16; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + + // Total number of operations to compute function values = 20 + for (unsigned int r = 0; r < 10; r++) + { + F0 += FE1[ip][r]*w[0][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 2 + double I[1]; + // Number of operations: 2 + I[0] = F0*W16[ip]*det; + + + // Number of operations for primary indices: 108 + for (unsigned int j = 0; j < 6; j++) + { + for (unsigned int k = 0; k < 6; k++) + { + // Number of operations to compute entry: 3 + A[j*6 + k] += FE0[ip][j]*FE0[ip][k]*I[0]; + }// 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 mass_matrix_f1_p3_q2_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p3_q2_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p3_q2_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1))), 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 mass_matrix_f1_p3_q2_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p3_q2_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p3_q2_quadrature_finite_element_0(); + 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 mass_matrix_f1_p3_q2_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p3_q2_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p3_q2_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f1_p3_q2_tensor.h b/mass_matrix_2d/mass_matrix_f1_p3_q2_tensor.h new file mode 100644 index 0000000..478ee64 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p3_q2_tensor.h @@ -0,0 +1,5308 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P3_Q2_TENSOR_H +#define __MASS_MATRIX_F1_P3_Q2_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p3_q2_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p3_q2_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p3_q2_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p3_q2_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p3_q2_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p3_q2_tensor_finite_element_1() + { + // 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p3_q2_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p3_q2_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p3_q2_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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.0*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 mass_matrix_f1_p3_q2_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p3_q2_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p3_q2_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f1_p3_q2_tensor_dofmap_1() + { + // 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 mass_matrix_f1_p3_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 mass_matrix_f1_p3_q2_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p3_q2_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 10 + // Number of operations (multiply-add pairs) for tensor contraction: 141 + // Total number of operations (multiply-add pairs): 160 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0 = det*w[0][0]*(1.0); + const double G0_1 = det*w[0][1]*(1.0); + const double G0_2 = det*w[0][2]*(1.0); + const double G0_3 = det*w[0][3]*(1.0); + const double G0_4 = det*w[0][4]*(1.0); + const double G0_5 = det*w[0][5]*(1.0); + const double G0_6 = det*w[0][6]*(1.0); + const double G0_7 = det*w[0][7]*(1.0); + const double G0_8 = det*w[0][8]*(1.0); + const double G0_9 = det*w[0][9]*(1.0); + + // Compute element tensor + A[9] = 0.000198412698412699*G0_0 + 0.00119047619047619*G0_1 + 0.000396825396825396*G0_2 + 0.00714285714285713*G0_3 - 0.00535714285714285*G0_4 - 0.00178571428571428*G0_6 - 0.00178571428571428*G0_7 + 0.00357142857142857*G0_8 - 0.00357142857142857*G0_9; + A[18] = -0.000396825396825397*G0_0 - 0.00178571428571428*G0_3 - 0.00178571428571428*G0_4 + 0.00178571428571429*G0_5 - 0.00178571428571429*G0_6 + 0.00178571428571429*G0_7 - 0.00178571428571429*G0_8 - 0.00714285714285714*G0_9; + A[20] = A[9] - 0.000793650793650791*G0_1 + 0.000793650793650795*G0_2 - 0.0125*G0_3 + 0.0125*G0_4 - 0.00178571428571429*G0_5 + 0.00535714285714286*G0_6 + 0.00178571428571428*G0_7 - 0.00535714285714285*G0_8; + A[13] = -A[9] + 0.000793650793650792*G0_1 + 0.00624999999999999*G0_3 - 0.00624999999999999*G0_4 + 0.000892857142857143*G0_5 - 0.00267857142857143*G0_6 - 0.000892857142857141*G0_7 + 0.00267857142857143*G0_8 - 0.00357142857142857*G0_9; + A[31] = A[9] + 0.000198412698412698*G0_0 - 0.000198412698412698*G0_2 - 0.00357142857142856*G0_3 + 0.00357142857142857*G0_4 - 0.00178571428571429*G0_5 + 0.00178571428571428*G0_6 - 0.00357142857142857*G0_7 + 0.00357142857142857*G0_8; + A[3] = A[18]; + A[17] = -A[18] - 0.000396825396825397*G0_0 - 0.000396825396825396*G0_2 - 0.00357142857142857*G0_3 - 0.00357142857142857*G0_8 - 0.0142857142857143*G0_9; + A[24] = A[9] + 0.000992063492063489*G0_0 - 0.00099206349206349*G0_1 - 0.00714285714285713*G0_3 + 0.00357142857142857*G0_4 + 0.00714285714285714*G0_5 - 0.00357142857142857*G0_6 + 0.00535714285714285*G0_7 - 0.00535714285714285*G0_8; + A[8] = A[13]; + A[21] = 0.00317460317460317*G0_0 + 0.0214285714285714*G0_3 + 0.0214285714285714*G0_4 - 0.00714285714285715*G0_5 + 0.00714285714285714*G0_6 - 0.00714285714285714*G0_7 + 0.00714285714285714*G0_8 + 0.0428571428571428*G0_9; + A[28] = -A[21] + 0.00317460317460317*G0_0 + 0.00317460317460317*G0_1 + 0.0142857142857142*G0_3 + 0.0285714285714285*G0_4 + 0.0142857142857142*G0_5 + 0.0285714285714285*G0_6 + 0.0857142857142857*G0_9; + A[11] = A[31]; + A[30] = A[9] + 0.000992063492063489*G0_0 - 0.000793650793650791*G0_1 - 0.000198412698412698*G0_2 - 0.00892857142857142*G0_3 + 0.00535714285714285*G0_4 + 0.00357142857142857*G0_5 + 0.00892857142857142*G0_7 - 0.00892857142857142*G0_8; + A[4] = A[24]; + A[25] = -A[18] - 0.000396825396825397*G0_0 - 0.000396825396825397*G0_1 - 0.00357142857142857*G0_4 - 0.00357142857142857*G0_6 - 0.0142857142857143*G0_9; + A[7] = 0.000595238095238096*G0_0 + 0.00476190476190476*G0_1 + 0.000595238095238095*G0_2 + 0.00535714285714285*G0_3 - 0.00178571428571428*G0_4 - 0.00178571428571428*G0_7 + 0.00535714285714285*G0_8 + 0.00357142857142857*G0_9; + A[34] = 0.000793650793650793*G0_1 + 0.000793650793650793*G0_2 + 0.00714285714285714*G0_5 + 0.00714285714285714*G0_7 + 0.0285714285714286*G0_9; + A[0] = 0.00476190476190476*G0_0 + 0.000595238095238095*G0_1 + 0.000595238095238095*G0_2 + 0.00535714285714285*G0_5 - 0.00178571428571428*G0_6 + 0.00535714285714285*G0_7 - 0.00178571428571428*G0_8 + 0.00357142857142857*G0_9; + A[29] = A[34]; + A[14] = 0.000595238095238095*G0_0 + 0.000595238095238095*G0_1 + 0.00476190476190476*G0_2 - 0.00178571428571429*G0_3 + 0.00535714285714286*G0_4 - 0.00178571428571429*G0_5 + 0.00535714285714285*G0_6 + 0.00357142857142857*G0_9; + A[10] = A[25]; + A[5] = A[30]; + A[26] = A[9] + 0.000198412698412698*G0_0 - 0.00099206349206349*G0_1 + 0.000793650793650793*G0_2 - 0.00892857142857141*G0_3 + 0.00892857142857142*G0_4 - 0.00535714285714285*G0_5 + 0.00892857142857142*G0_6 - 0.00357142857142857*G0_8; + A[6] = -A[13] - 0.000595238095238095*G0_0 - 0.000793650793650793*G0_1 - 0.000595238095238095*G0_2 - 0.00178571428571428*G0_3 - 0.00178571428571429*G0_8; + A[1] = A[6]; + A[35] = -A[21] + 0.00317460317460318*G0_0 + 0.00317460317460317*G0_2 + 0.0285714285714285*G0_3 + 0.0142857142857143*G0_4 + 0.0142857142857143*G0_7 + 0.0285714285714286*G0_8 + 0.0857142857142857*G0_9; + A[23] = 0.000793650793650795*G0_0 + 0.000793650793650793*G0_2 + 0.00714285714285714*G0_3 + 0.00714285714285715*G0_8 + 0.0285714285714286*G0_9; + A[33] = A[23]; + A[19] = A[9]; + A[16] = A[26]; + A[27] = 0.000793650793650794*G0_0 + 0.000793650793650793*G0_1 + 0.00714285714285714*G0_4 + 0.00714285714285714*G0_6 + 0.0285714285714286*G0_9; + A[22] = A[27]; + A[15] = A[20]; + A[32] = A[17]; + A[2] = -A[13] - 0.000595238095238095*G0_0 - 0.000595238095238095*G0_1 - 0.000793650793650793*G0_2 - 0.00178571428571428*G0_4 - 0.00178571428571428*G0_6; + A[12] = A[2]; + } + + /// 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 mass_matrix_f1_p3_q2_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p3_q2_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p3_q2_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1))), 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 mass_matrix_f1_p3_q2_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p3_q2_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p3_q2_tensor_finite_element_0(); + 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 mass_matrix_f1_p3_q2_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p3_q2_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p3_q2_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f1_p3_q3_excafe.h b/mass_matrix_2d/mass_matrix_f1_p3_q3_excafe.h new file mode 100644 index 0000000..ede4a77 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p3_q3_excafe.h @@ -0,0 +1,319 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 6.18 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 = -1.0000000000000000000000000*x[0][1]; + const double var_1 = var_0 + x[1][1]; + const double var_2 = -1.0000000000000000000000000*x[0][0]; + const double var_3 = x[2][0] + var_2; + const double var_4 = var_0 + x[2][1]; + const double var_5 = x[1][0] + var_2; + const double var_6 = var_4*var_5 + -1.0000000000000000000000000*var_1*var_3; + const double var_7 = std::abs(var_6); + const double var_8 = 0.0059172077922077922704225*var_7*w[0][9]; + const double var_9 = -1.0000000000000000000000000*w[0][2]; + const double var_10 = w[0][4] + -0.5000000000000000000000000*w[0][3]; + const double var_11 = -1.0000000000000000000000000*w[0][7]; + const double var_12 = -1.0000000000000000000000000*w[0][5]; + const double var_13 = 0.9000000000000000222044605*w[0][1]; + const double var_14 = 0.6000000000000000888178420*w[0][0]; + const double var_15 = 11.7000000000000010658141036*w[0][6] + 3.9000000000000003552713679*var_11 + var_9 + 4.5000000000000000000000000*var_12 + 7.8000000000000007105427358*var_10 + var_14 + var_13; + A[69] = -0.0023011363636363637089066*var_7*w[0][8] + 0.0010957792207792207105077*var_15*var_7 + var_8; + const double var_16 = -0.0042735389610389614215014*var_7*w[0][9]; + const double var_17 = -0.5000000000000000000000000*w[0][8] + w[0][7]; + const double var_18 = w[0][3] + -4.1428571428571423496123316*w[0][6]; + const double var_19 = -0.0464285714285714301574615*w[0][1]; + const double var_20 = -0.0303571428571428568454760*w[0][0]; + const double var_21 = 0.0535714285714285684547598*var_9; + const double var_22 = -1.0000000000000000000000000*w[0][4]; + const double var_23 = 0.2571428571428571174806166*var_22; + const double var_24 = var_20 + 0.1125000000000000027755576*var_18 + var_23 + 0.1446428571428571285828468*w[0][5] + var_19 + 0.0642857142857142793701541*var_17 + var_21; + A[36] = var_16 + 0.0102272727272727272096464*var_24*var_7; + const double var_25 = -1.0000000000000000000000000*w[0][9]; + const double var_26 = 0.0085470779220779228430027*var_7*w[0][9]; + const double var_27 = w[0][8] + w[0][3]; + const double var_28 = w[0][5] + w[0][6]; + const double var_29 = var_27 + -1.0000000000000000000000000*var_28; + const double var_30 = -0.0000121753246753246753141*var_7*w[0][9]; + const double var_31 = w[0][3] + w[0][5]; + const double var_32 = w[0][0] + w[0][1]; + const double var_33 = w[0][8] + w[0][7]; + const double var_34 = w[0][4] + w[0][6]; + const double var_35 = -1.0000000000000000000000000*var_34; + const double var_36 = 0.0651785714285714329330190*var_33 + 0.0285714285714285705364279*var_31 + 0.0833333333333333287074041*var_32 + 0.0062500000000000003469447*var_35 + 0.0238095238095238082021154*w[0][2]; + A[1] = 0.0022727272727272726168812*var_36*var_7 + var_30; + A[10] = A[1]; + const double var_37 = 0.0006574675324675324263046*var_7*w[0][9]; + const double var_38 = w[0][4] + 3.0000000000000000000000000*w[0][6]; + const double var_39 = -1.0000000000000000000000000*w[0][1]; + const double var_40 = -21.8571428571428576503876684*w[0][8] + var_39; + const double var_41 = 0.0521428571428571435708577*w[0][0]; + const double var_42 = 0.2142857142857142738190390*var_9; + const double var_43 = 0.2764285714285714123938931*w[0][7] + var_42 + 0.0771428571428571380197425*w[0][3] + 0.0050000000000000001040834*var_40 + -0.1928571428571428381104624*var_38 + 0.4628571428571428558740308*w[0][5] + var_41; + A[25] = var_37 + 0.0028409090909090909879420*var_43*var_7; + const double var_44 = 0.0128206168831168833971423*var_7*w[0][9]; + const double var_45 = -4.1428571428571423496123316*w[0][3] + w[0][7]; + const double var_46 = 0.4285714285714285476380780*w[0][2]; + const double var_47 = 0.2928571428571428714171532*w[0][1]; + const double var_48 = 0.2571428571428571174806166*w[0][0]; + const double var_49 = 0.2250000000000000055511151*var_45 + 1.4464285714285713968507707*var_38 + -0.4178571428571428714171532*w[0][8] + -0.2892857142857142571656937*w[0][5] + var_46 + var_47 + var_48; + A[66] = 0.0051136363636363636048232*var_49*var_7 + var_44; + const double var_50 = w[0][8] + -4.1428571428571423496123316*w[0][5]; + const double var_51 = -0.0303571428571428568454760*w[0][2]; + const double var_52 = -1.0000000000000000000000000*w[0][0]; + const double var_53 = 0.0535714285714285684547598*var_52; + const double var_54 = 0.2571428571428571174806166*var_11; + const double var_55 = 0.1446428571428571285828468*w[0][6] + var_53 + 0.1125000000000000027755576*var_50 + var_51 + var_19 + 0.0642857142857142793701541*var_10 + var_54; + const double var_56 = 3.0000000000000000000000000*w[0][4] + w[0][6]; + const double var_57 = 0.2928571428571428714171532*w[0][0]; + const double var_58 = 0.2571428571428571174806166*w[0][1]; + const double var_59 = -0.4178571428571428714171532*w[0][7] + 0.2250000000000000055511151*var_50 + -0.2892857142857142571656937*w[0][3] + var_57 + var_58 + 1.4464285714285713968507707*var_56 + var_46; + A[44] = 0.0051136363636363636048232*var_59*var_7 + var_44; + const double var_60 = w[0][1] + -7.3125000000000000000000000*w[0][7]; + const double var_61 = 4.8750000000000000000000000*w[0][2]; + const double var_62 = 0.4562500000000000444089210*w[0][0]; + const double var_63 = 6.7500000000000000000000000*w[0][6] + var_62 + 0.0562500000000000013877788*w[0][8] + -5.0625000000000000000000000*w[0][5] + 0.2000000000000000111022302*var_60 + var_61 + 3.3750000000000000000000000*var_10; + const double var_64 = w[0][1] + w[0][2]; + const double var_65 = 0.0049310064935064934141251*var_25*var_7; + const double var_66 = w[0][4] + w[0][3]; + const double var_67 = w[0][5] + w[0][7]; + const double var_68 = var_67 + -1.0000000000000000000000000*var_66; + const double var_69 = w[0][8] + w[0][6]; + const double var_70 = -1.0000000000000000000000000*var_69; + const double var_71 = var_52 + 4.5000000000000000000000000*var_70 + 2.5312500000000000000000000*var_68; + A[34] = var_65 + -0.0016436688311688310657616*var_64*var_7 + 0.0005844155844155844150775*var_7*var_71; + A[43] = A[34]; + const double var_72 = 6.7500000000000000000000000*var_67 + w[0][0]; + const double var_73 = var_69 + var_66; + const double var_74 = 121.5000000000000000000000000*w[0][9] + 6.7500000000000000000000000*var_73 + var_72 + var_64; + const double var_75 = -0.5000000000000000000000000*w[0][4] + w[0][3]; + const double var_76 = w[0][6] + -4.1428571428571423496123316*w[0][7]; + const double var_77 = -0.0303571428571428568454760*w[0][1]; + const double var_78 = -0.0464285714285714301574615*w[0][2]; + const double var_79 = 0.2571428571428571174806166*var_12; + const double var_80 = 0.1125000000000000027755576*var_76 + var_53 + 0.1446428571428571285828468*w[0][8] + var_79 + var_77 + var_78 + 0.0642857142857142793701541*var_75; + const double var_81 = 0.9000000000000000222044605*w[0][2]; + const double var_82 = 4.5000000000000000000000000*var_11 + var_39 + var_81 + 11.7000000000000010658141036*w[0][8] + 3.9000000000000003552713679*var_12 + var_14 + 7.8000000000000007105427358*var_75; + A[89] = 0.0010957792207792207105077*var_7*var_82 + -0.0023011363636363637089066*var_7*w[0][6] + var_8; + A[98] = A[89]; + const double var_83 = 3.0000000000000000000000000*w[0][5] + w[0][7]; + const double var_84 = w[0][0] + w[0][2]; + const double var_85 = w[0][4] + w[0][7]; + const double var_86 = w[0][1] + 6.7500000000000000000000000*var_27; + const double var_87 = -1.8000000000000000444089210*var_85 + 0.7500000000000000000000000*var_86 + 0.5374999999999999777955395*var_84; + const double var_88 = 0.2571428571428571174806166*w[0][2]; + const double var_89 = w[0][8] + 3.0000000000000000000000000*w[0][3]; + const double var_90 = -21.8571428571428576503876684*w[0][5] + var_52; + const double var_91 = 0.0521428571428571435708577*w[0][2]; + const double var_92 = 0.2142857142857142738190390*var_39; + const double var_93 = 0.2764285714285714123938931*w[0][6] + 0.0771428571428571380197425*w[0][7] + -0.1928571428571428381104624*var_89 + var_91 + 0.4628571428571428558740308*w[0][4] + 0.0050000000000000001040834*var_90 + var_92; + A[14] = var_37 + 0.0028409090909090909879420*var_7*var_93; + A[41] = A[14]; + const double var_94 = -0.5000000000000000000000000*w[0][5] + w[0][6]; + const double var_95 = w[0][5] + -0.5000000000000000000000000*w[0][6]; + const double var_96 = 0.0008766233766233766768264*var_7*w[0][9]; + const double var_97 = -1.0000000000000000000000000*var_27; + const double var_98 = 0.9000000000000000222044605*var_85 + w[0][1] + 1.3500000000000000888178420*var_28 + 1.5000000000000000000000000*var_97; + A[19] = 0.0007305194805194805459519*var_7*var_98 + var_96 + -0.0000121753246753246753141*var_7*var_84; + A[91] = A[19]; + const double var_99 = w[0][4] + -4.1428571428571423496123316*w[0][8]; + const double var_100 = 0.0535714285714285684547598*var_39; + const double var_101 = -1.0000000000000000000000000*w[0][3]; + const double var_102 = 0.2571428571428571174806166*var_101; + const double var_103 = var_20 + 0.1446428571428571285828468*w[0][7] + 0.0642857142857142793701541*var_95 + 0.1125000000000000027755576*var_99 + var_100 + var_78 + var_102; + A[48] = var_16 + 0.0102272727272727272096464*var_103*var_7; + const double var_104 = 0.0023011363636363637089066*var_25*var_7; + const double var_105 = -0.0003287337662337662131523*var_33*var_7; + const double var_106 = 6.7500000000000000000000000*var_34 + w[0][2]; + const double var_107 = var_106 + -9.7500000000000000000000000*var_31; + A[35] = var_105 + 0.0000182629870129870129712*var_32*var_7 + var_104 + 0.0002191558441558441692066*var_107*var_7; + A[53] = A[35]; + const double var_108 = w[0][8] + -0.5000000000000000000000000*w[0][7]; + const double var_109 = w[0][0] + -7.3125000000000000000000000*w[0][6]; + const double var_110 = 0.4562500000000000444089210*w[0][2]; + const double var_111 = 4.8750000000000000000000000*w[0][1]; + const double var_112 = 0.2000000000000000111022302*var_109 + var_111 + 6.7500000000000000000000000*w[0][3] + 0.0562500000000000013877788*w[0][5] + -5.0625000000000000000000000*w[0][4] + var_110 + 3.3750000000000000000000000*var_108; + const double var_113 = 0.4285714285714285476380780*w[0][1]; + const double var_114 = 0.2250000000000000055511151*var_76 + 1.4464285714285713968507707*var_89 + -0.4178571428571428714171532*w[0][5] + var_88 + var_57 + var_113 + -0.2892857142857142571656937*w[0][4]; + const double var_115 = 0.0010957792207792207105077*var_25*var_7; + const double var_116 = w[0][0] + -7.3125000000000000000000000*w[0][8]; + const double var_117 = 0.4562500000000000444089210*w[0][1]; + const double var_118 = 0.0562500000000000013877788*w[0][7] + 0.2000000000000000111022302*var_116 + -5.0625000000000000000000000*w[0][3] + var_117 + var_61 + 6.7500000000000000000000000*w[0][4] + 3.3750000000000000000000000*var_94; + A[24] = var_115 + 0.0003246753246753246750431*var_118*var_7; + const double var_119 = 0.0521428571428571435708577*w[0][1]; + const double var_120 = -7.3125000000000000000000000*w[0][3] + w[0][2]; + const double var_121 = -7.3125000000000000000000000*w[0][4] + w[0][1]; + const double var_122 = 0.0007305194805194805459519*var_7*w[0][9]; + const double var_123 = -1.0000000000000000000000000*var_31; + const double var_124 = 0.0142857142857142852682140*var_33 + 0.0666666666666666657414808*var_32 + 0.2142857142857142738190390*var_123 + 0.5571428571428571618895376*var_34 + 0.8857142857142856762209249*w[0][2]; + A[22] = var_122 + 0.0028409090909090909879420*var_124*var_7; + A[58] = var_16 + 0.0102272727272727272096464*var_55*var_7; + const double var_125 = -4.1428571428571423496123316*w[0][4] + w[0][5]; + const double var_126 = -0.0003287337662337662131523*var_66*var_7; + const double var_127 = -1.8000000000000000444089210*var_69 + 0.7500000000000000000000000*var_72 + 0.5374999999999999777955395*var_64; + A[57] = var_26 + 0.0014610389610389610919039*var_127*var_7 + var_126; + A[75] = A[57]; + const double var_128 = 0.0178571428571428561515866*w[0][1]; + const double var_129 = 4.8750000000000000000000000*w[0][0]; + const double var_130 = -5.0625000000000000000000000*w[0][6] + var_129 + 0.0562500000000000013877788*w[0][3] + 6.7500000000000000000000000*w[0][5] + 3.3750000000000000000000000*var_17 + 0.2000000000000000111022302*var_121 + var_110; + A[5] = 0.0003246753246753246750431*var_130*var_7 + var_115; + A[50] = A[5]; + const double var_131 = -1.0000000000000000000000000*w[0][6]; + const double var_132 = 0.6000000000000000888178420*w[0][2]; + const double var_133 = 4.5000000000000000000000000*var_131 + 11.7000000000000010658141036*w[0][5] + 3.9000000000000003552713679*var_22 + 7.8000000000000007105427358*var_17 + var_52 + var_13 + var_132; + A[59] = -0.0023011363636363637089066*var_7*w[0][3] + 0.0010957792207792207105077*var_133*var_7 + var_8; + A[95] = A[59]; + const double var_134 = 0.0009862012987012986394569*var_7*w[0][9]; + const double var_135 = -21.8571428571428576503876684*w[0][4] + var_9; + const double var_136 = 0.2571428571428571174806166*var_131; + const double var_137 = 0.3455357142857142793701541*w[0][7] + var_136 + 0.0080357142857142849212693*w[0][3] + 0.0285714285714285705364279*var_116 + 0.6589285714285714190552312*w[0][5] + 0.0062500000000000003469447*var_135 + var_128; + A[15] = var_134 + 0.0022727272727272726168812*var_137*var_7; + A[51] = A[15]; + const double var_138 = var_9 + -21.8571428571428576503876684*w[0][6]; + A[26] = 0.0003246753246753246750431*var_63*var_7 + var_115; + A[62] = A[26]; + const double var_139 = 6.7500000000000000000000000*w[0][7] + 3.3750000000000000000000000*var_95 + var_129 + -5.0625000000000000000000000*w[0][8] + var_117 + 0.2000000000000000111022302*var_120 + 0.0562500000000000013877788*w[0][4]; + const double var_140 = 0.0178571428571428561515866*w[0][2]; + const double var_141 = 0.0080357142857142849212693*w[0][6] + var_140 + 0.3455357142857142793701541*w[0][3] + 0.6589285714285714190552312*w[0][8] + 0.0285714285714285705364279*var_121 + var_54 + 0.0062500000000000003469447*var_90; + A[28] = var_134 + 0.0022727272727272726168812*var_141*var_7; + const double var_142 = -1.0000000000000000000000000*var_85; + const double var_143 = 0.0142857142857142852682140*var_28 + 0.5571428571428571618895376*var_27 + 0.0666666666666666657414808*var_84 + 0.2142857142857142738190390*var_142 + 0.8857142857142856762209249*w[0][1]; + A[11] = var_122 + 0.0028409090909090909879420*var_143*var_7; + const double var_144 = -1.0000000000000000000000000*w[0][8]; + const double var_145 = 0.6000000000000000888178420*w[0][1]; + const double var_146 = 11.7000000000000010658141036*w[0][7] + var_81 + 7.8000000000000007105427358*var_95 + 3.9000000000000003552713679*var_101 + var_145 + 4.5000000000000000000000000*var_144 + var_52; + A[79] = -0.0023011363636363637089066*var_7*w[0][4] + 0.0010957792207792207105077*var_146*var_7 + var_8; + A[97] = A[79]; + const double var_147 = 2.5312500000000000000000000*var_29 + var_39 + 4.5000000000000000000000000*var_142; + const double var_148 = var_52 + -21.8571428571428576503876684*w[0][7]; + const double var_149 = 0.0050000000000000001040834*var_148 + var_42 + 0.4628571428571428558740308*w[0][3] + var_119 + 0.2764285714285714123938931*w[0][8] + 0.0771428571428571380197425*w[0][5] + -0.1928571428571428381104624*var_56; + const double var_150 = -0.0464285714285714301574615*w[0][0]; + const double var_151 = 0.2571428571428571174806166*var_144; + const double var_152 = var_150 + var_51 + 0.1125000000000000027755576*var_45 + var_100 + var_151 + 0.0642857142857142793701541*var_94 + 0.1446428571428571285828468*w[0][4]; + A[37] = var_16 + 0.0102272727272727272096464*var_152*var_7; + A[67] = var_16 + 0.0102272727272727272096464*var_7*var_80; + const double var_153 = -21.8571428571428576503876684*w[0][3] + var_39; + const double var_154 = 0.2142857142857142738190390*var_52; + const double var_155 = 0.4628571428571428558740308*w[0][6] + var_154 + 0.0771428571428571380197425*w[0][8] + 0.0050000000000000001040834*var_153 + var_91 + -0.1928571428571428381104624*var_83 + 0.2764285714285714123938931*w[0][4]; + A[6] = var_37 + 0.0028409090909090909879420*var_155*var_7; + A[13] = 0.0003246753246753246750431*var_112*var_7 + var_115; + A[31] = A[13]; + const double var_156 = -1.0000000000000000000000000*var_67; + const double var_157 = 0.0285714285714285705364279*var_69 + 0.0651785714285714329330190*var_66 + 0.0062500000000000003469447*var_156 + 0.0238095238095238082021154*w[0][0] + 0.0833333333333333287074041*var_64; + const double var_158 = 3.0000000000000000000000000*w[0][8] + w[0][3]; + const double var_159 = 0.2928571428571428714171532*w[0][2]; + const double var_160 = -0.4178571428571428714171532*w[0][6] + -0.2892857142857142571656937*w[0][7] + var_159 + 1.4464285714285713968507707*var_158 + var_113 + 0.2250000000000000055511151*var_125 + var_48; + A[12] = 0.0022727272727272726168812*var_157*var_7 + var_30; + const double var_161 = 0.0178571428571428561515866*w[0][0]; + const double var_162 = var_161 + var_23 + 0.6589285714285714190552312*w[0][3] + 0.3455357142857142793701541*w[0][8] + 0.0062500000000000003469447*var_138 + 0.0080357142857142849212693*w[0][5] + 0.0285714285714285705364279*var_60; + const double var_163 = var_34 + -1.0000000000000000000000000*var_33; + const double var_164 = 2.5312500000000000000000000*var_163 + var_9 + 4.5000000000000000000000000*var_123; + A[78] = 0.0005844155844155844150775*var_164*var_7 + var_65 + -0.0016436688311688310657616*var_32*var_7; + A[60] = A[6]; + const double var_165 = 0.4628571428571428558740308*w[0][7] + 0.2764285714285714123938931*w[0][5] + -0.1928571428571428381104624*var_158 + 0.0050000000000000001040834*var_138 + 0.0771428571428571380197425*w[0][4] + var_41 + var_92; + A[17] = var_37 + 0.0028409090909090909879420*var_165*var_7; + const double var_166 = -9.7500000000000000000000000*var_69 + var_72; + const double var_167 = 0.4285714285714285476380780*w[0][0]; + const double var_168 = -0.2892857142857142571656937*w[0][6] + var_167 + 0.2250000000000000055511151*var_99 + -0.4178571428571428714171532*w[0][3] + var_88 + 1.4464285714285713968507707*var_83 + var_47; + A[55] = var_44 + 0.0051136363636363636048232*var_168*var_7; + A[96] = A[69]; + const double var_169 = var_140 + 0.0285714285714285705364279*var_109 + 0.6589285714285714190552312*w[0][7] + 0.3455357142857142793701541*w[0][5] + var_151 + 0.0062500000000000003469447*var_153 + 0.0080357142857142849212693*w[0][4]; + A[27] = var_134 + 0.0022727272727272726168812*var_169*var_7; + A[72] = A[27]; + const double var_170 = 0.0651785714285714329330190*var_28 + 0.0062500000000000003469447*var_97 + 0.0833333333333333287074041*var_84 + 0.0285714285714285705364279*var_85 + 0.0238095238095238082021154*w[0][1]; + A[63] = A[36]; + A[76] = A[67]; + const double var_171 = w[0][5] + 3.0000000000000000000000000*w[0][7]; + const double var_172 = var_167 + 0.2250000000000000055511151*var_18 + var_159 + -0.2892857142857142571656937*w[0][8] + var_58 + -0.4178571428571428714171532*w[0][4] + 1.4464285714285713968507707*var_171; + A[42] = A[24]; + const double var_173 = -7.3125000000000000000000000*w[0][5] + w[0][2]; + const double var_174 = 0.0285714285714285705364279*var_173 + 0.3455357142857142793701541*w[0][6] + 0.0080357142857142849212693*w[0][7] + var_161 + 0.0062500000000000003469447*var_40 + var_102 + 0.6589285714285714190552312*w[0][4]; + A[4] = var_134 + 0.0022727272727272726168812*var_174*var_7; + A[40] = A[4]; + const double var_175 = var_150 + var_136 + 0.1446428571428571285828468*w[0][3] + var_77 + 0.1125000000000000027755576*var_125 + var_21 + 0.0642857142857142793701541*var_108; + A[45] = var_16 + 0.0102272727272727272096464*var_175*var_7; + A[54] = A[45]; + A[56] = var_65 + 0.0005844155844155844150775*var_147*var_7 + -0.0016436688311688310657616*var_7*var_84; + A[65] = A[56]; + A[71] = A[17]; + const double var_176 = w[0][0] + 0.9000000000000000222044605*var_69 + 1.5000000000000000000000000*var_156 + 1.3500000000000000888178420*var_66; + A[9] = -0.0000121753246753246753141*var_64*var_7 + var_96 + 0.0007305194805194805459519*var_176*var_7; + A[90] = A[9]; + A[68] = 0.0000182629870129870129712*var_64*var_7 + 0.0002191558441558441692066*var_166*var_7 + var_126 + var_104; + const double var_177 = 0.0771428571428571380197425*w[0][6] + var_154 + var_119 + 0.2764285714285714123938931*w[0][3] + 0.4628571428571428558740308*w[0][8] + 0.0050000000000000001040834*var_135 + -0.1928571428571428381104624*var_171; + const double var_178 = 0.0142857142857142852682140*var_66 + 0.2142857142857142738190390*var_70 + 0.8857142857142856762209249*w[0][0] + 0.5571428571428571618895376*var_67 + 0.0666666666666666657414808*var_64; + const double var_179 = 1.3500000000000000888178420*var_33 + 1.5000000000000000000000000*var_35 + 0.9000000000000000222044605*var_31 + w[0][2]; + A[29] = var_96 + 0.0007305194805194805459519*var_179*var_7 + -0.0000121753246753246753141*var_32*var_7; + A[92] = A[29]; + const double var_180 = 0.0062500000000000003469447*var_148 + 0.6589285714285714190552312*w[0][6] + 0.0080357142857142849212693*w[0][8] + var_79 + 0.0285714285714285705364279*var_120 + 0.3455357142857142793701541*w[0][4] + var_128; + const double var_181 = 0.0562500000000000013877788*w[0][6] + 0.2000000000000000111022302*var_173 + -5.0625000000000000000000000*w[0][7] + var_111 + var_62 + 6.7500000000000000000000000*w[0][8] + 3.3750000000000000000000000*var_75; + A[18] = 0.0003246753246753246750431*var_181*var_7 + var_115; + A[7] = 0.0003246753246753246750431*var_139*var_7 + var_115; + const double var_182 = 0.5374999999999999777955395*var_32 + 0.7500000000000000000000000*var_106 + -1.8000000000000000444089210*var_31; + const double var_183 = -0.0003287337662337662131523*var_28*var_7; + const double var_184 = 0.9000000000000000222044605*w[0][0]; + const double var_185 = 3.9000000000000003552713679*var_131 + var_184 + var_39 + 11.7000000000000010658141036*w[0][3] + 4.5000000000000000000000000*var_22 + var_132 + 7.8000000000000007105427358*var_108; + A[39] = 0.0010957792207792207105077*var_185*var_7 + -0.0023011363636363637089066*var_7*w[0][5] + var_8; + A[93] = A[39]; + const double var_186 = -117.0000000000000000000000000*var_85 + var_84; + A[16] = var_134 + 0.0022727272727272726168812*var_180*var_7; + A[81] = A[18]; + A[77] = 0.0051136363636363636048232*var_172*var_7 + var_44; + A[21] = A[12]; + A[87] = A[78]; + A[70] = A[7]; + A[33] = 0.0051136363636363636048232*var_114*var_7 + var_44; + A[8] = var_37 + 0.0028409090909090909879420*var_177*var_7; + A[73] = A[37]; + A[82] = A[28]; + A[47] = 0.0002191558441558441692066*var_7*var_86 + 0.0000182629870129870129712*var_186*var_7 + var_104 + var_183; + A[2] = 0.0022727272727272726168812*var_170*var_7 + var_30; + A[20] = A[2]; + const double var_187 = var_184 + 4.5000000000000000000000000*var_101 + var_9 + var_145 + 3.9000000000000003552713679*var_144 + 11.7000000000000010658141036*w[0][4] + 7.8000000000000007105427358*var_94; + A[49] = -0.0023011363636363637089066*var_7*w[0][7] + 0.0010957792207792207105077*var_187*var_7 + var_8; + A[52] = A[25]; + A[46] = var_26 + var_105 + 0.0014610389610389610919039*var_182*var_7; + A[64] = A[46]; + A[94] = A[49]; + A[38] = var_26 + 0.0014610389610389610919039*var_7*var_87 + var_183; + A[83] = A[38]; + A[74] = A[47]; + A[3] = var_134 + 0.0022727272727272726168812*var_162*var_7; + A[30] = A[3]; + A[61] = A[16]; + A[86] = A[68]; + A[88] = 0.0051136363636363636048232*var_160*var_7 + var_44; + A[85] = A[58]; + A[84] = A[48]; + A[23] = var_37 + 0.0028409090909090909879420*var_149*var_7; + A[99] = 0.0008766233766233766768264*var_7*var_74; + A[80] = A[8]; + A[0] = var_122 + 0.0028409090909090909879420*var_178*var_7; + A[32] = A[23]; + } + + 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/mass_matrix_2d/mass_matrix_f1_p3_q3_quadrature.h b/mass_matrix_2d/mass_matrix_f1_p3_q3_quadrature.h new file mode 100644 index 0000000..47c2df8 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p3_q3_quadrature.h @@ -0,0 +1,3422 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P3_Q3_QUADRATURE_H +#define __MASS_MATRIX_F1_P3_Q3_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p3_q3_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p3_q3_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p3_q3_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p3_q3_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p3_q3_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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.0*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 mass_matrix_f1_p3_q3_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class mass_matrix_f1_p3_q3_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p3_q3_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // 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[25][10] = \ + {{0.595361771100889, 0.0363240630142744, 0.0329620582231266, -0.00697876330105453, -0.00710543413900173, 0.286154010031837, -0.144363814874519, 0.323767019699913, -0.160427557536749, 0.0443066477812842}, + {0.144847707077251, 0.031491752557511, 0.056509372357196, -0.0297392974343587, -0.0136089104009562, 0.880722068301204, -0.276497422020097, 0.167331423967527, -0.114798724929776, 0.153742030524499}, + {-0.0638922318573471, 0.0233191863197456, -0.0471646056404562, -0.0478518692290425, 0.0163120554591614, 0.640806423249974, 0.331418250941681, 0.038574441798557, -0.0585247318831845, 0.167003080840912}, + {0.0211818331847306, 0.0133805365030047, 0.0326369349932555, -0.0427925717552784, 0.0485711762178746, -0.117406110387015, 0.98683910857276, -0.0024116832712123, -0.0178593517002863, 0.0778601276421673}, + {0.0579517721596659, 0.00452658789692546, 0.541134376806172, -0.0184907249626245, 0.0319586608616019, -0.273633189306433, 0.649316299328904, -0.0014030624094848, -0.00192632644777788, 0.010565606073051}, + {0.0969129145557495, 0.0495966310503562, 0.0329620582231266, -0.0133081629182569, -0.0349538534974921, 0.160876909651335, -0.116515395516028, 0.895428534283356, -0.246912783611135, 0.175913147778989}, + {-0.0391667888544834, 0.0594654509565622, 0.056509372357196, -0.0733496016702976, -0.0669464878724995, 0.467663868980969, -0.223159844548554, 0.437096058075966, -0.228522561505531, 0.610410534080673}, + {-0.0451321541833679, 0.0638185648099453, -0.0471646056404562, -0.15615892407532, 0.0802441041051714, 0.253054939278284, 0.267486202295671, 0.074936267198872, -0.154146013447678, 0.663061619658879}, + {0.045160818752146, 0.0496137334753148, 0.0326369349932555, -0.17356708239734, 0.238936811531546, -0.217903867034122, 0.796473473259088, -0.0220190689531468, -0.0584641485580772, 0.309132394931336}, + {0.0519031146003489, 0.0204647143413336, 0.541134376806172, -0.0859485068100627, 0.157214651192224, -0.23755901477889, 0.524060308998282, -0.00599217068695466, -0.00722668705539908, 0.0419492133929461}, + {-0.0591559090807405, -0.0591559090807405, 0.0329620582231266, 0.03786731225338, -0.0757346245067602, 0.03786731225338, -0.0757346245067601, 0.456668557219904, 0.456668557219904, 0.247747270005307}, + {-0.032436155693348, -0.032436155693348, 0.056509372357196, 0.0725265831052634, -0.145053166210527, 0.0725265831052632, -0.145053166210527, 0.146872235029605, 0.146872235029605, 0.859671635180817}, + {0.025515852626442, 0.0255158526264419, -0.0471646056404562, -0.0869325766002105, 0.173865153200421, -0.0869325766002107, 0.173865153200421, -0.0557775204375565, -0.0557775204375563, 0.933822788062264}, + {0.0638199343796498, 0.0638199343796498, 0.0326369349932555, -0.258852571197659, 0.517705142395317, -0.258852571197659, 0.517705142395317, -0.0566742670215316, -0.0566742670215314, 0.435366587895191}, + {0.0388828743119486, 0.0388828743119486, 0.541134376806172, -0.170318740047627, 0.340637480095253, -0.170318740047627, 0.340637480095253, -0.0093083887122843, -0.00930838871228411, 0.0590791718992466}, + {0.0495966310503563, 0.0969129145557494, 0.0329620582231266, 0.160876909651335, -0.116515395516028, -0.013308162918257, -0.034953853497492, -0.246912783611135, 0.895428534283356, 0.175913147778989}, + {0.0594654509565623, -0.0391667888544834, 0.056509372357196, 0.467663868980969, -0.223159844548554, -0.0733496016702976, -0.0669464878724995, -0.228522561505532, 0.437096058075966, 0.610410534080673}, + {0.0638185648099453, -0.0451321541833679, -0.0471646056404562, 0.253054939278284, 0.267486202295671, -0.15615892407532, 0.0802441041051715, -0.154146013447678, 0.0749362671988722, 0.663061619658879}, + {0.0496137334753148, 0.045160818752146, 0.0326369349932555, -0.217903867034122, 0.796473473259088, -0.17356708239734, 0.238936811531547, -0.0584641485580774, -0.0220190689531466, 0.309132394931336}, + {0.0204647143413336, 0.0519031146003489, 0.541134376806172, -0.23755901477889, 0.524060308998282, -0.0859485068100628, 0.157214651192223, -0.00722668705539924, -0.00599217068695446, 0.041949213392946}, + {0.0363240630142745, 0.595361771100889, 0.0329620582231266, 0.286154010031837, -0.144363814874519, -0.00697876330105458, -0.00710543413900171, -0.160427557536749, 0.323767019699913, 0.0443066477812842}, + {0.031491752557511, 0.144847707077251, 0.056509372357196, 0.880722068301204, -0.276497422020097, -0.0297392974343586, -0.0136089104009562, -0.114798724929776, 0.167331423967527, 0.153742030524498}, + {0.0233191863197457, -0.0638922318573471, -0.0471646056404562, 0.640806423249974, 0.331418250941681, -0.0478518692290426, 0.0163120554591614, -0.0585247318831847, 0.0385744417985573, 0.167003080840912}, + {0.0133805365030048, 0.0211818331847307, 0.0326369349932554, -0.117406110387015, 0.986839108572759, -0.0427925717552788, 0.0485711762178751, -0.0178593517002866, -0.00241168327121213, 0.0778601276421677}, + {0.00452658789692547, 0.057951772159666, 0.541134376806172, -0.273633189306433, 0.649316299328904, -0.0184907249626247, 0.0319586608616018, -0.00192632644777806, -0.0014030624094846, 0.0105656060730509}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 100; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 8050 + for (unsigned int ip = 0; ip < 25; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + + // Total number of operations to compute function values = 20 + for (unsigned int r = 0; r < 10; r++) + { + F0 += FE0[ip][r]*w[0][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 2 + double I[1]; + // Number of operations: 2 + I[0] = F0*W25[ip]*det; + + + // Number of operations for primary indices: 300 + for (unsigned int j = 0; j < 10; j++) + { + for (unsigned int k = 0; k < 10; k++) + { + // Number of operations to compute entry: 3 + A[j*10 + k] += FE0[ip][j]*FE0[ip][k]*I[0]; + }// 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 mass_matrix_f1_p3_q3_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p3_q3_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p3_q3_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1))), 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 mass_matrix_f1_p3_q3_quadrature_finite_element_0(); + break; + } + case 1: + { + return new mass_matrix_f1_p3_q3_quadrature_finite_element_0(); + break; + } + case 2: + { + return new mass_matrix_f1_p3_q3_quadrature_finite_element_0(); + 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 mass_matrix_f1_p3_q3_quadrature_dofmap_0(); + break; + } + case 1: + { + return new mass_matrix_f1_p3_q3_quadrature_dofmap_0(); + break; + } + case 2: + { + return new mass_matrix_f1_p3_q3_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f1_p3_q3_tensor.h b/mass_matrix_2d/mass_matrix_f1_p3_q3_tensor.h new file mode 100644 index 0000000..06d7ef7 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p3_q3_tensor.h @@ -0,0 +1,3464 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P3_Q3_TENSOR_H +#define __MASS_MATRIX_F1_P3_Q3_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p3_q3_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p3_q3_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p3_q3_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p3_q3_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p3_q3_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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.0*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 mass_matrix_f1_p3_q3_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class mass_matrix_f1_p3_q3_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p3_q3_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 10 + // Number of operations (multiply-add pairs) for tensor contraction: 450 + // Total number of operations (multiply-add pairs): 469 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0 = det*w[0][0]*(1.0); + const double G0_1 = det*w[0][1]*(1.0); + const double G0_2 = det*w[0][2]*(1.0); + const double G0_3 = det*w[0][3]*(1.0); + const double G0_4 = det*w[0][4]*(1.0); + const double G0_5 = det*w[0][5]*(1.0); + const double G0_6 = det*w[0][6]*(1.0); + const double G0_7 = det*w[0][7]*(1.0); + const double G0_8 = det*w[0][8]*(1.0); + const double G0_9 = det*w[0][9]*(1.0); + + // Compute element tensor + A[73] = -0.000474837662337661*G0_0 - 0.000547889610389608*G0_1 - 0.000310470779220778*G0_2 - 0.0047666396103896*G0_3 + 0.00147930194805195*G0_4 - 0.000328733766233766*G0_5 + 0.000657467532467532*G0_6 + 0.00115056818181818*G0_7 - 0.00262987012987012*G0_8 - 0.00427353896103895*G0_9; + A[37] = A[73]; + A[85] = A[73] - 7.30519480519467e-05*G0_0 + 7.30519480519474e-05*G0_1 + 0.00443790584415583*G0_3 - 0.000821834415584414*G0_4 - 0.00443790584415583*G0_5 + 0.000821834415584413*G0_6 - 0.0037804383116883*G0_7 + 0.0037804383116883*G0_8; + A[58] = A[85]; + A[90] = A[73] + 0.00120535714285714*G0_0 + 0.000535714285714283*G0_1 + 0.000298295454545453*G0_2 + 0.00575284090909089*G0_3 - 0.000493100649350649*G0_4 - 0.000767045454545453*G0_5 - 0.00224634740259739*G0_7 + 0.00328733766233765*G0_8 + 0.00515016233766232*G0_9; + A[7] = -A[90] + 0.00231331168831168*G0_0 + 0.000135957792207791*G0_1 + 5.27597402597394e-05*G0_2 + 0.000511363636363635*G0_3 + 0.00100446428571428*G0_4 + 0.000109577922077925*G0_6 + 0.00109577922077921*G0_7 - 0.000986201298701292*G0_8 - 0.000219155844155843*G0_9; + A[16] = A[7] - 0.00159699675324674*G0_0 - 0.0001075487012987*G0_1 + 0.000767045454545452*G0_4 - 0.0016801948051948*G0_5 + 0.00204545454545454*G0_6 - 0.00250202922077921*G0_7 + 0.00166193181818181*G0_8 + 0.00208198051948051*G0_9; + A[40] = A[16] + 5.47889610389605e-05*G0_0 - 5.47889610389606e-05*G0_1 - 0.000109577922077922*G0_3 + 0.000712256493506492*G0_4 + 0.000109577922077921*G0_5 - 0.00071225649350649*G0_6 + 0.000328733766233765*G0_7 - 0.000328733766233765*G0_8; + A[25] = A[40] + 0.000107548701298701*G0_0 - 0.000673701298701295*G0_2 + 0.000803571428571425*G0_3 - 0.00204545454545454*G0_4 + 0.00178977272727272*G0_5 - 0.00242897727272726*G0_6 + 0.000767045454545452*G0_7 - 0.000328733766233765*G0_9; + A[67] = A[85] + 0.000164366883116882*G0_1 - 0.000164366883116882*G0_2 + 0.000986201298701298*G0_3 - 0.000986201298701299*G0_4 + 0.00213676948051947*G0_5 - 0.000328733766233773*G0_6 - 0.00213676948051947*G0_7 + 0.000328733766233769*G0_8; + A[76] = A[67]; + A[4] = A[40]; + A[32] = A[7] - 0.00159699675324674*G0_0 - 0.000673701298701295*G0_2 + 0.00178977272727272*G0_3 - 0.00166193181818181*G0_4 - 0.000876623376623372*G0_5 - 0.00250202922077921*G0_7 + 0.00242897727272726*G0_8 + 0.00175324675324675*G0_9; + A[82] = A[16] + 2.4350649350649e-05*G0_1 - 2.43506493506486e-05*G0_2 + 0.0012601461038961*G0_3 - 0.0012601461038961*G0_4 + 0.000273944805194804*G0_5 - 0.00147930194805194*G0_6 - 0.000273944805194804*G0_7 + 0.00147930194805194*G0_8; + A[45] = A[73] + 0.000237418831168829*G0_1 - 0.000237418831168829*G0_2 + 0.00624594155844154*G0_3 - 0.00624594155844154*G0_4 + 0.00147930194805195*G0_5 - 0.00328733766233766*G0_6 - 0.00147930194805194*G0_7 + 0.00328733766233765*G0_8; + A[60] = A[25] - 0.000756899350649346*G0_0 + 0.000756899350649347*G0_2 - 0.000529626623376621*G0_3 + 0.00133319805194805*G0_4 - 0.00295860389610388*G0_5 + 0.00295860389610388*G0_6 - 0.00133319805194805*G0_7 + 0.000529626623376622*G0_8; + A[1] = -A[7] + 0.00177218614718614*G0_0 + 0.000337527056277054*G0_1 + 0.000119047619047618*G0_2 - 0.000409902597402596*G0_3 + 4.05844155844131e-06*G0_4 + 0.00116071428571428*G0_5 - 0.000562094155844152*G0_6 + 0.00233969155844155*G0_7 - 0.00149553571428571*G0_8 - 0.00110795454545454*G0_9; + A[31] = A[60] + 0.000673701298701294*G0_0 + 0.00159699675324674*G0_1 + 0.00250202922077921*G0_3 - 0.00242897727272726*G0_4 + 0.00166193181818181*G0_5 - 0.00178977272727272*G0_6 + 0.000876623376623372*G0_8 - 0.00175324675324675*G0_9; + A[99] = 0.000876623376623375*G0_0 + 0.000876623376623369*G0_1 + 0.000876623376623376*G0_2 + 0.00591720779220777*G0_3 + 0.00591720779220777*G0_4 + 0.00591720779220775*G0_5 + 0.00591720779220776*G0_6 + 0.00591720779220776*G0_7 + 0.00591720779220779*G0_8 + 0.10650974025974*G0_9; + A[21] = A[1] - 0.000135281385281384*G0_0 + 0.000135281385281385*G0_2 + 8.31980519480515e-05*G0_3 + 0.000162337662337661*G0_4 - 7.91396103896095e-05*G0_5 + 7.91396103896095e-05*G0_6 - 0.000162337662337661*G0_7 - 8.31980519480518e-05*G0_8; + A[51] = A[16] + 7.91396103896094e-05*G0_0 - 7.91396103896096e-05*G0_2 + 0.000493100649350648*G0_3 - 0.00109577922077922*G0_4 + 0.00208198051948051*G0_5 - 0.00208198051948051*G0_6 + 0.00109577922077922*G0_7 - 0.000493100649350648*G0_8; + A[72] = A[40] + 2.4350649350649e-05*G0_0 - 2.43506493506495e-05*G0_2 + 0.000273944805194804*G0_3 - 0.00147930194805194*G0_4 + 0.0012601461038961*G0_5 - 0.0012601461038961*G0_6 + 0.00147930194805194*G0_7 - 0.000273944805194805*G0_8; + A[15] = A[51]; + A[36] = A[85] + 0.000237418831168829*G0_0 - 0.000237418831168828*G0_2 + 0.00147930194805195*G0_3 - 0.00328733766233765*G0_4 + 0.00624594155844154*G0_5 - 0.00624594155844154*G0_6 + 0.00328733766233765*G0_7 - 0.00147930194805194*G0_8; + A[22] = A[1] + 0.0024621212121212*G0_2 - 0.000673701298701295*G0_3 + 0.00159699675324674*G0_4 - 0.000673701298701295*G0_5 + 0.00159699675324674*G0_6 - 0.000107548701298701*G0_7 - 0.0001075487012987*G0_8 + 0.000742694805194803*G0_9; + A[11] = A[22] + 0.00232683982683981*G0_1 - 0.00232683982683981*G0_2 + 0.00219155844155843*G0_3 - 0.00219155844155843*G0_4 + 0.000649350649350646*G0_5 - 0.00154220779220778*G0_6 - 0.000649350649350646*G0_7 + 0.00154220779220778*G0_8; + A[86] = -A[90] + 0.000949675324675321*G0_0 + 6.08766233766257e-06*G0_1 + 6.08766233766268e-06*G0_2 + 0.00065746753246753*G0_3 + 0.000657467532467532*G0_4 + 0.000383522727272727*G0_5 - 0.00147930194805194*G0_6 + 0.000383522727272725*G0_7 - 0.00147930194805194*G0_8 - 0.00142451298701298*G0_9; + A[75] = A[86] + 0.000876623376623371*G0_0 + 0.00076704545454545*G0_1 + 0.000767045454545451*G0_2 + 0.00591720779220776*G0_5 - 0.000493100649350649*G0_6 + 0.00591720779220776*G0_7 - 0.000493100649350646*G0_8 + 0.0108482142857142*G0_9; + A[41] = A[32] - 0.000756899350649346*G0_1 + 0.000756899350649346*G0_2 - 0.00295860389610388*G0_3 + 0.00295860389610388*G0_4 - 0.000529626623376621*G0_5 + 0.00133319805194805*G0_6 + 0.000529626623376621*G0_7 - 0.00133319805194804*G0_8; + A[64] = A[75] - 0.000310470779220775*G0_0 + 0.000310470779220775*G0_2 - 0.00230113636363636*G0_3 + 0.00772524350649348*G0_4 - 0.0100263798701298*G0_5 + 0.0100263798701298*G0_6 - 0.00772524350649347*G0_7 + 0.00230113636363635*G0_8; + A[69] = -A[64] + 0.00144277597402597*G0_0 + 0.00177150974025973*G0_1 - 0.00690340909090907*G0_3 + 0.0159435876623376*G0_4 - 0.00756087662337661*G0_5 + 0.0202171266233766*G0_6 - 0.00460227272727272*G0_7 - 0.00262987012987012*G0_8 + 0.0144642857142857*G0_9; + A[93] = A[69] + 0.000328733766233764*G0_0 - 0.00208198051948051*G0_1 + 0.00175324675324675*G0_2 + 0.0170941558441558*G0_3 - 0.0134780844155844*G0_4 + 0.00262987012987013*G0_5 - 0.0170941558441558*G0_6 + 0.0108482142857142*G0_8; + A[78] = A[64] - 0.00242897727272726*G0_0 - 0.00242897727272726*G0_1 - 0.0016801948051948*G0_2 - 0.00591720779220778*G0_4 - 0.00591720779220777*G0_6 - 0.00115056818181817*G0_7 - 0.00115056818181818*G0_8 - 0.0134780844155844*G0_9; + A[89] = A[69] - 0.00208198051948051*G0_1 + 0.00208198051948051*G0_2 + 0.0128206168831168*G0_3 - 0.0128206168831168*G0_4 + 0.000657467532467534*G0_5 - 0.0151217532467532*G0_6 - 0.000657467532467533*G0_7 + 0.0151217532467532*G0_8; + A[94] = A[69] + 0.000328733766233764*G0_0 - 0.000328733766233764*G0_1 - 0.000657467532467533*G0_3 + 0.00427353896103895*G0_4 + 0.000657467532467533*G0_5 - 0.00427353896103895*G0_6 + 0.00197240259740259*G0_7 - 0.00197240259740259*G0_8; + A[97] = A[69] - 0.00175324675324675*G0_0 - 0.000328733766233766*G0_1 + 0.00208198051948051*G0_2 - 0.0108482142857143*G0_4 + 0.0134780844155844*G0_5 - 0.0170941558441558*G0_6 + 0.0170941558441558*G0_7 - 0.00262987012987013*G0_8; + A[54] = A[45]; + A[71] = A[25] - 0.000594561688311686*G0_1 + 0.000594561688311685*G0_2 - 0.00076704545454545*G0_3 + 0.00076704545454545*G0_4 - 0.000529626623376622*G0_5 + 0.00133319805194804*G0_6 + 0.000529626623376619*G0_7 - 0.00133319805194804*G0_8; + A[26] = A[71] + 0.000673701298701296*G0_1 + 0.00159699675324674*G0_2 + 0.000876623376623371*G0_4 - 0.00242897727272726*G0_5 + 0.00250202922077921*G0_6 - 0.00178977272727272*G0_7 + 0.00166193181818181*G0_8 - 0.00175324675324675*G0_9; + A[5] = A[7] - 8.31980519480517e-05*G0_1 + 8.31980519480516e-05*G0_2 + 0.000493100649350647*G0_3 - 0.000493100649350648*G0_4 + 0.00109577922077921*G0_5 - 0.00109577922077922*G0_6 - 0.00109577922077922*G0_7 + 0.00109577922077922*G0_8; + A[10] = A[1]; + A[8] = A[32] - 0.000594561688311685*G0_0 + 0.000594561688311685*G0_2 - 0.00052962662337662*G0_3 + 0.00133319805194804*G0_4 - 0.00076704545454545*G0_5 + 0.000767045454545449*G0_6 - 0.00133319805194804*G0_7 + 0.00052962662337662*G0_8; + A[35] = A[86] - 0.000200892857142856*G0_0 + 0.000200892857142855*G0_2 - 0.00180803571428571*G0_3 + 0.00180803571428571*G0_4 - 0.00361607142857142*G0_5 + 0.00361607142857142*G0_6 - 0.00180803571428571*G0_7 + 0.00180803571428571*G0_8; + A[27] = A[72]; + A[83] = A[75] - 0.000310470779220776*G0_0 + 0.000310470779220776*G0_1 + 0.00772524350649348*G0_3 - 0.00230113636363636*G0_4 - 0.00772524350649347*G0_5 + 0.00230113636363635*G0_6 - 0.0100263798701298*G0_7 + 0.0100263798701298*G0_8; + A[46] = A[64]; + A[92] = A[90] - 0.000742694805194803*G0_0 + 0.000742694805194803*G0_2 - 0.000328733766233765*G0_3 - 0.00208198051948051*G0_4 + 0.00175324675324675*G0_5 - 0.00175324675324675*G0_6 + 0.00208198051948051*G0_7 + 0.000328733766233764*G0_8; + A[61] = A[16]; + A[57] = A[75]; + A[74] = A[86] - 0.000200892857142856*G0_0 + 0.000200892857142855*G0_1 + 0.00180803571428571*G0_3 - 0.00180803571428571*G0_4 - 0.00180803571428571*G0_5 + 0.0018080357142857*G0_6 - 0.00361607142857141*G0_7 + 0.00361607142857141*G0_8; + A[2] = A[1] - 0.000135281385281385*G0_1 + 0.000135281385281385*G0_2 - 7.91396103896096e-05*G0_3 + 7.91396103896095e-05*G0_4 + 8.31980519480517e-05*G0_5 + 0.000162337662337661*G0_6 - 8.31980519480515e-05*G0_7 - 0.000162337662337661*G0_8; + A[13] = A[31]; + A[48] = A[73] + 0.000164366883116883*G0_0 - 0.000164366883116881*G0_2 + 0.00213676948051948*G0_3 - 0.000328733766233767*G0_4 + 0.000986201298701297*G0_5 - 0.000986201298701297*G0_6 + 0.000328733766233766*G0_7 - 0.00213676948051947*G0_8; + A[55] = A[48] + 0.00250202922077921*G0_0 + 0.00204545454545454*G0_1 + 0.00178977272727272*G0_2 + 0.000493100649350644*G0_3 + 0.0215320616883116*G0_5 - 0.00115056818181818*G0_6 + 0.00591720779220776*G0_7 + 0.0170941558441558*G0_9; + A[30] = A[40] + 7.91396103896096e-05*G0_1 - 7.91396103896095e-05*G0_2 + 0.00208198051948051*G0_3 - 0.00208198051948051*G0_4 + 0.000493100649350648*G0_5 - 0.00109577922077922*G0_6 - 0.000493100649350647*G0_7 + 0.00109577922077922*G0_8; + A[28] = A[82]; + A[98] = A[89]; + A[80] = A[8]; + A[62] = A[26]; + A[50] = A[5]; + A[14] = A[41]; + A[39] = A[93]; + A[23] = A[32]; + A[19] = A[90] - 0.000742694805194803*G0_0 + 0.000742694805194803*G0_1 - 0.00208198051948051*G0_3 - 0.000328733766233764*G0_4 + 0.00208198051948051*G0_5 + 0.000328733766233765*G0_6 + 0.00175324675324675*G0_7 - 0.00175324675324675*G0_8; + A[87] = A[78]; + A[42] = A[7] - 0.00151785714285713*G0_0 + 0.00151785714285713*G0_2 - 0.00116883116883116*G0_3 + 0.00217329545454544*G0_4 - 0.00164366883116882*G0_5 + 0.00164366883116882*G0_6 - 0.00217329545454544*G0_7 + 0.00116883116883116*G0_8; + A[96] = A[69]; + A[65] = A[78] + 0.00105925324675324*G0_1 - 0.00105925324675324*G0_2 + 0.00410917207792207*G0_3 - 0.00410917207792207*G0_4 + 0.00115056818181818*G0_5 - 0.00295860389610389*G0_6 - 0.00115056818181818*G0_7 + 0.00295860389610389*G0_8; + A[53] = A[35]; + A[70] = A[7]; + A[68] = A[86]; + A[6] = A[60]; + A[17] = A[71]; + A[9] = A[90]; + A[34] = A[86] - 0.000803571428571425*G0_0 - 0.00166193181818181*G0_1 - 0.00166193181818181*G0_2 - 0.00115056818181818*G0_3 - 0.00115056818181818*G0_4 - 0.000493100649350652*G0_6 - 0.000493100649350648*G0_8 - 0.00262987012987013*G0_9; + A[24] = A[42]; + A[84] = A[48]; + A[59] = A[69] - 0.00175324675324675*G0_0 + 0.00175324675324675*G0_2 + 0.00197240259740259*G0_3 - 0.0128206168831168*G0_4 + 0.0177516233766233*G0_5 - 0.0177516233766233*G0_6 + 0.0128206168831168*G0_7 - 0.0019724025974026*G0_8; + A[47] = A[74]; + A[91] = A[19]; + A[66] = A[73] + 0.00178977272727272*G0_0 + 0.00204545454545454*G0_1 + 0.00250202922077921*G0_2 + 0.00591720779220777*G0_4 - 0.00115056818181818*G0_5 + 0.0215320616883116*G0_6 + 0.000493100649350651*G0_8 + 0.0170941558441558*G0_9; + A[56] = A[65]; + A[77] = A[36] + 0.00250202922077921*G0_0 + 0.00178977272727272*G0_1 + 0.00204545454545453*G0_2 + 0.000493100649350652*G0_4 + 0.00591720779220776*G0_5 + 0.0215320616883116*G0_7 - 0.00115056818181817*G0_8 + 0.0170941558441558*G0_9; + A[3] = A[30]; + A[12] = A[21]; + A[49] = A[94]; + A[33] = A[67] + 0.00204545454545454*G0_0 + 0.00250202922077921*G0_1 + 0.00178977272727272*G0_2 + 0.0215320616883116*G0_3 - 0.00115056818181817*G0_4 + 0.000493100649350645*G0_5 + 0.00591720779220777*G0_8 + 0.0170941558441558*G0_9; + A[29] = A[92]; + A[81] = A[7] - 0.00143465909090908*G0_0 + 0.00143465909090908*G0_1 + 0.00157061688311687*G0_3 - 0.000566152597402593*G0_4 - 0.00157061688311687*G0_5 + 0.000566152597402594*G0_6 - 0.00383522727272725*G0_7 + 0.00383522727272725*G0_8; + A[44] = A[85] + 0.00204545454545454*G0_0 + 0.00178977272727272*G0_1 + 0.00250202922077921*G0_2 - 0.00115056818181818*G0_3 + 0.0215320616883116*G0_4 + 0.00591720779220778*G0_6 + 0.000493100649350642*G0_7 + 0.0170941558441558*G0_9; + A[63] = A[36]; + A[0] = A[21] + 0.0024621212121212*G0_0 - 0.0001075487012987*G0_3 - 0.000107548701298701*G0_4 + 0.00159699675324674*G0_5 - 0.000673701298701294*G0_6 + 0.00159699675324674*G0_7 - 0.000673701298701295*G0_8 + 0.000742694805194803*G0_9; + A[79] = A[97]; + A[38] = A[83]; + A[20] = A[2]; + A[18] = A[81]; + A[88] = A[45] + 0.00178977272727272*G0_0 + 0.00250202922077921*G0_1 + 0.00204545454545453*G0_2 + 0.00591720779220776*G0_3 + 0.000493100649350652*G0_6 - 0.00115056818181818*G0_7 + 0.0215320616883116*G0_8 + 0.0170941558441558*G0_9; + A[43] = A[34]; + A[95] = A[59]; + A[52] = A[25]; + } + + /// 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 mass_matrix_f1_p3_q3_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p3_q3_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p3_q3_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1))), 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 mass_matrix_f1_p3_q3_tensor_finite_element_0(); + break; + } + case 1: + { + return new mass_matrix_f1_p3_q3_tensor_finite_element_0(); + break; + } + case 2: + { + return new mass_matrix_f1_p3_q3_tensor_finite_element_0(); + 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 mass_matrix_f1_p3_q3_tensor_dofmap_0(); + break; + } + case 1: + { + return new mass_matrix_f1_p3_q3_tensor_dofmap_0(); + break; + } + case 2: + { + return new mass_matrix_f1_p3_q3_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f1_p3_q4_excafe.h b/mass_matrix_2d/mass_matrix_f1_p3_q4_excafe.h new file mode 100644 index 0000000..48d31c1 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p3_q4_excafe.h @@ -0,0 +1,578 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 23.46 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 = -1.5943562610229276010898047*w[0][2]; + const double var_1 = -1.0000000000000000000000000*x[0][1]; + const double var_2 = x[1][1] + var_1; + const double var_3 = -1.0000000000000000000000000*x[0][0]; + const double var_4 = x[2][0] + var_3; + const double var_5 = var_1 + x[2][1]; + const double var_6 = x[1][0] + var_3; + const double var_7 = var_5*var_6 + -1.0000000000000000000000000*var_2*var_4; + const double var_8 = std::abs(var_7); + const double var_9 = -0.0003219003219003219000427*var_8*w[0][9]; + const double var_10 = 33.7666666666666657192763523*w[0][1]; + const double var_11 = 0.9855555555555555180546889*w[0][0]; + const double var_12 = 1.6311111111111111782179250*w[0][2]; + const double var_13 = var_11 + -5.7099999999999999644728632*w[0][6] + -6.9500000000000001776356839*w[0][7] + var_10 + 27.8000000000000007105427358*w[0][3] + 13.9000000000000003552713679*w[0][8] + -0.3400000000000000244249065*w[0][5] + var_12 + -18.2500000000000000000000000*w[0][4]; + A[18] = var_9 + 0.0000370000370000369977462*var_13*var_8; + const double var_14 = w[0][8] + w[0][6]; + const double var_15 = w[0][1] + w[0][2]; + const double var_16 = w[0][5] + w[0][7]; + const double var_17 = w[0][4] + w[0][3]; + const double var_18 = 0.5925925925925925596970956*w[0][0]; + const double var_19 = -0.5606060606060606632539134*var_16 + 0.3757575757575757346984346*var_14 + var_18 + -0.0090909090909090904675249*var_15 + 0.4787878787878787623100152*var_17; + const double var_20 = -0.0006793206793206793200901*var_8*w[0][9]; + const double var_21 = w[0][4] + w[0][7]; + const double var_22 = w[0][8] + w[0][3]; + const double var_23 = w[0][0] + w[0][2]; + const double var_24 = w[0][5] + w[0][6]; + const double var_25 = 0.0119913419913419919821118*var_22 + 0.0005194805194805194800689*var_24 + -0.0148917748917748917619752*var_21 + 0.0018518518518518519225258*var_23 + 0.0153920153920153925802827*w[0][1]; + A[70] = var_20 + 0.0769230769230769273470116*var_25*var_8; + const double var_26 = -1.0000000000000000000000000*w[0][3]; + const double var_27 = w[0][3] + w[0][5]; + const double var_28 = var_27 + -0.2158730158730158832369739*w[0][2]; + const double var_29 = -0.2031746031746031744269487*w[0][1]; + const double var_30 = -0.3682539682539682779349732*w[0][0]; + const double var_31 = 0.2285714285714285642914234*w[0][7]; + const double var_32 = -2.7714285714285713524418497*w[0][6] + var_31 + var_30 + 1.3428571428571427492926205*w[0][8] + var_29 + var_28 + -1.6571428571428570286627746*w[0][4]; + const double var_33 = 0.0005594405594405594400742*var_8*w[0][9]; + const double var_34 = 0.5925925925925925596970956*w[0][1]; + const double var_35 = -0.5606060606060606632539134*var_22 + 0.4787878787878787623100152*var_24 + 0.3757575757575757346984346*var_21 + var_34 + -0.0090909090909090904675249*var_23; + A[28] = 0.0007326007326007326000972*var_35*var_8 + var_33; + const double var_36 = w[0][0] + w[0][1]; + const double var_37 = w[0][4] + w[0][6]; + const double var_38 = w[0][8] + w[0][7]; + const double var_39 = -0.0039682539682539680336859*var_37 + 0.2484126984126984183376408*var_27 + 0.4370370370370370571855290*var_36 + -0.5071428571428571174806166*var_38 + 0.0439153439153439212327967*w[0][2]; + const double var_40 = 0.0030369630369630369604028*var_8*w[0][9]; + const double var_41 = -1.0000000000000000000000000*w[0][5]; + const double var_42 = 0.2349206349206349186964360*w[0][1]; + const double var_43 = -1.1428571428571427937015414*w[0][0]; + const double var_44 = -0.8888888888888888395456433*w[0][2]; + const double var_45 = 6.4857142857142857650387668*w[0][6] + 1.0571428571428571618895376*var_41 + -5.5428571428571427048836995*w[0][7] + var_44 + -1.4000000000000001332267630*w[0][3] + var_42 + 0.2000000000000000111022302*w[0][8] + var_43 + 3.4857142857142857650387668*w[0][4]; + A[117] = var_40 + 0.0009324009324009324001237*var_45*var_8; + A[187] = A[117]; + const double var_46 = 0.0023443223443223443203109*var_8*w[0][9]; + const double var_47 = -1.0000000000000000000000000*w[0][6]; + const double var_48 = 0.0414814814814814802890197*w[0][2]; + const double var_49 = 0.0431746031746031780351736*w[0][1]; + const double var_50 = 0.0634920634920634885389745*w[0][0]; + const double var_51 = 0.5542857142857142704883699*w[0][7] + -0.1066666666666666735130420*w[0][3] + -0.2457142857142857184093998*w[0][8] + var_49 + 0.3695238095238095321626304*w[0][5] + 0.1847619047619047660813152*var_47 + var_48 + -0.0552380952380952389146884*w[0][4] + var_50; + A[147] = var_46 + 0.0186480186480186480024734*var_51*var_8; + const double var_52 = 0.0119913419913419919821118*var_37 + -0.0148917748917748917619752*var_27 + 0.0018518518518518519225258*var_36 + 0.0005194805194805194800689*var_38 + 0.0153920153920153925802827*w[0][2]; + const double var_53 = 0.0006393606393606393600848*var_8*w[0][9]; + const double var_54 = 0.0039249639249639249605206*w[0][2]; + const double var_55 = 0.0016161616161616161602144*w[0][0]; + const double var_56 = -1.0000000000000000000000000*w[0][1]; + const double var_57 = 0.0016161616161616161602144*var_56; + const double var_58 = 0.0285714285714285705364279*w[0][6] + -0.0301298701298701315787198*w[0][7] + 0.0400000000000000008326673*var_41 + var_54 + var_57 + var_55 + 0.0119480519480519489089465*w[0][8] + 0.0519480519480519514763373*w[0][4] + 0.0025974025974025974003445*var_26; + A[104] = 0.0683760683760683829479632*var_58*var_8 + var_53; + A[216] = A[104]; + const double var_59 = -0.0214225589225589228836721*w[0][1]; + const double var_60 = -1.0000000000000000000000000*w[0][8]; + const double var_61 = -1.1428571428571427937015414*w[0][1]; + const double var_62 = 0.2349206349206349186964360*w[0][2]; + const double var_63 = -0.8888888888888888395456433*w[0][0]; + const double var_64 = -1.4000000000000001332267630*w[0][6] + 6.4857142857142857650387668*w[0][7] + 1.0571428571428571618895376*var_60 + -5.5428571428571427048836995*w[0][3] + var_63 + var_61 + var_62 + 3.4857142857142857650387668*w[0][5] + 0.2000000000000000111022302*w[0][4]; + A[163] = 0.0009324009324009324001237*var_64*var_8 + var_40; + A[205] = A[163]; + const double var_65 = 0.6443268665490887725511016*w[0][0]; + const double var_66 = 0.2345679012345678882134337*w[0][1]; + const double var_67 = 0.2251616696061140565632286*w[0][2]; + const double var_68 = -0.5185185185185184897349586*w[0][6] + 2.2063492063492060601959110*w[0][7] + var_66 + -0.8571428571428570952761561*w[0][8] + 1.1798941798941797731714587*w[0][5] + var_65 + 0.0952380952380952328084618*w[0][4] + var_67 + 0.1904761904761904656169236*var_26; + const double var_69 = 1.4090909090909091716525836*w[0][0]; + const double var_70 = -0.0631072631072630979565119*w[0][1]; + const double var_71 = 0.2364718614718614719816259*var_37 + -0.0990259740259740312007253*var_27 + 0.0296416546416546425324334*var_36 + 0.0101010101010101018687015*var_38 + 0.5661375661375661616503407*w[0][2]; + const double var_72 = -0.2158730158730158832369739*w[0][0] + var_14; + const double var_73 = -0.2031746031746031744269487*w[0][2]; + const double var_74 = 0.2285714285714285642914234*w[0][3]; + const double var_75 = -0.3682539682539682779349732*w[0][1]; + const double var_76 = var_72 + var_75 + var_74 + -2.7714285714285713524418497*w[0][7] + -1.6571428571428570286627746*w[0][5] + var_73 + 1.3428571428571427492926205*w[0][4]; + const double var_77 = -1.0000000000000000000000000*w[0][4]; + const double var_78 = 0.2345679012345678882134337*w[0][2]; + const double var_79 = 0.2251616696061140565632286*w[0][1]; + const double var_80 = -0.8571428571428570952761561*w[0][6] + 1.1798941798941797731714587*w[0][7] + var_79 + 0.0952380952380952328084618*w[0][3] + -0.5185185185185184897349586*w[0][8] + 2.2063492063492060601959110*w[0][5] + var_65 + var_78 + 0.1904761904761904656169236*var_77; + const double var_81 = 8.5925925925925916715186759*w[0][1]; + const double var_82 = 0.0076923076923076927347012*var_8*w[0][9]; + const double var_83 = -5.1500000000000003552713679*var_22 + 17.2785714285714284699224663*var_24 + 6.4642857142857135244184974*var_21 + 2.0317460317460316332471848*var_23 + 2.1746031746031744269487262*w[0][1]; + A[112] = var_82 + 0.0004662004662004662000618*var_8*var_83; + const double var_84 = 0.0303030303030303038713811*var_22 + 0.1818181818181818232282865*var_24 + 0.7272727272727272929131459*var_21 + var_34 + 0.2659932659932660037327423*var_23; + const double var_85 = 0.0414814814814814802890197*w[0][1]; + const double var_86 = 0.0431746031746031780351736*w[0][2]; + const double var_87 = -0.2457142857142857184093998*w[0][6] + 0.3695238095238095321626304*w[0][7] + 0.1847619047619047660813152*var_60 + -0.0552380952380952389146884*w[0][3] + 0.5542857142857142704883699*w[0][5] + var_86 + var_85 + -0.1066666666666666735130420*w[0][4] + var_50; + A[102] = var_46 + 0.0186480186480186480024734*var_8*var_87; + const double var_88 = 0.9855555555555555180546889*w[0][1]; + const double var_89 = 33.7666666666666657192763523*w[0][0]; + const double var_90 = -18.2500000000000000000000000*w[0][6] + var_89 + 13.9000000000000003552713679*w[0][7] + -0.3400000000000000244249065*w[0][3] + -6.9500000000000001776356839*w[0][8] + var_88 + 27.8000000000000007105427358*w[0][5] + var_12 + -5.7099999999999999644728632*w[0][4]; + A[6] = 0.0000370000370000369977462*var_8*var_90 + var_9; + A[90] = A[6]; + const double var_91 = -0.3368606701940035086373371*w[0][2]; + const double var_92 = -1.5943562610229276010898047*w[0][0]; + const double var_93 = -1.0502645502645502340044459*w[0][1]; + const double var_94 = 1.8373015873015872134743631*w[0][6] + -5.7500000000000000000000000*w[0][7] + var_93 + var_92 + 1.7500000000000000000000000*w[0][8] + -3.2579365079365079083117962*w[0][5] + var_91 + 0.5833333333333332593184650*w[0][4] + 0.2500000000000000000000000*var_26; + const double var_95 = 0.5925925925925925596970956*w[0][2]; + const double var_96 = var_95 + -0.5606060606060606632539134*var_37 + 0.3757575757575757346984346*var_27 + -0.0090909090909090904675249*var_36 + 0.4787878787878787623100152*var_38; + A[44] = 0.0007326007326007326000972*var_8*var_96 + var_33; + A[212] = A[44]; + const double var_97 = 0.0007459207459207459200989*var_8*w[0][9]; + const double var_98 = 0.0571428571428571410728559*w[0][6]; + const double var_99 = -1.2867724867724867898743923*w[0][1]; + const double var_100 = -0.4645502645502646021924420*w[0][2]; + const double var_101 = 0.0476190476190476164042309*w[0][0]; + const double var_102 = 0.5904761904761904878213841*w[0][7] + 0.0095238095238095246686250*w[0][3] + -1.2666666666666666074547720*w[0][8] + var_101 + -0.1142857142857142821457117*w[0][5] + var_98 + var_99 + 2.0380952380952384039858316*w[0][4] + var_100; + A[69] = var_97 + 0.0004662004662004662000618*var_102*var_8; + const double var_103 = -0.0755892255892255948701575*w[0][2]; + const double var_104 = -0.6319865319865319852610241*w[0][1]; + const double var_105 = -0.2500000000000000000000000*w[0][6] + 2.1727272727272728403136171*w[0][7] + -1.2439393939393939003679179*w[0][3] + -1.9681818181818180324427203*w[0][8] + var_69 + 0.6909090909090909171652584*w[0][5] + var_103 + 0.5424242424242424753799696*w[0][4] + var_104; + const double var_106 = -5.0000000000000000000000000*var_22 + 5.0800000000000000710542736*var_24 + 8.9199999999999999289457264*var_21 + 7.9288888888888893191619900*var_23 + 2.0622222222222221788001661*w[0][1]; + const double var_107 = 52.3333333333333285963817616*var_22 + -0.8000000000000000444089210*var_24 + -21.8666666666666671403618238*var_21 + 5.7259259259259263075136914*var_23 + 21.9259259259259238206141163*w[0][1]; + const double var_108 = -0.2847522847522847566636983*w[0][0]; + const double var_109 = 0.2285714285714285642914234*w[0][6]; + const double var_110 = -0.0022910422910422910403039*var_8*w[0][9]; + const double var_111 = -0.2847522847522847566636983*w[0][1]; + const double var_112 = -0.0728234728234728179163682*w[0][0]; + const double var_113 = -0.0759018759018759009427058*w[0][2]; + const double var_114 = 0.0363636363636363618700997*var_41 + var_31 + -0.8476190476190477163243031*w[0][3] + -0.5116883116883116366935269*w[0][8] + var_98 + var_112 + var_111 + 0.3393939393939394144616983*w[0][4] + var_113; + A[55] = 0.0051282051282051282006802*var_114*var_8 + var_110; + const double var_115 = -0.8888888888888888395456433*w[0][1]; + const double var_116 = -0.0126503126503126495788765*w[0][1]; + const double var_117 = -0.2158730158730158832369739*w[0][1] + var_21; + const double var_118 = -0.0001576201576201576200209*var_8*w[0][9]; + const double var_119 = -0.0755892255892255948701575*w[0][1]; + const double var_120 = 1.4090909090909091716525836*w[0][2]; + const double var_121 = -0.6319865319865319852610241*w[0][0]; + const double var_122 = 2.1727272727272728403136171*w[0][6] + -1.2439393939393939003679179*w[0][7] + -0.2500000000000000000000000*w[0][3] + 0.5424242424242424753799696*w[0][8] + var_120 + -1.9681818181818180324427203*w[0][5] + var_121 + var_119 + 0.6909090909090909171652584*w[0][4]; + A[36] = var_118 + 0.0002442002442002442000324*var_122*var_8; + A[92] = A[36]; + const double var_123 = 26.0500000000000007105427358*var_22 + -40.8500000000000014210854715*var_24 + -33.6499999999999985789145285*var_21 + -84.5111111111111199534207117*var_23 + 3.7222222222222218768195034*w[0][1]; + const double var_124 = 0.0634920634920634885389745*w[0][1]; + const double var_125 = 0.0431746031746031780351736*w[0][0]; + const double var_126 = -0.0552380952380952389146884*w[0][6] + -0.2457142857142857184093998*w[0][7] + var_124 + 0.3695238095238095321626304*w[0][3] + 0.5542857142857142704883699*w[0][8] + var_125 + -0.1066666666666666735130420*w[0][5] + var_48 + 0.1847619047619047660813152*var_77; + A[178] = var_46 + 0.0186480186480186480024734*var_126*var_8; + const double var_127 = -0.0002353202353202353200312*var_8*w[0][9]; + const double var_128 = -1.5943562610229276010898047*w[0][1]; + const double var_129 = -1.0502645502645502340044459*w[0][0]; + const double var_130 = var_128 + 0.5833333333333332593184650*w[0][6] + 1.7500000000000000000000000*w[0][7] + 0.2500000000000000000000000*var_41 + -3.2579365079365079083117962*w[0][3] + -5.7500000000000000000000000*w[0][8] + var_129 + var_91 + 1.8373015873015872134743631*w[0][4]; + A[41] = var_127 + 0.0000932400932400932400124*var_130*var_8; + A[167] = A[41]; + const double var_131 = -0.0002430902430902430900322*var_8*w[0][9]; + A[40] = var_131 + 0.0003496503496503496500464*var_39*var_8; + const double var_132 = -0.0002131202131202131200283*var_8*w[0][9]; + const double var_133 = -0.3682539682539682779349732*w[0][2]; + const double var_134 = 0.2285714285714285642914234*w[0][4]; + const double var_135 = var_72 + -1.6571428571428570286627746*w[0][7] + 1.3428571428571427492926205*w[0][3] + var_134 + -2.7714285714285713524418497*w[0][5] + var_29 + var_133; + A[103] = var_132 + 0.0012432012432012432001649*var_135*var_8; + const double var_136 = 0.2345679012345678882134337*w[0][0]; + const double var_137 = 0.6443268665490887725511016*w[0][1]; + const double var_138 = 0.0952380952380952328084618*w[0][6] + 0.1904761904761904656169236*var_41 + -0.8571428571428570952761561*w[0][7] + 1.1798941798941797731714587*w[0][3] + 2.2063492063492060601959110*w[0][8] + var_137 + var_67 + -0.5185185185185184897349586*w[0][4] + var_136; + const double var_139 = 1.6311111111111111782179250*w[0][1]; + const double var_140 = 33.7666666666666657192763523*w[0][2]; + const double var_141 = var_11 + 13.9000000000000003552713679*w[0][6] + -0.3400000000000000244249065*w[0][7] + var_139 + -18.2500000000000000000000000*w[0][3] + -5.7099999999999999644728632*w[0][8] + -6.9500000000000001776356839*w[0][5] + 27.8000000000000007105427358*w[0][4] + var_140; + const double var_142 = -0.0038361638361638361605088*var_8*w[0][9]; + const double var_143 = -0.4285714285714285476380780*var_22 + -1.0000000000000000000000000*var_21 + 0.1481481481481481399242739*w[0][1] + -0.2539682539682539541558981*var_23; + A[194] = 0.0044755244755244755205936*var_143*var_8 + 0.0023443223443223443203109*var_24*var_8 + var_142; + A[222] = A[194]; + const double var_144 = -0.0028504828504828504803781*var_8*w[0][9]; + const double var_145 = -0.1513548180214847049818161*w[0][2]; + const double var_146 = -0.0303350970017636709097353*w[0][0]; + const double var_147 = -0.1757575757575757513517800*w[0][4]; + const double var_148 = -0.1705627705627705548163675*w[0][6] + var_146 + var_145 + 0.0516594516594516620089372*w[0][7] + -0.0903318903318903326793432*w[0][8] + 0.0943722943722943713451556*w[0][5] + var_147 + var_70 + 0.0129870129870129878690843*var_26; + A[65] = 0.0153846153846153854694023*var_148*var_8 + var_144; + const double var_149 = -0.0004528804528804528800601*var_8*w[0][9]; + const double var_150 = -0.1757575757575757513517800*w[0][5]; + const double var_151 = -0.0126503126503126495788765*w[0][0]; + const double var_152 = 0.0058201058201058208235734*w[0][2]; + const double var_153 = -0.0423280423280423256926497*w[0][1]; + const double var_154 = 0.0060606060606060606008039*w[0][6] + -0.0658008658008658042781747*w[0][7] + 0.0376623376623376610039529*w[0][3] + var_153 + var_151 + 0.0705627705627705631430402*w[0][8] + var_150 + -0.0103896103896103896013781*w[0][4] + var_152; + A[27] = var_149 + 0.0051282051282051282006802*var_154*var_8; + A[181] = A[27]; + const double var_155 = 0.0039249639249639249605206*w[0][0]; + const double var_156 = 0.0016161616161616161602144*w[0][2]; + const double var_157 = 0.0519480519480519514763373*w[0][7] + 0.0119480519480519489089465*w[0][3] + 0.0025974025974025974003445*var_60 + var_57 + var_155 + var_156 + 0.0285714285714285705364279*w[0][5] + 0.0400000000000000008326673*var_47 + -0.0301298701298701315787198*w[0][4]; + const double var_158 = 0.0571428571428571410728559*w[0][4]; + const double var_159 = 0.0011366411366411366401508*var_8*w[0][9]; + A[129] = 0.0011188811188811188801484*var_68*var_8 + var_159; + const double var_160 = 43.8518518518518476412282325*w[0][2]; + const double var_161 = 8.5925925925925916715186759*w[0][0]; + const double var_162 = 13.5111111111111110716365147*w[0][1]; + const double var_163 = 52.3333333333333285963817616*w[0][6] + -8.5999999999999996447286321*w[0][7] + var_162 + -39.8000000000000042632564146*w[0][3] + 6.2000000000000001776356839*w[0][8] + -30.4666666666666650087336166*w[0][5] + var_161 + var_160 + 157.0000000000000000000000000*w[0][4]; + const double var_164 = -0.0728234728234728179163682*w[0][1]; + const double var_165 = 0.2285714285714285642914234*w[0][8]; + const double var_166 = 0.3393939393939394144616983*w[0][6] + var_158 + -0.5116883116883116366935269*w[0][7] + var_165 + var_164 + -0.8476190476190477163243031*w[0][5] + var_108 + var_113 + 0.0363636363636363618700997*var_26; + const double var_167 = -5.1500000000000003552713679*var_37 + 6.4642857142857135244184974*var_27 + 2.0317460317460316332471848*var_36 + 17.2785714285714284699224663*var_38 + 2.1746031746031744269487262*w[0][2]; + const double var_168 = -0.0631072631072630979565119*w[0][2]; + const double var_169 = -0.1757575757575757513517800*w[0][3]; + const double var_170 = -0.1513548180214847049818161*w[0][1]; + const double var_171 = -0.0903318903318903326793432*w[0][6] + var_146 + 0.0943722943722943713451556*w[0][7] + var_168 + var_170 + var_169 + -0.1705627705627705548163675*w[0][8] + 0.0516594516594516620089372*w[0][5] + 0.0129870129870129878690843*var_77; + A[49] = 0.0153846153846153854694023*var_171*var_8 + var_144; + const double var_172 = 13.5111111111111110716365147*w[0][0]; + const double var_173 = 157.0000000000000000000000000*w[0][6] + 6.2000000000000001776356839*w[0][7] + var_172 + -30.4666666666666650087336166*w[0][3] + -8.5999999999999996447286321*w[0][8] + var_81 + -39.8000000000000042632564146*w[0][5] + var_160 + 52.3333333333333285963817616*w[0][4]; + const double var_174 = 0.9855555555555555180546889*w[0][2]; + const double var_175 = -6.9500000000000001776356839*w[0][6] + var_89 + 27.8000000000000007105427358*w[0][7] + var_139 + -5.7099999999999999644728632*w[0][3] + -18.2500000000000000000000000*w[0][8] + 13.9000000000000003552713679*w[0][5] + -0.3400000000000000244249065*w[0][4] + var_174; + const double var_176 = -0.6319865319865319852610241*w[0][2]; + const double var_177 = -1.9681818181818180324427203*w[0][6] + 0.6909090909090909171652584*w[0][7] + 0.5424242424242424753799696*w[0][3] + -0.2500000000000000000000000*w[0][8] + var_119 + 2.1727272727272728403136171*w[0][5] + var_69 + -1.2439393939393939003679179*w[0][4] + var_176; + A[8] = var_118 + 0.0002442002442002442000324*var_177*var_8; + A[120] = A[8]; + const double var_178 = 0.2349206349206349186964360*w[0][0]; + const double var_179 = -1.1428571428571427937015414*w[0][2]; + const double var_180 = -5.5428571428571427048836995*w[0][6] + -1.4000000000000001332267630*w[0][7] + var_178 + 6.4857142857142857650387668*w[0][3] + 3.4857142857142857650387668*w[0][8] + 0.2000000000000000111022302*w[0][5] + var_115 + var_179 + 1.0571428571428571618895376*var_77; + A[74] = var_40 + 0.0009324009324009324001237*var_180*var_8; + A[214] = A[74]; + const double var_181 = 0.0571428571428571410728559*w[0][3]; + const double var_182 = 0.0001970251970251970250261*var_8*w[0][9]; + A[32] = 0.0025641025641025641003401*var_71*var_8 + var_182; + const double var_183 = 0.0003113553113553113550413*var_8*w[0][9]; + const double var_184 = 0.0414814814814814802890197*w[0][0]; + const double var_185 = 0.2364718614718614719816259*var_16 + -0.0990259740259740312007253*var_14 + 0.0296416546416546425324334*var_15 + 0.5661375661375661616503407*w[0][0] + 0.0101010101010101018687015*var_17; + A[0] = var_182 + 0.0025641025641025641003401*var_185*var_8; + const double var_186 = -0.0303350970017636709097353*w[0][1]; + const double var_187 = -0.0631072631072630979565119*w[0][0]; + const double var_188 = -0.1757575757575757513517800*w[0][6]; + const double var_189 = var_145 + 0.0129870129870129878690843*var_41 + -0.0903318903318903326793432*w[0][7] + var_187 + 0.0943722943722943713451556*w[0][3] + 0.0516594516594516620089372*w[0][8] + var_186 + var_188 + -0.1705627705627705548163675*w[0][4]; + A[113] = 0.0153846153846153854694023*var_189*var_8 + var_144; + A[127] = A[113]; + const double var_190 = 0.0374579124579124539407005*w[0][0]; + const double var_191 = -0.0039682539682539680336859*var_16 + 0.2484126984126984183376408*var_14 + 0.4370370370370370571855290*var_15 + 0.0439153439153439212327967*w[0][0] + -0.5071428571428571174806166*var_17; + A[133] = 0.0012432012432012432001649*var_32*var_8 + var_132; + A[203] = A[133]; + const double var_192 = -0.1513548180214847049818161*w[0][0]; + const double var_193 = var_168 + -0.1705627705627705548163675*w[0][7] + 0.0516594516594516620089372*w[0][3] + 0.0943722943722943713451556*w[0][8] + var_192 + var_150 + var_186 + 0.0129870129870129878690843*var_47 + -0.0903318903318903326793432*w[0][4]; + const double var_194 = -0.2031746031746031744269487*w[0][0]; + const double var_195 = 0.0045820845820845820806078*var_8*w[0][9]; + const double var_196 = 43.8518518518518476412282325*w[0][1]; + const double var_197 = 13.5111111111111110716365147*w[0][2]; + const double var_198 = 6.2000000000000001776356839*w[0][6] + -30.4666666666666650087336166*w[0][7] + 157.0000000000000000000000000*w[0][3] + var_196 + 52.3333333333333285963817616*w[0][8] + -8.5999999999999996447286321*w[0][5] + var_161 + var_197 + -39.8000000000000042632564146*w[0][4]; + A[48] = 0.0000888000888000888000118*var_198*var_8 + var_195; + const double var_199 = -0.0039682539682539680336859*var_22 + -0.5071428571428571174806166*var_24 + 0.2484126984126984183376408*var_21 + 0.4370370370370370571855290*var_23 + 0.0439153439153439212327967*w[0][1]; + A[22] = var_131 + 0.0003496503496503496500464*var_199*var_8; + A[106] = A[22]; + const double var_200 = 0.0571428571428571410728559*w[0][5]; + const double var_201 = -0.4645502645502646021924420*w[0][0]; + const double var_202 = 0.0476190476190476164042309*w[0][2]; + const double var_203 = -0.1142857142857142821457117*w[0][6] + var_202 + 2.0380952380952384039858316*w[0][7] + -1.2666666666666666074547720*w[0][3] + 0.0095238095238095246686250*w[0][8] + var_201 + var_99 + 0.5904761904761904878213841*w[0][4] + var_200; + A[85] = var_97 + 0.0004662004662004662000618*var_203*var_8; + A[186] = A[102]; + const double var_204 = -0.0214225589225589228836721*w[0][2]; + const double var_205 = 0.0374579124579124539407005*w[0][1]; + const double var_206 = -1.1308922558922558376792722*w[0][0]; + const double var_207 = 0.2155303030303030165093503*w[0][6] + -1.3333333333333332593184650*w[0][7] + 0.5034090909090909171652584*w[0][3] + 1.0223484848484849507599392*w[0][8] + var_205 + -0.5265151515151514916013298*w[0][5] + var_204 + -0.1545454545454545414173708*w[0][4] + var_206; + const double var_208 = -0.0423280423280423256926497*w[0][0]; + const double var_209 = -0.0103896103896103896013781*w[0][6] + 0.0705627705627705631430402*w[0][7] + var_169 + -0.0658008658008658042781747*w[0][8] + 0.0376623376623376610039529*w[0][5] + var_116 + var_208 + 0.0060606060606060606008039*w[0][4] + var_152; + A[13] = var_149 + 0.0051282051282051282006802*var_209*var_8; + const double var_210 = 1.4090909090909091716525836*w[0][1]; + const double var_211 = -0.0755892255892255948701575*w[0][0]; + const double var_212 = -1.2439393939393939003679179*w[0][6] + -0.2500000000000000000000000*w[0][7] + var_210 + var_211 + 2.1727272727272728403136171*w[0][3] + 0.6909090909090909171652584*w[0][8] + 0.5424242424242424753799696*w[0][5] + var_176 + -1.9681818181818180324427203*w[0][4]; + const double var_213 = 0.0571428571428571410728559*w[0][8]; + const double var_214 = -0.4645502645502646021924420*w[0][1]; + const double var_215 = -1.2867724867724867898743923*w[0][2]; + const double var_216 = var_215 + -1.2666666666666666074547720*w[0][6] + -0.1142857142857142821457117*w[0][7] + var_213 + 2.0380952380952384039858316*w[0][3] + var_101 + 0.5904761904761904878213841*w[0][5] + var_214 + 0.0095238095238095246686250*w[0][4]; + A[66] = var_97 + 0.0004662004662004662000618*var_216*var_8; + A[94] = A[66]; + A[12] = 0.0007326007326007326000972*var_19*var_8 + var_33; + A[180] = A[12]; + const double var_217 = -24.3333333333333321490954404*var_38 + var_37 + -2.0000000000000000000000000*var_27 + -0.6666666666666666296592325*w[0][2]; + A[155] = A[85]; + const double var_218 = -1.0000000000000000000000000*w[0][7]; + const double var_219 = 0.6443268665490887725511016*w[0][2]; + const double var_220 = 2.2063492063492060601959110*w[0][6] + var_79 + var_219 + -0.5185185185185184897349586*w[0][3] + 0.0952380952380952328084618*w[0][8] + -0.8571428571428570952761561*w[0][5] + 0.1904761904761904656169236*var_218 + 1.1798941798941797731714587*w[0][4] + var_136; + A[53] = 0.0011188811188811188801484*var_220*var_8 + var_159; + const double var_221 = 0.0058201058201058208235734*w[0][0]; + const double var_222 = -0.0126503126503126495788765*w[0][2]; + const double var_223 = var_221 + -0.0103896103896103896013781*w[0][7] + 0.0705627705627705631430402*w[0][3] + 0.0376623376623376610039529*w[0][8] + var_153 + 0.0060606060606060606008039*w[0][5] + var_188 + -0.0658008658008658042781747*w[0][4] + var_222; + A[29] = 0.0051282051282051282006802*var_223*var_8 + var_149; + const double var_224 = 0.2285714285714285642914234*w[0][5]; + const double var_225 = -0.2847522847522847566636983*w[0][2]; + const double var_226 = -0.0759018759018759009427058*w[0][1]; + const double var_227 = -0.5116883116883116366935269*w[0][6] + var_224 + var_213 + 0.3393939393939394144616983*w[0][3] + var_112 + 0.0363636363636363618700997*var_218 + -0.8476190476190477163243031*w[0][4] + var_226 + var_225; + A[82] = var_110 + 0.0051282051282051282006802*var_227*var_8; + A[110] = A[82]; + const double var_228 = 0.0030547230547230547204052*var_8*w[0][9]; + const double var_229 = -0.3368606701940035086373371*w[0][1]; + const double var_230 = 0.0571428571428571410728559*w[0][7]; + const double var_231 = 0.0476190476190476164042309*w[0][1]; + const double var_232 = 0.0095238095238095246686250*w[0][6] + var_215 + var_230 + 0.5904761904761904878213841*w[0][3] + -0.1142857142857142821457117*w[0][8] + 2.0380952380952384039858316*w[0][5] + var_231 + var_201 + -1.2666666666666666074547720*w[0][4]; + const double var_233 = -1.1308922558922558376792722*w[0][1]; + const double var_234 = -0.0728234728234728179163682*w[0][2]; + const double var_235 = -0.0759018759018759009427058*w[0][0]; + const double var_236 = var_234 + var_235 + 0.3393939393939394144616983*w[0][7] + -0.5116883116883116366935269*w[0][3] + -0.8476190476190477163243031*w[0][8] + var_134 + 0.0363636363636363618700997*var_47 + var_111 + var_200; + A[71] = 0.0051282051282051282006802*var_236*var_8 + var_110; + A[169] = A[71]; + A[10] = 0.0007326007326007326000972*var_207*var_8 + var_183; + const double var_237 = 1.6311111111111111782179250*w[0][0]; + const double var_238 = -0.3400000000000000244249065*w[0][6] + -18.2500000000000000000000000*w[0][7] + var_10 + 13.9000000000000003552713679*w[0][3] + 27.8000000000000007105427358*w[0][8] + -5.7099999999999999644728632*w[0][5] + var_237 + -6.9500000000000001776356839*w[0][4] + var_174; + const double var_239 = -0.1066666666666666735130420*w[0][6] + var_124 + 0.5542857142857142704883699*w[0][3] + 0.3695238095238095321626304*w[0][8] + var_86 + -0.0552380952380952389146884*w[0][5] + var_184 + 0.1847619047619047660813152*var_218 + -0.2457142857142857184093998*w[0][4]; + A[58] = 0.0186480186480186480024734*var_239*var_8 + var_46; + A[149] = 0.0012432012432012432001649*var_76*var_8 + var_132; + const double var_240 = var_117 + var_194 + -2.7714285714285713524418497*w[0][3] + -1.6571428571428570286627746*w[0][8] + 1.3428571428571427492926205*w[0][5] + var_133 + var_109; + A[57] = var_132 + 0.0012432012432012432001649*var_240*var_8; + A[183] = A[57]; + const double var_241 = -0.0039960039960039960005300*var_8*w[0][9]; + const double var_242 = var_22 + -0.6666666666666666296592325*w[0][1] + -2.0000000000000000000000000*var_21 + -24.3333333333333321490954404*var_24; + A[118] = 0.0000799200799200799200106*var_242*var_8 + var_241 + 0.0006630406630406630039479*var_23*var_8; + const double var_243 = -1.2867724867724867898743923*w[0][0]; + const double var_244 = 2.0380952380952384039858316*w[0][6] + -1.2666666666666666074547720*w[0][7] + var_158 + -0.1142857142857142821457117*w[0][3] + 0.5904761904761904878213841*w[0][8] + var_243 + 0.0095238095238095246686250*w[0][5] + var_231 + var_100; + const double var_245 = -0.0214225589225589228836721*w[0][0]; + const double var_246 = 0.0374579124579124539407005*w[0][2]; + const double var_247 = 0.5034090909090909171652584*w[0][6] + 0.2155303030303030165093503*w[0][7] + -1.3333333333333332593184650*w[0][3] + var_233 + -0.5265151515151514916013298*w[0][8] + -0.1545454545454545414173708*w[0][5] + var_246 + var_245 + 1.0223484848484849507599392*w[0][4]; + const double var_248 = 8.5925925925925916715186759*w[0][2]; + const double var_249 = -8.5999999999999996447286321*w[0][6] + var_248 + -39.8000000000000042632564146*w[0][7] + var_172 + 52.3333333333333285963817616*w[0][3] + 157.0000000000000000000000000*w[0][8] + var_196 + 6.2000000000000001776356839*w[0][5] + -30.4666666666666650087336166*w[0][4]; + const double var_250 = -1.1308922558922558376792722*w[0][2]; + const double var_251 = -0.5265151515151514916013298*w[0][6] + -0.1545454545454545414173708*w[0][7] + 1.0223484848484849507599392*w[0][3] + 0.5034090909090909171652584*w[0][8] + var_205 + 0.2155303030303030165093503*w[0][5] + var_250 + var_245 + -1.3333333333333332593184650*w[0][4]; + A[34] = 0.0007326007326007326000972*var_251*var_8 + var_183; + const double var_252 = 27.8000000000000007105427358*w[0][6] + -5.7099999999999999644728632*w[0][7] + -6.9500000000000001776356839*w[0][3] + -0.3400000000000000244249065*w[0][8] + -18.2500000000000000000000000*w[0][5] + var_88 + var_237 + 13.9000000000000003552713679*w[0][4] + var_140; + A[38] = var_9 + 0.0000370000370000369977462*var_252*var_8; + const double var_253 = 0.0634920634920634885389745*w[0][2]; + const double var_254 = 0.3695238095238095321626304*w[0][6] + -0.0552380952380952389146884*w[0][7] + 0.1847619047619047660813152*var_41 + -0.2457142857142857184093998*w[0][3] + -0.1066666666666666735130420*w[0][8] + var_49 + var_253 + var_184 + 0.5542857142857142704883699*w[0][4]; + const double var_255 = 0.0014563214563214563201932*var_8*w[0][9]; + const double var_256 = -0.3368606701940035086373371*w[0][0]; + const double var_257 = -3.2579365079365079083117962*w[0][6] + 0.5833333333333332593184650*w[0][7] + 0.2500000000000000000000000*var_60 + 1.7500000000000000000000000*w[0][3] + var_93 + var_0 + 1.8373015873015872134743631*w[0][5] + var_256 + -5.7500000000000000000000000*w[0][4]; + A[5] = 0.0000932400932400932400124*var_257*var_8 + var_127; + A[75] = A[5]; + const double var_258 = 0.2000000000000000111022302*w[0][6] + 3.4857142857142857650387668*w[0][3] + 6.4857142857142857650387668*w[0][8] + var_62 + -5.5428571428571427048836995*w[0][5] + var_115 + 1.0571428571428571618895376*var_218 + var_43 + -1.4000000000000001332267630*w[0][4]; + A[196] = A[28]; + A[89] = 0.0186480186480186480024734*var_254*var_8 + var_46; + A[215] = A[89]; + const double var_259 = 0.0039249639249639249605206*w[0][1]; + A[160] = var_82 + 0.0004662004662004662000618*var_167*var_8; + const double var_260 = 0.2251616696061140565632286*w[0][0]; + const double var_261 = -0.5185185185185184897349586*w[0][7] + 2.2063492063492060601959110*w[0][3] + 1.1798941798941797731714587*w[0][8] + var_260 + 0.0952380952380952328084618*w[0][5] + var_137 + 0.1904761904761904656169236*var_47 + -0.8571428571428570952761561*w[0][4] + var_78; + A[54] = 0.0011188811188811188801484*var_261*var_8 + var_159; + A[153] = A[55]; + const double var_262 = 3.4857142857142857650387668*w[0][7] + 0.2000000000000000111022302*w[0][3] + var_42 + var_63 + -1.4000000000000001332267630*w[0][8] + 6.4857142857142857650387668*w[0][5] + 1.0571428571428571618895376*var_47 + -5.5428571428571427048836995*w[0][4] + var_179; + A[119] = var_40 + 0.0009324009324009324001237*var_262*var_8; + A[217] = A[119]; + const double var_263 = 52.3333333333333285963817616*var_16 + -21.8666666666666671403618238*var_14 + 5.7259259259259263075136914*var_15 + 21.9259259259259238206141163*w[0][0] + -0.8000000000000000444089210*var_17; + const double var_264 = -0.8476190476190477163243031*w[0][6] + var_74 + var_235 + var_164 + var_230 + 0.0363636363636363618700997*var_60 + 0.3393939393939394144616983*w[0][5] + -0.5116883116883116366935269*w[0][4] + var_225; + A[68] = 0.0051282051282051282006802*var_264*var_8 + var_110; + A[101] = 0.0011188811188811188801484*var_8*var_80 + var_159; + A[19] = 0.0007326007326007326000972*var_247*var_8 + var_183; + A[80] = 0.0000888000888000888000118*var_163*var_8 + var_195; + const double var_265 = 0.0058201058201058208235734*w[0][1]; + const double var_266 = -0.0658008658008658042781747*w[0][6] + 0.0376623376623376610039529*w[0][7] + 0.0060606060606060606008039*w[0][3] + -0.0103896103896103896013781*w[0][8] + 0.0705627705627705631430402*w[0][5] + var_265 + var_208 + var_147 + var_222; + const double var_267 = 52.3333333333333285963817616*var_37 + -21.8666666666666671403618238*var_27 + 5.7259259259259263075136914*var_36 + -0.8000000000000000444089210*var_38 + 21.9259259259259238206141163*w[0][2]; + A[83] = var_228 + 0.0000888000888000888000118*var_267*var_8; + A[125] = A[83]; + const double var_268 = -1.6571428571428570286627746*w[0][6] + var_75 + 1.3428571428571427492926205*w[0][7] + var_194 + var_165 + var_28 + -2.7714285714285713524418497*w[0][4]; + A[87] = var_132 + 0.0012432012432012432001649*var_268*var_8; + const double var_269 = 26.0500000000000007105427358*var_37 + -33.6499999999999985789145285*var_27 + -84.5111111111111199534207117*var_36 + -40.8500000000000014210854715*var_38 + 3.7222222222222218768195034*w[0][2]; + const double var_270 = 1.3428571428571427492926205*w[0][6] + var_117 + var_224 + -1.6571428571428570286627746*w[0][3] + var_30 + -2.7714285714285713524418497*w[0][8] + var_73; + A[179] = var_132 + 0.0012432012432012432001649*var_270*var_8; + A[221] = A[179]; + const double var_271 = 0.0016161616161616161602144*w[0][1]; + const double var_272 = -1.0000000000000000000000000*w[0][0]; + const double var_273 = 0.0016161616161616161602144*var_272; + const double var_274 = 0.0519480519480519514763373*w[0][6] + 0.0025974025974025974003445*var_41 + 0.0119480519480519489089465*w[0][7] + var_54 + -0.0301298701298701315787198*w[0][8] + var_273 + var_271 + 0.0285714285714285705364279*w[0][4] + 0.0400000000000000008326673*var_26; + const double var_275 = -1.3333333333333332593184650*w[0][6] + 0.5034090909090909171652584*w[0][7] + 0.2155303030303030165093503*w[0][3] + -0.1545454545454545414173708*w[0][8] + var_250 + 1.0223484848484849507599392*w[0][5] + var_59 + -0.5265151515151514916013298*w[0][4] + var_190; + A[37] = 0.0007326007326007326000972*var_275*var_8 + var_183; + A[107] = A[37]; + A[52] = var_97 + 0.0004662004662004662000618*var_232*var_8; + A[108] = A[52]; + const double var_276 = -0.1757575757575757513517800*w[0][8]; + const double var_277 = -0.0423280423280423256926497*w[0][2]; + const double var_278 = var_221 + 0.0376623376623376610039529*w[0][6] + 0.0060606060606060606008039*w[0][7] + -0.0658008658008658042781747*w[0][3] + var_276 + var_277 + -0.0103896103896103896013781*w[0][5] + var_116 + 0.0705627705627705631430402*w[0][4]; + A[43] = var_149 + 0.0051282051282051282006802*var_278*var_8; + A[197] = A[43]; + const double var_279 = -1.0502645502645502340044459*w[0][2]; + const double var_280 = var_128 + 1.8373015873015872134743631*w[0][7] + -5.7500000000000000000000000*w[0][3] + -3.2579365079365079083117962*w[0][8] + 0.5833333333333332593184650*w[0][5] + var_256 + 0.2500000000000000000000000*var_47 + 1.7500000000000000000000000*w[0][4] + var_279; + const double var_281 = 1.7500000000000000000000000*w[0][6] + -3.2579365079365079083117962*w[0][7] + 0.5833333333333332593184650*w[0][3] + var_92 + 1.8373015873015872134743631*w[0][8] + -5.7500000000000000000000000*w[0][5] + var_229 + var_279 + 0.2500000000000000000000000*var_77; + A[21] = var_127 + 0.0000932400932400932400124*var_281*var_8; + A[91] = A[21]; + const double var_282 = 0.0000044400044400044400006*var_8*w[0][9]; + const double var_283 = -1.0000000000000000000000000*w[0][2]; + A[195] = A[13]; + A[11] = var_118 + 0.0002442002442002442000324*var_105*var_8; + const double var_284 = -5.1500000000000003552713679*var_16 + 6.4642857142857135244184974*var_14 + 2.0317460317460316332471848*var_15 + 2.1746031746031744269487262*w[0][0] + 17.2785714285714284699224663*var_17; + A[64] = var_82 + 0.0004662004662004662000618*var_284*var_8; + const double var_285 = 43.8518518518518476412282325*w[0][0]; + const double var_286 = -39.8000000000000042632564146*w[0][6] + 52.3333333333333285963817616*w[0][7] + -8.5999999999999996447286321*w[0][3] + -30.4666666666666650087336166*w[0][8] + 157.0000000000000000000000000*w[0][5] + var_81 + var_285 + var_197 + 6.2000000000000001776356839*w[0][4]; + A[96] = 0.0000888000888000888000118*var_286*var_8 + var_195; + A[162] = var_40 + 0.0009324009324009324001237*var_258*var_8; + A[100] = 0.0051282051282051282006802*var_166*var_8 + var_110; + A[156] = A[100]; + A[211] = A[29]; + const double var_287 = -30.4666666666666650087336166*w[0][6] + 157.0000000000000000000000000*w[0][7] + var_248 + var_162 + 6.2000000000000001776356839*w[0][3] + -39.8000000000000042632564146*w[0][8] + 52.3333333333333285963817616*w[0][5] + var_285 + -8.5999999999999996447286321*w[0][4]; + A[144] = 0.0000888000888000888000118*var_287*var_8 + var_195; + const double var_288 = -5.0000000000000000000000000*var_37 + 8.9199999999999999289457264*var_27 + 7.9288888888888893191619900*var_36 + 5.0800000000000000710542736*var_38 + 2.0622222222222221788001661*w[0][2]; + A[146] = var_255 + 0.0001480001480001479909846*var_288*var_8; + A[201] = A[103]; + A[206] = A[178]; + const double var_289 = 0.5904761904761904878213841*w[0][6] + 0.0095238095238095246686250*w[0][7] + var_202 + 2.0380952380952384039858316*w[0][8] + var_243 + var_181 + -1.2666666666666666074547720*w[0][5] + var_214 + -0.1142857142857142821457117*w[0][4]; + const double var_290 = -0.6666666666666666296592325*w[0][0] + var_16 + -24.3333333333333321490954404*var_17 + -2.0000000000000000000000000*var_14; + A[72] = 0.0000799200799200799200106*var_290*var_8 + var_241 + 0.0006630406630406630039479*var_15*var_8; + A[184] = A[72]; + const double var_291 = -0.2539682539682539541558981*var_36 + -0.4285714285714285476380780*var_37 + -1.0000000000000000000000000*var_27 + 0.1481481481481481399242739*w[0][2]; + A[193] = 0.0044755244755244755205936*var_291*var_8 + 0.0023443223443223443203109*var_38*var_8 + var_142; + const double var_292 = 0.6909090909090909171652584*w[0][6] + 0.5424242424242424753799696*w[0][7] + -1.9681818181818180324427203*w[0][3] + var_211 + -1.2439393939393939003679179*w[0][8] + var_120 + -0.2500000000000000000000000*w[0][5] + 2.1727272727272728403136171*w[0][4] + var_104; + A[33] = var_118 + 0.0002442002442002442000324*var_292*var_8; + const double var_293 = 1.1798941798941797731714587*w[0][6] + 0.0952380952380952328084618*w[0][7] + var_66 + var_219 + -0.8571428571428570952761561*w[0][3] + 0.1904761904761904656169236*var_60 + -0.5185185185185184897349586*w[0][5] + var_260 + 2.2063492063492060601959110*w[0][4]; + A[81] = 0.0011188811188811188801484*var_293*var_8 + var_159; + const double var_294 = -0.0303350970017636709097353*w[0][2]; + const double var_295 = 0.0516594516594516620089372*w[0][6] + var_187 + -0.1705627705627705548163675*w[0][3] + var_170 + var_276 + -0.0903318903318903326793432*w[0][5] + var_294 + 0.0129870129870129878690843*var_218 + 0.0943722943722943713451556*w[0][4]; + A[161] = 0.0153846153846153854694023*var_295*var_8 + var_144; + A[175] = A[161]; + A[97] = 0.0153846153846153854694023*var_193*var_8 + var_144; + A[219] = A[149]; + A[35] = var_9 + 0.0000370000370000369977462*var_141*var_8; + A[77] = A[35]; + const double var_296 = 1.0223484848484849507599392*w[0][6] + -0.5265151515151514916013298*w[0][7] + -0.1545454545454545414173708*w[0][3] + 0.2155303030303030165093503*w[0][8] + -1.3333333333333332593184650*w[0][5] + var_246 + var_59 + 0.5034090909090909171652584*w[0][4] + var_206; + A[7] = var_183 + 0.0007326007326007326000972*var_296*var_8; + A[105] = A[7]; + const double var_297 = 3.4857142857142857650387668*w[0][6] + 0.2000000000000000111022302*w[0][7] + var_178 + var_44 + var_61 + -5.5428571428571427048836995*w[0][8] + -1.4000000000000001332267630*w[0][5] + 6.4857142857142857650387668*w[0][4] + 1.0571428571428571618895376*var_26; + A[73] = var_40 + 0.0009324009324009324001237*var_297*var_8; + const double var_298 = var_95 + 0.0303030303030303038713811*var_37 + 0.7272727272727272929131459*var_27 + 0.2659932659932660037327423*var_36 + 0.1818181818181818232282865*var_38; + const double var_299 = -0.4285714285714285476380780*var_16 + 0.1481481481481481399242739*w[0][0] + -0.2539682539682539541558981*var_15 + -1.0000000000000000000000000*var_14; + A[209] = 0.0044755244755244755205936*var_299*var_8 + 0.0023443223443223443203109*var_17*var_8 + var_142; + A[223] = A[209]; + A[198] = A[58]; + const double var_300 = 0.0016161616161616161602144*var_283; + const double var_301 = 0.0285714285714285705364279*w[0][7] + var_300 + 0.0400000000000000008326673*var_60 + -0.0301298701298701315787198*w[0][3] + var_155 + 0.0519480519480519514763373*w[0][5] + var_271 + 0.0025974025974025974003445*var_47 + 0.0119480519480519489089465*w[0][4]; + A[177] = 0.0683760683760683829479632*var_301*var_8 + var_53; + A[191] = A[177]; + A[2] = 0.0000009250009250009249648*var_123*var_8 + var_282; + A[30] = A[2]; + const double var_302 = -0.1545454545454545414173708*w[0][6] + 1.0223484848484849507599392*w[0][7] + -0.5265151515151514916013298*w[0][3] + var_233 + -1.3333333333333332593184650*w[0][8] + 0.5034090909090909171652584*w[0][5] + var_204 + 0.2155303030303030165093503*w[0][4] + var_190; + A[25] = 0.0007326007326007326000972*var_302*var_8 + var_183; + A[59] = 0.0683760683760683829479632*var_274*var_8 + var_53; + A[213] = A[59]; + A[164] = 0.0006630406630406630039479*var_36*var_8 + var_241 + 0.0000799200799200799200106*var_217*var_8; + const double var_303 = -0.1757575757575757513517800*w[0][7]; + const double var_304 = 0.0943722943722943713451556*w[0][6] + -0.0903318903318903326793432*w[0][3] + 0.0129870129870129878690843*var_60 + var_303 + -0.1705627705627705548163675*w[0][5] + var_192 + var_294 + var_70 + 0.0516594516594516620089372*w[0][4]; + A[145] = 0.0153846153846153854694023*var_304*var_8 + var_144; + A[123] = A[53]; + A[62] = A[34]; + const double var_305 = 0.0119913419913419919821118*var_16 + -0.0148917748917748917619752*var_14 + 0.0018518518518518519225258*var_15 + 0.0153920153920153925802827*w[0][0] + 0.0005194805194805194800689*var_17; + A[115] = var_20 + 0.0769230769230769273470116*var_305*var_8; + const double var_306 = 0.0705627705627705631430402*w[0][6] + var_303 + -0.0103896103896103896013781*w[0][3] + 0.0060606060606060606008039*w[0][8] + var_151 + -0.0658008658008658042781747*w[0][5] + var_277 + var_265 + 0.0376623376623376610039529*w[0][4]; + A[42] = var_149 + 0.0051282051282051282006802*var_306*var_8; + A[182] = A[42]; + A[4] = var_131 + 0.0003496503496503496500464*var_191*var_8; + A[60] = A[4]; + const double var_307 = 8.4666666666666667850904560*var_22 + -0.6000000000000000888178420*var_24 + -2.7333333333333333925452280*var_21 + 0.4444444444444444197728217*var_56 + 0.9185185185185185119394191*var_23; + A[86] = 0.0011188811188811188801484*var_138*var_8 + var_159; + A[56] = var_228 + 0.0000888000888000888000118*var_107*var_8; + const double var_308 = 0.5424242424242424753799696*w[0][6] + -1.9681818181818180324427203*w[0][7] + var_210 + 0.6909090909090909171652584*w[0][3] + 2.1727272727272728403136171*w[0][8] + -1.2439393939393939003679179*w[0][5] + var_121 + var_103 + -0.2500000000000000000000000*w[0][4]; + A[24] = var_118 + 0.0002442002442002442000324*var_308*var_8; + A[124] = A[68]; + const double var_309 = 0.0004972804972804972800660*var_8*w[0][9]; + const double var_310 = 0.0303030303030303038713811*var_16 + 0.7272727272727272929131459*var_14 + var_18 + 0.2659932659932660037327423*var_15 + 0.1818181818181818232282865*var_17; + A[131] = 0.0005860805860805860800777*var_310*var_8 + var_309; + A[51] = 0.0005860805860805860800777*var_298*var_8 + var_309; + A[95] = A[81]; + const double var_311 = 0.0119480519480519489089465*w[0][6] + var_300 + var_259 + 0.0519480519480519514763373*w[0][3] + var_55 + 0.0285714285714285705364279*w[0][8] + -0.0301298701298701315787198*w[0][5] + 0.0400000000000000008326673*var_218 + 0.0025974025974025974003445*var_77; + A[148] = var_53 + 0.0683760683760683829479632*var_311*var_8; + A[204] = A[148]; + A[9] = 0.0000370000370000369977462*var_175*var_8 + var_9; + A[135] = A[9]; + A[143] = A[129]; + const double var_312 = -5.0000000000000000000000000*var_16 + 8.9199999999999999289457264*var_14 + 7.9288888888888893191619900*var_15 + 2.0622222222222221788001661*w[0][0] + 5.0800000000000000710542736*var_17; + A[50] = 0.0001480001480001479909846*var_312*var_8 + var_255; + A[78] = A[50]; + A[111] = A[97]; + A[116] = var_97 + 0.0004662004662004662000618*var_244*var_8; + A[172] = A[116]; + A[152] = A[40]; + A[165] = A[11]; + A[79] = A[65]; + A[151] = A[25]; + A[154] = A[70]; + A[98] = var_255 + 0.0001480001480001479909846*var_106*var_8; + A[126] = A[98]; + const double var_313 = -0.0301298701298701315787198*w[0][6] + var_259 + 0.0285714285714285705364279*w[0][3] + 0.0519480519480519514763373*w[0][8] + var_156 + 0.0119480519480519489089465*w[0][5] + var_273 + 0.0025974025974025974003445*var_218 + 0.0400000000000000008326673*var_77; + A[88] = 0.0683760683760683829479632*var_313*var_8 + var_53; + A[200] = A[88]; + const double var_314 = -5.7500000000000000000000000*w[0][6] + 1.8373015873015872134743631*w[0][3] + 0.5833333333333332593184650*w[0][8] + 1.7500000000000000000000000*w[0][5] + var_129 + var_0 + var_229 + 0.2500000000000000000000000*var_218 + -3.2579365079365079083117962*w[0][4]; + const double var_315 = var_234 + -0.8476190476190477163243031*w[0][7] + 0.3393939393939394144616983*w[0][8] + -0.5116883116883116366935269*w[0][5] + var_181 + var_108 + var_109 + var_226 + 0.0363636363636363618700997*var_77; + A[114] = 0.0051282051282051282006802*var_315*var_8 + var_110; + A[142] = A[114]; + const double var_316 = 8.4666666666666667850904560*var_16 + 0.4444444444444444197728217*var_272 + -2.7333333333333333925452280*var_14 + 0.9185185185185185119394191*var_15 + -0.6000000000000000888178420*var_17; + A[138] = A[54]; + A[14] = var_149 + 0.0051282051282051282006802*var_266*var_8; + A[210] = A[14]; + A[202] = A[118]; + A[189] = A[147]; + const double var_317 = 0.0575424575424575424076323*var_8*w[0][9]; + A[208] = var_317 + 0.0031968031968031968004240*var_307*var_8; + A[136] = A[24]; + A[63] = A[49]; + A[130] = var_97 + 0.0004662004662004662000618*var_289*var_8; + A[139] = A[69]; + A[173] = A[131]; + A[220] = A[164]; + A[39] = var_127 + 0.0000932400932400932400124*var_8*var_94; + A[93] = A[51]; + A[1] = 0.0000009250009250009249648*var_269*var_8 + var_282; + A[15] = A[1]; + A[3] = var_127 + 0.0000932400932400932400124*var_280*var_8; + A[20] = var_118 + 0.0002442002442002442000324*var_212*var_8; + A[76] = A[20]; + A[176] = var_195 + 0.0000888000888000888000118*var_249*var_8; + A[192] = var_317 + 0.0031968031968031968004240*var_316*var_8; + A[171] = A[101]; + const double var_318 = 0.5542857142857142704883699*w[0][6] + -0.1066666666666666735130420*w[0][7] + -0.0552380952380952389146884*w[0][8] + var_125 + -0.2457142857142857184093998*w[0][5] + var_253 + var_85 + 0.3695238095238095321626304*w[0][4] + 0.1847619047619047660813152*var_26; + A[134] = 0.0186480186480186480024734*var_318*var_8 + var_46; + A[99] = var_228 + 0.0000888000888000888000118*var_263*var_8; + A[132] = 0.0683760683760683829479632*var_157*var_8 + var_53; + A[188] = A[132]; + A[47] = A[33]; + A[150] = A[10]; + A[45] = A[3]; + A[207] = A[193]; + A[170] = A[86]; + A[84] = 0.0005860805860805860800777*var_8*var_84 + var_309; + A[137] = A[39]; + const double var_319 = 26.0500000000000007105427358*var_16 + -33.6499999999999985789145285*var_14 + -84.5111111111111199534207117*var_15 + 3.7222222222222218768195034*w[0][0] + -40.8500000000000014210854715*var_17; + A[17] = 0.0000009250009250009249648*var_319*var_8 + var_282; + A[190] = A[162]; + A[174] = A[146]; + A[218] = A[134]; + A[168] = A[56]; + const double var_320 = 0.2364718614718614719816259*var_22 + 0.0101010101010101018687015*var_24 + -0.0990259740259740312007253*var_21 + 0.0296416546416546425324334*var_23 + 0.5661375661375661616503407*w[0][1]; + A[67] = var_20 + 0.0769230769230769273470116*var_52*var_8; + A[199] = A[73]; + A[158] = A[130]; + const double var_321 = 8.4666666666666667850904560*var_37 + 0.4444444444444444197728217*var_283 + -2.7333333333333333925452280*var_27 + 0.9185185185185185119394191*var_36 + -0.6000000000000000888178420*var_38; + A[224] = var_317 + 0.0031968031968031968004240*var_321*var_8; + A[16] = var_182 + 0.0025641025641025641003401*var_320*var_8; + A[109] = A[67]; + A[128] = 0.0000888000888000888000118*var_173*var_8 + var_195; + A[23] = var_127 + 0.0000932400932400932400124*var_314*var_8; + A[121] = A[23]; + A[26] = var_9 + 0.0000370000370000369977462*var_238*var_8; + A[141] = A[99]; + A[31] = A[17]; + A[185] = A[87]; + A[46] = A[18]; + A[166] = A[26]; + A[122] = A[38]; + A[61] = A[19]; + A[157] = A[115]; + A[159] = A[145]; + A[140] = A[84]; + } + + 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/mass_matrix_2d/mass_matrix_f1_p3_q4_quadrature.h b/mass_matrix_2d/mass_matrix_f1_p3_q4_quadrature.h new file mode 100644 index 0000000..2813ca4 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p3_q4_quadrature.h @@ -0,0 +1,8432 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P3_Q4_QUADRATURE_H +#define __MASS_MATRIX_F1_P3_Q4_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p3_q4_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p3_q4_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p3_q4_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p3_q4_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p3_q4_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p3_q4_quadrature_finite_element_1() + { + // 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.0224478343233824, 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.0412393049421162, -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.0388807895679869, 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.0439885919382571, 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.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 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.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.00927360943924092, 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.0535412090610519}; + + // 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.0622092633087791, -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.251415744421884, 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.0224478343233824, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0412393049421162, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0388807895679869, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0439885919382571, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.00927360943924092, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0622092633087791, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.251415744421884, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p3_q4_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p3_q4_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p3_q4_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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.0*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 mass_matrix_f1_p3_q4_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p3_q4_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p3_q4_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f1_p3_q4_quadrature_dofmap_1() + { + // 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.0*m.num_entities[1] + 3.0*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 mass_matrix_f1_p3_q4_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 mass_matrix_f1_p3_q4_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p3_q4_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Array of quadrature weights. + static const double W36[36] = {0.00619426535265906, 0.0116108747669979, 0.0120606064042655, 0.0084515357969434, 0.0037652982126918, 0.000748542561236343, 0.0130433943300833, 0.0244492622580587, 0.0253962715890485, 0.0177965759970269, 0.00792866733379675, 0.00157622175402364, 0.0169175056800133, 0.0317111115907051, 0.0329393989007878, 0.023082463651359, 0.0102836172287667, 0.00204438659154493, 0.0169175056800133, 0.0317111115907051, 0.0329393989007878, 0.023082463651359, 0.0102836172287667, 0.00204438659154493, 0.0130433943300833, 0.0244492622580587, 0.0253962715890485, 0.0177965759970269, 0.00792866733379675, 0.00157622175402364, 0.00619426535265908, 0.0116108747669979, 0.0120606064042655, 0.00845153579694342, 0.00376529821269181, 0.000748542561236345}; + // Quadrature points on the UFC reference element: (0.0327753666144599, 0.0293164271597849), (0.0287653330125591, 0.148078599668484), (0.0223868729780306, 0.336984690281154), (0.0149015633666711, 0.55867151877155), (0.00779187470128645, 0.769233862030055), (0.00246669715267023, 0.926945671319741), (0.164429241594827, 0.0293164271597849), (0.144311486950417, 0.148078599668484), (0.112311681780954, 0.336984690281154), (0.0747589734626491, 0.55867151877155), (0.0390907007328242, 0.769233862030055), (0.01237506041744, 0.926945671319741), (0.369529924372377, 0.0293164271597849), (0.324318304588776, 0.148078599668484), (0.252403568076518, 0.336984690281154), (0.168009519121192, 0.55867151877155), (0.0878504549759972, 0.769233862030055), (0.0278110821153606, 0.926945671319741), (0.601153648467838, 0.0293164271597849), (0.52760309574274, 0.148078599668484), (0.410611741642328, 0.336984690281154), (0.273318962107258, 0.55867151877155), (0.142915682993948, 0.769233862030055), (0.0452432465648983, 0.926945671319741), (0.806254331245388, 0.0293164271597849), (0.707609913381099, 0.148078599668484), (0.550703627937892, 0.336984690281154), (0.366569507765801, 0.55867151877155), (0.191675437237121, 0.769233862030055), (0.0606792682628189, 0.926945671319741), (0.937908206225755, 0.0293164271597849), (0.823156067318956, 0.148078599668484), (0.640628436740815, 0.336984690281154), (0.426426917861779, 0.55867151877155), (0.222974263268659, 0.769233862030055), (0.0705876315275886, 0.926945671319741) + + // Value of basis functions at quadrature points. + static const double FE0[36][10] = \ + {{0.692116405326339, 0.02809979214053, 0.0255622715011347, -0.00389870712577275, -0.00394357498286782, 0.224416734425978, -0.112850342203846, 0.250894855131633, -0.124729708262302, 0.0243322740491734}, + {0.283934759651154, 0.0251489409971642, 0.0640171956914923, -0.0175137741663261, -0.0106528248707412, 0.806022543976085, -0.304843939147456, 0.156575676330067, -0.0973575486190499, 0.0946689701576109}, + {-0.0230667189458806, 0.0201820871510281, -0.00182545940770507, -0.0316681717528919, 0.000371870446193849, 0.89558289813655, 0.0106415390326746, 0.0594961764142811, -0.0602031247994332, 0.130488903725183}, + {-0.042916247694867, 0.0139171991648146, -0.0611798040376018, -0.0357880903185195, 0.0253254357551023, 0.299401977386427, 0.724719094689676, 0.00798601215243768, -0.0273165975674619, 0.0958510204699925}, + {0.0491311892659461, 0.00752079361748066, 0.154762873078755, -0.026341495488006, 0.0352713041777646, -0.255537670979266, 1.00933258876242, -0.0025884423606554, -0.00763548751524317, 0.0360843474408066}, + {0.0497485688239403, 0.00243938401571425, 0.644479118812606, -0.0102130829170651, 0.0183234311516915, -0.232087782696187, 0.524347954533704, -0.000617609305981537, -0.000777734182289297, 0.00435775176386716}, + {0.239508104110957, 0.0627683640711487, 0.0255622715011347, -0.0109916789233747, -0.0197843414303476, 0.150905638607928, -0.0970095757563665, 0.846395762124882, -0.302290885970787, 0.104936341664825}, + {0.0487956775975465, 0.0641196764159749, 0.0640171956914923, -0.0545304359767136, -0.0534436711248166, 0.529434975607773, -0.26205309289338, 0.515966174346368, -0.260579700000555, 0.40827320033631}, + {-0.0624669400507792, 0.0619241738506681, -0.00182545940770509, -0.112928533782117, 0.00186561987722207, 0.544580480381976, 0.00914778960164644, 0.181500084071326, -0.18454889805122, 0.562751683508982}, + {-0.0164528736892738, 0.0514890982575726, -0.0611798040376018, -0.145793810693828, 0.127054023323504, 0.0918877602754595, 0.622990507121273, 0.0122960172501371, -0.0956618757635125, 0.413370957956269}, + {0.0580370533440932, 0.0324831299939718, 0.154762873078755, -0.119445891298145, 0.176950996894466, -0.281967732783221, 0.867652896045716, -0.0143289535245541, -0.0297631768059827, 0.1556188050549}, + {0.045115774663025, 0.0116944490193934, 0.644479118812606, -0.0497031543433876, 0.0919259858517786, -0.207033374665612, 0.450745399833617, -0.00276397053159101, -0.00325364379944372, 0.0187934151596152}, + {-0.0474645235382767, -0.0178848851455664, 0.0255622715011347, 0.00529373373938191, -0.044462323864076, 0.0637197133595963, -0.0723315933226381, 0.803179075351347, 0.108551677668697, 0.1758368542504}, + {-0.0641414000235847, 0.00450421741088884, 0.0640171956914923, -0.00584473256502761, -0.120106591488146, 0.204898420912783, -0.195390172530051, 0.448763755411812, -0.0208247444397816, 0.684124051619613}, + {-0.0365624407658455, 0.0380796136728451, -0.00182545940770511, -0.0929282395408237, 0.00419269933650997, 0.144355545313924, 0.00682071014235854, 0.108123175205576, -0.11323192829258, 0.94297632433574}, + {0.029034487004146, 0.062328097021337, -0.0611798040376018, -0.209488219289238, 0.285534757531946, -0.123712995627073, 0.464509772912832, -0.037204260833003, -0.102487957137557, 0.692666122454212}, + {0.0641393355313791, 0.0561718105163469, 0.154762873078755, -0.223953257707656, 0.397670681113729, -0.282604617367218, 0.646933211826454, -0.0322748977125214, -0.0416081953276764, 0.260763056048409}, + {0.0364487137089397, 0.024427326771013, 0.644479118812606, -0.106328278377059, 0.206589790661253, -0.163106070537901, 0.336081595024143, -0.00489365931747124, -0.00518977181109788, 0.0314912350655752}, + {-0.0178848851455664, -0.0474645235382767, 0.0255622715011347, 0.0637197133595962, -0.072331593322638, 0.00529373373938194, -0.044462323864076, 0.108551677668697, 0.803179075351347, 0.1758368542504}, + {0.00450421741088887, -0.0641414000235847, 0.0640171956914923, 0.204898420912783, -0.195390172530051, -0.00584473256502761, -0.120106591488146, -0.0208247444397817, 0.448763755411812, 0.684124051619613}, + {0.0380796136728452, -0.0365624407658455, -0.00182545940770511, 0.144355545313924, 0.00682071014235857, -0.0929282395408238, 0.00419269933651001, -0.11323192829258, 0.108123175205576, 0.94297632433574}, + {0.062328097021337, 0.029034487004146, -0.0611798040376018, -0.123712995627073, 0.464509772912832, -0.209488219289239, 0.285534757531946, -0.102487957137557, -0.0372042608330028, 0.692666122454212}, + {0.0561718105163469, 0.0641393355313791, 0.154762873078755, -0.282604617367218, 0.646933211826454, -0.223953257707657, 0.397670681113729, -0.0416081953276766, -0.0322748977125212, 0.260763056048409}, + {0.0244273267710131, 0.0364487137089397, 0.644479118812606, -0.163106070537901, 0.336081595024142, -0.106328278377059, 0.206589790661253, -0.00518977181109807, -0.00489365931747109, 0.0314912350655752}, + {0.0627683640711488, 0.239508104110958, 0.0255622715011347, 0.150905638607928, -0.0970095757563665, -0.0109916789233747, -0.0197843414303476, -0.302290885970787, 0.846395762124882, 0.104936341664825}, + {0.064119676415975, 0.0487956775975466, 0.0640171956914923, 0.529434975607773, -0.26205309289338, -0.0545304359767137, -0.0534436711248165, -0.260579700000555, 0.515966174346368, 0.40827320033631}, + {0.0619241738506681, -0.0624669400507792, -0.00182545940770511, 0.544580480381976, 0.00914778960164649, -0.112928533782117, 0.00186561987722211, -0.18454889805122, 0.181500084071326, 0.562751683508982}, + {0.0514890982575726, -0.0164528736892739, -0.0611798040376018, 0.0918877602754599, 0.622990507121273, -0.145793810693828, 0.127054023323504, -0.0956618757635126, 0.0122960172501373, 0.413370957956269}, + {0.0324831299939719, 0.0580370533440933, 0.154762873078755, -0.28196773278322, 0.867652896045716, -0.119445891298145, 0.176950996894467, -0.0297631768059829, -0.0143289535245539, 0.1556188050549}, + {0.0116944490193935, 0.0451157746630249, 0.644479118812606, -0.207033374665612, 0.450745399833616, -0.0497031543433881, 0.091925985851779, -0.00325364379944393, -0.0027639705315908, 0.0187934151596153}, + {0.02809979214053, 0.692116405326339, 0.0255622715011347, 0.224416734425978, -0.112850342203846, -0.00389870712577277, -0.00394357498286788, -0.124729708262302, 0.250894855131634, 0.0243322740491735}, + {0.0251489409971643, 0.283934759651153, 0.0640171956914923, 0.806022543976084, -0.304843939147455, -0.0175137741663261, -0.0106528248707413, -0.0973575486190503, 0.156575676330067, 0.0946689701576112}, + {0.0201820871510282, -0.0230667189458806, -0.0018254594077051, 0.89558289813655, 0.0106415390326748, -0.0316681717528918, 0.000371870446193856, -0.0602031247994334, 0.0594961764142812, 0.130488903725183}, + {0.0139171991648146, -0.042916247694867, -0.0611798040376018, 0.299401977386428, 0.724719094689675, -0.0357880903185195, 0.0253254357551024, -0.027316597567462, 0.00798601215243784, 0.0958510204699924}, + {0.00752079361748067, 0.0491311892659461, 0.154762873078755, -0.255537670979266, 1.00933258876242, -0.026341495488006, 0.0352713041777647, -0.00763548751524335, -0.00258844236065517, 0.0360843474408064}, + {0.00243938401571438, 0.0497485688239402, 0.644479118812606, -0.232087782696186, 0.524347954533703, -0.0102130829170658, 0.0183234311516924, -0.000777734182289533, -0.00061760930598137, 0.00435775176386732}}; + + static const double FE1[36][15] = \ + {{0.56630237132032, -0.025448739951231, -0.02340903093109, 0.00416085056960128, 0.00294793329848728, 0.00425839910756952, 0.353405794301071, -0.267147951008896, 0.121859429227921, 0.395102868735011, -0.293986529335415, 0.133116353941705, 0.0793522773075458, -0.0250575137648273, -0.0254565128177721}, + {0.118972466830072, -0.0230709318617449, -0.0341013730463095, 0.018947016495499, 0.00614695794455526, 0.00651870726857255, 0.963270822664205, -0.455714379551745, 0.186540981008593, 0.18712228544335, -0.192157632298739, 0.105324818176152, 0.257233041221556, -0.099290349448832, -0.045742430845185}, + {-0.0410559740731875, -0.0188884466735285, 0.0210511710271628, 0.0349917675522029, -0.00955924750821981, -0.00456418811345946, 0.505990196901837, 0.469464799398205, -0.130609964999847, 0.0336144002765209, -0.0816095123137331, 0.0665214829999042, 0.241648244025793, -0.140804681095384, 0.0538099525957325}, + {0.0191042291114048, -0.0133255662493701, -0.0206485123834592, 0.0405094826163528, -0.0386646995111557, 0.00643281363514752, -0.131939141811172, 0.830314310030356, 0.184083027003091, -0.00351924058446104, -0.0168682880103284, 0.0309203767076776, 0.080169244991654, -0.106829866961562, 0.140261831415824}, + {-0.00938453904605184, -0.00735417356108037, 0.0220620722354296, 0.0304878329277379, -0.0482427486128633, 0.0357504701324324, 0.0547897737103965, -0.154040051327386, 1.02304452328671, 0.000554987335758502, 0.000727851735427045, 0.00883736717957267, -0.00462319916590223, -0.0414337049897014, 0.0888235381595224}, + {-0.039411023284595, -0.00242231653722821, 0.505649261589883, 0.0120147467421047, -0.0245209639812787, 0.0281958543435565, 0.215079260438399, -0.508591455559504, 0.806859721248732, 0.000572347890212842, 0.000494891999080295, 0.000914932279387579, -0.00370647497562177, -0.0051137834055052, 0.0139850012123767}, + {0.0824161637725179, -0.0294914855256902, -0.02340903093109, 0.00590593006797314, 0.00582593260452294, 0.0213637682196615, 0.171801701915994, -0.185697684231962, 0.104754060115829, 0.963597078074327, -0.40385910184121, 0.162423670230445, 0.276723174191905, -0.0425693977624813, -0.109784778900741}, + {-0.0303969806920391, -0.0350490773722188, -0.0341013730463095, 0.0342751641157549, 0.0147321571899481, 0.0327034051200263, 0.424735375088394, -0.312771366460782, 0.160356283157139, 0.413930126815579, -0.316080712840952, 0.163787650378721, 0.885711947101502, -0.204561955373223, -0.19727064318154}, + {-0.0178494055445301, -0.0407795027424123, 0.0210511710271628, 0.0861992776649916, -0.0290104851672837, -0.0228978671335801, 0.120724252767667, 0.310663028371925, -0.112276285979726, 0.040235489181343, -0.163892320828179, 0.140867690149755, 0.802235130592271, -0.36733313364048, 0.232062961281076}, + {0.0233190985494116, -0.0401256259898051, -0.0206485123834592, 0.132794326958115, -0.144587977270839, 0.032272489268862, -0.135906939764466, 0.47160061549191, 0.158243351369376, -0.0181864708721552, -0.0358278205906738, 0.0871323298781454, 0.228439462369848, -0.343417130728224, 0.604898803713954}, + {-0.0205277588289655, -0.0288155938118291, 0.0220620722354296, 0.124718754065599, -0.21075144429941, 0.179354902713459, 0.113128801818687, -0.285771773170361, 0.879440090705682, 0.00574894626256647, 0.0058988467391181, 0.031077053282736, -0.0430288533926338, -0.155598000009121, 0.383063955689044}, + {-0.0371082327213856, -0.0112820903294173, 0.505649261589883, 0.0567111236787091, -0.118093887044145, 0.141454495394839, 0.199601225425082, -0.461345808814886, 0.69360108019745, 0.00266474864758105, 0.00216201065863758, 0.00371239609144181, -0.0168674754837758, -0.0211711248206387, 0.0603122775306251}, + {-0.0339024544799458, 0.023387640004351, -0.02340903093109, -0.00720836763307398, -0.0182888871179095, 0.0480118473937476, 0.0267093906452789, -0.0874064926762268, 0.0781059809417426, 0.336668552801051, 0.596745158445697, -0.147812572060763, 0.292720606365088, 0.0996397790360984, -0.183961150734045}, + {-0.0095906246236551, 0.0192268203241027, -0.0341013730463094, -0.0267531412354512, -0.0232811757502806, 0.0734959712974962, 0.0255429142588088, -0.141471609601455, 0.119563716979669, 0.0559434966647409, 0.225932583629769, -0.0953212697058672, 0.900337562556068, 0.241033195353002, -0.330557067100639}, + {0.0213409951908707, 0.000797264231187582, 0.0210511710271628, -0.00215970873408773, 0.00113811168767276, -0.0514595033589619, -0.0847594279128907, 0.123720487246374, -0.0837146497543445, -0.0634853233702957, 0.00256059295790888, -0.00263157879369526, 0.717999738211763, 0.0107449258196653, 0.388856905551671}, + {0.00734599742741782, -0.02839014160368, -0.0206485123834592, 0.109010467002261, -0.152030381966887, 0.0725275529045928, -0.0344381186867421, 0.0703415678092674, 0.117988287733645, -0.0103565898127769, -0.00561896434021046, 0.0533312093041724, 0.0765736536295873, -0.269236283109832, 1.01360025609264}, + {-0.0353878578540361, -0.0414666912205211, 0.0220620722354296, 0.192691111987477, -0.364133910121009, 0.403073096930251, 0.179359194783873, -0.391207466820726, 0.65572189648889, 0.0204837405679316, 0.0139522896496609, 0.0358000125005907, -0.132378708183015, -0.200450896105804, 0.641882115161008}, + {-0.031669348089454, -0.0224768586657739, 0.505649261589883, 0.115398208580281, -0.248158040619958, 0.317897646905111, 0.166615019902697, -0.372031802654953, 0.517157928687178, 0.00499893806458903, 0.00366363544055174, 0.00563246559694469, -0.0305685004026728, -0.0331709792809288, 0.101062424946505}, + {0.023387640004351, -0.0339024544799458, -0.02340903093109, 0.0267093906452788, -0.0874064926762267, 0.0781059809417426, -0.00720836763307393, -0.0182888871179095, 0.0480118473937476, -0.147812572060763, 0.596745158445697, 0.336668552801051, 0.0996397790360983, 0.292720606365088, -0.183961150734045}, + {0.0192268203241027, -0.00959062462365504, -0.0341013730463094, 0.0255429142588087, -0.141471609601455, 0.119563716979669, -0.0267531412354512, -0.0232811757502805, 0.0734959712974963, -0.0953212697058673, 0.22593258362977, 0.0559434966647408, 0.241033195353002, 0.900337562556068, -0.330557067100639}, + {0.000797264231187593, 0.0213409951908707, 0.0210511710271628, -0.0847594279128908, 0.123720487246374, -0.0837146497543445, -0.00215970873408771, 0.00113811168767294, -0.0514595033589619, -0.00263157879369533, 0.00256059295790887, -0.0634853233702957, 0.0107449258196652, 0.717999738211763, 0.388856905551671}, + {-0.0283901416036801, 0.00734599742741785, -0.0206485123834592, -0.0344381186867421, 0.0703415678092673, 0.117988287733645, 0.109010467002261, -0.152030381966887, 0.0725275529045927, 0.0533312093041724, -0.00561896434021046, -0.0103565898127769, -0.269236283109833, 0.0765736536295877, 1.01360025609264}, + {-0.0414666912205212, -0.035387857854036, 0.0220620722354296, 0.179359194783873, -0.391207466820727, 0.65572189648889, 0.192691111987477, -0.364133910121008, 0.403073096930251, 0.0358000125005907, 0.0139522896496609, 0.0204837405679316, -0.200450896105804, -0.132378708183015, 0.641882115161008}, + {-0.0224768586657739, -0.031669348089454, 0.505649261589883, 0.166615019902697, -0.372031802654953, 0.517157928687178, 0.115398208580281, -0.248158040619958, 0.317897646905111, 0.00563246559694458, 0.00366363544055176, 0.00499893806458915, -0.0331709792809289, -0.0305685004026726, 0.101062424946505}, + {-0.0294914855256903, 0.0824161637725182, -0.02340903093109, 0.171801701915994, -0.185697684231962, 0.104754060115829, 0.00590593006797323, 0.00582593260452294, 0.0213637682196615, 0.162423670230446, -0.40385910184121, 0.963597078074327, -0.0425693977624813, 0.276723174191904, -0.109784778900741}, + {-0.0350490773722189, -0.030396980692039, -0.0341013730463095, 0.424735375088395, -0.312771366460783, 0.160356283157139, 0.034275164115755, 0.0147321571899484, 0.0327034051200263, 0.163787650378721, -0.316080712840952, 0.41393012681558, -0.204561955373223, 0.885711947101502, -0.19727064318154}, + {-0.0407795027424123, -0.0178494055445301, 0.0210511710271628, 0.120724252767667, 0.310663028371925, -0.112276285979726, 0.0861992776649916, -0.0290104851672834, -0.0228978671335801, 0.140867690149755, -0.163892320828179, 0.040235489181343, -0.36733313364048, 0.802235130592271, 0.232062961281076}, + {-0.0401256259898051, 0.0233190985494116, -0.0206485123834592, -0.135906939764466, 0.471600615491911, 0.158243351369376, 0.132794326958115, -0.144587977270839, 0.0322724892688619, 0.0871323298781453, -0.0358278205906738, -0.0181864708721552, -0.343417130728224, 0.228439462369848, 0.604898803713953}, + {-0.0288155938118291, -0.0205277588289655, 0.0220620722354296, 0.113128801818687, -0.285771773170361, 0.879440090705682, 0.124718754065599, -0.21075144429941, 0.179354902713459, 0.0310770532827359, 0.00589884673911823, 0.00574894626256647, -0.155598000009122, -0.0430288533926335, 0.383063955689044}, + {-0.0112820903294174, -0.0371082327213855, 0.505649261589883, 0.199601225425082, -0.461345808814886, 0.693601080197449, 0.0567111236787092, -0.118093887044145, 0.141454495394839, 0.0037123960914417, 0.00216201065863769, 0.00266474864758115, -0.021171124820639, -0.0168674754837758, 0.0603122775306252}, + {-0.0254487399512311, 0.566302371320319, -0.02340903093109, 0.35340579430107, -0.267147951008896, 0.121859429227921, 0.00416085056960128, 0.00294793329848743, 0.00425839910756955, 0.133116353941706, -0.293986529335416, 0.395102868735012, -0.0250575137648273, 0.0793522773075462, -0.0254565128177724}, + {-0.0230709318617449, 0.118972466830072, -0.0341013730463095, 0.963270822664205, -0.455714379551745, 0.186540981008593, 0.018947016495499, 0.00614695794455568, 0.00651870726857255, 0.105324818176152, -0.192157632298739, 0.18712228544335, -0.0992903494488324, 0.257233041221557, -0.045742430845185}, + {-0.0188884466735285, -0.0410559740731874, 0.0210511710271628, 0.505990196901837, 0.469464799398205, -0.130609964999847, 0.034991767552203, -0.00955924750821949, -0.00456418811345951, 0.0665214829999044, -0.0816095123137332, 0.0336144002765209, -0.140804681095384, 0.241648244025794, 0.0538099525957328}, + {-0.0133255662493701, 0.0191042291114048, -0.0206485123834592, -0.131939141811172, 0.830314310030356, 0.184083027003091, 0.0405094826163529, -0.0386646995111555, 0.00643281363514756, 0.0309203767076776, -0.0168682880103284, -0.00351924058446107, -0.106829866961562, 0.0801692449916541, 0.140261831415824}, + {-0.00735417356108038, -0.00938453904605184, 0.0220620722354296, 0.0547897737103965, -0.154040051327387, 1.02304452328671, 0.0304878329277378, -0.0482427486128629, 0.0357504701324325, 0.00883736717957254, 0.000727851735427243, 0.000554987335758443, -0.0414337049897016, -0.00462319916590201, 0.0888235381595222}, + {-0.00242231653722834, -0.0394110232845949, 0.505649261589883, 0.215079260438399, -0.508591455559504, 0.806859721248731, 0.0120147467421051, -0.0245209639812793, 0.0281958543435579, 0.000914932279387486, 0.000494891999080461, 0.000572347890212904, -0.00511378340550558, -0.00370647497562168, 0.0139850012123772}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 225; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 25092 + for (unsigned int ip = 0; ip < 36; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + + // Total number of operations to compute function values = 20 + for (unsigned int r = 0; r < 10; r++) + { + F0 += FE0[ip][r]*w[0][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 2 + double I[1]; + // Number of operations: 2 + I[0] = F0*W36[ip]*det; + + + // Number of operations for primary indices: 675 + for (unsigned int j = 0; j < 15; j++) + { + for (unsigned int k = 0; k < 15; k++) + { + // Number of operations to compute entry: 3 + A[j*15 + k] += FE1[ip][j]*FE1[ip][k]*I[0]; + }// 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 mass_matrix_f1_p3_q4_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p3_q4_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p3_q4_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 1))), 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 mass_matrix_f1_p3_q4_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p3_q4_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p3_q4_quadrature_finite_element_0(); + 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 mass_matrix_f1_p3_q4_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p3_q4_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p3_q4_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f1_p3_q4_tensor.h b/mass_matrix_2d/mass_matrix_f1_p3_q4_tensor.h new file mode 100644 index 0000000..27f8826 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f1_p3_q4_tensor.h @@ -0,0 +1,8550 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F1_P3_Q4_TENSOR_H +#define __MASS_MATRIX_F1_P3_Q4_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p3_q4_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p3_q4_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p3_q4_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f1_p3_q4_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f1_p3_q4_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p3_q4_tensor_finite_element_1() + { + // 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.0224478343233824, 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.0412393049421162, -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.0388807895679869, 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.0439885919382571, 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.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 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.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.00927360943924092, 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.0535412090610519}; + + // 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.0622092633087791, -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.251415744421884, 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.0224478343233824, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0412393049421162, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0388807895679869, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0439885919382571, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.00927360943924092, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0622092633087791, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.251415744421884, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f1_p3_q4_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p3_q4_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p3_q4_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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.0*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 mass_matrix_f1_p3_q4_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f1_p3_q4_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f1_p3_q4_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f1_p3_q4_tensor_dofmap_1() + { + // 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.0*m.num_entities[1] + 3.0*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 mass_matrix_f1_p3_q4_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 mass_matrix_f1_p3_q4_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f1_p3_q4_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 10 + // Number of operations (multiply-add pairs) for tensor contraction: 1035 + // Total number of operations (multiply-add pairs): 1054 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0 = det*w[0][0]*(1.0); + const double G0_1 = det*w[0][1]*(1.0); + const double G0_2 = det*w[0][2]*(1.0); + const double G0_3 = det*w[0][3]*(1.0); + const double G0_4 = det*w[0][4]*(1.0); + const double G0_5 = det*w[0][5]*(1.0); + const double G0_6 = det*w[0][6]*(1.0); + const double G0_7 = det*w[0][7]*(1.0); + const double G0_8 = det*w[0][8]*(1.0); + const double G0_9 = det*w[0][9]*(1.0); + + // Compute element tensor + A[108] = -0.00021657354990689*G0_0 + 2.2200022200024e-05*G0_1 - 0.000599893933227286*G0_2 + 0.000275280275280289*G0_3 - 0.000590520590520612*G0_4 + 0.00095016095016098*G0_5 + 4.44000444000382e-06*G0_6 + 2.66400266400272e-05*G0_7 - 5.32800532800531e-05*G0_8 + 0.000745920745920771*G0_9; + A[7] = -A[108] - 0.00104506604506608*G0_0 + 6.50583983917449e-06*G0_1 - 0.000572452239118924*G0_2 + 0.000162060162060172*G0_3 - 0.00022172272172273*G0_4 - 2.66400266400286e-05*G0_5 + 0.000753413253413278*G0_6 - 0.000359085359085371*G0_7 + 0.00010461760461761*G0_8 + 0.00105727605727609*G0_9; + A[10] = A[7] + 4.31358764692119e-05*G0_1 - 4.31358764692114e-05*G0_2 + 0.000482017982018*G0_3 - 0.000482017982017999*G0_4 + 0.00059107559107561*G0_5 - 0.000591075591075611*G0_6 - 0.000591075591075613*G0_7 + 0.000591075591075613*G0_8; + A[52] = A[108]; + A[60] = 1.53550153550157e-05*G0_0 + 0.000152810152810158*G0_1 + 0.000152810152810158*G0_2 - 0.000177322677322683*G0_3 - 0.000177322677322684*G0_4 - 1.38750138750169e-06*G0_5 + 8.685758685759e-05*G0_6 - 1.38750138750178e-06*G0_7 + 8.68575868575904e-05*G0_8 - 0.000243090243090251*G0_9; + A[202] = A[60] + 0.00064768564768567*G0_0 - 0.000206090206090214*G0_1 + 0.000510230510230527*G0_2 + 0.000257242757242775*G0_3 + 1.74825174825151e-05*G0_4 - 0.00194333444333451*G0_5 - 0.0020315795315796*G0_6 - 0.000158452658452666*G0_7 - 6.9375069375013e-06*G0_8 - 0.00375291375291387*G0_9; + A[4] = A[60]; + A[47] = -A[60] - 3.10389199278124e-06*G0_0 - 1.52111263222358e-06*G0_1 + 0.000496910496910514*G0_2 - 0.000657953157953181*G0_3 + 0.000353257853257865*G0_4 - 6.24375624375649e-05*G0_5 + 0.000255577755577765*G0_6 + 0.000131072631072636*G0_7 - 0.000216912716912724*G0_8 - 0.000400710400710414*G0_9; + A[165] = A[47] + 0.000362559251448153*G0_0 - 0.000362559251448153*G0_2 + 0.000176860176860182*G0_3 - 0.000398120398120411*G0_4 + 0.000229770229770238*G0_5 - 0.000229770229770238*G0_6 + 0.000398120398120413*G0_7 - 0.000176860176860184*G0_8; + A[212] = -6.66000666000689e-06*G0_0 - 6.66000666000683e-06*G0_1 + 0.000434133767467115*G0_2 + 0.000275280275280285*G0_3 - 0.000410700410700425*G0_4 + 0.000275280275280285*G0_5 - 0.000410700410700425*G0_6 + 0.000350760350760362*G0_7 + 0.000350760350760363*G0_8 + 0.000559440559440579*G0_9; + A[1] = -7.81728559506365e-05*G0_0 - 7.81728559506368e-05*G0_1 + 3.44305899861466e-06*G0_2 - 3.11262811262824e-05*G0_3 + 2.4096274096275e-05*G0_4 - 3.11262811262822e-05*G0_5 + 2.4096274096275e-05*G0_6 - 3.77862877862889e-05*G0_7 - 3.77862877862895e-05*G0_8 + 4.44000444000449e-06*G0_9; + A[16] = -A[1] - 2.16861327972423e-06*G0_0 + 0.00137346192901753*G0_1 + 7.94473016695266e-05*G0_2 + 0.000575211825211844*G0_3 - 0.000229816479816487*G0_4 - 5.22625522625559e-06*G0_5 + 4.99962999963016e-05*G0_6 - 0.000291699041699053*G0_7 + 0.00056855181855184*G0_8 + 0.000201465201465208*G0_9; + A[164] = A[202] + 0.000716320716320743*G0_1 - 0.00071632071632074*G0_2 - 0.000239760239760255*G0_3 + 0.000239760239760253*G0_4 + 0.00178488178488184*G0_5 + 0.00202464202464209*G0_6 - 0.00178488178488185*G0_7 - 0.0020246420246421*G0_8; + A[14] = A[108] - 4.93333826667356e-07*G0_0 + 7.64667431334023e-06*G0_1 + 0.000535020535020552*G0_2 - 0.000244200244200257*G0_3 - 0.000310800310800321*G0_4 - 0.000588300588300605*G0_5 - 0.000341880341880354*G0_6 + 0.000166500166500173*G0_7 - 0.00119880119880124*G0_9; + A[31] = A[1] + 8.16159149492511e-05*G0_0 - 8.1615914949251e-05*G0_2 - 6.66000666000666e-06*G0_3 - 6.18825618825641e-05*G0_4 + 5.52225552225571e-05*G0_5 - 5.52225552225572e-05*G0_6 + 6.1882561882564e-05*G0_7 + 6.6600066600071e-06*G0_8; + A[157] = -A[31] + 0.00118744424299984*G0_0 + 6.42772864995101e-05*G0_1 + 6.42772864995108e-05*G0_2 + 2.1737521737509e-06*G0_3 + 2.17375217375122e-06*G0_4 + 0.000946507196507228*G0_5 - 0.00117664742664747*G0_6 + 0.00094650719650723*G0_7 - 0.00117664742664747*G0_8 - 0.000674880674880697*G0_9; + A[186] = A[157] + 0.000631097297763987*G0_1 + 0.000662670662670686*G0_2 - 0.00107004107004111*G0_3 - 0.0020290820290821*G0_4 + 0.00941391941391974*G0_5 - 0.00343656343656356*G0_6 + 0.00596847596847617*G0_7 - 0.00229992229992238*G0_8 + 0.00302364302364313*G0_9; + A[218] = A[186] - 0.000378880378880392*G0_0 + 0.000378880378880392*G0_2 - 0.0024153624153625*G0_3 + 0.00888000888000918*G0_4 - 0.0149184149184154*G0_5 + 0.0149184149184154*G0_6 - 0.00888000888000919*G0_7 + 0.0024153624153625*G0_8; + A[89] = A[218] - 3.15733649066998e-05*G0_0 + 3.1573364906699e-05*G0_1 - 0.00113664113664117*G0_3 + 0.00344544344544357*G0_4 + 0.00113664113664118*G0_5 - 0.00344544344544357*G0_6 + 0.000959040959040993*G0_7 - 0.000959040959040991*G0_8; + A[72] = A[202] - 0.000716320716320741*G0_0 + 0.000716320716320743*G0_1 - 0.0020246420246421*G0_3 - 0.00178488178488184*G0_4 + 0.00202464202464209*G0_5 + 0.00178488178488185*G0_6 + 0.000239760239760251*G0_7 - 0.000239760239760253*G0_8; + A[107] = A[7] + 0.00085593418926755*G0_0 - 0.000855934189267551*G0_2 + 0.00027111777111778*G0_3 - 0.00075452325452328*G0_4 + 0.00172577422577428*G0_5 - 0.00172577422577428*G0_6 + 0.00075452325452328*G0_7 - 0.00027111777111778*G0_8; + A[215] = A[89]; + A[198] = A[186] - 0.00041045374378709*G0_0 + 0.000410453743787099*G0_1 + 0.0113664113664118*G0_3 - 0.00259296259296269*G0_4 - 0.0113664113664118*G0_5 + 0.00259296259296268*G0_6 - 0.0103363303363307*G0_7 + 0.0103363303363307*G0_8; + A[193] = A[202] - 0.00179968179968186*G0_0 - 0.00108336108336112*G0_1 - 0.00455544455544473*G0_3 - 0.00175824175824181*G0_4 - 0.00253080253080262*G0_5 + 2.66400266400284e-05*G0_6 + 0.0025041625041626*G0_7 + 0.00226440226440233*G0_8 + 0.000159840159840149*G0_9; + A[192] = A[193] - 0.000284160284160293*G0_0 + 0.00407296407296422*G0_1 + 0.00227328227328235*G0_2 + 0.00255744255744265*G0_3 + 0.0315417915417926*G0_5 - 0.00681984681984707*G0_6 + 0.0247219447219456*G0_7 - 0.0110822510822515*G0_8 + 0.0613786213786235*G0_9; + A[208] = A[192] + 0.00435712435712451*G0_0 - 0.0043571243571245*G0_1 + 0.02898434898435*G0_3 - 0.00681984681984706*G0_4 - 0.02898434898435*G0_5 + 0.00681984681984706*G0_6 - 0.0358041958041971*G0_7 + 0.035804195804197*G0_8; + A[11] = A[165]; + A[32] = -A[1] - 2.16861327972451e-06*G0_0 - 2.16861327972489e-06*G0_1 + 0.00145507784396678*G0_2 - 0.000285039035039044*G0_3 + 0.000630434380434401*G0_4 - 0.000285039035039045*G0_5 + 0.000630434380434402*G0_6 - 1.18862618862626e-05*G0_7 - 1.18862618862626e-05*G0_8 + 0.000201465201465209*G0_9; + A[25] = A[10] + 0.000855934189267551*G0_0 - 0.000855934189267556*G0_1 - 0.000754523254523283*G0_3 + 0.000271117771117781*G0_4 + 0.00075452325452328*G0_5 - 0.00027111777111778*G0_6 + 0.00172577422577429*G0_7 - 0.00172577422577429*G0_8; + A[126] = A[7] + 0.00200196922419151*G0_0 + 0.000320903376458943*G0_1 + 0.00114603503492396*G0_2 - 0.000626780626780648*G0_3 + 0.000951363451363483*G0_4 + 0.00172864172864178*G0_5 + 2.86750286750386e-06*G0_6 + 0.00170588670588676*G0_7 - 0.000897898397898427*G0_8 + 0.00114496614496618*G0_9; + A[61] = A[7] + 0.000812798312798339*G0_0 - 0.00081279831279834*G0_1 - 0.000863580863580892*G0_3 + 0.000380175380175394*G0_4 + 0.000863580863580892*G0_5 - 0.000380175380175393*G0_6 + 0.000543623043623062*G0_7 - 0.000543623043623063*G0_8; + A[106] = 0.000152810152810158*G0_0 + 1.53550153550162e-05*G0_1 + 0.000152810152810158*G0_2 - 1.38750138750116e-06*G0_3 + 8.68575868575895e-05*G0_4 - 0.000177322677322683*G0_5 - 0.000177322677322683*G0_6 + 8.68575868575899e-05*G0_7 - 1.38750138750143e-06*G0_8 - 0.000243090243090251*G0_9; + A[174] = A[126] + 0.000868267534934237*G0_1 - 0.000868267534934231*G0_2 + 0.00206016206016213*G0_3 - 0.00206016206016213*G0_4 + 0.000568320568320592*G0_5 - 0.00149184149184154*G0_6 - 0.000568320568320587*G0_7 + 0.00149184149184155*G0_8; + A[15] = A[1]; + A[50] = A[126] - 0.000868267534934229*G0_0 + 0.000868267534934232*G0_1 + 0.00149184149184154*G0_3 - 0.000568320568320589*G0_4 - 0.00149184149184154*G0_5 + 0.000568320568320587*G0_6 - 0.00206016206016213*G0_7 + 0.00206016206016213*G0_8; + A[37] = A[107]; + A[160] = 0.000947200947200981*G0_0 + 0.000947200947200986*G0_1 + 0.00101380101380105*G0_2 + 0.00301365301365312*G0_3 - 0.00240093240093249*G0_4 + 0.00301365301365311*G0_5 - 0.00240093240093248*G0_6 + 0.00805527805527833*G0_7 + 0.00805527805527834*G0_8 + 0.00769230769230796*G0_9; + A[109] = -A[1] + 6.4277286499511e-05*G0_0 + 6.42772864995095e-05*G0_1 + 0.00118744424299984*G0_2 - 0.00117664742664747*G0_3 + 0.000946507196507229*G0_4 - 0.00117664742664747*G0_5 + 0.000946507196507227*G0_6 + 2.17375217375195e-06*G0_7 + 2.17375217375062e-06*G0_8 - 0.000674880674880696*G0_9; + A[222] = A[193] + 0.00179968179968186*G0_1 - 0.00179968179968186*G0_2 + 0.00255744255744266*G0_3 - 0.00255744255744265*G0_4 + 0.00681984681984704*G0_5 + 0.0042624042624044*G0_6 - 0.00681984681984707*G0_7 - 0.0042624042624044*G0_8; + A[184] = A[72]; + A[2] = A[1] + 8.16159149492515e-05*G0_1 - 8.16159149492512e-05*G0_2 + 5.52225552225575e-05*G0_3 - 5.52225552225574e-05*G0_4 - 6.66000666000676e-06*G0_5 - 6.18825618825642e-05*G0_6 + 6.66000666000684e-06*G0_7 + 6.18825618825645e-05*G0_8; + A[70] = -A[2] + 6.42772864995113e-05*G0_0 + 0.00118744424299984*G0_1 + 6.42772864995112e-05*G0_2 + 0.000946507196507232*G0_3 - 0.00117664742664747*G0_4 + 2.17375217375332e-06*G0_5 + 2.1737521737505e-06*G0_6 - 0.00117664742664747*G0_7 + 0.000946507196507233*G0_8 - 0.000674880674880695*G0_9; + A[154] = A[70]; + A[189] = A[186] + 3.15733649066988e-05*G0_1 - 3.15733649066991e-05*G0_2 - 0.000959040959040994*G0_3 + 0.000959040959040993*G0_4 - 0.00344544344544357*G0_5 + 0.00113664113664117*G0_6 + 0.00344544344544357*G0_7 - 0.00113664113664118*G0_8; + A[207] = A[193]; + A[146] = A[174]; + A[150] = A[10]; + A[178] = A[218] + 0.000410453743787097*G0_1 - 0.000410453743787091*G0_2 + 0.0103363303363307*G0_3 - 0.0103363303363307*G0_4 + 0.00259296259296268*G0_5 - 0.0113664113664118*G0_6 - 0.00259296259296268*G0_7 + 0.0113664113664118*G0_8; + A[220] = A[164]; + A[194] = A[222]; + A[19] = A[61]; + A[12] = 0.000434133767467116*G0_0 - 6.66000666000669e-06*G0_1 - 6.66000666000695e-06*G0_2 + 0.000350760350760363*G0_3 + 0.000350760350760363*G0_4 - 0.000410700410700425*G0_5 + 0.000275280275280285*G0_6 - 0.000410700410700426*G0_7 + 0.000275280275280285*G0_8 + 0.000559440559440578*G0_9; + A[33] = A[47]; + A[62] = A[10] + 0.00081279831279834*G0_0 - 0.00081279831279834*G0_2 + 0.000380175380175392*G0_3 - 0.000863580863580893*G0_4 + 0.000543623043623062*G0_5 - 0.000543623043623062*G0_6 + 0.000863580863580894*G0_7 - 0.000380175380175394*G0_8; + A[44] = A[212]; + A[78] = A[50]; + A[105] = A[7]; + A[98] = A[126]; + A[180] = A[12]; + A[118] = A[202]; + A[22] = A[106]; + A[34] = A[62]; + A[147] = A[189]; + A[67] = A[109]; + A[112] = A[160] + 6.66000666000616e-05*G0_1 - 6.66000666000708e-05*G0_2 - 0.0054145854145856*G0_3 + 0.00541458541458559*G0_4 + 0.0050416250416252*G0_5 + 0.0104562104562108*G0_6 - 0.00504162504162522*G0_7 - 0.0104562104562108*G0_8; + A[223] = A[193] + 0.00179968179968186*G0_0 - 0.00179968179968186*G0_2 + 0.00681984681984706*G0_3 + 0.00426240426240441*G0_4 + 0.00255744255744265*G0_5 - 0.00255744255744264*G0_6 - 0.00426240426240441*G0_7 - 0.00681984681984705*G0_8; + A[210] = A[14]; + A[17] = A[31]; + A[134] = A[218]; + A[121] = -A[108] - 0.000314500314500325*G0_0 - 9.20889809778621e-06*G0_1 - 0.000748551859662995*G0_2 + 0.000446590446590467*G0_3 - 0.000894290894290926*G0_4 + 0.00111333111333115*G0_5 - 0.000531690531690551*G0_6 + 3.33000333000323e-06*G0_7 + 1.11000111000312e-06*G0_8 + 0.000510600510600528*G0_9; + A[41] = A[121] - 0.0001172490061379*G0_1 + 0.000117249006137899*G0_2 - 0.000475080475080492*G0_3 + 0.000475080475080492*G0_4 - 0.000186480186480193*G0_5 + 0.000590520590520611*G0_6 + 0.000186480186480193*G0_7 - 0.000590520590520611*G0_8; + A[5] = A[121] + 6.65178442956242e-05*G0_0 - 6.65178442956246e-05*G0_1 - 8.14000814000851e-06*G0_3 - 0.000232360232360241*G0_4 + 8.14000814000827e-06*G0_5 + 0.00023236023236024*G0_6 + 7.77000777000803e-05*G0_7 - 7.77000777000806e-05*G0_8; + A[35] = -A[5] + 5.05667172333837e-06*G0_0 - 3.75755931311503e-05*G0_1 + 0.00110070998959891*G0_2 - 0.000512080512080529*G0_3 + 0.000492470492470508*G0_4 - 8.58400858400888e-05*G0_5 + 0.000210530210530218*G0_6 + 4.18100418100433e-05*G0_7 - 0.000234580234580243*G0_8 - 0.000557220557220577*G0_9; + A[135] = A[35] + 0.00121290232401348*G0_0 - 0.00121290232401347*G0_2 + 0.000463980463980479*G0_3 - 0.00104118104118108*G0_4 + 0.000771450771450797*G0_5 - 0.000771450771450798*G0_6 + 0.00104118104118108*G0_7 - 0.000463980463980481*G0_8; + A[26] = A[135] - 0.00118901674457234*G0_0 + 0.00118901674457235*G0_1 + 0.000725570725570753*G0_3 - 0.000244570244570254*G0_4 - 0.00072557072557075*G0_5 + 0.000244570244570253*G0_6 - 0.00170385170385177*G0_7 + 0.00170385170385177*G0_8; + A[122] = A[35] + 2.3885579441136e-05*G0_0 - 2.38855794411357e-05*G0_1 + 0.000418100418100432*G0_3 - 0.000514300514300531*G0_4 - 0.000418100418100432*G0_5 + 0.000514300514300532*G0_6 - 0.000198690198690206*G0_7 + 0.000198690198690206*G0_8; + A[90] = A[135] - 2.38855794411356e-05*G0_1 + 2.38855794411357e-05*G0_2 + 0.000198690198690206*G0_3 - 0.000198690198690206*G0_4 + 0.000514300514300531*G0_5 - 0.000418100418100432*G0_6 - 0.000514300514300533*G0_7 + 0.000418100418100433*G0_8; + A[46] = A[35] + 0.00118901674457234*G0_1 - 0.00118901674457234*G0_2 + 0.00170385170385176*G0_3 - 0.00170385170385176*G0_4 + 0.000244570244570253*G0_5 - 0.000725570725570751*G0_6 - 0.000244570244570254*G0_7 + 0.000725570725570753*G0_8; + A[76] = A[5] + 1.29500129500137e-05*G0_0 + 0.000442027108693791*G0_1 - 5.6733390066723e-06*G0_2 + 0.00036741036741038*G0_3 + 5.55000555000583e-05*G0_4 - 3.88500388500403e-05*G0_5 - 0.00011544011544012*G0_7 + 0.0001920301920302*G0_8 + 7.77000777000811e-05*G0_9; + A[20] = A[76]; + A[94] = -A[5] - 9.20889809778804e-06*G0_0 - 0.000314500314500326*G0_1 - 0.000748551859662997*G0_2 + 0.00111333111333115*G0_3 - 0.00053169053169055*G0_4 + 0.00044659044659046*G0_5 - 0.000894290894290925*G0_6 + 1.11000111000104e-06*G0_7 + 3.33000333000372e-06*G0_8 + 0.000510600510600526*G0_9; + A[117] = -A[94] - 0.00104340104340108*G0_0 + 2.46666913333567e-06*G0_1 - 0.00142869476202814*G0_2 - 0.00035520035520037*G0_3 + 0.00325452325452336*G0_4 - 0.000710400710400739*G0_5 + 0.00545676545676564*G0_6 - 0.0052214452214454*G0_7 + 0.000213120213120221*G0_8 + 0.00378288378288391*G0_9; + A[199] = A[117] + 0.00128464128464133*G0_0 - 0.00128464128464133*G0_1 + 0.00031968031968033*G0_3 + 0.0027972027972029*G0_4 - 0.00031968031968033*G0_5 - 0.00279720279720289*G0_6 + 0.00535464535464554*G0_7 - 0.00535464535464553*G0_8; + A[214] = A[199] + 0.00023680023680025*G0_1 - 0.000236800236800244*G0_2 + 0.00703296703296728*G0_3 - 0.00703296703296728*G0_4 + 0.00149184149184155*G0_5 - 0.0084182484182487*G0_6 - 0.00149184149184154*G0_7 + 0.0084182484182487*G0_8; + A[211] = A[94] + 7.64667431334168e-06*G0_0 - 4.93333826667491e-07*G0_1 + 0.000535020535020553*G0_2 - 0.000588300588300609*G0_3 - 0.000341880341880354*G0_4 - 0.000244200244200249*G0_5 - 0.000310800310800322*G0_6 + 0.000166500166500171*G0_8 - 0.00119880119880124*G0_9; + A[181] = A[211] - 9.4720094720098e-05*G0_0 + 9.47200947200979e-05*G0_2 - 0.000168720168720175*G0_3 + 0.000284160284160294*G0_4 - 0.000932400932400966*G0_5 + 0.000932400932400965*G0_6 - 0.000284160284160294*G0_7 + 0.000168720168720175*G0_8; + A[158] = A[181] - 0.000535020535020552*G0_0 + 4.93333826668332e-07*G0_1 - 7.64667431334095e-06*G0_2 - 0.000166500166500173*G0_3 + 0.000310800310800324*G0_5 + 0.000244200244200252*G0_6 + 0.000341880341880355*G0_7 + 0.000588300588300607*G0_8 + 0.00119880119880124*G0_9; + A[100] = -A[181] - 0.00152514152514158*G0_0 - 0.000590520590520612*G0_1 - 0.000359393692727038*G0_2 + 6.66000666000601e-06*G0_3 + 0.000239760239760249*G0_4 - 0.00524808524808543*G0_5 + 0.00177156177156183*G0_6 - 0.00296148296148306*G0_7 + 0.00153402153402158*G0_8 - 0.00274392274392284*G0_9; + A[163] = A[199] - 0.00104784104784108*G0_0 + 0.00104784104784108*G0_2 - 0.00418248418248433*G0_3 - 0.00586080586080606*G0_4 + 0.00455544455544471*G0_5 - 0.00455544455544471*G0_6 + 0.00586080586080606*G0_7 + 0.00418248418248432*G0_8; + A[205] = A[163]; + A[27] = A[181]; + A[153] = A[100] + 0.00108681442014779*G0_0 - 0.00108681442014779*G0_1 - 0.00416028416028431*G0_3 + 0.0014474414474415*G0_4 + 0.0041602841602843*G0_5 - 0.0014474414474415*G0_6 + 0.00379620379620393*G0_7 - 0.00379620379620393*G0_8; + A[110] = A[153] + 0.00107102773769445*G0_1 - 0.00107102773769444*G0_2 + 0.0060872460872463*G0_3 - 0.00608724608724629*G0_4 + 0.0013586413586414*G0_5 - 0.00291708291708301*G0_6 - 0.00135864135864141*G0_7 + 0.00291708291708303*G0_8; + A[142] = A[100] - 1.5786682453349e-05*G0_1 + 1.578668245335e-05*G0_2 + 0.000479520479520497*G0_3 - 0.000479520479520496*G0_4 + 0.00172272172272178*G0_5 - 0.000568320568320587*G0_6 - 0.00172272172272178*G0_7 + 0.000568320568320588*G0_8; + A[169] = A[153] - 1.57866824533492e-05*G0_0 + 1.57866824533502e-05*G0_2 + 0.00172272172272179*G0_3 - 0.000568320568320591*G0_4 + 0.000479520479520495*G0_5 - 0.000479520479520497*G0_6 + 0.000568320568320585*G0_7 - 0.00172272172272177*G0_8; + A[187] = A[117]; + A[8] = A[121] + 0.00044202710869379*G0_0 + 1.29500129500133e-05*G0_1 - 5.67333900667282e-06*G0_2 - 3.88500388500402e-05*G0_3 + 0.000367410367410379*G0_5 + 5.55000555000575e-05*G0_6 + 0.000192030192030198*G0_7 - 0.000115440115440119*G0_8 + 7.77000777000797e-05*G0_9; + A[71] = A[169]; + A[85] = -A[41] - 0.000314500314500325*G0_0 - 0.000748551859662998*G0_1 - 9.20889809778708e-06*G0_2 - 0.000894290894290928*G0_3 + 0.000446590446590465*G0_4 + 3.33000333000309e-06*G0_5 + 1.11000111000231e-06*G0_6 + 0.00111333111333115*G0_7 - 0.000531690531690552*G0_8 + 0.000510600510600527*G0_9; + A[170] = -A[85] + 4.58800458800478e-05*G0_0 + 0.000121031232142348*G0_1 + 0.000274129163018062*G0_2 + 0.000729640729640753*G0_3 - 0.000304880304880313*G0_4 - 0.000186480186480194*G0_5 + 5.32800532800563e-05*G0_6 - 8.88000888001007e-06*G0_7 + 0.00247308247308256*G0_8 + 0.00188256188256195*G0_9; + A[149] = -A[170] - 5.92000592000572e-06*G0_0 + 0.000263111374222496*G0_1 - 6.5777843555651e-07*G0_2 + 0.00160432160432166*G0_3 + 0.00108928108928113*G0_4 - 0.00227328227328235*G0_5 + 0.0013497613497614*G0_6 - 0.00440448440448456*G0_7 + 0.00371184371184384*G0_8 + 0.000923520923520952*G0_9; + A[86] = A[170]; + A[138] = A[170] - 1.05244549688995e-05*G0_0 + 1.05244549689e-05*G0_2 + 0.00114848114848119*G0_3 - 0.000378880378880394*G0_4 + 0.00031968031968033*G0_5 - 0.000319680319680331*G0_6 + 0.000378880378880388*G0_7 - 0.00114848114848118*G0_8; + A[103] = A[149] + 0.000205226871893546*G0_1 - 0.000205226871893545*G0_2 + 0.00138528138528143*G0_3 - 0.00138528138528143*G0_4 - 0.00138528138528143*G0_5 + 0.00138528138528144*G0_7; + A[57] = A[103] + 1.57866824533492e-05*G0_0 - 1.57866824533527e-05*G0_1 - 0.0051148851148853*G0_3 + 0.000959040959040994*G0_4 + 0.00511488511488528*G0_5 - 0.000959040959040992*G0_6 + 0.00330336330336341*G0_7 - 0.00330336330336342*G0_8; + A[195] = A[85] - 4.93333826668088e-07*G0_0 + 0.000535020535020554*G0_1 + 7.64667431334089e-06*G0_2 - 0.000310800310800321*G0_3 - 0.000244200244200255*G0_4 + 0.000166500166500173*G0_5 - 0.000588300588300608*G0_7 - 0.000341880341880353*G0_8 - 0.00119880119880124*G0_9; + A[129] = A[170] + 0.000458471569582695*G0_0 - 0.000458471569582698*G0_1 - 0.00153328153328159*G0_3 + 0.00068672068672071*G0_4 + 0.00153328153328158*G0_5 - 0.00068672068672071*G0_6 + 0.00342768342768354*G0_7 - 0.00342768342768354*G0_8; + A[101] = A[138] + 0.000468996024551595*G0_0 - 0.000468996024551598*G0_1 - 0.00236208236208245*G0_3 + 0.000745920745920774*G0_4 + 0.00236208236208244*G0_5 - 0.000745920745920771*G0_6 + 0.00190032190032197*G0_7 - 0.00190032190032197*G0_8; + A[201] = A[103]; + A[123] = A[170] - 0.000468996024551598*G0_1 + 0.000468996024551596*G0_2 - 0.00190032190032197*G0_3 + 0.00190032190032197*G0_4 - 0.000745920745920772*G0_5 + 0.00236208236208244*G0_6 + 0.000745920745920771*G0_7 - 0.00236208236208244*G0_8; + A[66] = A[94]; + A[137] = -A[158] - 0.000748551859662995*G0_0 - 0.000314500314500325*G0_1 - 9.20889809778745e-06*G0_2 + 3.33000333000208e-06*G0_3 + 1.11000111000247e-06*G0_4 - 0.000894290894290923*G0_5 + 0.000446590446590462*G0_6 - 0.000531690531690549*G0_7 + 0.00111333111333115*G0_8 + 0.000510600510600528*G0_9; + A[21] = A[137] + 6.65178442956245e-05*G0_1 - 6.65178442956242e-05*G0_2 + 7.77000777000808e-05*G0_3 - 7.77000777000803e-05*G0_4 - 0.000232360232360241*G0_5 - 8.14000814000813e-06*G0_6 + 0.00023236023236024*G0_7 + 8.140008140009e-06*G0_8; + A[36] = A[21] - 5.67333900667227e-06*G0_0 + 1.29500129500134e-05*G0_1 + 0.00044202710869379*G0_2 - 0.00011544011544012*G0_3 + 0.000192030192030199*G0_4 + 5.55000555000581e-05*G0_5 + 0.00036741036741038*G0_6 - 3.88500388500404e-05*G0_8 + 7.77000777000803e-05*G0_9; + A[99] = A[36] + 0.00210135543468884*G0_0 + 0.000526921638032768*G0_1 + 0.000164362386584615*G0_2 - 9.99000999001075e-06*G0_3 - 0.000239760239760249*G0_4 + 0.0051278351278353*G0_5 - 0.00247234247234256*G0_6 + 0.00495097495097512*G0_7 - 0.00207422207422215*G0_8 + 0.00321234321234332*G0_9; + A[125] = A[99] - 0.00143856143856149*G0_0 + 0.00143856143856149*G0_2 - 0.00187072187072193*G0_3 + 0.00471824471824488*G0_4 - 0.00658896658896681*G0_5 + 0.00658896658896682*G0_6 - 0.00471824471824488*G0_7 + 0.00187072187072194*G0_8; + A[83] = A[125]; + A[191] = -A[137] + 0.000119715675271235*G0_0 + 1.25800125800111e-05*G0_1 - 0.000141915697471258*G0_2 - 0.00208347208347216*G0_3 + 0.000871350871350902*G0_4 + 0.00324823324823336*G0_5 - 6.29000629000722e-06*G0_6 + 0.00141747141747147*G0_7 - 0.00257187257187266*G0_8 + 0.00040404040404042*G0_9; + A[132] = A[191] - 0.000221013554346894*G0_1 + 0.000221013554346894*G0_2 + 0.00287712287712298*G0_3 - 0.00287712287712298*G0_4 - 0.00159840159840165*G0_5 - 0.00255744255744265*G0_6 + 0.00159840159840165*G0_7 + 0.00255744255744265*G0_8; + A[188] = A[132]; + A[56] = A[99] - 0.00143856143856149*G0_0 + 0.00143856143856149*G0_1 + 0.00471824471824489*G0_3 - 0.00187072187072194*G0_4 - 0.00471824471824488*G0_5 + 0.00187072187072193*G0_6 - 0.00658896658896682*G0_7 + 0.00658896658896682*G0_8; + A[176] = A[56] + 0.000691325135769605*G0_0 + 0.00194702416924647*G0_1 + 0.000254560254560263*G0_2 - 0.000763680763680789*G0_4 + 0.000621600621600642*G0_5 - 0.000692640692640717*G0_6 - 0.00159248159248165*G0_7 + 0.00929440929440962*G0_8 + 0.00152736152736158*G0_9; + A[144] = A[176] + 0.00269426047203834*G0_0 - 0.00269426047203835*G0_1 - 0.00409664409664424*G0_3 + 0.00194176194176201*G0_4 + 0.00409664409664424*G0_5 - 0.00194176194176201*G0_6 + 0.0174758574758581*G0_7 - 0.0174758574758581*G0_8; + A[80] = A[144] - 0.00313102535324769*G0_0 + 0.00313102535324768*G0_2 - 0.00408480408480423*G0_3 + 0.0147052947052952*G0_4 - 0.0073526473526476*G0_5 + 0.00735264735264761*G0_6 - 0.0147052947052952*G0_7 + 0.00408480408480423*G0_8; + A[104] = A[132] - 0.000157866824533497*G0_0 + 0.000157866824533497*G0_2 - 0.00099456099456103*G0_3 + 0.0056121656121658*G0_4 - 0.00468864468864485*G0_5 + 0.00468864468864485*G0_6 - 0.0056121656121658*G0_7 + 0.000994560994561028*G0_8; + A[51] = -A[21] + 7.23556279111866e-06*G0_0 + 0.000124484568929018*G0_1 + 0.000249380249380258*G0_2 + 0.000480630480630498*G0_3 - 5.55000555000583e-06*G0_4 - 0.000109890109890115*G0_5 + 0.000180930180930188*G0_6 - 0.000197210197210205*G0_7 + 0.000277870277870288*G0_8 + 0.000261960261960271*G0_9; + A[216] = A[104]; + A[148] = A[191] - 0.000157866824533496*G0_0 + 0.000157866824533501*G0_1 + 0.00561216561216582*G0_3 - 0.000994560994561032*G0_4 - 0.0056121656121658*G0_5 + 0.000994560994561029*G0_6 - 0.00468864468864485*G0_7 + 0.00468864468864485*G0_8; + A[91] = A[21]; + A[82] = A[110]; + A[168] = A[56]; + A[213] = A[191] - 0.000378880378880391*G0_0 + 0.000378880378880392*G0_2 - 0.000674880674880697*G0_3 + 0.00113664113664118*G0_4 - 0.00372960372960386*G0_5 + 0.00372960372960386*G0_6 - 0.00113664113664118*G0_7 + 0.000674880674880699*G0_8; + A[204] = A[148]; + A[18] = A[46]; + A[133] = A[103] - 0.000189440189440196*G0_0 + 0.000189440189440196*G0_2 - 0.00042624042624044*G0_3 - 0.00234432234432242*G0_4 + 0.00468864468864485*G0_5 - 0.00468864468864485*G0_6 + 0.00234432234432242*G0_7 + 0.000426240426240442*G0_8; + A[68] = A[100] + 0.00107102773769444*G0_0 - 0.00107102773769444*G0_2 + 0.0013586413586414*G0_3 - 0.00291708291708302*G0_4 + 0.00608724608724629*G0_5 - 0.0060872460872463*G0_6 + 0.00291708291708302*G0_7 - 0.0013586413586414*G0_8; + A[45] = A[41] + 6.65178442956242e-05*G0_0 - 6.65178442956247e-05*G0_2 - 0.000232360232360242*G0_3 - 8.14000814000794e-06*G0_4 + 7.77000777000807e-05*G0_5 - 7.77000777000805e-05*G0_6 + 8.14000814000897e-06*G0_7 + 0.000232360232360239*G0_8; + A[139] = -A[45] - 9.20889809778784e-06*G0_0 - 0.000748551859662999*G0_1 - 0.000314500314500326*G0_2 - 0.000531690531690554*G0_3 + 0.00111333111333115*G0_4 + 1.11000111000085e-06*G0_5 + 3.33000333000387e-06*G0_6 + 0.000446590446590464*G0_7 - 0.000894290894290928*G0_8 + 0.000510600510600526*G0_9; + A[38] = A[122]; + A[143] = A[129]; + A[120] = A[8]; + A[88] = A[132] - 0.000378880378880391*G0_0 + 0.000378880378880395*G0_1 + 0.00113664113664118*G0_3 - 0.000674880674880697*G0_4 - 0.00113664113664117*G0_5 + 0.000674880674880701*G0_6 - 0.00372960372960385*G0_7 + 0.00372960372960386*G0_8; + A[92] = A[36]; + A[179] = A[57] - 0.000205226871893545*G0_0 + 0.000205226871893546*G0_2 + 0.00138528138528144*G0_3 - 0.00138528138528143*G0_5 + 0.00138528138528144*G0_6 - 0.00138528138528143*G0_8; + A[116] = -A[21] - 0.000748551859662996*G0_0 - 9.2088980977867e-06*G0_1 - 0.000314500314500325*G0_2 + 1.1100011100031e-06*G0_3 + 3.33000333000278e-06*G0_4 - 0.00053169053169055*G0_5 + 0.00111333111333115*G0_6 - 0.000894290894290925*G0_7 + 0.000446590446590464*G0_8 + 0.000510600510600529*G0_9; + A[42] = A[116] + 0.000535020535020553*G0_0 + 7.64667431334076e-06*G0_1 - 4.93333826667844e-07*G0_2 + 0.000166500166500173*G0_4 - 0.000341880341880354*G0_5 - 0.000588300588300608*G0_6 - 0.000310800310800322*G0_7 - 0.000244200244200254*G0_8 - 0.00119880119880124*G0_9; + A[182] = A[42]; + A[219] = A[149]; + A[55] = A[153]; + A[29] = A[211]; + A[130] = A[158]; + A[73] = A[199]; + A[43] = A[139] + 7.64667431334152e-06*G0_0 + 0.000535020535020554*G0_1 - 4.93333826666732e-07*G0_2 - 0.000341880341880353*G0_3 - 0.00058830058830061*G0_4 + 0.000166500166500172*G0_6 - 0.000244200244200254*G0_7 - 0.00031080031080032*G0_8 - 0.00119880119880124*G0_9; + A[97] = -A[43] - 0.00229868896535571*G0_0 - 0.000531567198233883*G0_1 - 0.00118794785461456*G0_2 + 0.000457320457320472*G0_3 - 0.00102786102786106*G0_4 - 0.00275724275724284*G0_5 - 6.66000666000563e-06*G0_6 - 0.00259296259296268*G0_7 + 0.000550560550560569*G0_8 - 0.00330336330336341*G0_9; + A[111] = A[97]; + A[113] = A[97] + 0.00135765469098807*G0_0 - 0.00135765469098807*G0_2 + 0.000657120657120678*G0_3 - 0.00123432123432127*G0_4 + 0.00250416250416258*G0_5 - 0.00250416250416258*G0_6 + 0.00123432123432128*G0_7 - 0.00065712065712068*G0_8; + A[65] = A[113] + 0.000504187170853852*G0_0 - 0.000504187170853855*G0_1 - 0.00165168165168171*G0_3 - 7.99200799200812e-05*G0_4 + 0.00165168165168171*G0_5 + 7.99200799200769e-05*G0_6 + 0.00218448218448226*G0_7 - 0.00218448218448226*G0_8; + A[175] = A[113] - 0.00186184186184194*G0_1 + 0.00186184186184192*G0_2 - 0.00407592407592422*G0_3 + 0.00407592407592421*G0_4 - 0.00118992118992123*G0_5 + 0.00349872349872361*G0_6 + 0.00118992118992123*G0_7 - 0.00349872349872363*G0_8; + A[159] = A[97] - 0.000504187170853859*G0_1 + 0.000504187170853854*G0_2 - 0.00218448218448226*G0_3 + 0.00218448218448226*G0_4 + 7.99200799200756e-05*G0_5 + 0.00165168165168171*G0_6 - 7.99200799200821e-05*G0_7 - 0.00165168165168171*G0_8; + A[79] = A[65]; + A[75] = A[5]; + A[183] = A[57]; + A[119] = A[117] + 0.000236800236800247*G0_0 - 0.000236800236800246*G0_2 + 0.00149184149184154*G0_3 - 0.00841824841824869*G0_4 + 0.00703296703296726*G0_5 - 0.00703296703296726*G0_6 + 0.0084182484182487*G0_7 - 0.00149184149184154*G0_8; + A[197] = A[43]; + A[54] = A[138]; + A[24] = A[137] - 5.6733390066726e-06*G0_0 + 0.000442027108693792*G0_1 + 1.29500129500138e-05*G0_2 + 0.0001920301920302*G0_3 - 0.00011544011544012*G0_4 - 3.88500388500402e-05*G0_6 + 5.5500055500056e-05*G0_7 + 0.000367410367410383*G0_8 + 7.77000777000807e-05*G0_9; + A[127] = A[113]; + A[141] = A[99]; + A[95] = A[138] - 0.000458471569582699*G0_1 + 0.000458471569582696*G0_2 - 0.00342768342768355*G0_3 + 0.00342768342768355*G0_4 - 0.000686720686720709*G0_5 + 0.00153328153328159*G0_6 + 0.000686720686720714*G0_7 - 0.00153328153328159*G0_8; + A[172] = A[116]; + A[155] = A[85]; + A[173] = -A[121] + 0.000249380249380258*G0_0 + 0.000124484568929018*G0_1 + 7.23556279111858e-06*G0_2 + 0.000277870277870288*G0_3 - 0.000197210197210204*G0_4 + 0.000180930180930186*G0_5 - 0.000109890109890112*G0_6 - 5.55000555000649e-06*G0_7 + 0.000480630480630498*G0_8 + 0.000261960261960271*G0_9; + A[217] = A[119]; + A[200] = A[88]; + A[6] = A[90]; + A[9] = A[135]; + A[49] = A[97] + 0.00186184186184192*G0_0 - 0.00186184186184193*G0_1 - 0.00349872349872361*G0_3 + 0.00118992118992123*G0_4 + 0.00349872349872361*G0_5 - 0.00118992118992123*G0_6 + 0.00407592407592422*G0_7 - 0.00407592407592422*G0_8; + A[124] = A[68]; + A[84] = -A[5] + 0.000124484568929017*G0_0 + 0.000249380249380258*G0_1 + 7.23556279111798e-06*G0_2 + 0.000180930180930188*G0_3 - 0.000109890109890115*G0_4 + 0.000277870277870287*G0_5 - 0.000197210197210205*G0_6 + 0.000480630480630496*G0_7 - 5.55000555000456e-06*G0_8 + 0.000261960261960271*G0_9; + A[161] = A[175]; + A[136] = A[24]; + A[96] = A[144] - 0.000436764881209342*G0_1 + 0.000436764881209341*G0_2 - 0.00131424131424136*G0_3 + 0.00131424131424136*G0_4 + 0.00929440929440961*G0_5 - 0.000828800828800855*G0_6 - 0.00929440929440962*G0_7 + 0.000828800828800858*G0_8; + A[81] = A[95]; + A[167] = A[41]; + A[156] = A[100]; + A[185] = A[133] + 0.000205226871893545*G0_0 - 0.000205226871893547*G0_1 - 0.00138528138528144*G0_4 + 0.00138528138528143*G0_6 + 0.00138528138528143*G0_7 - 0.00138528138528143*G0_8; + A[203] = A[133]; + A[3] = A[45]; + A[59] = A[213]; + A[69] = A[139]; + A[48] = A[176] - 0.000436764881209341*G0_0 + 0.000436764881209341*G0_2 + 0.00929440929440961*G0_3 - 0.000828800828800855*G0_4 - 0.00131424131424136*G0_5 + 0.00131424131424136*G0_6 + 0.000828800828800857*G0_7 - 0.00929440929440962*G0_8; + A[39] = A[137]; + A[87] = A[185]; + A[64] = A[160] + 6.66000666000683e-05*G0_0 - 6.66000666000708e-05*G0_2 + 0.00504162504162521*G0_3 + 0.0104562104562108*G0_4 - 0.0054145854145856*G0_5 + 0.0054145854145856*G0_6 - 0.0104562104562108*G0_7 - 0.00504162504162522*G0_8; + A[162] = A[117] - 0.00104784104784108*G0_1 + 0.00104784104784108*G0_2 + 0.00455544455544472*G0_3 - 0.00455544455544471*G0_4 - 0.00418248418248432*G0_5 - 0.00586080586080606*G0_6 + 0.00418248418248432*G0_7 + 0.00586080586080606*G0_8; + A[93] = A[51]; + A[166] = A[26]; + A[115] = A[157]; + A[224] = A[192] + 0.00435712435712451*G0_0 - 0.0043571243571245*G0_2 - 0.00681984681984705*G0_3 + 0.02898434898435*G0_4 - 0.035804195804197*G0_5 + 0.035804195804197*G0_6 - 0.02898434898435*G0_7 + 0.00681984681984706*G0_8; + A[190] = A[162]; + A[206] = A[178]; + A[0] = -A[1] + 0.00137346192901753*G0_0 - 2.16861327972469e-06*G0_1 + 7.94473016695266e-05*G0_2 - 5.22625522625569e-06*G0_3 + 4.99962999963018e-05*G0_4 + 0.000575211825211844*G0_5 - 0.000229816479816488*G0_6 + 0.000568551818551838*G0_7 - 0.000291699041699052*G0_8 + 0.000201465201465208*G0_9; + A[58] = A[198]; + A[28] = -6.66000666000649e-06*G0_0 + 0.000434133767467118*G0_1 - 6.66000666000658e-06*G0_2 - 0.000410700410700422*G0_3 + 0.000275280275280284*G0_4 + 0.000350760350760362*G0_5 + 0.000350760350760362*G0_6 + 0.000275280275280283*G0_7 - 0.000410700410700422*G0_8 + 0.000559440559440581*G0_9; + A[131] = A[173]; + A[74] = A[214]; + A[40] = 0.000152810152810158*G0_0 + 0.000152810152810158*G0_1 + 1.5355015355016e-05*G0_2 + 8.68575868575904e-05*G0_3 - 1.38750138750168e-06*G0_4 + 8.68575868575898e-05*G0_5 - 1.38750138750153e-06*G0_6 - 0.000177322677322684*G0_7 - 0.000177322677322683*G0_8 - 0.000243090243090251*G0_9; + A[145] = A[159]; + A[151] = A[25]; + A[102] = A[186]; + A[177] = A[191]; + A[114] = A[142]; + A[221] = A[179]; + A[196] = A[28]; + A[209] = A[223]; + A[13] = A[195]; + A[53] = A[123]; + A[30] = A[2]; + A[23] = A[121]; + A[128] = A[176] - 0.0031310253532477*G0_1 + 0.00313102535324768*G0_2 - 0.00735264735264761*G0_3 + 0.00735264735264761*G0_4 - 0.00408480408480423*G0_5 + 0.0147052947052952*G0_6 + 0.00408480408480423*G0_7 - 0.0147052947052952*G0_8; + A[63] = A[49]; + A[140] = A[84]; + A[77] = A[35]; + A[171] = A[101]; + A[152] = A[40]; + } + + /// 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 mass_matrix_f1_p3_q4_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f1_p3_q4_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f1_p3_q4_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 1))), 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 mass_matrix_f1_p3_q4_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p3_q4_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p3_q4_tensor_finite_element_0(); + 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 mass_matrix_f1_p3_q4_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f1_p3_q4_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f1_p3_q4_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f2_p1_q1_excafe.h b/mass_matrix_2d/mass_matrix_f2_p1_q1_excafe.h new file mode 100644 index 0000000..ecca412 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p1_q1_excafe.h @@ -0,0 +1,69 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 0.07 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][2]*w[1][2]; + const double var_1 = w[0][0]*w[1][0]; + const double var_2 = var_1 + var_0; + const double var_3 = w[0][1]*w[1][2] + w[0][2]*w[1][1]; + const double var_4 = w[0][1]*w[1][0] + w[0][0]*w[1][1]; + const double var_5 = var_3 + var_4; + const double var_6 = w[0][1]*w[1][1]; + const double var_7 = var_6 + var_5; + const double var_8 = 0.3333333333333333148296163*var_7 + var_2; + const double var_9 = -1.0000000000000000000000000*x[0][0]; + const double var_10 = x[1][0] + var_9; + const double var_11 = w[0][2]*w[1][0] + w[0][0]*w[1][2]; + const double var_12 = var_11 + var_3; + const double var_13 = var_0 + var_12; + const double var_14 = -1.0000000000000000000000000*x[0][1]; + const double var_15 = var_6 + var_0; + const double var_16 = x[1][1] + var_14; + const double var_17 = x[2][0] + var_9; + const double var_18 = x[2][1] + var_14; + const double var_19 = var_10*var_18 + -1.0000000000000000000000000*var_16*var_17; + const double var_20 = std::abs(var_19); + A[2] = 0.0083333333333333332176851*var_20*var_8 + 0.0055555555555555557675773*var_11*var_20; + A[6] = A[2]; + const double var_21 = var_11 + var_4; + const double var_22 = var_21 + var_1; + const double var_23 = var_6 + var_1; + const double var_24 = 0.1666666666666666574148081*var_23 + 0.0833333333333333287074041*var_4 + var_0 + 0.2500000000000000000000000*var_12; + const double var_25 = 0.2500000000000000000000000*var_21 + 0.1666666666666666574148081*var_15 + var_1 + 0.0833333333333333287074041*var_3; + A[0] = 0.0333333333333333328707404*var_20*var_25; + A[8] = 0.0333333333333333328707404*var_20*var_24; + const double var_26 = 0.5000000000000000000000000*var_13 + var_4; + A[1] = 0.0055555555555555557675773*var_20*var_26 + 0.0083333333333333332176851*var_20*var_23; + A[3] = A[1]; + const double var_27 = var_6 + 0.2500000000000000000000000*var_5 + 0.0833333333333333287074041*var_11 + 0.1666666666666666574148081*var_2; + A[4] = 0.0333333333333333328707404*var_20*var_27; + const double var_28 = var_15 + 0.3333333333333333148296163*var_22; + A[5] = 0.0055555555555555557675773*var_20*var_3 + 0.0083333333333333332176851*var_20*var_28; + A[7] = A[5]; + } + + 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/mass_matrix_2d/mass_matrix_f2_p1_q1_quadrature.h b/mass_matrix_2d/mass_matrix_f2_p1_q1_quadrature.h new file mode 100644 index 0000000..80e668e --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p1_q1_quadrature.h @@ -0,0 +1,1451 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P1_Q1_QUADRATURE_H +#define __MASS_MATRIX_F2_P1_Q1_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p1_q1_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p1_q1_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f2_p1_q1_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p1_q1_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p1_q1_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f2_p1_q1_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class mass_matrix_f2_p1_q1_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p1_q1_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // 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[6][3] = \ + {{0.09157621350977, 0.816847572980459, 0.091576213509771}, + {0.09157621350977, 0.0915762135097711, 0.816847572980459}, + {0.816847572980458, 0.091576213509771, 0.091576213509771}, + {0.445948490915965, 0.10810301816807, 0.445948490915965}, + {0.445948490915965, 0.445948490915965, 0.10810301816807}, + {0.10810301816807, 0.445948490915965, 0.445948490915965}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 9; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 252 + for (unsigned int ip = 0; ip < 6; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + + // Total number of operations to compute function values = 12 + for (unsigned int r = 0; r < 3; r++) + { + F0 += FE0[ip][r]*w[0][r]; + F1 += FE0[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 3 + double I[1]; + // Number of operations: 3 + I[0] = F0*F1*W6[ip]*det; + + + // Number of operations for primary indices: 27 + for (unsigned int j = 0; j < 3; j++) + { + for (unsigned int k = 0; k < 3; k++) + { + // Number of operations to compute entry: 3 + A[j*3 + k] += FE0[ip][j]*FE0[ip][k]*I[0]; + }// 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 mass_matrix_f2_p1_q1_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p1_q1_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p1_q1_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1))), 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 mass_matrix_f2_p1_q1_quadrature_finite_element_0(); + break; + } + case 1: + { + return new mass_matrix_f2_p1_q1_quadrature_finite_element_0(); + break; + } + case 2: + { + return new mass_matrix_f2_p1_q1_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p1_q1_quadrature_finite_element_0(); + 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 mass_matrix_f2_p1_q1_quadrature_dofmap_0(); + break; + } + case 1: + { + return new mass_matrix_f2_p1_q1_quadrature_dofmap_0(); + break; + } + case 2: + { + return new mass_matrix_f2_p1_q1_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p1_q1_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f2_p1_q1_tensor.h b/mass_matrix_2d/mass_matrix_f2_p1_q1_tensor.h new file mode 100644 index 0000000..4206919 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p1_q1_tensor.h @@ -0,0 +1,1418 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P1_Q1_TENSOR_H +#define __MASS_MATRIX_F2_P1_Q1_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p1_q1_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p1_q1_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f2_p1_q1_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p1_q1_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p1_q1_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f2_p1_q1_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class mass_matrix_f2_p1_q1_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p1_q1_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 13 + // Number of operations (multiply-add pairs) for tensor contraction: 39 + // Total number of operations (multiply-add pairs): 61 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0 = det*w[0][0]*w[1][0]*(1.0); + const double G0_0_1 = det*w[0][0]*w[1][1]*(1.0); + const double G0_0_2 = det*w[0][0]*w[1][2]*(1.0); + const double G0_1_0 = det*w[0][1]*w[1][0]*(1.0); + const double G0_1_1 = det*w[0][1]*w[1][1]*(1.0); + const double G0_1_2 = det*w[0][1]*w[1][2]*(1.0); + const double G0_2_0 = det*w[0][2]*w[1][0]*(1.0); + const double G0_2_1 = det*w[0][2]*w[1][1]*(1.0); + const double G0_2_2 = det*w[0][2]*w[1][2]*(1.0); + + // Compute element tensor + A[1] = 0.00833333333333333*G0_0_0 + 0.00555555555555555*G0_0_1 + 0.00277777777777777*G0_0_2 + 0.00555555555555555*G0_1_0 + 0.00833333333333331*G0_1_1 + 0.00277777777777777*G0_1_2 + 0.00277777777777777*G0_2_0 + 0.00277777777777777*G0_2_1 + 0.00277777777777777*G0_2_2; + A[5] = A[1] - 0.00555555555555556*G0_0_0 - 0.00277777777777778*G0_0_1 - 0.00277777777777778*G0_1_0 + 0.00277777777777779*G0_1_2 + 0.00277777777777779*G0_2_1 + 0.00555555555555558*G0_2_2; + A[0] = A[1] + 0.025*G0_0_0 + 0.00277777777777779*G0_0_1 + 0.00555555555555556*G0_0_2 + 0.00277777777777779*G0_1_0 - 0.00277777777777777*G0_1_1 + 0.00555555555555556*G0_2_0 + 0.00277777777777778*G0_2_2; + A[7] = A[5]; + A[6] = A[1] - 0.00277777777777777*G0_0_1 + 0.00277777777777778*G0_0_2 - 0.00277777777777777*G0_1_0 - 0.00555555555555554*G0_1_1 + 0.00277777777777778*G0_2_0 + 0.00555555555555554*G0_2_2; + A[2] = A[6]; + A[8] = A[0] - 0.0277777777777778*G0_0_0 - 0.00555555555555556*G0_0_1 - 0.00555555555555556*G0_1_0 + 0.00555555555555557*G0_1_2 + 0.00555555555555557*G0_2_1 + 0.0277777777777779*G0_2_2; + A[3] = A[1]; + A[4] = A[0] - 0.0277777777777778*G0_0_0 - 0.00555555555555556*G0_0_2 + 0.0277777777777779*G0_1_1 + 0.00555555555555557*G0_1_2 - 0.00555555555555556*G0_2_0 + 0.00555555555555557*G0_2_1; + } + + /// 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 mass_matrix_f2_p1_q1_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p1_q1_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p1_q1_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1))), 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 mass_matrix_f2_p1_q1_tensor_finite_element_0(); + break; + } + case 1: + { + return new mass_matrix_f2_p1_q1_tensor_finite_element_0(); + break; + } + case 2: + { + return new mass_matrix_f2_p1_q1_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p1_q1_tensor_finite_element_0(); + 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 mass_matrix_f2_p1_q1_tensor_dofmap_0(); + break; + } + case 1: + { + return new mass_matrix_f2_p1_q1_tensor_dofmap_0(); + break; + } + case 2: + { + return new mass_matrix_f2_p1_q1_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p1_q1_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f2_p1_q2_excafe.h b/mass_matrix_2d/mass_matrix_f2_p1_q2_excafe.h new file mode 100644 index 0000000..2adb28a --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p1_q2_excafe.h @@ -0,0 +1,123 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 0.43 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 = -1.0000000000000000000000000*x[0][1]; + const double var_1 = x[1][1] + var_0; + const double var_2 = -1.0000000000000000000000000*x[0][0]; + const double var_3 = x[2][0] + var_2; + const double var_4 = var_0 + x[2][1]; + const double var_5 = x[1][0] + var_2; + const double var_6 = var_4*var_5 + -1.0000000000000000000000000*var_1*var_3; + const double var_7 = std::abs(var_6); + const double var_8 = w[0][1]*w[1][0] + w[0][0]*w[1][1]; + const double var_9 = w[0][1]*w[1][2] + w[0][2]*w[1][1]; + const double var_10 = var_8 + var_9; + const double var_11 = w[0][1]*w[1][1]; + const double var_12 = w[0][2]*w[1][0] + w[0][0]*w[1][2]; + const double var_13 = w[0][0]*w[1][0]; + const double var_14 = w[0][2]*w[1][2]; + const double var_15 = var_14 + var_13; + const double var_16 = 0.5000000000000000000000000*var_15 + 0.3333333333333333148296163*var_12; + const double var_17 = 0.5000000000000000000000000*var_10 + var_16 + var_11; + A[23] = 0.0095238095238095246686250*var_17*var_7; + A[33] = A[23]; + const double var_18 = var_14 + var_11; + const double var_19 = 0.3333333333333333148296163*var_9 + 0.5000000000000000000000000*var_18; + const double var_20 = var_8 + var_12; + const double var_21 = 0.1666666666666666574148081*var_20; + const double var_22 = var_19 + var_21; + A[3] = -0.0047619047619047623343125*var_22*var_7; + A[18] = A[3]; + const double var_23 = -1.0000000000000000000000000*var_8 + var_14; + const double var_24 = -0.1666666666666666574148081*var_8 + var_14; + const double var_25 = 0.0047619047619047623343125*var_24*var_7; + const double var_26 = -0.0023809523809523811671562*var_13*var_7; + const double var_27 = -0.0007936507936507936501053*var_11*var_7; + A[16] = var_25 + var_26 + var_27; + A[26] = A[16]; + const double var_28 = 0.1666666666666666574148081*var_10; + const double var_29 = var_28 + 0.6666666666666666296592325*var_15 + 0.1111111111111111049432054*w[0][1]*w[1][1] + 0.5000000000000000000000000*var_12; + A[28] = 0.0285714285714285705364279*var_29*var_7; + const double var_30 = var_11 + var_13; + const double var_31 = 0.3333333333333333148296163*var_23 + -1.0000000000000000000000000*var_30; + A[1] = 0.0011904761904761905835781*var_31*var_7; + A[6] = A[1]; + const double var_32 = -0.1666666666666666574148081*var_9 + var_13; + const double var_33 = 0.0047619047619047623343125*var_32*var_7; + const double var_34 = 0.0833333333333333287074041*var_15 + 0.1250000000000000000000000*var_10 + 0.0416666666666666643537020*var_12 + var_11; + const double var_35 = -0.0023809523809523811671562*var_11*var_7; + const double var_36 = -0.0007936507936507936501053*var_14*var_7; + A[5] = var_33 + var_35 + var_36; + const double var_37 = 0.3333333333333333148296163*var_8 + 0.5000000000000000000000000*var_30; + const double var_38 = var_12 + var_9; + const double var_39 = 0.1666666666666666574148081*var_38; + const double var_40 = var_37 + var_39; + A[17] = -0.0047619047619047623343125*var_40*var_7; + A[32] = A[17]; + A[7] = 0.0095238095238095246686250*var_34*var_7; + const double var_41 = 0.5000000000000000000000000*var_8 + 0.1111111111111111049432054*w[0][2]*w[1][2] + 0.6666666666666666296592325*var_30 + var_39; + A[35] = 0.0285714285714285705364279*var_41*var_7; + const double var_42 = var_28 + var_16; + const double var_43 = -0.0023809523809523811671562*var_14*var_7; + const double var_44 = 0.0416666666666666643537020*var_9 + var_13 + 0.0833333333333333287074041*var_18 + 0.1250000000000000000000000*var_20; + A[0] = 0.0095238095238095246686250*var_44*var_7; + A[30] = A[5]; + const double var_45 = -0.1666666666666666574148081*var_12 + var_11; + const double var_46 = 0.0047619047619047623343125*var_45*var_7; + A[11] = var_46 + var_26 + var_36; + const double var_47 = 0.5000000000000000000000000*var_38 + var_37 + var_14; + A[22] = 0.0095238095238095246686250*var_47*var_7; + const double var_48 = -1.0000000000000000000000000*var_9 + var_13; + const double var_49 = 0.3333333333333333148296163*var_48 + -1.0000000000000000000000000*var_18; + const double var_50 = -0.0007936507936507936501053*var_13*var_7; + A[15] = var_50 + var_25 + var_35; + A[20] = A[15]; + const double var_51 = 0.1111111111111111049432054*w[0][0]*w[1][0] + 0.5000000000000000000000000*var_9 + var_21 + 0.6666666666666666296592325*var_18; + A[21] = 0.0285714285714285705364279*var_51*var_7; + const double var_52 = var_19 + 0.5000000000000000000000000*var_20 + var_13; + A[29] = 0.0095238095238095246686250*var_52*var_7; + A[34] = A[29]; + const double var_53 = -1.0000000000000000000000000*var_12 + var_11; + const double var_54 = -1.0000000000000000000000000*var_15 + 0.3333333333333333148296163*var_53; + A[9] = var_50 + var_46 + var_43; + const double var_55 = 0.0416666666666666643537020*var_8 + 0.1250000000000000000000000*var_38 + var_14 + 0.0833333333333333287074041*var_30; + A[4] = var_33 + var_27 + var_43; + A[8] = 0.0011904761904761905835781*var_49*var_7; + A[24] = A[4]; + A[31] = A[11]; + A[10] = -0.0047619047619047623343125*var_42*var_7; + A[2] = 0.0011904761904761905835781*var_54*var_7; + A[13] = A[8]; + A[19] = A[9]; + A[14] = 0.0095238095238095246686250*var_55*var_7; + A[27] = A[22]; + A[12] = A[2]; + A[25] = A[10]; + } + + 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/mass_matrix_2d/mass_matrix_f2_p1_q2_quadrature.h b/mass_matrix_2d/mass_matrix_f2_p1_q2_quadrature.h new file mode 100644 index 0000000..f463d83 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p1_q2_quadrature.h @@ -0,0 +1,3379 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P1_Q2_QUADRATURE_H +#define __MASS_MATRIX_F2_P1_Q2_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p1_q2_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p1_q2_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f2_p1_q2_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p1_q2_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p1_q2_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p1_q2_quadrature_finite_element_1() + { + // 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p1_q2_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p1_q2_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p1_q2_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f2_p1_q2_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p1_q2_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p1_q2_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_p1_q2_quadrature_dofmap_1() + { + // 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 mass_matrix_f2_p1_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 mass_matrix_f2_p1_q2_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p1_q2_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // 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[12][3] = \ + {{0.063089014491502, 0.873821971016996, 0.063089014491502}, + {0.063089014491502, 0.0630890144915021, 0.873821971016996}, + {0.873821971016996, 0.0630890144915021, 0.063089014491502}, + {0.249286745170911, 0.501426509658179, 0.24928674517091}, + {0.249286745170911, 0.24928674517091, 0.501426509658179}, + {0.50142650965818, 0.24928674517091, 0.24928674517091}, + {0.0531450498448159, 0.636502499121399, 0.310352451033785}, + {0.310352451033785, 0.636502499121399, 0.053145049844816}, + {0.053145049844816, 0.310352451033785, 0.636502499121399}, + {0.636502499121399, 0.310352451033785, 0.053145049844816}, + {0.310352451033785, 0.0531450498448161, 0.636502499121399}, + {0.636502499121399, 0.053145049844816, 0.310352451033785}}; + + static const double FE1[12][6] = \ + {{-0.0551285669924842, 0.65330770304706, -0.0551285669924841, 0.220514267969936, 0.0159208949980358, 0.220514267969937}, + {-0.0551285669924841, -0.055128566992484, 0.65330770304706, 0.220514267969936, 0.220514267969936, 0.0159208949980359}, + {0.653307703047059, -0.0551285669924842, -0.0551285669924842, 0.0159208949980359, 0.220514267969937, 0.220514267969937}, + {-0.124998982535098, 0.00143057951778881, -0.124998982535098, 0.499995930140389, 0.248575525271626, 0.499995930140391}, + {-0.124998982535098, -0.124998982535098, 0.00143057951778877, 0.499995930140389, 0.499995930140391, 0.248575525271626}, + {0.00143057951778977, -0.124998982535098, -0.124998982535098, 0.248575525271625, 0.49999593014039, 0.49999593014039}, + {-0.0474962571988001, 0.173768363654174, -0.117715163308429, 0.790160442765823, 0.0659747859186054, 0.135307828168627}, + {-0.117715163308429, 0.173768363654174, -0.0474962571988, 0.135307828168627, 0.0659747859186052, 0.790160442765823}, + {-0.0474962571988, -0.117715163308429, 0.173768363654174, 0.790160442765823, 0.135307828168627, 0.0659747859186053}, + {0.173768363654174, -0.117715163308429, -0.0474962571988, 0.0659747859186053, 0.135307828168627, 0.790160442765823}, + {-0.117715163308429, -0.0474962571988, 0.173768363654174, 0.135307828168627, 0.790160442765823, 0.0659747859186053}, + {0.173768363654174, -0.0474962571988001, -0.117715163308429, 0.0659747859186055, 0.790160442765823, 0.135307828168627}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 36; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 1476 + for (unsigned int ip = 0; ip < 12; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + + // Total number of operations to compute function values = 12 + for (unsigned int r = 0; r < 3; r++) + { + F0 += FE0[ip][r]*w[0][r]; + F1 += FE0[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 3 + double I[1]; + // Number of operations: 3 + I[0] = F0*F1*W12[ip]*det; + + + // Number of operations for primary indices: 108 + for (unsigned int j = 0; j < 6; j++) + { + for (unsigned int k = 0; k < 6; k++) + { + // Number of operations to compute entry: 3 + A[j*6 + k] += FE1[ip][j]*FE1[ip][k]*I[0]; + }// 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 mass_matrix_f2_p1_q2_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p1_q2_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p1_q2_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1))), 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 mass_matrix_f2_p1_q2_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p1_q2_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p1_q2_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p1_q2_quadrature_finite_element_0(); + 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 mass_matrix_f2_p1_q2_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p1_q2_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p1_q2_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p1_q2_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f2_p1_q2_tensor.h b/mass_matrix_2d/mass_matrix_f2_p1_q2_tensor.h new file mode 100644 index 0000000..6b58515 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p1_q2_tensor.h @@ -0,0 +1,3353 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P1_Q2_TENSOR_H +#define __MASS_MATRIX_F2_P1_Q2_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p1_q2_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p1_q2_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f2_p1_q2_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p1_q2_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p1_q2_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p1_q2_tensor_finite_element_1() + { + // 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p1_q2_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p1_q2_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p1_q2_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f2_p1_q2_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p1_q2_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p1_q2_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_p1_q2_tensor_dofmap_1() + { + // 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 mass_matrix_f2_p1_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 mass_matrix_f2_p1_q2_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p1_q2_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 13 + // Number of operations (multiply-add pairs) for tensor contraction: 105 + // Total number of operations (multiply-add pairs): 127 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0 = det*w[0][0]*w[1][0]*(1.0); + const double G0_0_1 = det*w[0][0]*w[1][1]*(1.0); + const double G0_0_2 = det*w[0][0]*w[1][2]*(1.0); + const double G0_1_0 = det*w[0][1]*w[1][0]*(1.0); + const double G0_1_1 = det*w[0][1]*w[1][1]*(1.0); + const double G0_1_2 = det*w[0][1]*w[1][2]*(1.0); + const double G0_2_0 = det*w[0][2]*w[1][0]*(1.0); + const double G0_2_1 = det*w[0][2]*w[1][1]*(1.0); + const double G0_2_2 = det*w[0][2]*w[1][2]*(1.0); + + // Compute element tensor + A[9] = -0.00079365079365079*G0_0_0 - 0.000793650793650788*G0_0_2 + 0.00476190476190479*G0_1_1 - 0.000793650793650788*G0_2_0 - 0.00238095238095238*G0_2_2; + A[18] = A[9] + 0.000793650793650794*G0_0_0 - 0.000793650793650787*G0_0_1 - 0.000793650793650787*G0_1_0 - 0.00714285714285716*G0_1_1 - 0.00158730158730159*G0_1_2 - 0.00158730158730159*G0_2_1; + A[20] = -0.00079365079365079*G0_0_0 - 0.000793650793650788*G0_0_1 - 0.000793650793650788*G0_1_0 - 0.00238095238095238*G0_1_1 + 0.00476190476190479*G0_2_2; + A[13] = 0.000396825396825396*G0_0_0 - 0.0011904761904762*G0_1_1 - 0.0003968253968254*G0_1_2 - 0.0003968253968254*G0_2_1 - 0.00119047619047619*G0_2_2; + A[31] = A[9] - 0.00158730158730159*G0_0_0 + 0.00158730158730159*G0_2_2; + A[3] = A[18]; + A[17] = A[31] - 0.00158730158730159*G0_0_1 - 0.00158730158730159*G0_1_0 - 0.00714285714285717*G0_1_1 - 0.000793650793650789*G0_1_2 - 0.00079365079365079*G0_2_1 + 0.00079365079365079*G0_2_2; + A[24] = 0.0047619047619048*G0_0_0 - 0.000793650793650787*G0_1_1 - 0.000793650793650787*G0_1_2 - 0.000793650793650787*G0_2_1 - 0.00238095238095238*G0_2_2; + A[8] = A[13]; + A[11] = A[31]; + A[30] = A[24] - 0.00158730158730159*G0_1_1 + 0.00158730158730159*G0_2_2; + A[4] = A[24]; + A[25] = A[18] - 0.00238095238095238*G0_0_0 - 0.000793650793650796*G0_0_2 + 0.00238095238095237*G0_1_1 + 0.000793650793650788*G0_1_2 - 0.000793650793650796*G0_2_0 + 0.000793650793650787*G0_2_1; + A[34] = A[9] + 0.0103174603174603*G0_0_0 + 0.00476190476190474*G0_0_1 + 0.00555555555555553*G0_0_2 + 0.00476190476190474*G0_1_0 + 0.00317460317460314*G0_1_2 + 0.00555555555555553*G0_2_0 + 0.00317460317460314*G0_2_1 + 0.00714285714285711*G0_2_2; + A[21] = A[34] - 0.00634920634920634*G0_0_0 + 0.0142857142857144*G0_1_1 + 0.0111111111111112*G0_1_2 + 0.0111111111111112*G0_2_1 + 0.0142857142857144*G0_2_2; + A[28] = A[21] + 0.015873015873016*G0_0_0 + 0.00952380952380968*G0_0_2 - 0.015873015873016*G0_1_1 - 0.00952380952380963*G0_1_2 + 0.00952380952380968*G0_2_0 - 0.00952380952380963*G0_2_1; + A[29] = A[34]; + A[10] = A[25]; + A[5] = A[30]; + A[26] = A[20] - 0.00158730158730159*G0_0_0 + 0.00158730158730159*G0_1_1; + A[6] = -0.0011904761904762*G0_0_0 - 0.000396825396825401*G0_0_1 - 0.000396825396825401*G0_1_0 - 0.0011904761904762*G0_1_1 + 0.000396825396825394*G0_2_2; + A[1] = A[6]; + A[14] = -A[6] - 0.000396825396825403*G0_0_0 + 0.00119047619047619*G0_0_2 - 0.000396825396825403*G0_1_1 + 0.00119047619047619*G0_1_2 + 0.00119047619047619*G0_2_0 + 0.00119047619047619*G0_2_1 + 0.00992063492063499*G0_2_2; + A[7] = A[14] + 0.000793650793650801*G0_0_1 - 0.000793650793650801*G0_0_2 + 0.000793650793650801*G0_1_0 + 0.00873015873015881*G0_1_1 - 0.000793650793650801*G0_2_0 - 0.00873015873015881*G0_2_2; + A[0] = A[14] + 0.0087301587301588*G0_0_0 + 0.000793650793650801*G0_0_1 + 0.000793650793650802*G0_1_0 - 0.000793650793650801*G0_1_2 - 0.000793650793650801*G0_2_1 - 0.0087301587301588*G0_2_2; + A[35] = A[21] + 0.015873015873016*G0_0_0 + 0.00952380952380969*G0_0_1 + 0.00952380952380969*G0_1_0 - 0.00952380952380964*G0_1_2 - 0.00952380952380964*G0_2_1 - 0.015873015873016*G0_2_2; + A[23] = A[28] - 0.0142857142857145*G0_0_0 - 0.0111111111111113*G0_0_2 + 0.00634920634920632*G0_1_1 - 0.0111111111111113*G0_2_0 - 0.0142857142857145*G0_2_2; + A[33] = A[23]; + A[19] = A[9]; + A[16] = A[26]; + A[27] = A[35] - 0.0142857142857145*G0_0_0 - 0.0111111111111113*G0_0_1 - 0.0111111111111113*G0_1_0 - 0.0142857142857145*G0_1_1 + 0.00634920634920632*G0_2_2; + A[22] = A[27]; + A[15] = A[20]; + A[32] = A[17]; + A[2] = -0.0011904761904762*G0_0_0 - 0.0003968253968254*G0_0_2 + 0.000396825396825394*G0_1_1 - 0.0003968253968254*G0_2_0 - 0.0011904761904762*G0_2_2; + A[12] = A[2]; + } + + /// 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 mass_matrix_f2_p1_q2_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p1_q2_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p1_q2_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1))), 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 mass_matrix_f2_p1_q2_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p1_q2_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p1_q2_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p1_q2_tensor_finite_element_0(); + 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 mass_matrix_f2_p1_q2_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p1_q2_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p1_q2_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p1_q2_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f2_p1_q3_excafe.h b/mass_matrix_2d/mass_matrix_f2_p1_q3_excafe.h new file mode 100644 index 0000000..41c7d2e --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p1_q3_excafe.h @@ -0,0 +1,238 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 0.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 = -1.0000000000000000000000000*x[0][1]; + const double var_1 = x[1][1] + var_0; + const double var_2 = -1.0000000000000000000000000*x[0][0]; + const double var_3 = x[2][0] + var_2; + const double var_4 = var_0 + x[2][1]; + const double var_5 = x[1][0] + var_2; + const double var_6 = -1.0000000000000000000000000*var_1*var_3 + var_4*var_5; + const double var_7 = std::abs(var_6); + const double var_8 = w[0][2]*w[1][0] + w[0][0]*w[1][2]; + const double var_9 = w[0][2]*w[1][2]; + const double var_10 = var_9 + var_8; + const double var_11 = w[0][1]*w[1][2] + w[0][2]*w[1][1]; + const double var_12 = -0.0012053571428571427815585*var_11*var_7; + const double var_13 = w[0][1]*w[1][0] + w[0][0]*w[1][1]; + const double var_14 = w[0][0]*w[1][0]; + const double var_15 = var_14 + var_13; + const double var_16 = -0.0008035714285714285571791*var_15*var_7; + const double var_17 = w[0][1]*w[1][1]; + const double var_18 = -0.0040178571428571424606346*var_17*var_7; + A[37] = -0.0004017857142857142785895*var_10*var_7 + var_16 + var_12 + var_18; + A[73] = A[37]; + const double var_19 = 0.0001785714285714285712737*var_7*var_8; + const double var_20 = -0.0001339285714285714352315*var_7*w[0][1]*w[1][1] + var_19; + const double var_21 = 0.0000446428571428571428184*var_13*var_7 + 0.0010714285714285714818522*var_7*var_9; + const double var_22 = 0.0003125000000000000065052*var_11*var_7; + A[4] = var_21 + var_20 + var_22; + A[40] = A[4]; + const double var_23 = var_11 + var_8; + const double var_24 = var_23 + var_13; + const double var_25 = -1.0000000000000000000000000*var_14 + var_11; + const double var_26 = 0.0016071428571428571143581*var_25*var_7; + const double var_27 = -0.0013392857142857142981052*var_7*w[0][1]*w[1][1] + var_19; + const double var_28 = 0.0000446428571428571428184*var_7*w[0][0]*w[1][0]; + const double var_29 = 0.0009375000000000000737257*var_7*w[0][2]*w[1][2]; + A[14] = var_29 + var_28 + var_27; + const double var_30 = var_14 + var_17; + const double var_31 = 1.5000000000000000000000000*var_30 + var_13; + A[29] = 0.0005357142857142857409261*var_31*var_7; + const double var_32 = var_9 + var_11; + const double var_33 = -0.0006696428571428571490526*var_7*w[0][1]*w[1][1]; + const double var_34 = 0.0026785714285714285962103*var_14*var_7; + A[7] = var_33 + -0.0002232142857142857073158*var_32*var_7 + var_34; + A[70] = A[7]; + const double var_35 = var_13 + var_17; + const double var_36 = -0.0008035714285714285571791*var_35*var_7; + const double var_37 = 0.0001785714285714285712737*var_13*var_7; + const double var_38 = var_37 + -0.0001339285714285714352315*var_7*w[0][2]*w[1][2]; + const double var_39 = 0.0000446428571428571428184*var_7*var_8 + 0.0010714285714285714818522*var_17*var_7; + A[3] = var_22 + var_39 + var_38; + const double var_40 = var_14 + var_8; + const double var_41 = -0.0012053571428571427815585*var_13*var_7; + const double var_42 = -0.0008035714285714285571791*var_32*var_7; + A[48] = var_41 + var_42 + -0.0004017857142857142785895*var_40*var_7 + var_18; + const double var_43 = 0.0024107142857142855631170*var_13*var_7; + const double var_44 = 0.0333333333333333328707404*var_23 + var_30 + 0.1833333333333333203807314*w[0][2]*w[1][2] + 0.2166666666666666740681535*var_13; + const double var_45 = var_9 + var_14; + const double var_46 = -0.0004017857142857142785895*var_24*var_7; + const double var_47 = 0.0008035714285714285571791*var_17*var_7; + A[47] = var_46 + var_47 + -0.0012053571428571427815585*var_45*var_7; + const double var_48 = -0.0008035714285714285571791*var_40*var_7; + const double var_49 = -0.0040178571428571424606346*var_7*var_9; + A[45] = var_48 + var_49 + var_12 + -0.0004017857142857142785895*var_35*var_7; + const double var_50 = 0.0020089285714285712303173*var_13*var_7 + 0.0048214285714285711262339*var_7*var_9; + const double var_51 = 0.0750000000000000111022302*var_8 + var_17; + const double var_52 = 0.0160714285714285698425385*var_51*var_7; + const double var_53 = var_9 + var_17; + const double var_54 = 1.5000000000000000000000000*var_53 + var_11; + const double var_55 = 0.0080357142857142849212693*var_14*var_7; + const double var_56 = 0.0024107142857142855631170*var_7*var_8; + const double var_57 = var_11 + var_17; + const double var_58 = -0.0008035714285714285571791*var_57*var_7; + const double var_59 = -1.0000000000000000000000000*var_9 + var_13; + const double var_60 = 0.0016071428571428571143581*var_59*var_7; + A[59] = var_58 + var_60 + var_56 + var_55; + A[95] = A[59]; + const double var_61 = var_37 + -0.0013392857142857142981052*var_7*w[0][2]*w[1][2]; + const double var_62 = 0.0009375000000000000737257*var_7*w[0][1]*w[1][1]; + A[23] = var_61 + var_62 + var_28; + const double var_63 = 0.0000446428571428571428184*var_7*w[0][1]*w[1][1]; + const double var_64 = 0.0009375000000000000737257*var_7*w[0][0]*w[1][0]; + A[25] = var_61 + var_63 + var_64; + A[52] = A[25]; + const double var_65 = var_8 + var_13; + A[57] = 0.0008035714285714285571791*var_54*var_7 + var_55 + 0.0020089285714285712303173*var_65*var_7; + const double var_66 = 0.0060267857142857136909520*var_7*var_8 + var_47; + const double var_67 = 0.0001785714285714285712737*var_11*var_7; + const double var_68 = var_67 + -0.0001339285714285714352315*var_7*w[0][0]*w[1][0]; + const double var_69 = 0.0003125000000000000065052*var_13*var_7; + A[28] = var_68 + var_69 + var_39; + const double var_70 = -0.0006696428571428571490526*var_7*w[0][0]*w[1][0]; + const double var_71 = 0.0026785714285714285962103*var_7*var_9; + A[26] = var_70 + var_71 + -0.0002232142857142857073158*var_35*var_7; + A[62] = A[26]; + const double var_72 = var_8 + -1.0000000000000000000000000*var_17; + const double var_73 = 0.0016071428571428571143581*var_7*var_72; + A[79] = var_43 + var_55 + var_73 + var_42; + A[54] = A[45]; + const double var_74 = 0.7500000000000000000000000*var_24 + var_53 + var_14; + A[99] = 0.0192857142857142845049356*var_7*var_74; + const double var_75 = var_14 + 0.0750000000000000111022302*var_11; + const double var_76 = 0.0160714285714285698425385*var_7*var_75; + A[55] = var_50 + var_66 + var_76; + const double var_77 = var_11 + var_13; + const double var_78 = var_9 + 0.0750000000000000111022302*var_13; + const double var_79 = 0.0160714285714285698425385*var_7*var_78; + const double var_80 = 0.0048214285714285711262339*var_14*var_7 + 0.0020089285714285712303173*var_11*var_7; + A[66] = var_66 + var_80 + var_79; + const double var_81 = 13.0000000000000000000000000*w[0][0]*w[1][0] + 0.3333333333333333148296163*var_11 + var_65; + A[0] = 0.0002976190476190476458945*var_7*var_81 + 0.0001984126984126984125263*var_53*var_7; + A[32] = A[23]; + const double var_82 = 0.0010714285714285714818522*var_14*var_7 + 0.0000446428571428571428184*var_11*var_7; + const double var_83 = 0.0003125000000000000065052*var_7*var_8; + A[15] = var_82 + var_83 + var_38; + const double var_84 = 0.0080357142857142849212693*var_17*var_7; + const double var_85 = 0.0024107142857142855631170*var_11*var_7; + A[39] = var_48 + var_84 + var_60 + var_85; + A[93] = A[39]; + A[41] = A[14]; + const double var_86 = 0.0000446428571428571428184*var_7*w[0][2]*w[1][2]; + A[17] = var_27 + var_64 + var_86; + A[71] = A[17]; + A[1] = 0.0002976190476190476458945*var_44*var_7; + A[10] = A[1]; + const double var_87 = 0.0008035714285714285571791*var_7*var_9; + A[35] = var_87 + var_46 + -0.0012053571428571427815585*var_30*var_7; + A[16] = var_68 + var_21 + var_83; + const double var_88 = 1.5000000000000000000000000*var_45 + var_8; + A[38] = var_84 + 0.0008035714285714285571791*var_7*var_88 + 0.0020089285714285712303173*var_7*var_77; + A[83] = A[38]; + A[82] = A[28]; + const double var_89 = 0.0080357142857142849212693*var_7*var_9; + A[46] = var_89 + 0.0008035714285714285571791*var_31*var_7 + 0.0020089285714285712303173*var_23*var_7; + A[64] = A[46]; + const double var_90 = var_53 + 0.1833333333333333203807314*w[0][0]*w[1][0] + 0.2166666666666666740681535*var_11 + 0.0333333333333333328707404*var_65; + A[12] = 0.0002976190476190476458945*var_7*var_90; + A[21] = A[12]; + const double var_91 = var_53 + 0.1000000000000000055511151*var_14 + 0.2000000000000000111022302*var_65; + A[61] = A[16]; + const double var_92 = -0.0008035714285714285571791*var_10*var_7; + const double var_93 = -0.0040178571428571424606346*var_14*var_7; + A[67] = -0.0004017857142857142785895*var_57*var_7 + var_92 + var_41 + var_93; + A[76] = A[67]; + const double var_94 = var_77 + 0.3333333333333333148296163*var_8 + 13.0000000000000000000000000*w[0][1]*w[1][1]; + const double var_95 = -0.0012053571428571427815585*var_7*var_8; + A[36] = var_58 + var_49 + var_95 + -0.0004017857142857142785895*var_15*var_7; + A[63] = A[36]; + const double var_96 = var_67 + -0.0013392857142857142981052*var_7*w[0][0]*w[1][0]; + A[8] = var_62 + var_96 + var_86; + A[80] = A[8]; + const double var_97 = 0.0008035714285714285571791*var_14*var_7; + const double var_98 = var_23 + 13.0000000000000000000000000*w[0][2]*w[1][2] + 0.3333333333333333148296163*var_13; + const double var_99 = 0.0020089285714285712303173*var_7*var_8 + 0.0048214285714285711262339*var_17*var_7; + const double var_100 = var_97 + 0.0060267857142857136909520*var_11*var_7; + A[44] = var_99 + var_79 + var_100; + A[58] = var_93 + var_36 + var_95 + -0.0004017857142857142785895*var_32*var_7; + A[69] = var_89 + var_26 + var_56 + var_36; + A[75] = A[57]; + A[49] = var_89 + var_16 + var_85 + var_73; + A[94] = A[49]; + A[27] = var_82 + var_20 + var_69; + A[72] = A[27]; + const double var_101 = 0.2000000000000000111022302*var_77 + var_45 + 0.1000000000000000055511151*var_17; + A[96] = A[69]; + const double var_102 = -0.0006696428571428571490526*var_7*w[0][2]*w[1][2]; + const double var_103 = 0.0026785714285714285962103*var_17*var_7; + A[13] = var_103 + -0.0002232142857142857073158*var_40*var_7 + var_102; + A[31] = A[13]; + A[22] = 0.0001984126984126984125263*var_30*var_7 + 0.0002976190476190476458945*var_7*var_98; + A[11] = 0.0002976190476190476458945*var_7*var_94 + 0.0001984126984126984125263*var_45*var_7; + A[97] = A[79]; + const double var_104 = 0.0333333333333333328707404*var_77 + var_45 + 0.2166666666666666740681535*var_8 + 0.1833333333333333203807314*w[0][1]*w[1][1]; + A[2] = 0.0002976190476190476458945*var_104*var_7; + A[20] = A[2]; + A[85] = A[58]; + A[18] = -0.0002232142857142857073158*var_10*var_7 + var_70 + var_103; + A[81] = A[18]; + A[19] = 0.0005357142857142857409261*var_7*var_88; + A[91] = A[19]; + A[74] = A[47]; + const double var_105 = var_87 + 0.0060267857142857136909520*var_13*var_7; + A[77] = var_99 + var_76 + var_105; + A[68] = var_46 + var_97 + -0.0012053571428571427815585*var_53*var_7; + A[86] = A[68]; + A[51] = A[15]; + A[6] = var_63 + var_29 + var_96; + A[24] = var_33 + var_71 + -0.0002232142857142857073158*var_15*var_7; + const double var_106 = 0.1000000000000000055511151*var_9 + 0.2000000000000000111022302*var_23 + var_30; + A[53] = A[35]; + A[5] = -0.0002232142857142857073158*var_57*var_7 + var_102 + var_34; + A[30] = A[3]; + A[60] = A[6]; + A[56] = -0.0040178571428571424606346*var_101*var_7 + var_95; + A[50] = A[5]; + A[89] = var_26 + var_84 + var_92 + var_43; + A[98] = A[89]; + A[78] = var_41 + -0.0040178571428571424606346*var_106*var_7; + A[87] = A[78]; + A[34] = -0.0040178571428571424606346*var_7*var_91 + var_12; + A[65] = A[56]; + A[9] = 0.0005357142857142857409261*var_54*var_7; + A[90] = A[9]; + A[33] = var_50 + var_100 + var_52; + A[92] = A[29]; + A[43] = A[34]; + A[88] = var_80 + var_105 + var_52; + A[84] = A[48]; + A[42] = A[24]; + } + + 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/mass_matrix_2d/mass_matrix_f2_p1_q3_quadrature.h b/mass_matrix_2d/mass_matrix_f2_p1_q3_quadrature.h new file mode 100644 index 0000000..7ac1d46 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p1_q3_quadrature.h @@ -0,0 +1,4605 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P1_Q3_QUADRATURE_H +#define __MASS_MATRIX_F2_P1_Q3_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p1_q3_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p1_q3_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f2_p1_q3_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p1_q3_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p1_q3_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p1_q3_quadrature_finite_element_1() + { + // 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p1_q3_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p1_q3_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p1_q3_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f2_p1_q3_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p1_q3_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p1_q3_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_p1_q3_quadrature_dofmap_1() + { + // 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.0*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 mass_matrix_f2_p1_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 mass_matrix_f2_p1_q3_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p1_q3_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // 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[25][3] = \ + {{0.915147549378728, 0.0450425935698037, 0.0398098570514687}, + {0.764365329781281, 0.0376212523451112, 0.198013417873608}, + {0.535660544808143, 0.026364644944471, 0.437974810247386}, + {0.290249932250793, 0.0142857943955714, 0.695464273353636}, + {0.09391279733378, 0.00462228846504648, 0.901464914201173}, + {0.738611533396152, 0.221578609552379, 0.0398098570514687}, + {0.616915871859002, 0.185070710267389, 0.198013417873608}, + {0.43232925297036, 0.129695936782254, 0.437974810247386}, + {0.234259434638082, 0.0702762920082818, 0.695464273353636}, + {0.0757966027350624, 0.0227384830637641, 0.901464914201173}, + {0.480095071474266, 0.480095071474266, 0.0398098570514687}, + {0.400993291063196, 0.400993291063196, 0.198013417873608}, + {0.281012594876307, 0.281012594876307, 0.437974810247386}, + {0.152267863323182, 0.152267863323182, 0.695464273353636}, + {0.0492675428994132, 0.0492675428994133, 0.901464914201173}, + {0.221578609552379, 0.738611533396152, 0.0398098570514687}, + {0.185070710267389, 0.616915871859002, 0.198013417873608}, + {0.129695936782254, 0.43232925297036, 0.437974810247386}, + {0.0702762920082818, 0.234259434638082, 0.695464273353636}, + {0.022738483063764, 0.0757966027350624, 0.901464914201173}, + {0.0450425935698037, 0.915147549378728, 0.0398098570514687}, + {0.0376212523451112, 0.764365329781281, 0.198013417873608}, + {0.0263646449444709, 0.535660544808143, 0.437974810247386}, + {0.0142857943955715, 0.290249932250793, 0.695464273353636}, + {0.00462228846504642, 0.0939127973337801, 0.901464914201173}}; + + static const double FE1[25][10] = \ + {{0.595361771100889, 0.0363240630142744, 0.0329620582231266, -0.00697876330105453, -0.00710543413900173, 0.286154010031837, -0.144363814874519, 0.323767019699913, -0.160427557536749, 0.0443066477812842}, + {0.144847707077251, 0.031491752557511, 0.056509372357196, -0.0297392974343587, -0.0136089104009562, 0.880722068301204, -0.276497422020097, 0.167331423967527, -0.114798724929776, 0.153742030524499}, + {-0.0638922318573471, 0.0233191863197456, -0.0471646056404562, -0.0478518692290425, 0.0163120554591614, 0.640806423249974, 0.331418250941681, 0.038574441798557, -0.0585247318831845, 0.167003080840912}, + {0.0211818331847306, 0.0133805365030047, 0.0326369349932555, -0.0427925717552784, 0.0485711762178746, -0.117406110387015, 0.98683910857276, -0.0024116832712123, -0.0178593517002863, 0.0778601276421673}, + {0.0579517721596659, 0.00452658789692546, 0.541134376806172, -0.0184907249626245, 0.0319586608616019, -0.273633189306433, 0.649316299328904, -0.0014030624094848, -0.00192632644777788, 0.010565606073051}, + {0.0969129145557495, 0.0495966310503562, 0.0329620582231266, -0.0133081629182569, -0.0349538534974921, 0.160876909651335, -0.116515395516028, 0.895428534283356, -0.246912783611135, 0.175913147778989}, + {-0.0391667888544834, 0.0594654509565622, 0.056509372357196, -0.0733496016702976, -0.0669464878724995, 0.467663868980969, -0.223159844548554, 0.437096058075966, -0.228522561505531, 0.610410534080673}, + {-0.0451321541833679, 0.0638185648099453, -0.0471646056404562, -0.15615892407532, 0.0802441041051714, 0.253054939278284, 0.267486202295671, 0.074936267198872, -0.154146013447678, 0.663061619658879}, + {0.045160818752146, 0.0496137334753148, 0.0326369349932555, -0.17356708239734, 0.238936811531546, -0.217903867034122, 0.796473473259088, -0.0220190689531468, -0.0584641485580772, 0.309132394931336}, + {0.0519031146003489, 0.0204647143413336, 0.541134376806172, -0.0859485068100627, 0.157214651192224, -0.23755901477889, 0.524060308998282, -0.00599217068695466, -0.00722668705539908, 0.0419492133929461}, + {-0.0591559090807405, -0.0591559090807405, 0.0329620582231266, 0.03786731225338, -0.0757346245067602, 0.03786731225338, -0.0757346245067601, 0.456668557219904, 0.456668557219904, 0.247747270005307}, + {-0.032436155693348, -0.032436155693348, 0.056509372357196, 0.0725265831052634, -0.145053166210527, 0.0725265831052632, -0.145053166210527, 0.146872235029605, 0.146872235029605, 0.859671635180817}, + {0.025515852626442, 0.0255158526264419, -0.0471646056404562, -0.0869325766002105, 0.173865153200421, -0.0869325766002107, 0.173865153200421, -0.0557775204375565, -0.0557775204375563, 0.933822788062264}, + {0.0638199343796498, 0.0638199343796498, 0.0326369349932555, -0.258852571197659, 0.517705142395317, -0.258852571197659, 0.517705142395317, -0.0566742670215316, -0.0566742670215314, 0.435366587895191}, + {0.0388828743119486, 0.0388828743119486, 0.541134376806172, -0.170318740047627, 0.340637480095253, -0.170318740047627, 0.340637480095253, -0.0093083887122843, -0.00930838871228411, 0.0590791718992466}, + {0.0495966310503563, 0.0969129145557494, 0.0329620582231266, 0.160876909651335, -0.116515395516028, -0.013308162918257, -0.034953853497492, -0.246912783611135, 0.895428534283356, 0.175913147778989}, + {0.0594654509565623, -0.0391667888544834, 0.056509372357196, 0.467663868980969, -0.223159844548554, -0.0733496016702976, -0.0669464878724995, -0.228522561505532, 0.437096058075966, 0.610410534080673}, + {0.0638185648099453, -0.0451321541833679, -0.0471646056404562, 0.253054939278284, 0.267486202295671, -0.15615892407532, 0.0802441041051715, -0.154146013447678, 0.0749362671988722, 0.663061619658879}, + {0.0496137334753148, 0.045160818752146, 0.0326369349932555, -0.217903867034122, 0.796473473259088, -0.17356708239734, 0.238936811531547, -0.0584641485580774, -0.0220190689531466, 0.309132394931336}, + {0.0204647143413336, 0.0519031146003489, 0.541134376806172, -0.23755901477889, 0.524060308998282, -0.0859485068100628, 0.157214651192223, -0.00722668705539924, -0.00599217068695446, 0.041949213392946}, + {0.0363240630142745, 0.595361771100889, 0.0329620582231266, 0.286154010031837, -0.144363814874519, -0.00697876330105458, -0.00710543413900171, -0.160427557536749, 0.323767019699913, 0.0443066477812842}, + {0.031491752557511, 0.144847707077251, 0.056509372357196, 0.880722068301204, -0.276497422020097, -0.0297392974343586, -0.0136089104009562, -0.114798724929776, 0.167331423967527, 0.153742030524498}, + {0.0233191863197457, -0.0638922318573471, -0.0471646056404562, 0.640806423249974, 0.331418250941681, -0.0478518692290426, 0.0163120554591614, -0.0585247318831847, 0.0385744417985573, 0.167003080840912}, + {0.0133805365030048, 0.0211818331847307, 0.0326369349932554, -0.117406110387015, 0.986839108572759, -0.0427925717552788, 0.0485711762178751, -0.0178593517002866, -0.00241168327121213, 0.0778601276421677}, + {0.00452658789692547, 0.057951772159666, 0.541134376806172, -0.273633189306433, 0.649316299328904, -0.0184907249626247, 0.0319586608616018, -0.00192632644777806, -0.0014030624094846, 0.0105656060730509}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 100; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 7875 + for (unsigned int ip = 0; ip < 25; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + + // Total number of operations to compute function values = 12 + for (unsigned int r = 0; r < 3; r++) + { + F0 += FE0[ip][r]*w[0][r]; + F1 += FE0[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 3 + double I[1]; + // Number of operations: 3 + I[0] = F0*F1*W25[ip]*det; + + + // Number of operations for primary indices: 300 + for (unsigned int j = 0; j < 10; j++) + { + for (unsigned int k = 0; k < 10; k++) + { + // Number of operations to compute entry: 3 + A[j*10 + k] += FE1[ip][j]*FE1[ip][k]*I[0]; + }// 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 mass_matrix_f2_p1_q3_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p1_q3_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p1_q3_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1))), 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 mass_matrix_f2_p1_q3_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p1_q3_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p1_q3_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p1_q3_quadrature_finite_element_0(); + 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 mass_matrix_f2_p1_q3_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p1_q3_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p1_q3_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p1_q3_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f2_p1_q3_tensor.h b/mass_matrix_2d/mass_matrix_f2_p1_q3_tensor.h new file mode 100644 index 0000000..80b5e43 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p1_q3_tensor.h @@ -0,0 +1,4617 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P1_Q3_TENSOR_H +#define __MASS_MATRIX_F2_P1_Q3_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p1_q3_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p1_q3_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f2_p1_q3_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p1_q3_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p1_q3_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p1_q3_tensor_finite_element_1() + { + // 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p1_q3_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p1_q3_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p1_q3_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f2_p1_q3_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p1_q3_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p1_q3_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_p1_q3_tensor_dofmap_1() + { + // 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.0*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 mass_matrix_f2_p1_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 mass_matrix_f2_p1_q3_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p1_q3_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 13 + // Number of operations (multiply-add pairs) for tensor contraction: 288 + // Total number of operations (multiply-add pairs): 310 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0 = det*w[0][0]*w[1][0]*(1.0); + const double G0_0_1 = det*w[0][0]*w[1][1]*(1.0); + const double G0_0_2 = det*w[0][0]*w[1][2]*(1.0); + const double G0_1_0 = det*w[0][1]*w[1][0]*(1.0); + const double G0_1_1 = det*w[0][1]*w[1][1]*(1.0); + const double G0_1_2 = det*w[0][1]*w[1][2]*(1.0); + const double G0_2_0 = det*w[0][2]*w[1][0]*(1.0); + const double G0_2_1 = det*w[0][2]*w[1][1]*(1.0); + const double G0_2_2 = det*w[0][2]*w[1][2]*(1.0); + + // Compute element tensor + A[73] = -0.000803571428571426*G0_0_0 - 0.000803571428571426*G0_0_1 - 0.000401785714285713*G0_0_2 - 0.000803571428571426*G0_1_0 - 0.00401785714285713*G0_1_1 - 0.00120535714285714*G0_1_2 - 0.000401785714285713*G0_2_0 - 0.00120535714285714*G0_2_1 - 0.000401785714285712*G0_2_2; + A[7] = 0.00267857142857141*G0_0_0 - 0.000669642857142855*G0_1_1 - 0.000223214285714285*G0_1_2 - 0.000223214285714285*G0_2_1 - 0.000223214285714285*G0_2_2; + A[37] = A[73]; + A[25] = 0.000937499999999996*G0_0_0 + 0.000178571428571428*G0_0_1 + 0.000178571428571428*G0_1_0 + 4.46428571428568e-05*G0_1_1 - 0.00133928571428571*G0_2_2; + A[85] = A[73] - 0.0032142857142857*G0_0_0 - 0.000803571428571425*G0_0_2 + 0.0032142857142857*G0_1_1 + 0.000803571428571426*G0_1_2 - 0.000803571428571425*G0_2_0 + 0.000803571428571426*G0_2_1; + A[69] = A[85] + 0.00241071428571427*G0_0_0 + 0.00361607142857141*G0_0_2 + 0.00200892857142856*G0_1_2 + 0.00361607142857141*G0_2_0 + 0.00200892857142856*G0_2_1 + 0.00843749999999997*G0_2_2; + A[58] = A[85]; + A[90] = 0.000803571428571426*G0_1_1 + 0.000535714285714284*G0_1_2 + 0.000535714285714284*G0_2_1 + 0.000803571428571426*G0_2_2; + A[55] = -A[73] + 0.0152678571428571*G0_0_0 + 0.00120535714285714*G0_0_1 + 0.00562499999999997*G0_0_2 + 0.00120535714285714*G0_1_0 - 0.0032142857142857*G0_1_1 + 0.00562499999999997*G0_2_0 + 0.00441964285714284*G0_2_2; + A[11] = 0.000198412698412697*G0_0_0 + 0.000297619047619046*G0_0_1 + 9.92063492063488e-05*G0_0_2 + 0.000297619047619046*G0_1_0 + 0.0038690476190476*G0_1_1 + 0.000297619047619046*G0_1_2 + 9.92063492063488e-05*G0_2_0 + 0.000297619047619046*G0_2_1 + 0.000198412698412698*G0_2_2; + A[32] = A[25] - 0.000892857142857139*G0_0_0 + 0.000892857142857139*G0_1_1; + A[26] = -0.000669642857142854*G0_0_0 - 0.000223214285714285*G0_0_1 - 0.000223214285714285*G0_1_0 - 0.000223214285714285*G0_1_1 + 0.00267857142857141*G0_2_2; + A[60] = -0.00133928571428571*G0_0_0 + 4.46428571428572e-05*G0_1_1 + 0.000178571428571428*G0_1_2 + 0.000178571428571428*G0_2_1 + 0.000937499999999996*G0_2_2; + A[16] = A[60] + 0.00120535714285713*G0_0_0 + 4.46428571428569e-05*G0_0_1 + 0.000312499999999998*G0_0_2 + 4.46428571428569e-05*G0_1_0 - 4.46428571428569e-05*G0_1_1 + 0.000312499999999998*G0_2_0 + 0.000133928571428571*G0_2_2; + A[40] = A[16] + 0.00013392857142857*G0_0_0 - 0.000133928571428571*G0_0_2 - 0.000133928571428571*G0_1_1 + 0.000133928571428571*G0_1_2 - 0.000133928571428571*G0_2_0 + 0.000133928571428571*G0_2_1; + A[4] = A[40]; + A[82] = A[16] + 0.000267857142857141*G0_0_1 - 0.000267857142857142*G0_0_2 + 0.000267857142857141*G0_1_0 + 0.00107142857142857*G0_1_1 - 0.000267857142857142*G0_2_0 - 0.00107142857142857*G0_2_2; + A[1] = 0.000297619047619046*G0_0_0 + 6.44841269841265e-05*G0_0_1 + 9.92063492063481e-06*G0_0_2 + 6.44841269841265e-05*G0_1_0 + 0.000297619047619046*G0_1_1 + 9.92063492063483e-06*G0_1_2 + 9.92063492063481e-06*G0_2_0 + 9.92063492063483e-06*G0_2_1 + 5.45634920634918e-05*G0_2_2; + A[31] = -0.000223214285714285*G0_0_0 - 0.000223214285714285*G0_0_2 + 0.00267857142857141*G0_1_1 - 0.000223214285714285*G0_2_0 - 0.000669642857142854*G0_2_2; + A[99] = 0.0192857142857142*G0_0_0 + 0.0144642857142857*G0_0_1 + 0.0144642857142857*G0_0_2 + 0.0144642857142857*G0_1_0 + 0.0192857142857142*G0_1_1 + 0.0144642857142857*G0_1_2 + 0.0144642857142857*G0_2_0 + 0.0144642857142857*G0_2_1 + 0.0192857142857142*G0_2_2; + A[21] = 5.45634920634917e-05*G0_0_0 + 9.92063492063474e-06*G0_0_1 + 9.9206349206348e-06*G0_0_2 + 9.92063492063474e-06*G0_1_0 + 0.000297619047619046*G0_1_1 + 6.44841269841266e-05*G0_1_2 + 9.9206349206348e-06*G0_2_0 + 6.44841269841266e-05*G0_2_1 + 0.000297619047619046*G0_2_2; + A[89] = A[69] + 0.0032142857142857*G0_0_1 - 0.0032142857142857*G0_0_2 + 0.0032142857142857*G0_1_0 + 0.00883928571428568*G0_1_1 - 0.0032142857142857*G0_2_0 - 0.00883928571428568*G0_2_2; + A[94] = A[73] + 0.00200892857142856*G0_0_2 + 0.00241071428571428*G0_1_1 + 0.00361607142857142*G0_1_2 + 0.00200892857142856*G0_2_0 + 0.00361607142857142*G0_2_1 + 0.00843749999999997*G0_2_2; + A[51] = A[16] + 0.00120535714285714*G0_0_0 + 0.00013392857142857*G0_0_1 + 0.00013392857142857*G0_1_0 - 0.000133928571428571*G0_1_2 - 0.000133928571428571*G0_2_1 - 0.00120535714285714*G0_2_2; + A[72] = A[40] + 0.00107142857142857*G0_0_0 + 0.000267857142857141*G0_0_1 + 0.000267857142857141*G0_1_0 - 0.000267857142857142*G0_1_2 - 0.000267857142857142*G0_2_1 - 0.00107142857142857*G0_2_2; + A[15] = A[51]; + A[22] = A[11] - 0.000198412698412697*G0_0_1 + 0.000198412698412697*G0_0_2 - 0.000198412698412697*G0_1_0 - 0.0036706349206349*G0_1_1 + 0.000198412698412697*G0_2_0 + 0.0036706349206349*G0_2_2; + A[86] = A[73] + 0.00160714285714285*G0_0_0 + 0.000401785714285713*G0_0_1 + 0.000401785714285713*G0_1_0 + 0.00281249999999999*G0_1_1 + 0.000803571428571426*G0_1_2 + 0.000803571428571426*G0_2_1 - 0.000803571428571424*G0_2_2; + A[41] = 4.46428571428571e-05*G0_0_0 + 0.000178571428571428*G0_0_2 - 0.00133928571428571*G0_1_1 + 0.000178571428571428*G0_2_0 + 0.000937499999999996*G0_2_2; + A[71] = A[41] + 0.000892857142857138*G0_0_0 - 0.00089285714285714*G0_2_2; + A[5] = A[7] + 0.000446428571428569*G0_1_1 - 0.00044642857142857*G0_2_2; + A[10] = A[1]; + A[8] = A[60] + 0.000892857142857138*G0_1_1 - 0.000892857142857139*G0_2_2; + A[35] = A[86] - 0.00200892857142857*G0_0_0 + 0.00200892857142856*G0_2_2; + A[27] = A[72]; + A[92] = 0.000803571428571425*G0_0_0 + 0.000535714285714284*G0_0_1 + 0.000535714285714284*G0_1_0 + 0.000803571428571425*G0_1_1; + A[61] = A[16]; + A[74] = A[86] - 0.00200892857142856*G0_0_0 + 0.00200892857142856*G0_1_1; + A[2] = 0.000297619047619046*G0_0_0 + 9.92063492063482e-06*G0_0_1 + 6.44841269841266e-05*G0_0_2 + 9.92063492063482e-06*G0_1_0 + 5.45634920634918e-05*G0_1_1 + 9.92063492063482e-06*G0_1_2 + 6.44841269841266e-05*G0_2_0 + 9.92063492063481e-06*G0_2_1 + 0.000297619047619046*G0_2_2; + A[13] = A[31]; + A[30] = A[40] + 0.000133928571428571*G0_0_1 - 0.000133928571428571*G0_0_2 + 0.000133928571428571*G0_1_0 + 0.00120535714285714*G0_1_1 - 0.000133928571428571*G0_2_0 - 0.00120535714285714*G0_2_2; + A[28] = A[82]; + A[98] = A[89]; + A[80] = A[8]; + A[62] = A[26]; + A[50] = A[5]; + A[14] = A[41]; + A[23] = A[32]; + A[19] = 0.000803571428571425*G0_0_0 + 0.000535714285714283*G0_0_2 + 0.000535714285714283*G0_2_0 + 0.000803571428571426*G0_2_2; + A[42] = A[26] + 0.00044642857142857*G0_0_0 - 0.000446428571428569*G0_1_1; + A[96] = A[69]; + A[65] = A[85] + 0.000401785714285715*G0_1_1 - 0.000401785714285714*G0_1_2 - 0.000401785714285714*G0_2_1 - 0.00361607142857142*G0_2_2; + A[75] = -A[65] + 0.00401785714285713*G0_0_0 + 0.00120535714285714*G0_0_1 + 0.000803571428571423*G0_0_2 + 0.00120535714285714*G0_1_0 + 0.000803571428571425*G0_1_1 + 0.000803571428571423*G0_2_0 - 0.00281249999999999*G0_2_2; + A[36] = A[65] + 0.00361607142857141*G0_0_0 + 0.000401785714285712*G0_0_1 + 0.000401785714285712*G0_1_0 - 0.000401785714285712*G0_1_1; + A[64] = A[75] - 0.00683035714285711*G0_0_0 - 0.00120535714285714*G0_0_1 - 0.00120535714285714*G0_1_0 + 0.00120535714285714*G0_1_2 + 0.00120535714285714*G0_2_1 + 0.00683035714285712*G0_2_2; + A[83] = A[75] - 0.00683035714285711*G0_0_0 - 0.00120535714285714*G0_0_2 + 0.00683035714285711*G0_1_1 + 0.00120535714285714*G0_1_2 - 0.00120535714285714*G0_2_0 + 0.00120535714285714*G0_2_1; + A[46] = A[64]; + A[57] = A[75]; + A[53] = A[35]; + A[70] = A[7]; + A[68] = A[86]; + A[6] = A[60]; + A[17] = A[71]; + A[9] = A[90]; + A[34] = A[73] + 0.000401785714285714*G0_0_0 - 0.000401785714285713*G0_0_2 - 0.000401785714285713*G0_2_0 - 0.00361607142857142*G0_2_2; + A[45] = A[34] - 0.000401785714285713*G0_0_0 + 0.000401785714285712*G0_0_1 + 0.000401785714285712*G0_1_0 + 0.00361607142857141*G0_1_1; + A[67] = A[45] - 0.0032142857142857*G0_0_0 - 0.000803571428571424*G0_0_1 - 0.000803571428571425*G0_1_0 + 0.000803571428571426*G0_1_2 + 0.000803571428571426*G0_2_1 + 0.0032142857142857*G0_2_2; + A[76] = A[67]; + A[93] = A[45] + 0.00200892857142856*G0_0_1 + 0.00200892857142856*G0_1_0 + 0.00843749999999997*G0_1_1 + 0.00361607142857142*G0_1_2 + 0.00361607142857142*G0_2_1 + 0.00241071428571428*G0_2_2; + A[78] = A[67] - 0.00361607142857141*G0_1_1 - 0.000401785714285712*G0_1_2 - 0.000401785714285712*G0_2_1 + 0.000401785714285717*G0_2_2; + A[54] = A[45]; + A[48] = A[78] + 0.00361607142857141*G0_0_0 + 0.000401785714285713*G0_0_2 + 0.000401785714285713*G0_2_0 - 0.000401785714285711*G0_2_2; + A[97] = A[48] + 0.00843749999999996*G0_0_0 + 0.00361607142857141*G0_0_1 + 0.00200892857142856*G0_0_2 + 0.00361607142857141*G0_1_0 + 0.00241071428571427*G0_1_1 + 0.00200892857142856*G0_2_0; + A[39] = A[93]; + A[87] = A[78]; + A[24] = A[42]; + A[84] = A[48]; + A[59] = A[36] + 0.00843749999999997*G0_0_0 + 0.00200892857142856*G0_0_1 + 0.00361607142857141*G0_0_2 + 0.00200892857142856*G0_1_0 + 0.00361607142857141*G0_2_0 + 0.00241071428571427*G0_2_2; + A[47] = A[74]; + A[91] = A[19]; + A[66] = A[55] - 0.0112499999999999*G0_0_0 - 0.000803571428571424*G0_0_1 - 0.000803571428571424*G0_1_0 + 0.000803571428571427*G0_1_2 + 0.000803571428571427*G0_2_1 + 0.01125*G0_2_2; + A[56] = A[65]; + A[77] = A[55] + 0.00401785714285712*G0_0_1 - 0.00401785714285712*G0_0_2 + 0.00401785714285712*G0_1_0 + 0.00401785714285712*G0_1_1 - 0.00401785714285712*G0_2_0 - 0.00401785714285713*G0_2_2; + A[3] = A[30]; + A[12] = A[21]; + A[49] = A[94]; + A[33] = A[55] - 0.0152678571428571*G0_0_0 - 0.00482142857142855*G0_0_2 + 0.0152678571428571*G0_1_1 + 0.00482142857142855*G0_1_2 - 0.00482142857142855*G0_2_0 + 0.00482142857142855*G0_2_1; + A[29] = A[92]; + A[81] = A[31] - 0.000446428571428569*G0_0_0 + 0.00044642857142857*G0_2_2; + A[44] = A[66] - 0.00401785714285713*G0_0_0 - 0.00401785714285713*G0_0_2 + 0.00401785714285713*G0_1_1 + 0.00401785714285712*G0_1_2 - 0.00401785714285713*G0_2_0 + 0.00401785714285712*G0_2_1; + A[63] = A[36]; + A[0] = A[11] + 0.0036706349206349*G0_0_0 + 0.000198412698412697*G0_0_2 - 0.0036706349206349*G0_1_1 - 0.000198412698412697*G0_1_2 + 0.000198412698412697*G0_2_0 - 0.000198412698412697*G0_2_1; + A[79] = A[97]; + A[38] = A[83]; + A[20] = A[2]; + A[18] = A[81]; + A[88] = A[66] + 0.00482142857142855*G0_0_1 - 0.00482142857142856*G0_0_2 + 0.00482142857142855*G0_1_0 + 0.0152678571428571*G0_1_1 - 0.00482142857142856*G0_2_0 - 0.0152678571428571*G0_2_2; + A[43] = A[34]; + A[95] = A[59]; + A[52] = A[25]; + } + + /// 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 mass_matrix_f2_p1_q3_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p1_q3_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p1_q3_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1))), 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 mass_matrix_f2_p1_q3_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p1_q3_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p1_q3_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p1_q3_tensor_finite_element_0(); + 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 mass_matrix_f2_p1_q3_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p1_q3_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p1_q3_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p1_q3_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f2_p1_q4_excafe.h b/mass_matrix_2d/mass_matrix_f2_p1_q4_excafe.h new file mode 100644 index 0000000..911ddb2 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p1_q4_excafe.h @@ -0,0 +1,535 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 5.03 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 = -1.0000000000000000000000000*x[0][1]; + const double var_1 = var_0 + x[1][1]; + const double var_2 = -1.0000000000000000000000000*x[0][0]; + const double var_3 = x[2][0] + var_2; + const double var_4 = var_0 + x[2][1]; + const double var_5 = x[1][0] + var_2; + const double var_6 = -1.0000000000000000000000000*var_1*var_3 + var_4*var_5; + const double var_7 = std::abs(var_6); + const double var_8 = w[0][1]*w[1][1]; + const double var_9 = 0.0000064133397466730803773*var_7*var_8; + const double var_10 = w[0][1]*w[1][0] + w[0][0]*w[1][1]; + const double var_11 = w[0][1]*w[1][2] + w[0][2]*w[1][1]; + const double var_12 = var_11 + var_10; + const double var_13 = -1.0000000000000000000000000*var_12; + const double var_14 = w[0][2]*w[1][2]; + const double var_15 = w[0][0]*w[1][0]; + const double var_16 = var_14 + var_15; + const double var_17 = w[0][2]*w[1][0] + w[0][0]*w[1][2]; + const double var_18 = -1.0000000000000000000000000*var_17; + const double var_19 = 0.6212121212121212154855243*var_16 + var_18; + A[22] = 0.0001058201058201058245315*var_19*var_7 + 0.0000080166746833413496246*var_13*var_7 + var_9; + const double var_20 = 0.0017957351290684624243316*var_7*var_8; + const double var_21 = -2.0000000000000000000000000*w[0][0]*w[1][0]; + const double var_22 = 19.0000000000000000000000000*var_11 + var_21; + const double var_23 = 0.0000769600769600769645277*var_22*var_7; + const double var_24 = 2.0000000000000000000000000*w[0][1]*w[1][1]; + const double var_25 = 0.0007696007696007695639620*var_18*var_7 + 0.0016931216931216931925047*var_24*var_7; + const double var_26 = 2.0000000000000000000000000*w[0][2]*w[1][2]; + const double var_27 = -0.0013852813852813852801837*var_26*var_7 + 0.0007696007696007695639620*var_10*var_7; + A[74] = var_27 + var_23 + var_25; + const double var_28 = -2.0000000000000000000000000*w[0][2]*w[1][2]; + const double var_29 = var_28 + var_10; + const double var_30 = 0.0008209074875741542882956*var_29*var_7; + const double var_31 = 2.4285714285714283811046243*w[0][2]*w[1][2] + var_10; + const double var_32 = -0.0000448933782267115592530*var_31*var_7; + const double var_33 = 0.0015392015392015391279240*var_17*var_7; + const double var_34 = var_15 + var_8; + const double var_35 = var_17 + var_11; + const double var_36 = 0.3333333333333333148296163*var_10; + const double var_37 = var_35 + var_36; + const double var_38 = 0.6250000000000000000000000*var_37 + 0.4166666666666666296592325*var_34 + 12.2000000000000010658141036*w[0][2]*w[1][2]; + A[32] = 0.0001603334936668270060446*var_38*var_7; + const double var_39 = var_34 + var_14; + const double var_40 = -2.0000000000000000000000000*w[0][1]*w[1][1]; + const double var_41 = var_17 + var_40; + const double var_42 = 0.0008209074875741542882956*var_41*var_7; + const double var_43 = -1.0000000000000000000000000*var_10; + const double var_44 = var_43 + 4.0000000000000000000000000*var_14; + const double var_45 = 0.0001026134359467692860370*var_44*var_7; + const double var_46 = -1.0000000000000000000000000*var_11; + const double var_47 = 0.0002052268718935385720739*var_46*var_7; + const double var_48 = var_47 + 0.0024627224627224628648869*var_15*var_7; + A[177] = var_48 + var_45 + var_42; + A[191] = A[177]; + const double var_49 = 0.0000368767035433702130166*var_7*w[0][2]*w[1][2]; + const double var_50 = 0.0004377104377104376739180*var_7*w[0][0]*w[1][0]; + const double var_51 = -1.0000000000000000000000000*var_8; + const double var_52 = 0.0703703703703703747907028*var_17 + var_51 + -0.0123456790123456783270228*var_12; + const double var_53 = 0.0012987012987012987001723*var_52*var_7; + A[25] = var_49 + var_50 + var_53; + A[151] = A[25]; + const double var_54 = 0.0000427555983111538691821*var_11*var_7; + const double var_55 = 2.0000000000000000000000000*var_34 + var_35 + var_14; + A[164] = -0.0004617604617604617600612*var_55*var_7 + -0.0013083213083213084647338*var_10*var_7; + A[220] = A[164]; + const double var_56 = -0.0024627224627224628648869*var_39*var_7; + const double var_57 = var_17 + var_10; + const double var_58 = -1.0000000000000000000000000*var_57; + const double var_59 = 0.3333333333333333148296163*var_11; + const double var_60 = var_59 + var_58; + A[209] = 0.0018470418470418470402450*var_60*var_7 + var_56; + const double var_61 = 0.0001026134359467692860370*var_17*var_7; + const double var_62 = 0.0023601090267756936330601*var_7*w[0][1]*w[1][1] + var_61; + const double var_63 = var_59 + -4.0000000000000000000000000*var_15; + const double var_64 = var_11 + 2.4285714285714283811046243*w[0][0]*w[1][0]; + const double var_65 = 0.3333333333333333148296163*var_12; + const double var_66 = -5.0833333333333330372738601*var_17 + -1.0000000000000000000000000*var_65 + 5.7500000000000000000000000*w[0][1]*w[1][1] + -34.2500000000000000000000000*var_16; + A[2] = 0.0000032066698733365401887*var_66*var_7; + const double var_67 = -0.0005772005772005772000766*var_10*var_7; + const double var_68 = -0.0002437069103735770611140*var_7*w[0][2]*w[1][2] + var_67; + const double var_69 = 2.0000000000000000000000000*w[0][0]*w[1][0]; + const double var_70 = var_11 + -0.4000000000000000222044605*var_69; + const double var_71 = 5.6666666666666660745477202*var_35 + var_26 + 9.6666666666666660745477202*var_10; + const double var_72 = var_17 + var_14; + const double var_73 = -0.0006413339746673080241784*var_7*w[0][0]*w[1][0] + 0.0000769600769600769645277*var_11*var_7; + const double var_74 = 0.0000128266794933461607546*var_10*var_7; + const double var_75 = 0.0001410934744268077479720*var_7*var_8; + A[116] = var_74 + var_73 + 0.0002950136283469617041325*var_7*var_72 + var_75; + const double var_76 = 0.0041045374378707710077974*var_24*var_7; + A[106] = A[22]; + const double var_77 = var_11 + var_8; + const double var_78 = 0.0000769600769600769645277*var_10*var_7 + -0.0006413339746673080241784*var_7*w[0][2]*w[1][2]; + const double var_79 = 0.0000128266794933461607546*var_17*var_7; + const double var_80 = 0.0001410934744268077479720*var_15*var_7; + A[66] = var_78 + var_80 + var_79 + 0.0002950136283469617041325*var_7*var_77; + A[94] = A[66]; + const double var_81 = var_43 + -26.5555555555555535818257340*w[0][2]*w[1][2]; + const double var_82 = 0.0000192400192400192411319*var_7*var_81; + const double var_83 = 0.0001026134359467692860370*var_11*var_7; + const double var_84 = var_83 + 0.0023601090267756936330601*var_7*w[0][0]*w[1][0]; + const double var_85 = var_11 + var_21; + const double var_86 = 0.0008209074875741542882956*var_7*var_85; + const double var_87 = var_18 + 4.0000000000000000000000000*var_8; + const double var_88 = 0.0001026134359467692860370*var_7*var_87; + const double var_89 = 0.0002052268718935385720739*var_43*var_7; + const double var_90 = 0.0024627224627224628648869*var_14*var_7 + var_89; + A[104] = var_90 + var_88 + var_86; + A[216] = A[104]; + const double var_91 = -0.0000555822778045000299367*var_10*var_7; + const double var_92 = -0.0001154401154401154400153*var_14*var_7 + var_91; + const double var_93 = -0.0013852813852813852801837*var_24*var_7 + 0.0007696007696007695639620*var_17*var_7; + const double var_94 = 0.0016931216931216931925047*var_26*var_7 + 0.0007696007696007695639620*var_43*var_7; + A[73] = var_93 + var_94 + var_23; + const double var_95 = 0.0000641333974667307969968*var_63*var_7; + const double var_96 = 9.6666666666666660745477202*var_17 + 5.6666666666666660745477202*var_12 + var_24; + const double var_97 = var_46 + 4.0000000000000000000000000*var_15; + const double var_98 = 0.0001026134359467692860370*var_7*var_97; + A[59] = var_90 + var_98 + var_42; + const double var_99 = var_11 + 10.8571428571428558740308290*w[0][0]*w[1][0]; + const double var_100 = 0.0000368767035433702130166*var_7*w[0][0]*w[1][0]; + const double var_101 = var_17 + 2.4285714285714283811046243*w[0][1]*w[1][1]; + const double var_102 = 0.0017957351290684624243316*var_15*var_7; + const double var_103 = 0.3333333333333333148296163*var_17; + const double var_104 = var_103 + 0.0363636363636363618700997*w[0][1]*w[1][1]; + const double var_105 = 0.0084656084656084661793640*var_104*var_7; + const double var_106 = 0.0004617604617604617600612*var_11*var_7; + const double var_107 = var_106 + 0.0119715675271230819615154*var_7*w[0][0]*w[1][0]; + const double var_108 = 0.0009235209235209235201225*var_26*var_7 + 0.0009406231628453850949004*var_10*var_7; + A[96] = var_108 + var_105 + var_107; + const double var_109 = -0.0000448933782267115592530*var_101*var_7; + const double var_110 = var_11 + 32.3333333333333285963817616*w[0][0]*w[1][0]; + const double var_111 = -0.0000192400192400192411319*var_110*var_7; + const double var_112 = var_14 + 3.8000000000000002664535259*var_10; + const double var_113 = -0.0000641333974667307969968*var_112*var_7; + A[42] = var_111 + var_109 + var_113; + A[182] = A[42]; + const double var_114 = var_10 + var_8; + const double var_115 = 0.0004617604617604617600612*var_17*var_7; + const double var_116 = 0.0001539201539201539290554*var_14*var_7; + A[101] = var_84 + var_115 + var_116 + 0.0002907380685158463375431*var_114*var_7; + A[171] = A[101]; + const double var_117 = var_34 + 0.6666666666666666296592325*var_10; + const double var_118 = 0.3333333333333333148296163*var_35; + const double var_119 = 2.0000000000000000000000000*var_14 + 3.4000000000000003552713679*var_117 + var_118; + A[44] = 0.0000962000962000961954953*var_119*var_7; + const double var_120 = 0.0000368767035433702130166*var_7*w[0][1]*w[1][1]; + const double var_121 = -1.0000000000000000000000000*var_14; + const double var_122 = -0.0123456790123456783270228*var_35 + var_121 + 0.0703703703703703747907028*var_10; + const double var_123 = 0.0012987012987012987001723*var_122*var_7; + A[37] = var_123 + var_120 + var_50; + A[107] = A[37]; + const double var_124 = 3.8000000000000002664535259*var_17 + var_8; + const double var_125 = -0.0000641333974667307969968*var_124*var_7; + const double var_126 = -26.5555555555555535818257340*w[0][1]*w[1][1] + var_18; + const double var_127 = 0.0000192400192400192411319*var_126*var_7; + const double var_128 = var_14 + var_11; + const double var_129 = -0.0006413339746673080241784*var_7*w[0][1]*w[1][1] + 0.0000769600769600769645277*var_17*var_7; + A[69] = var_74 + 0.0002950136283469617041325*var_128*var_7 + var_129 + var_80; + const double var_130 = var_17 + var_15; + const double var_131 = -0.4000000000000000222044605*var_26 + var_10; + const double var_132 = 0.0010261343594676927519493*var_131*var_7; + const double var_133 = 0.0015392015392015391279240*var_11*var_7; + A[58] = var_76 + -0.0004104537437870771441478*var_130*var_7 + var_133 + var_132; + A[198] = A[58]; + const double var_134 = var_28 + var_36; + const double var_135 = 0.0012313612313612314324435*var_134*var_7; + const double var_136 = 0.0002052268718935385720739*var_18*var_7; + const double var_137 = var_46 + 0.8000000000000000444089210*var_69; + const double var_138 = 0.0005130671797338463759747*var_137*var_7; + A[87] = var_135 + var_136 + var_138; + A[185] = A[87]; + const double var_139 = 0.0001026134359467692860370*var_10*var_7; + const double var_140 = 0.0023601090267756936330601*var_7*w[0][2]*w[1][2] + var_139; + const double var_141 = var_43 + -2.1666666666666665186369300*var_35 + 29.0000000000000000000000000*w[0][2]*w[1][2]; + const double var_142 = 0.8000000000000000444089210*var_24 + var_18; + const double var_143 = 0.0005130671797338463759747*var_142*var_7; + A[133] = var_143 + var_135 + var_47; + const double var_144 = var_103 + -4.0000000000000000000000000*var_8; + const double var_145 = 0.0000641333974667307969968*var_144*var_7; + const double var_146 = var_14 + var_8; + const double var_147 = 1.8888888888888888395456433*var_57 + var_11 + 1.3333333333333332593184650*var_146; + const double var_148 = var_59 + var_21; + const double var_149 = 0.0012313612313612314324435*var_148*var_7; + const double var_150 = 0.0001539201539201539290554*var_15*var_7; + A[53] = var_150 + var_115 + 0.0002907380685158463375431*var_7*var_77 + var_140; + const double var_151 = 0.0000064133397466730803773*var_14*var_7; + const double var_152 = -0.0001090267756934423630261*var_10*var_7 + var_151; + const double var_153 = 10.8571428571428558740308290*w[0][2]*w[1][2] + var_10; + const double var_154 = -0.0004489337822671156060829*var_153*var_7; + const double var_155 = var_43 + 0.8000000000000000444089210*var_26; + const double var_156 = 0.0005130671797338463759747*var_155*var_7; + const double var_157 = -0.0005772005772005772000766*var_11*var_7; + const double var_158 = -0.0002437069103735770611140*var_7*w[0][0]*w[1][0] + var_157; + const double var_159 = 1.8571428571428569842538536*var_17 + var_8; + const double var_160 = -0.0004489337822671156060829*var_159*var_7; + const double var_161 = -0.0022446689113355781930448*var_26*var_7 + -0.0002308802308802308800306*var_10*var_7; + A[68] = var_161 + var_160 + var_158; + A[124] = A[68]; + const double var_162 = var_103 + var_12; + const double var_163 = 0.6250000000000000000000000*var_162 + 12.2000000000000010658141036*w[0][1]*w[1][1] + 0.4166666666666666296592325*var_16; + const double var_164 = 0.0010261343594676927519493*var_7*var_70; + A[134] = 0.0041045374378707710077974*var_26*var_7 + var_164 + var_33 + -0.0004104537437870771441478*var_114*var_7; + A[218] = A[134]; + const double var_165 = -0.0004467960023515579227882*var_7*w[0][0]*w[1][0] + 0.0000064133397466730803773*var_11*var_7; + const double var_166 = var_51 + 0.3333333333333333148296163*var_18; + const double var_167 = 0.0000192400192400192411319*var_166*var_7; + const double var_168 = 0.0005772005772005772000766*var_14*var_7 + var_91; + A[36] = var_167 + var_168 + var_165; + const double var_169 = 0.0000064133397466730803773*var_15*var_7; + const double var_170 = var_46 + 0.6212121212121212154855243*var_146; + A[4] = 0.0000080166746833413496246*var_58*var_7 + 0.0001058201058201058245315*var_170*var_7 + var_169; + const double var_171 = var_169 + -0.0001090267756934423630261*var_11*var_7; + A[3] = var_92 + var_127 + var_171; + A[45] = A[3]; + const double var_172 = 0.3333333333333333148296163*var_57; + const double var_173 = var_172 + var_146; + A[131] = 0.0004617604617604617600612*var_173*var_7 + var_83 + 0.0005130671797338463759747*var_15*var_7; + const double var_174 = 0.0017957351290684624243316*var_14*var_7; + const double var_175 = -1.0000000000000000000000000*var_35; + const double var_176 = var_36 + var_175; + A[193] = var_56 + 0.0018470418470418470402450*var_176*var_7; + A[207] = A[193]; + const double var_177 = -0.0005772005772005772000766*var_17*var_7; + const double var_178 = -0.0002437069103735770611140*var_7*w[0][1]*w[1][1] + var_177; + const double var_179 = var_59 + var_57; + const double var_180 = 0.6250000000000000000000000*var_179 + 12.2000000000000010658141036*w[0][0]*w[1][0] + 0.4166666666666666296592325*var_146; + A[0] = 0.0001603334936668270060446*var_180*var_7; + const double var_181 = -34.2500000000000000000000000*var_34 + 5.7500000000000000000000000*w[0][2]*w[1][2] + -5.0833333333333330372738601*var_10 + -1.0000000000000000000000000*var_118; + const double var_182 = 0.0000128266794933461607546*var_11*var_7; + A[52] = var_182 + 0.0002950136283469617041325*var_130*var_7 + var_78 + var_75; + const double var_183 = 1.8571428571428569842538536*var_11 + var_15; + const double var_184 = -0.0004489337822671156060829*var_183*var_7; + A[82] = var_161 + var_184 + var_178; + A[110] = A[82]; + const double var_185 = var_15 + var_10; + const double var_186 = var_17 + -0.4000000000000000222044605*var_24; + const double var_187 = 0.0010261343594676927519493*var_186*var_7; + A[89] = var_187 + 0.0082090748757415420155947*var_7*w[0][2]*w[1][2] + var_133 + -0.0004104537437870771441478*var_185*var_7; + const double var_188 = var_28 + 19.0000000000000000000000000*var_10; + const double var_189 = 0.0000769600769600769645277*var_188*var_7; + const double var_190 = -0.0013852813852813852801837*var_69*var_7 + 0.0007696007696007695639620*var_11*var_7; + A[162] = var_190 + var_189 + var_25; + A[190] = A[162]; + const double var_191 = -0.0000555822778045000299367*var_11*var_7; + const double var_192 = -1.0000000000000000000000000*var_172 + -5.0833333333333330372738601*var_11 + 5.7500000000000000000000000*w[0][0]*w[1][0] + -34.2500000000000000000000000*var_146; + A[17] = 0.0000032066698733365401887*var_192*var_7; + A[98] = 0.0000513067179733846430185*var_7*var_96 + 0.0022574955908289239675524*var_16*var_7; + const double var_193 = var_57 + var_15 + 2.0000000000000000000000000*var_146; + A[72] = -0.0004617604617604617600612*var_193*var_7 + -0.0013083213083213084647338*var_11*var_7; + A[184] = A[72]; + const double var_194 = var_191 + -0.0001154401154401154400153*var_15*var_7; + const double var_195 = -0.0004489337822671156060829*var_7*var_99; + const double var_196 = -0.0022061888728555395684794*var_7*w[0][1]*w[1][1] + var_177; + const double var_197 = 0.0800000000000000016653345*var_14 + var_36; + const double var_198 = -0.0028860028860028860003828*var_197*var_7; + A[145] = var_196 + var_198 + var_195; + A[159] = A[145]; + const double var_199 = var_103 + var_40; + const double var_200 = 0.0012313612313612314324435*var_199*var_7; + A[57] = var_200 + var_138 + var_89; + const double var_201 = -0.0004467960023515579227882*var_7*w[0][1]*w[1][1] + 0.0000064133397466730803773*var_17*var_7; + const double var_202 = -1.0000000000000000000000000*var_15; + const double var_203 = 0.3333333333333333148296163*var_46 + var_202; + const double var_204 = 0.0000192400192400192411319*var_203*var_7; + A[33] = var_168 + var_201 + var_204; + const double var_205 = var_14 + 1.8571428571428569842538536*var_10; + const double var_206 = -0.0004489337822671156060829*var_205*var_7; + const double var_207 = -0.0022446689113355781930448*var_69*var_7 + -0.0002308802308802308800306*var_11*var_7; + A[114] = var_206 + var_178 + var_207; + const double var_208 = 0.0004377104377104376739180*var_7*w[0][1]*w[1][1]; + const double var_209 = -0.0123456790123456783270228*var_57 + 0.0703703703703703747907028*var_11 + var_202; + const double var_210 = 0.0012987012987012987001723*var_209*var_7; + A[10] = var_49 + var_208 + var_210; + const double var_211 = 0.0004377104377104376739180*var_7*w[0][2]*w[1][2]; + const double var_212 = 0.6666666666666666296592325*var_11 + var_146; + A[173] = A[131]; + const double var_213 = 32.3333333333333285963817616*w[0][2]*w[1][2] + var_10; + const double var_214 = -0.0000192400192400192411319*var_213*var_7; + const double var_215 = 3.8000000000000002664535259*var_11 + var_15; + const double var_216 = -0.0000641333974667307969968*var_215*var_7; + A[14] = var_216 + var_109 + var_214; + const double var_217 = 0.0016931216931216931925047*var_69*var_7 + 0.0007696007696007695639620*var_46*var_7; + A[34] = var_100 + var_123 + var_208; + A[62] = A[34]; + const double var_218 = 1.8888888888888888395456433*var_35 + 1.3333333333333332593184650*var_34 + var_10; + const double var_219 = -0.0022446689113355781930448*var_24*var_7 + -0.0002308802308802308800306*var_17*var_7; + A[55] = var_219 + var_184 + var_68; + A[153] = A[55]; + const double var_220 = 19.0000000000000000000000000*var_17 + var_40; + const double var_221 = 0.0000769600769600769645277*var_220*var_7; + A[117] = var_221 + var_190 + var_94; + A[187] = A[117]; + const double var_222 = 0.0000427555983111538691821*var_17*var_7; + A[38] = var_174 + var_95 + var_222 + -0.0000855111966223077383641*var_114*var_7; + A[122] = A[38]; + const double var_223 = var_191 + 0.0005772005772005772000766*var_15*var_7; + const double var_224 = var_59 + 0.0800000000000000016653345*var_15; + const double var_225 = 9.6666666666666660745477202*var_11 + 5.6666666666666660745477202*var_57 + var_69; + A[50] = 0.0000513067179733846430185*var_225*var_7 + 0.0022574955908289239675524*var_146*var_7; + A[78] = A[50]; + const double var_226 = 0.0119715675271230819615154*var_7*w[0][1]*w[1][1] + var_115; + const double var_227 = -0.0028860028860028860003828*var_224*var_7; + A[65] = var_196 + var_227 + var_154; + A[79] = A[65]; + const double var_228 = 0.0024627224627224628648869*var_7*var_8 + var_136; + A[88] = var_228 + var_98 + var_30; + A[200] = A[88]; + A[149] = var_149 + var_136 + var_156; + A[219] = A[149]; + const double var_229 = 0.0010582010582010582724205*var_35 + 0.0005194805194805194800689*var_117 + 0.0067340067340067337117726*w[0][2]*w[1][2]; + const double var_230 = 29.0000000000000000000000000*w[0][0]*w[1][0] + -2.1666666666666665186369300*var_57 + var_46; + A[115] = -0.0003174603174603174600421*var_146*var_7 + 0.0000577200577200577200077*var_230*var_7; + A[157] = A[115]; + A[179] = var_200 + var_47 + var_156; + A[221] = A[179]; + A[7] = var_120 + var_211 + var_210; + A[105] = A[7]; + const double var_231 = var_17 + 32.3333333333333285963817616*w[0][1]*w[1][1]; + const double var_232 = -0.0001090267756934423630261*var_17*var_7 + var_9; + A[23] = var_232 + var_194 + var_82; + const double var_233 = var_65 + var_16; + A[84] = 0.0004617604617604617600612*var_233*var_7 + 0.0005130671797338463759747*var_7*var_8 + var_61; + const double var_234 = var_17 + 10.8571428571428558740308290*w[0][1]*w[1][1]; + const double var_235 = -0.0004489337822671156060829*var_234*var_7; + const double var_236 = var_34 + var_118; + const double var_237 = 0.0000064133397466730803773*var_10*var_7 + -0.0004467960023515579227882*var_7*w[0][2]*w[1][2]; + const double var_238 = 0.0004617604617604617600612*var_10*var_7; + const double var_239 = 0.0001539201539201539290554*var_7*var_8; + A[129] = var_84 + var_238 + var_239 + 0.0002907380685158463375431*var_7*var_72; + const double var_240 = var_46 + -26.5555555555555535818257340*w[0][0]*w[1][0]; + const double var_241 = 0.0000192400192400192411319*var_240*var_7; + A[21] = var_232 + var_92 + var_241; + A[91] = A[21]; + A[121] = A[23]; + const double var_242 = var_36 + 0.0363636363636363618700997*w[0][2]*w[1][2]; + const double var_243 = var_121 + 0.3333333333333333148296163*var_43; + const double var_244 = 0.0000192400192400192411319*var_243*var_7; + const double var_245 = -0.0022061888728555395684794*var_7*w[0][2]*w[1][2] + var_67; + const double var_246 = var_103 + 0.0800000000000000016653345*var_8; + const double var_247 = -0.0028860028860028860003828*var_246*var_7; + A[97] = var_247 + var_195 + var_245; + A[111] = A[97]; + const double var_248 = 10.9761904761904762750646114*var_17 + 2.4523809523809521060400129*var_12 + 18.1904761904761897994831088*var_16 + var_8; + A[112] = 0.0004040404040404040400536*var_248*var_7; + A[103] = var_143 + var_149 + var_89; + A[201] = A[103]; + const double var_249 = var_238 + 0.0119715675271230819615154*var_7*w[0][2]*w[1][2]; + A[81] = 0.0002907380685158463375431*var_130*var_7 + var_239 + var_106 + var_140; + A[95] = A[81]; + A[16] = 0.0001603334936668270060446*var_163*var_7; + A[199] = A[73]; + A[1] = 0.0000032066698733365401887*var_181*var_7; + A[15] = A[1]; + A[100] = var_160 + var_207 + var_68; + const double var_250 = 0.0000427555983111538691821*var_10*var_7; + A[26] = var_95 + -0.0000855111966223077383641*var_7*var_72 + var_20 + var_250; + A[166] = A[26]; + const double var_251 = 2.4523809523809521060400129*var_35 + 18.1904761904761897994831088*var_34 + var_14 + 10.9761904761904762750646114*var_10; + A[160] = 0.0004040404040404040400536*var_251*var_7; + A[215] = A[89]; + const double var_252 = 8.2000000000000010658141036*var_34 + var_175; + A[40] = 0.0001058201058201058245315*var_43*var_7 + var_151 + 0.0000080166746833413496246*var_252*var_7; + const double var_253 = 0.0005194805194805194800689*var_212 + 0.0010582010582010582724205*var_57 + 0.0067340067340067337117726*w[0][0]*w[1][0]; + A[148] = var_228 + var_45 + var_86; + A[150] = A[10]; + A[163] = var_93 + var_217 + var_189; + A[205] = A[163]; + const double var_254 = 3.4000000000000003552713679*var_212 + var_172 + 2.0000000000000000000000000*var_15; + A[12] = 0.0000962000962000961954953*var_254*var_7; + A[210] = A[14]; + const double var_255 = 0.0009235209235209235201225*var_69*var_7 + 0.0009406231628453850949004*var_11*var_7; + A[132] = var_48 + var_88 + var_30; + A[188] = A[132]; + A[47] = A[33]; + const double var_256 = -0.0000192400192400192411319*var_231*var_7; + const double var_257 = -0.0000448933782267115592530*var_64*var_7; + A[43] = var_256 + var_257 + var_113; + A[197] = A[43]; + const double var_258 = 0.0001410934744268077479720*var_14*var_7; + A[85] = var_182 + var_129 + var_258 + 0.0002950136283469617041325*var_185*var_7; + const double var_259 = 0.6666666666666666296592325*var_17 + var_16; + const double var_260 = 0.0010582010582010582724205*var_12 + 0.0067340067340067337117726*w[0][1]*w[1][1] + 0.0005194805194805194800689*var_259; + A[56] = 0.8888888888888888395456433*var_260*var_7; + const double var_261 = -0.0000555822778045000299367*var_17*var_7; + const double var_262 = -0.0001154401154401154400153*var_7*var_8 + var_261; + const double var_263 = var_59 + 0.0363636363636363618700997*w[0][0]*w[1][0]; + const double var_264 = 0.0084656084656084661793640*var_263*var_7; + A[223] = A[209]; + A[67] = 0.0000577200577200577200077*var_141*var_7 + -0.0003174603174603174600421*var_34*var_7; + A[109] = A[67]; + A[35] = var_174 + var_54 + var_145 + -0.0000855111966223077383641*var_185*var_7; + A[77] = A[35]; + const double var_265 = var_12 + 2.0000000000000000000000000*var_16 + var_8; + A[118] = -0.0004617604617604617600612*var_265*var_7 + -0.0013083213083213084647338*var_17*var_7; + A[202] = A[118]; + A[13] = var_216 + var_256 + var_32; + A[195] = A[13]; + const double var_266 = -2.1666666666666665186369300*var_12 + 29.0000000000000000000000000*w[0][1]*w[1][1] + var_18; + A[29] = var_257 + var_125 + var_214; + A[39] = var_262 + var_152 + var_241; + A[137] = A[39]; + A[119] = var_27 + var_221 + var_217; + A[217] = A[119]; + A[168] = A[56]; + const double var_267 = var_15 + 10.9761904761904762750646114*var_11 + 2.4523809523809521060400129*var_57 + 18.1904761904761897994831088*var_146; + const double var_268 = 0.0005772005772005772000766*var_7*var_8 + var_261; + A[108] = A[52]; + const double var_269 = -0.0022061888728555395684794*var_7*w[0][0]*w[1][0] + var_157; + A[113] = var_247 + var_269 + var_154; + A[127] = A[113]; + A[27] = var_111 + var_125 + var_32; + A[181] = A[27]; + const double var_270 = 0.0082090748757415420155947*var_7*w[0][0]*w[1][0]; + A[102] = var_33 + -0.0004104537437870771441478*var_7*var_77 + var_132 + var_270; + A[186] = A[102]; + A[64] = 0.0004040404040404040400536*var_267*var_7; + const double var_271 = -4.0000000000000000000000000*var_14 + var_36; + const double var_272 = 0.0000641333974667307969968*var_271*var_7; + A[6] = var_222 + var_102 + var_272 + -0.0000855111966223077383641*var_7*var_77; + A[90] = A[6]; + A[60] = A[4]; + const double var_273 = var_65 + 3.4000000000000003552713679*var_259 + 2.0000000000000000000000000*var_8; + A[28] = 0.0000962000962000961954953*var_273*var_7; + A[128] = var_249 + var_255 + var_105; + A[19] = var_100 + var_211 + var_53; + A[61] = A[19]; + A[9] = -0.0000855111966223077383641*var_128*var_7 + var_102 + var_145 + var_250; + A[135] = A[9]; + A[11] = var_201 + var_244 + var_223; + A[99] = 0.8888888888888888395456433*var_253*var_7; + const double var_274 = var_17 + 1.8888888888888888395456433*var_12 + 1.3333333333333332593184650*var_16; + A[208] = 0.0270899470899470910800755*var_7*w[0][1]*w[1][1] + 0.0055411255411255411207350*var_274*var_7; + const double var_275 = 0.0009235209235209235201225*var_24*var_7 + 0.0009406231628453850949004*var_17*var_7; + A[123] = A[53]; + A[152] = A[40]; + A[139] = A[69]; + const double var_276 = 0.0015392015392015391279240*var_10*var_7; + A[147] = -0.0004104537437870771441478*var_128*var_7 + var_187 + var_276 + var_270; + const double var_277 = 0.0084656084656084661793640*var_242*var_7; + A[176] = var_255 + var_226 + var_277; + A[156] = A[100]; + A[71] = var_206 + var_158 + var_219; + A[169] = A[71]; + A[83] = 0.8888888888888888395456433*var_229*var_7; + A[155] = A[85]; + A[130] = var_258 + var_79 + var_73 + 0.0002950136283469617041325*var_114*var_7; + A[158] = A[130]; + A[204] = A[148]; + A[146] = 0.0022574955908289239675524*var_34*var_7 + 0.0000513067179733846430185*var_7*var_71; + A[41] = var_194 + var_127 + var_152; + A[167] = A[41]; + A[142] = A[114]; + A[214] = A[74]; + A[178] = var_76 + var_164 + var_276 + -0.0004104537437870771441478*var_7*var_72; + A[206] = A[178]; + A[212] = A[44]; + A[54] = var_62 + var_106 + var_116 + 0.0002907380685158463375431*var_185*var_7; + A[140] = A[84]; + A[31] = A[17]; + A[5] = var_262 + var_171 + var_82; + A[75] = A[5]; + A[48] = var_264 + var_108 + var_226; + A[143] = A[129]; + A[224] = 0.0270899470899470910800755*var_7*w[0][2]*w[1][2] + 0.0055411255411255411207350*var_218*var_7; + const double var_278 = var_103 + var_13; + A[80] = var_264 + var_249 + var_275; + A[180] = A[12]; + A[196] = A[28]; + A[161] = var_198 + var_235 + var_269; + A[175] = A[161]; + A[138] = A[54]; + A[51] = 0.0005130671797338463759747*var_14*var_7 + 0.0004617604617604617600612*var_236*var_7 + var_139; + A[93] = A[51]; + A[192] = 0.0055411255411255411207350*var_147*var_7 + 0.0270899470899470910800755*var_7*w[0][0]*w[1][0]; + A[49] = var_235 + var_227 + var_245; + A[63] = A[49]; + A[70] = 0.0000577200577200577200077*var_266*var_7 + -0.0003174603174603174600421*var_16*var_7; + A[154] = A[70]; + A[213] = A[59]; + A[211] = A[29]; + A[174] = A[146]; + A[141] = A[99]; + A[20] = var_237 + var_268 + var_204; + A[76] = A[20]; + A[194] = var_56 + 0.0018470418470418470402450*var_278*var_7; + A[24] = var_268 + var_244 + var_165; + A[136] = A[24]; + A[86] = var_150 + 0.0002907380685158463375431*var_128*var_7 + var_238 + var_62; + A[8] = var_237 + var_167 + var_223; + A[120] = A[8]; + A[222] = A[194]; + A[183] = A[57]; + A[172] = A[116]; + A[203] = A[133]; + A[18] = -0.0000855111966223077383641*var_130*var_7 + var_272 + var_54 + var_20; + A[46] = A[18]; + A[125] = A[83]; + A[30] = A[2]; + A[165] = A[11]; + A[189] = A[147]; + A[170] = A[86]; + A[126] = A[98]; + A[144] = var_277 + var_275 + var_107; + A[92] = A[36]; + } + + 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/mass_matrix_2d/mass_matrix_f2_p1_q4_quadrature.h b/mass_matrix_2d/mass_matrix_f2_p1_q4_quadrature.h new file mode 100644 index 0000000..d2db7a7 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p1_q4_quadrature.h @@ -0,0 +1,6480 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P1_Q4_QUADRATURE_H +#define __MASS_MATRIX_F2_P1_Q4_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p1_q4_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p1_q4_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f2_p1_q4_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p1_q4_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p1_q4_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p1_q4_quadrature_finite_element_1() + { + // 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.0224478343233824, 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.0412393049421162, -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.0388807895679869, 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.0439885919382571, 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.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 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.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.00927360943924092, 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.0535412090610519}; + + // 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.0622092633087791, -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.251415744421884, 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.0224478343233824, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0412393049421162, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0388807895679869, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0439885919382571, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.00927360943924092, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0622092633087791, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.251415744421884, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p1_q4_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p1_q4_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p1_q4_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f2_p1_q4_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p1_q4_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p1_q4_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_p1_q4_quadrature_dofmap_1() + { + // 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.0*m.num_entities[1] + 3.0*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 mass_matrix_f2_p1_q4_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 mass_matrix_f2_p1_q4_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p1_q4_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Array of quadrature weights. + static const double W36[36] = {0.00619426535265906, 0.0116108747669979, 0.0120606064042655, 0.0084515357969434, 0.0037652982126918, 0.000748542561236343, 0.0130433943300833, 0.0244492622580587, 0.0253962715890485, 0.0177965759970269, 0.00792866733379675, 0.00157622175402364, 0.0169175056800133, 0.0317111115907051, 0.0329393989007878, 0.023082463651359, 0.0102836172287667, 0.00204438659154493, 0.0169175056800133, 0.0317111115907051, 0.0329393989007878, 0.023082463651359, 0.0102836172287667, 0.00204438659154493, 0.0130433943300833, 0.0244492622580587, 0.0253962715890485, 0.0177965759970269, 0.00792866733379675, 0.00157622175402364, 0.00619426535265908, 0.0116108747669979, 0.0120606064042655, 0.00845153579694342, 0.00376529821269181, 0.000748542561236345}; + // Quadrature points on the UFC reference element: (0.0327753666144599, 0.0293164271597849), (0.0287653330125591, 0.148078599668484), (0.0223868729780306, 0.336984690281154), (0.0149015633666711, 0.55867151877155), (0.00779187470128645, 0.769233862030055), (0.00246669715267023, 0.926945671319741), (0.164429241594827, 0.0293164271597849), (0.144311486950417, 0.148078599668484), (0.112311681780954, 0.336984690281154), (0.0747589734626491, 0.55867151877155), (0.0390907007328242, 0.769233862030055), (0.01237506041744, 0.926945671319741), (0.369529924372377, 0.0293164271597849), (0.324318304588776, 0.148078599668484), (0.252403568076518, 0.336984690281154), (0.168009519121192, 0.55867151877155), (0.0878504549759972, 0.769233862030055), (0.0278110821153606, 0.926945671319741), (0.601153648467838, 0.0293164271597849), (0.52760309574274, 0.148078599668484), (0.410611741642328, 0.336984690281154), (0.273318962107258, 0.55867151877155), (0.142915682993948, 0.769233862030055), (0.0452432465648983, 0.926945671319741), (0.806254331245388, 0.0293164271597849), (0.707609913381099, 0.148078599668484), (0.550703627937892, 0.336984690281154), (0.366569507765801, 0.55867151877155), (0.191675437237121, 0.769233862030055), (0.0606792682628189, 0.926945671319741), (0.937908206225755, 0.0293164271597849), (0.823156067318956, 0.148078599668484), (0.640628436740815, 0.336984690281154), (0.426426917861779, 0.55867151877155), (0.222974263268659, 0.769233862030055), (0.0705876315275886, 0.926945671319741) + + // Value of basis functions at quadrature points. + static const double FE0[36][3] = \ + {{0.937908206225755, 0.03277536661446, 0.0293164271597848}, + {0.823156067318957, 0.0287653330125592, 0.148078599668484}, + {0.640628436740815, 0.0223868729780305, 0.336984690281154}, + {0.426426917861779, 0.0149015633666711, 0.55867151877155}, + {0.222974263268659, 0.00779187470128651, 0.769233862030055}, + {0.0705876315275887, 0.00246669715267028, 0.926945671319741}, + {0.806254331245388, 0.164429241594827, 0.0293164271597848}, + {0.707609913381099, 0.144311486950417, 0.148078599668484}, + {0.550703627937892, 0.112311681780954, 0.336984690281154}, + {0.366569507765801, 0.0747589734626491, 0.55867151877155}, + {0.191675437237121, 0.0390907007328243, 0.769233862030055}, + {0.0606792682628189, 0.0123750604174401, 0.926945671319741}, + {0.601153648467838, 0.369529924372377, 0.0293164271597848}, + {0.52760309574274, 0.324318304588776, 0.148078599668484}, + {0.410611741642328, 0.252403568076518, 0.336984690281154}, + {0.273318962107258, 0.168009519121192, 0.55867151877155}, + {0.142915682993948, 0.0878504549759972, 0.769233862030055}, + {0.0452432465648984, 0.0278110821153607, 0.926945671319741}, + {0.369529924372377, 0.601153648467839, 0.0293164271597848}, + {0.324318304588776, 0.52760309574274, 0.148078599668484}, + {0.252403568076518, 0.410611741642328, 0.336984690281154}, + {0.168009519121192, 0.273318962107258, 0.55867151877155}, + {0.0878504549759972, 0.142915682993948, 0.769233862030055}, + {0.0278110821153607, 0.0452432465648984, 0.926945671319741}, + {0.164429241594827, 0.806254331245388, 0.0293164271597848}, + {0.144311486950417, 0.707609913381099, 0.148078599668484}, + {0.112311681780954, 0.550703627937892, 0.336984690281154}, + {0.0747589734626489, 0.366569507765801, 0.55867151877155}, + {0.0390907007328242, 0.191675437237121, 0.769233862030055}, + {0.0123750604174401, 0.0606792682628189, 0.926945671319741}, + {0.03277536661446, 0.937908206225755, 0.0293164271597848}, + {0.0287653330125592, 0.823156067318957, 0.148078599668484}, + {0.0223868729780305, 0.640628436740815, 0.336984690281154}, + {0.0149015633666711, 0.426426917861779, 0.55867151877155}, + {0.00779187470128645, 0.222974263268659, 0.769233862030055}, + {0.00246669715267034, 0.0705876315275887, 0.926945671319741}}; + + static const double FE1[36][15] = \ + {{0.56630237132032, -0.025448739951231, -0.02340903093109, 0.00416085056960128, 0.00294793329848728, 0.00425839910756952, 0.353405794301071, -0.267147951008896, 0.121859429227921, 0.395102868735011, -0.293986529335415, 0.133116353941705, 0.0793522773075458, -0.0250575137648273, -0.0254565128177721}, + {0.118972466830072, -0.0230709318617449, -0.0341013730463095, 0.018947016495499, 0.00614695794455526, 0.00651870726857255, 0.963270822664205, -0.455714379551745, 0.186540981008593, 0.18712228544335, -0.192157632298739, 0.105324818176152, 0.257233041221556, -0.099290349448832, -0.045742430845185}, + {-0.0410559740731875, -0.0188884466735285, 0.0210511710271628, 0.0349917675522029, -0.00955924750821981, -0.00456418811345946, 0.505990196901837, 0.469464799398205, -0.130609964999847, 0.0336144002765209, -0.0816095123137331, 0.0665214829999042, 0.241648244025793, -0.140804681095384, 0.0538099525957325}, + {0.0191042291114048, -0.0133255662493701, -0.0206485123834592, 0.0405094826163528, -0.0386646995111557, 0.00643281363514752, -0.131939141811172, 0.830314310030356, 0.184083027003091, -0.00351924058446104, -0.0168682880103284, 0.0309203767076776, 0.080169244991654, -0.106829866961562, 0.140261831415824}, + {-0.00938453904605184, -0.00735417356108037, 0.0220620722354296, 0.0304878329277379, -0.0482427486128633, 0.0357504701324324, 0.0547897737103965, -0.154040051327386, 1.02304452328671, 0.000554987335758502, 0.000727851735427045, 0.00883736717957267, -0.00462319916590223, -0.0414337049897014, 0.0888235381595224}, + {-0.039411023284595, -0.00242231653722821, 0.505649261589883, 0.0120147467421047, -0.0245209639812787, 0.0281958543435565, 0.215079260438399, -0.508591455559504, 0.806859721248732, 0.000572347890212842, 0.000494891999080295, 0.000914932279387579, -0.00370647497562177, -0.0051137834055052, 0.0139850012123767}, + {0.0824161637725179, -0.0294914855256902, -0.02340903093109, 0.00590593006797314, 0.00582593260452294, 0.0213637682196615, 0.171801701915994, -0.185697684231962, 0.104754060115829, 0.963597078074327, -0.40385910184121, 0.162423670230445, 0.276723174191905, -0.0425693977624813, -0.109784778900741}, + {-0.0303969806920391, -0.0350490773722188, -0.0341013730463095, 0.0342751641157549, 0.0147321571899481, 0.0327034051200263, 0.424735375088394, -0.312771366460782, 0.160356283157139, 0.413930126815579, -0.316080712840952, 0.163787650378721, 0.885711947101502, -0.204561955373223, -0.19727064318154}, + {-0.0178494055445301, -0.0407795027424123, 0.0210511710271628, 0.0861992776649916, -0.0290104851672837, -0.0228978671335801, 0.120724252767667, 0.310663028371925, -0.112276285979726, 0.040235489181343, -0.163892320828179, 0.140867690149755, 0.802235130592271, -0.36733313364048, 0.232062961281076}, + {0.0233190985494116, -0.0401256259898051, -0.0206485123834592, 0.132794326958115, -0.144587977270839, 0.032272489268862, -0.135906939764466, 0.47160061549191, 0.158243351369376, -0.0181864708721552, -0.0358278205906738, 0.0871323298781454, 0.228439462369848, -0.343417130728224, 0.604898803713954}, + {-0.0205277588289655, -0.0288155938118291, 0.0220620722354296, 0.124718754065599, -0.21075144429941, 0.179354902713459, 0.113128801818687, -0.285771773170361, 0.879440090705682, 0.00574894626256647, 0.0058988467391181, 0.031077053282736, -0.0430288533926338, -0.155598000009121, 0.383063955689044}, + {-0.0371082327213856, -0.0112820903294173, 0.505649261589883, 0.0567111236787091, -0.118093887044145, 0.141454495394839, 0.199601225425082, -0.461345808814886, 0.69360108019745, 0.00266474864758105, 0.00216201065863758, 0.00371239609144181, -0.0168674754837758, -0.0211711248206387, 0.0603122775306251}, + {-0.0339024544799458, 0.023387640004351, -0.02340903093109, -0.00720836763307398, -0.0182888871179095, 0.0480118473937476, 0.0267093906452789, -0.0874064926762268, 0.0781059809417426, 0.336668552801051, 0.596745158445697, -0.147812572060763, 0.292720606365088, 0.0996397790360984, -0.183961150734045}, + {-0.0095906246236551, 0.0192268203241027, -0.0341013730463094, -0.0267531412354512, -0.0232811757502806, 0.0734959712974962, 0.0255429142588088, -0.141471609601455, 0.119563716979669, 0.0559434966647409, 0.225932583629769, -0.0953212697058672, 0.900337562556068, 0.241033195353002, -0.330557067100639}, + {0.0213409951908707, 0.000797264231187582, 0.0210511710271628, -0.00215970873408773, 0.00113811168767276, -0.0514595033589619, -0.0847594279128907, 0.123720487246374, -0.0837146497543445, -0.0634853233702957, 0.00256059295790888, -0.00263157879369526, 0.717999738211763, 0.0107449258196653, 0.388856905551671}, + {0.00734599742741782, -0.02839014160368, -0.0206485123834592, 0.109010467002261, -0.152030381966887, 0.0725275529045928, -0.0344381186867421, 0.0703415678092674, 0.117988287733645, -0.0103565898127769, -0.00561896434021046, 0.0533312093041724, 0.0765736536295873, -0.269236283109832, 1.01360025609264}, + {-0.0353878578540361, -0.0414666912205211, 0.0220620722354296, 0.192691111987477, -0.364133910121009, 0.403073096930251, 0.179359194783873, -0.391207466820726, 0.65572189648889, 0.0204837405679316, 0.0139522896496609, 0.0358000125005907, -0.132378708183015, -0.200450896105804, 0.641882115161008}, + {-0.031669348089454, -0.0224768586657739, 0.505649261589883, 0.115398208580281, -0.248158040619958, 0.317897646905111, 0.166615019902697, -0.372031802654953, 0.517157928687178, 0.00499893806458903, 0.00366363544055174, 0.00563246559694469, -0.0305685004026728, -0.0331709792809288, 0.101062424946505}, + {0.023387640004351, -0.0339024544799458, -0.02340903093109, 0.0267093906452788, -0.0874064926762267, 0.0781059809417426, -0.00720836763307393, -0.0182888871179095, 0.0480118473937476, -0.147812572060763, 0.596745158445697, 0.336668552801051, 0.0996397790360983, 0.292720606365088, -0.183961150734045}, + {0.0192268203241027, -0.00959062462365504, -0.0341013730463094, 0.0255429142588087, -0.141471609601455, 0.119563716979669, -0.0267531412354512, -0.0232811757502805, 0.0734959712974963, -0.0953212697058673, 0.22593258362977, 0.0559434966647408, 0.241033195353002, 0.900337562556068, -0.330557067100639}, + {0.000797264231187593, 0.0213409951908707, 0.0210511710271628, -0.0847594279128908, 0.123720487246374, -0.0837146497543445, -0.00215970873408771, 0.00113811168767294, -0.0514595033589619, -0.00263157879369533, 0.00256059295790887, -0.0634853233702957, 0.0107449258196652, 0.717999738211763, 0.388856905551671}, + {-0.0283901416036801, 0.00734599742741785, -0.0206485123834592, -0.0344381186867421, 0.0703415678092673, 0.117988287733645, 0.109010467002261, -0.152030381966887, 0.0725275529045927, 0.0533312093041724, -0.00561896434021046, -0.0103565898127769, -0.269236283109833, 0.0765736536295877, 1.01360025609264}, + {-0.0414666912205212, -0.035387857854036, 0.0220620722354296, 0.179359194783873, -0.391207466820727, 0.65572189648889, 0.192691111987477, -0.364133910121008, 0.403073096930251, 0.0358000125005907, 0.0139522896496609, 0.0204837405679316, -0.200450896105804, -0.132378708183015, 0.641882115161008}, + {-0.0224768586657739, -0.031669348089454, 0.505649261589883, 0.166615019902697, -0.372031802654953, 0.517157928687178, 0.115398208580281, -0.248158040619958, 0.317897646905111, 0.00563246559694458, 0.00366363544055176, 0.00499893806458915, -0.0331709792809289, -0.0305685004026726, 0.101062424946505}, + {-0.0294914855256903, 0.0824161637725182, -0.02340903093109, 0.171801701915994, -0.185697684231962, 0.104754060115829, 0.00590593006797323, 0.00582593260452294, 0.0213637682196615, 0.162423670230446, -0.40385910184121, 0.963597078074327, -0.0425693977624813, 0.276723174191904, -0.109784778900741}, + {-0.0350490773722189, -0.030396980692039, -0.0341013730463095, 0.424735375088395, -0.312771366460783, 0.160356283157139, 0.034275164115755, 0.0147321571899484, 0.0327034051200263, 0.163787650378721, -0.316080712840952, 0.41393012681558, -0.204561955373223, 0.885711947101502, -0.19727064318154}, + {-0.0407795027424123, -0.0178494055445301, 0.0210511710271628, 0.120724252767667, 0.310663028371925, -0.112276285979726, 0.0861992776649916, -0.0290104851672834, -0.0228978671335801, 0.140867690149755, -0.163892320828179, 0.040235489181343, -0.36733313364048, 0.802235130592271, 0.232062961281076}, + {-0.0401256259898051, 0.0233190985494116, -0.0206485123834592, -0.135906939764466, 0.471600615491911, 0.158243351369376, 0.132794326958115, -0.144587977270839, 0.0322724892688619, 0.0871323298781453, -0.0358278205906738, -0.0181864708721552, -0.343417130728224, 0.228439462369848, 0.604898803713953}, + {-0.0288155938118291, -0.0205277588289655, 0.0220620722354296, 0.113128801818687, -0.285771773170361, 0.879440090705682, 0.124718754065599, -0.21075144429941, 0.179354902713459, 0.0310770532827359, 0.00589884673911823, 0.00574894626256647, -0.155598000009122, -0.0430288533926335, 0.383063955689044}, + {-0.0112820903294174, -0.0371082327213855, 0.505649261589883, 0.199601225425082, -0.461345808814886, 0.693601080197449, 0.0567111236787092, -0.118093887044145, 0.141454495394839, 0.0037123960914417, 0.00216201065863769, 0.00266474864758115, -0.021171124820639, -0.0168674754837758, 0.0603122775306252}, + {-0.0254487399512311, 0.566302371320319, -0.02340903093109, 0.35340579430107, -0.267147951008896, 0.121859429227921, 0.00416085056960128, 0.00294793329848743, 0.00425839910756955, 0.133116353941706, -0.293986529335416, 0.395102868735012, -0.0250575137648273, 0.0793522773075462, -0.0254565128177724}, + {-0.0230709318617449, 0.118972466830072, -0.0341013730463095, 0.963270822664205, -0.455714379551745, 0.186540981008593, 0.018947016495499, 0.00614695794455568, 0.00651870726857255, 0.105324818176152, -0.192157632298739, 0.18712228544335, -0.0992903494488324, 0.257233041221557, -0.045742430845185}, + {-0.0188884466735285, -0.0410559740731874, 0.0210511710271628, 0.505990196901837, 0.469464799398205, -0.130609964999847, 0.034991767552203, -0.00955924750821949, -0.00456418811345951, 0.0665214829999044, -0.0816095123137332, 0.0336144002765209, -0.140804681095384, 0.241648244025794, 0.0538099525957328}, + {-0.0133255662493701, 0.0191042291114048, -0.0206485123834592, -0.131939141811172, 0.830314310030356, 0.184083027003091, 0.0405094826163529, -0.0386646995111555, 0.00643281363514756, 0.0309203767076776, -0.0168682880103284, -0.00351924058446107, -0.106829866961562, 0.0801692449916541, 0.140261831415824}, + {-0.00735417356108038, -0.00938453904605184, 0.0220620722354296, 0.0547897737103965, -0.154040051327387, 1.02304452328671, 0.0304878329277378, -0.0482427486128629, 0.0357504701324325, 0.00883736717957254, 0.000727851735427243, 0.000554987335758443, -0.0414337049897016, -0.00462319916590201, 0.0888235381595222}, + {-0.00242231653722834, -0.0394110232845949, 0.505649261589883, 0.215079260438399, -0.508591455559504, 0.806859721248731, 0.0120147467421051, -0.0245209639812793, 0.0281958543435579, 0.000914932279387486, 0.000494891999080461, 0.000572347890212904, -0.00511378340550558, -0.00370647497562168, 0.0139850012123772}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 225; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 24840 + for (unsigned int ip = 0; ip < 36; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + + // Total number of operations to compute function values = 12 + for (unsigned int r = 0; r < 3; r++) + { + F0 += FE0[ip][r]*w[0][r]; + F1 += FE0[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 3 + double I[1]; + // Number of operations: 3 + I[0] = F0*F1*W36[ip]*det; + + + // Number of operations for primary indices: 675 + for (unsigned int j = 0; j < 15; j++) + { + for (unsigned int k = 0; k < 15; k++) + { + // Number of operations to compute entry: 3 + A[j*15 + k] += FE1[ip][j]*FE1[ip][k]*I[0]; + }// 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 mass_matrix_f2_p1_q4_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p1_q4_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p1_q4_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1))), 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 mass_matrix_f2_p1_q4_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p1_q4_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p1_q4_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p1_q4_quadrature_finite_element_0(); + 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 mass_matrix_f2_p1_q4_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p1_q4_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p1_q4_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p1_q4_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f2_p1_q4_tensor.h b/mass_matrix_2d/mass_matrix_f2_p1_q4_tensor.h new file mode 100644 index 0000000..6514ae4 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p1_q4_tensor.h @@ -0,0 +1,6595 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P1_Q4_TENSOR_H +#define __MASS_MATRIX_F2_P1_Q4_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p1_q4_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p1_q4_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f2_p1_q4_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p1_q4_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p1_q4_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p1_q4_tensor_finite_element_1() + { + // 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.0224478343233824, 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.0412393049421162, -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.0388807895679869, 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.0439885919382571, 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.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 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.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.00927360943924092, 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.0535412090610519}; + + // 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.0622092633087791, -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.251415744421884, 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.0224478343233824, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0412393049421162, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0388807895679869, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0439885919382571, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.00927360943924092, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0622092633087791, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.251415744421884, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p1_q4_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p1_q4_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p1_q4_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f2_p1_q4_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p1_q4_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p1_q4_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_p1_q4_tensor_dofmap_1() + { + // 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.0*m.num_entities[1] + 3.0*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 mass_matrix_f2_p1_q4_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 mass_matrix_f2_p1_q4_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p1_q4_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 13 + // Number of operations (multiply-add pairs) for tensor contraction: 801 + // Total number of operations (multiply-add pairs): 823 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0 = det*w[0][0]*w[1][0]*(1.0); + const double G0_0_1 = det*w[0][0]*w[1][1]*(1.0); + const double G0_0_2 = det*w[0][0]*w[1][2]*(1.0); + const double G0_1_0 = det*w[0][1]*w[1][0]*(1.0); + const double G0_1_1 = det*w[0][1]*w[1][1]*(1.0); + const double G0_1_2 = det*w[0][1]*w[1][2]*(1.0); + const double G0_2_0 = det*w[0][2]*w[1][0]*(1.0); + const double G0_2_1 = det*w[0][2]*w[1][1]*(1.0); + const double G0_2_2 = det*w[0][2]*w[1][2]*(1.0); + + // Compute element tensor + A[108] = 0.000295013628346971*G0_0_0 + 7.696007696008e-05*G0_0_1 + 0.000295013628346971*G0_0_2 + 7.696007696008e-05*G0_1_0 + 0.000141093474426817*G0_1_1 + 1.28266794933473e-05*G0_1_2 + 0.000295013628346971*G0_2_0 + 1.28266794933473e-05*G0_2_1 - 0.00064133397466733*G0_2_2; + A[181] = -A[108] - 0.00032708032708034*G0_0_0 + 3.20666987333665e-05*G0_0_1 + 5.13067179733851e-05*G0_0_2 + 3.20666987333664e-05*G0_1_0 + 7.69600769600819e-05*G0_1_1 - 6.41333974667289e-06*G0_1_2 + 5.13067179733853e-05*G0_2_0 - 6.41333974667287e-06*G0_2_1 - 0.000750360750360776*G0_2_2; + A[192] = 0.027089947089948*G0_0_0 + 0.0104665704665708*G0_0_1 + 0.0104665704665708*G0_0_2 + 0.0104665704665708*G0_1_0 + 0.00738816738816765*G0_1_1 + 0.00554112554112573*G0_1_2 + 0.0104665704665708*G0_2_0 + 0.00554112554112573*G0_2_1 + 0.00738816738816764*G0_2_2; + A[21] = A[181] + 0.000111164555609004*G0_0_0 - 1.06888995777885e-05*G0_0_1 + 0.000134680134680139*G0_0_2 - 1.06888995777885e-05*G0_1_0 + 7.05467372134082e-05*G0_1_1 + 0.000134680134680139*G0_2_0 - 6.41333974667331e-06*G0_2_2; + A[52] = A[108]; + A[26] = -A[181] - 0.000878627545294243*G0_0_0 - 2.13777991555733e-06*G0_0_1 - 0.000329218106995896*G0_0_2 - 2.13777991555735e-06*G0_1_0 + 0.0017316017316018*G0_1_1 + 2.13777991555771e-06*G0_1_2 - 0.000329218106995896*G0_2_0 + 2.13777991555773e-06*G0_2_1 - 0.000194537972315757*G0_2_2; + A[60] = 6.413339746673e-06*G0_0_0 - 8.01667468334152e-06*G0_0_1 - 8.01667468334157e-06*G0_0_2 - 8.01667468334152e-06*G0_1_0 + 6.5736732403402e-05*G0_1_1 - 0.000105820105820109*G0_1_2 - 8.01667468334156e-06*G0_2_0 - 0.000105820105820109*G0_2_1 + 6.57367324034015e-05*G0_2_2; + A[4] = A[60]; + A[47] = -1.92400192400198e-05*G0_0_0 - 5.55822778045019e-05*G0_0_1 + 6.41333974667331e-06*G0_0_2 - 5.55822778045019e-05*G0_1_0 - 0.000446796002351574*G0_1_1 - 6.4133397466733e-06*G0_1_2 + 6.41333974667331e-06*G0_2_0 - 6.41333974667331e-06*G0_2_1 + 0.000577200577200597*G0_2_2; + A[100] = A[47] - 0.00447009780343129*G0_0_0 - 0.000521618299396096*G0_0_1 - 0.000840147506814202*G0_0_2 - 0.000521618299396096*G0_1_0 - 2.13777991555833e-06*G0_1_1 - 0.000224466891133565*G0_1_2 - 0.000840147506814202*G0_2_0 - 0.000224466891133565*G0_2_1 - 0.000820907487574182*G0_2_2; + A[97] = A[100] - 0.000384800384800391*G0_0_0 - 0.000128266794933464*G0_0_2 + 0.000218053551386894*G0_1_1 - 0.000218053551386892*G0_1_2 - 0.000128266794933464*G0_2_0 - 0.000218053551386891*G0_2_1 - 0.00196248196248203*G0_2_2; + A[111] = A[97]; + A[36] = A[47] - 0.000427555983111553*G0_0_0 + 0.000427555983111554*G0_1_1; + A[165] = 0.000577200577200597*G0_0_0 - 6.41333974667332e-06*G0_0_1 + 6.41333974667323e-06*G0_0_2 - 6.4133397466733e-06*G0_1_0 - 0.000446796002351575*G0_1_1 - 5.55822778045021e-05*G0_1_2 + 6.41333974667324e-06*G0_2_0 - 5.55822778045021e-05*G0_2_1 - 1.924001924002e-05*G0_2_2; + A[157] = A[165] + 0.00109668109668113*G0_0_0 - 0.000118646785313455*G0_0_1 - 0.000131473464806803*G0_0_2 - 0.000118646785313455*G0_1_0 + 0.000129335684891246*G0_1_1 - 2.13777991555799e-06*G0_1_2 - 0.000131473464806803*G0_2_0 - 2.13777991555798e-06*G0_2_1 - 0.000298220298220309*G0_2_2; + A[70] = A[157] - 0.00199134199134206*G0_0_0 + 6.73400673400701e-05*G0_0_2 + 0.00199134199134206*G0_1_1 - 6.7340067340069e-05*G0_1_2 + 6.73400673400701e-05*G0_2_0 - 6.7340067340069e-05*G0_2_1; + A[1] = -0.00010982844316178*G0_0_0 - 1.63005718561281e-05*G0_0_1 - 1.06888995777888e-06*G0_0_2 - 1.63005718561281e-05*G0_1_0 - 0.000109828443161781*G0_1_1 - 1.06888995777892e-06*G0_1_2 - 1.06888995777888e-06*G0_2_0 - 1.06888995777892e-06*G0_2_1 + 1.84383517716858e-05*G0_2_2; + A[27] = A[181]; + A[113] = A[97] + 0.00266794933461609*G0_0_0 + 0.000128266794933467*G0_0_1 + 0.000128266794933467*G0_1_0 - 0.000128266794933466*G0_1_2 - 0.000128266794933466*G0_2_1 - 0.00266794933461609*G0_2_2; + A[65] = A[113] + 0.00197530864197537*G0_0_0 + 0.000384800384800396*G0_0_2 - 0.00197530864197538*G0_1_1 - 0.000384800384800397*G0_1_2 + 0.000384800384800396*G0_2_0 - 0.000384800384800398*G0_2_1; + A[208] = A[192] - 0.0197017797017804*G0_0_0 - 0.0049254449254451*G0_0_2 + 0.0197017797017804*G0_1_1 + 0.0049254449254451*G0_1_2 - 0.0049254449254451*G0_2_0 + 0.0049254449254451*G0_2_1; + A[31] = 1.84383517716857e-05*G0_0_0 - 1.06888995777891e-06*G0_0_1 - 1.06888995777889e-06*G0_0_2 - 1.06888995777891e-06*G0_1_0 - 0.00010982844316178*G0_1_1 - 1.6300571856128e-05*G0_1_2 - 1.06888995777889e-06*G0_2_0 - 1.6300571856128e-05*G0_2_1 - 0.00010982844316178*G0_2_2; + A[76] = -1.92400192400199e-05*G0_0_0 + 6.41333974667343e-06*G0_0_1 - 5.55822778045019e-05*G0_0_2 + 6.41333974667342e-06*G0_1_0 + 0.000577200577200597*G0_1_1 - 6.41333974667328e-06*G0_1_2 - 5.55822778045019e-05*G0_2_0 - 6.41333974667328e-06*G0_2_1 - 0.000446796002351573*G0_2_2; + A[153] = A[100] + 0.00404040404040418*G0_0_0 + 0.00060285393618729*G0_0_2 - 0.00404040404040419*G0_1_1 - 0.000602853936187292*G0_1_2 + 0.00060285393618729*G0_2_0 - 0.000602853936187292*G0_2_1; + A[110] = A[153] + 0.00034632034632036*G0_0_1 - 0.000346320346320357*G0_0_2 + 0.00034632034632036*G0_1_0 + 0.00424563091229774*G0_1_1 - 0.000346320346320357*G0_2_0 - 0.00424563091229772*G0_2_2; + A[175] = A[113] - 0.000513067179733865*G0_0_1 + 0.000513067179733862*G0_0_2 - 0.000513067179733865*G0_1_0 - 0.00464325797659148*G0_1_1 + 0.000513067179733862*G0_2_0 + 0.00464325797659146*G0_2_2; + A[20] = A[76]; + A[11] = A[165]; + A[25] = -A[26] + 0.000181176847843521*G0_0_0 + 2.67222489444724e-05*G0_0_1 + 5.87889476778387e-06*G0_0_2 + 2.67222489444724e-05*G0_1_0 + 0.000497033830367185*G0_1_1 + 5.34444978889447e-06*G0_1_2 + 5.87889476778387e-06*G0_2_0 + 5.34444978889448e-06*G0_2_1 - 4.86344930789393e-05*G0_2_2; + A[46] = -A[25] + 0.000352199241088143*G0_0_0 + 5.34444978889427e-06*G0_0_1 + 5.8788947677839e-06*G0_0_2 + 5.34444978889428e-06*G0_1_0 + 0.000497033830367176*G0_1_1 + 2.67222489444717e-05*G0_1_2 + 5.87889476778391e-06*G0_2_0 + 2.67222489444717e-05*G0_2_1 - 0.000219656886323561*G0_2_2; + A[35] = A[46] - 0.000106888995777889*G0_0_1 + 0.000106888995777888*G0_0_2 - 0.000106888995777889*G0_1_0 - 0.00205226871893546*G0_1_1 + 0.000106888995777888*G0_2_0 + 0.00205226871893545*G0_2_2; + A[211] = -A[46] - 0.000194537972315756*G0_0_0 + 2.13777991555801e-06*G0_0_1 - 0.000329218106995896*G0_0_2 + 2.13777991555803e-06*G0_1_0 + 0.00173160173160179*G0_1_1 - 2.13777991555802e-06*G0_1_2 - 0.000329218106995896*G0_2_0 - 2.13777991555799e-06*G0_2_1 - 0.000878627545294242*G0_2_2; + A[107] = -A[35] + 0.000352199241088142*G0_0_0 + 5.87889476778379e-06*G0_0_1 + 5.34444978889438e-06*G0_0_2 + 5.87889476778379e-06*G0_1_0 - 0.000219656886323561*G0_1_1 + 2.6722248944472e-05*G0_1_2 + 5.34444978889439e-06*G0_2_0 + 2.6722248944472e-05*G0_2_1 + 0.00049703383036718*G0_2_2; + A[122] = -A[107] + 0.000181176847843521*G0_0_0 + 5.87889476778382e-06*G0_0_1 + 2.67222489444721e-05*G0_0_2 + 5.87889476778381e-06*G0_1_0 - 4.86344930789394e-05*G0_1_1 + 5.3444497888945e-06*G0_1_2 + 2.67222489444721e-05*G0_2_0 + 5.34444978889451e-06*G0_2_1 + 0.000497033830367182*G0_2_2; + A[42] = -A[122] - 0.000878627545294242*G0_0_0 - 0.000329218106995896*G0_0_1 - 2.13777991555757e-06*G0_0_2 - 0.000329218106995896*G0_1_0 - 0.000194537972315756*G0_1_1 + 2.13777991555801e-06*G0_1_2 - 2.13777991555759e-06*G0_2_0 + 2.137779915558e-06*G0_2_1 + 0.00173160173160179*G0_2_2; + A[182] = A[42]; + A[61] = A[25] - 0.000400833734167082*G0_0_0 + 0.000400833734167081*G0_2_2; + A[7] = A[61] - 0.00133557800224471*G0_0_0 - 0.000107423440756777*G0_0_2 + 0.00133557800224471*G0_1_1 + 0.000107423440756777*G0_1_2 - 0.000107423440756777*G0_2_0 + 0.000107423440756777*G0_2_1; + A[10] = A[7] + 0.000400833734167083*G0_1_1 - 0.000400833734167081*G0_2_2; + A[135] = -A[7] + 0.000497033830367183*G0_0_0 + 2.67222489444722e-05*G0_0_1 + 5.34444978889458e-06*G0_0_2 + 2.67222489444721e-05*G0_1_0 - 0.000219656886323562*G0_1_1 + 5.87889476778362e-06*G0_1_2 + 5.34444978889458e-06*G0_2_0 + 5.87889476778363e-06*G0_2_1 + 0.000352199241088142*G0_2_2; + A[90] = -A[7] + 0.00049703383036718*G0_0_0 + 5.34444978889451e-06*G0_0_1 + 2.6722248944472e-05*G0_0_2 + 5.34444978889451e-06*G0_1_0 - 4.86344930789395e-05*G0_1_1 + 5.87889476778372e-06*G0_1_2 + 2.6722248944472e-05*G0_2_0 + 5.87889476778374e-06*G0_2_1 + 0.000181176847843521*G0_2_2; + A[195] = -A[135] + 0.00173160173160179*G0_0_0 - 2.13777991555808e-06*G0_0_1 + 2.13777991555748e-06*G0_0_2 - 2.13777991555814e-06*G0_1_0 - 0.000878627545294245*G0_1_1 - 0.000329218106995897*G0_1_2 + 2.13777991555749e-06*G0_2_0 - 0.000329218106995897*G0_2_1 - 0.000194537972315757*G0_2_2; + A[14] = -A[90] + 0.00173160173160179*G0_0_0 + 2.13777991555803e-06*G0_0_1 - 2.13777991555816e-06*G0_0_2 + 2.13777991555803e-06*G0_1_0 - 0.000194537972315757*G0_1_1 - 0.000329218106995896*G0_1_2 - 2.13777991555817e-06*G0_2_0 - 0.000329218106995896*G0_2_1 - 0.000878627545294242*G0_2_2; + A[159] = A[97] - 0.000384800384800398*G0_0_1 + 0.000384800384800395*G0_0_2 - 0.000384800384800398*G0_1_0 - 0.00197530864197538*G0_1_1 + 0.000384800384800395*G0_2_0 + 0.00197530864197537*G0_2_2; + A[142] = A[100] - 0.000256533589866931*G0_0_1 + 0.000256533589866933*G0_0_2 - 0.000256533589866931*G0_1_0 + 0.000205226871893548*G0_1_1 + 0.000256533589866933*G0_2_0 - 0.000205226871893544*G0_2_2; + A[94] = A[108] - 0.00015392015392016*G0_0_0 - 0.000282186948853625*G0_0_2 + 0.000153920153920155*G0_1_1 + 0.000282186948853624*G0_1_2 - 0.000282186948853625*G0_2_0 + 0.000282186948853624*G0_2_1; + A[158] = A[94] - 0.000782427449094139*G0_0_0 + 0.000218053551386892*G0_0_1 + 0.000218053551386892*G0_1_0 - 0.000218053551386892*G0_1_2 - 0.000218053551386892*G0_2_1 + 0.000782427449094143*G0_2_2; + A[139] = A[94] - 6.41333974667331e-05*G0_0_1 + 6.41333974667333e-05*G0_0_2 - 6.41333974667332e-05*G0_1_0 - 0.000936347603014304*G0_1_1 + 6.41333974667333e-05*G0_2_0 + 0.000936347603014302*G0_2_2; + A[170] = A[139] + 1.28266794933469e-05*G0_0_0 + 0.000448933782267131*G0_0_1 + 2.56533589866935e-05*G0_0_2 + 0.000448933782267131*G0_1_0 + 0.00300144300144311*G0_1_1 - 4.27555983111542e-06*G0_1_2 + 2.56533589866935e-05*G0_2_0 - 4.27555983111531e-06*G0_2_1 - 4.2755598311158e-06*G0_2_2; + A[202] = -A[170] - 0.000769600769600794*G0_0_0 - 0.00120570787237458*G0_0_2 + 0.00189834856501531*G0_1_1 - 0.000171022393244618*G0_1_2 - 0.00120570787237458*G0_2_0 - 0.000171022393244618*G0_2_1 - 0.000632782855005098*G0_2_2; + A[86] = A[170]; + A[138] = A[170] + 0.000136817914595696*G0_0_0 - 0.000171022393244621*G0_0_1 - 0.000171022393244621*G0_1_0 + 0.000171022393244622*G0_1_2 + 0.000171022393244622*G0_2_1 - 0.000136817914595697*G0_2_2; + A[164] = A[202] - 0.000846560846560878*G0_0_1 + 0.000846560846560874*G0_0_2 - 0.000846560846560878*G0_1_0 - 0.000461760461760483*G0_1_1 + 0.000846560846560874*G0_2_0 + 0.000461760461760479*G0_2_2; + A[129] = A[170] + 0.00220618887285561*G0_0_0 + 0.000188124632569083*G0_0_2 - 0.00220618887285562*G0_1_1 - 0.000188124632569084*G0_1_2 + 0.000188124632569083*G0_2_0 - 0.000188124632569084*G0_2_1; + A[117] = -A[129] - 0.000410453743787092*G0_0_0 - 0.000307840307840318*G0_0_1 + 0.00175297953075737*G0_0_2 - 0.000307840307840318*G0_1_0 + 0.000872214205547568*G0_1_2 + 0.00175297953075737*G0_2_0 + 0.000872214205547568*G0_2_1 + 0.00367698145475935*G0_2_2; + A[16] = A[129] - 0.00229330340441459*G0_0_0 - 0.000361552028218707*G0_0_1 - 0.000257335257335266*G0_0_2 - 0.000361552028218707*G0_1_0 + 0.0018021484688152*G0_1_1 - 2.40500240500252e-06*G0_1_2 - 0.000257335257335266*G0_2_0 - 2.40500240500255e-06*G0_2_1 - 0.000223932446154675*G0_2_2; + A[72] = A[202] + 0.000461760461760476*G0_0_0 + 0.000846560846560874*G0_0_2 - 0.000461760461760483*G0_1_1 - 0.000846560846560878*G0_1_2 + 0.000846560846560874*G0_2_0 - 0.000846560846560878*G0_2_1; + A[32] = A[16] - 6.68056223611806e-05*G0_0_1 + 6.68056223611802e-05*G0_0_2 - 6.68056223611806e-05*G0_1_0 - 0.00188926300037418*G0_1_1 + 6.68056223611802e-05*G0_2_0 + 0.00188926300037417*G0_2_2; + A[126] = A[94] + 0.00211640211640219*G0_0_0 + 0.000213777991555777*G0_0_1 + 0.000483138260916055*G0_0_2 + 0.000213777991555777*G0_1_0 - 0.000192400192400199*G0_1_1 - 4.27555983111558e-06*G0_1_2 + 0.000483138260916055*G0_2_0 - 4.27555983111553e-06*G0_2_1 + 0.00289882956549633*G0_2_2; + A[79] = A[65]; + A[169] = A[153] + 0.000205226871893546*G0_0_0 - 0.00025653358986693*G0_0_1 - 0.00025653358986693*G0_1_0 + 0.000256533589866934*G0_1_2 + 0.000256533589866934*G0_2_1 - 0.000205226871893545*G0_2_2; + A[154] = A[70]; + A[106] = 6.57367324034015e-05*G0_0_0 - 8.01667468334159e-06*G0_0_1 - 0.000105820105820109*G0_0_2 - 8.0166746833416e-06*G0_1_0 + 6.41333974667368e-06*G0_1_1 - 8.01667468334163e-06*G0_1_2 - 0.000105820105820109*G0_2_0 - 8.01667468334163e-06*G0_2_1 + 6.57367324034011e-05*G0_2_2; + A[101] = A[158] + 0.0030014430014431*G0_0_0 - 4.27555983111537e-06*G0_0_1 + 0.00044893378226713*G0_0_2 - 4.27555983111531e-06*G0_1_0 - 4.27555983111455e-06*G0_1_1 + 2.56533589866933e-05*G0_1_2 + 0.00044893378226713*G0_2_0 + 2.56533589866933e-05*G0_2_1 + 1.28266794933461e-05*G0_2_2; + A[176] = A[101] - 0.000513067179733862*G0_0_0 + 0.0025311314200204*G0_0_1 + 0.0025311314200204*G0_1_0 + 0.0116808294586077*G0_1_1 + 0.000838009726898645*G0_1_2 + 0.000838009726898645*G0_2_1 + 0.000153920153920159*G0_2_2; + A[144] = A[176] + 0.0101245256800816*G0_0_0 + 0.000478862701084939*G0_0_2 - 0.0101245256800816*G0_1_1 - 0.00047886270108494*G0_1_2 + 0.000478862701084939*G0_2_0 - 0.00047886270108494*G0_2_1; + A[99] = A[144] - 0.00598578376356175*G0_0_0 - 0.00188124632569084*G0_0_1 - 0.00188124632569084*G0_1_0 - 0.00138528138528144*G0_1_1 - 0.000153920153920159*G0_1_2 - 0.000153920153920159*G0_2_1 + 0.000153920153920159*G0_2_2; + A[125] = A[99] - 0.00552402330180127*G0_0_0 - 0.0006327828550051*G0_0_1 - 0.0006327828550051*G0_1_0 + 0.000632782855005099*G0_1_2 + 0.000632782855005099*G0_2_1 + 0.00552402330180126*G0_2_2; + A[83] = A[125]; + A[80] = A[144] - 0.0116637272192832*G0_0_0 - 0.00236010902677578*G0_0_1 - 0.00236010902677578*G0_1_0 + 0.00236010902677578*G0_1_2 + 0.00236010902677578*G0_2_1 + 0.0116637272192832*G0_2_2; + A[56] = A[99] - 0.00552402330180127*G0_0_0 - 0.000632782855005099*G0_0_2 + 0.00552402330180128*G0_1_1 + 0.0006327828550051*G0_1_2 - 0.000632782855005099*G0_2_0 + 0.0006327828550051*G0_2_1; + A[187] = A[117]; + A[174] = A[126] + 0.000205226871893546*G0_0_1 - 0.000205226871893545*G0_0_2 + 0.000205226871893546*G0_1_0 + 0.00215488215488224*G0_1_1 - 0.000205226871893545*G0_2_0 - 0.00215488215488223*G0_2_2; + A[5] = A[14] + 7.05467372134052e-05*G0_0_0 - 1.06888995777889e-05*G0_0_2 - 6.41333974667417e-06*G0_1_1 + 0.000134680134680139*G0_1_2 - 1.06888995777889e-05*G0_2_0 + 0.000134680134680139*G0_2_1 + 0.000111164555609003*G0_2_2; + A[15] = A[1]; + A[8] = A[165] + 0.000427555983111555*G0_1_1 - 0.000427555983111554*G0_2_2; + A[71] = A[169]; + A[50] = A[126] - 0.00215488215488222*G0_0_0 - 0.000205226871893544*G0_0_2 + 0.00215488215488223*G0_1_1 + 0.000205226871893545*G0_1_2 - 0.000205226871893545*G0_2_0 + 0.000205226871893545*G0_2_1; + A[37] = A[107]; + A[123] = A[94] + 1.28266794933481e-05*G0_0_0 + 2.56533589866932e-05*G0_0_1 + 0.000448933782267132*G0_0_2 + 2.56533589866932e-05*G0_1_0 - 4.2755598311152e-06*G0_1_1 - 4.27555983111531e-06*G0_1_2 + 0.000448933782267132*G0_2_0 - 4.27555983111526e-06*G0_2_1 + 0.00300144300144311*G0_2_2; + A[191] = -A[123] + 0.00261664261664271*G0_0_0 + 0.00128266794933466*G0_0_2 - 0.00135107690663251*G0_1_1 + 8.55111966223103e-05*G0_1_2 + 0.00128266794933466*G0_2_0 + 8.55111966223103e-05*G0_2_1 + 0.00277056277056287*G0_2_2; + A[132] = A[191] + 0.000923520923520953*G0_0_1 - 0.000923520923520957*G0_0_2 + 0.000923520923520953*G0_1_0 + 0.00205226871893546*G0_1_1 - 0.000923520923520957*G0_2_0 - 0.00205226871893546*G0_2_2; + A[188] = A[132]; + A[104] = A[132] - 0.00410453743787091*G0_0_0 - 0.00102613435946773*G0_0_1 - 0.00102613435946773*G0_1_0 + 0.00102613435946773*G0_1_2 + 0.00102613435946773*G0_2_1 + 0.00410453743787091*G0_2_2; + A[193] = -A[191] + 0.000513067179733865*G0_0_1 - 0.00102613435946773*G0_0_2 + 0.000513067179733865*G0_1_0 - 0.00410453743787092*G0_1_1 - 0.00205226871893546*G0_1_2 - 0.00102613435946773*G0_2_0 - 0.00205226871893546*G0_2_1 - 0.00205226871893545*G0_2_2; + A[51] = A[123] + 0.000307840307840318*G0_0_0 - 0.000307840307840318*G0_0_2 + 0.000171022393244622*G0_1_1 - 0.000136817914595697*G0_1_2 - 0.000307840307840318*G0_2_0 - 0.000136817914595697*G0_2_1 - 0.00184704184704191*G0_2_2; + A[216] = A[104]; + A[148] = A[191] - 0.00410453743787091*G0_0_0 - 0.00102613435946773*G0_0_2 + 0.00410453743787092*G0_1_1 + 0.00102613435946773*G0_1_2 - 0.00102613435946773*G0_2_0 + 0.00102613435946773*G0_2_1; + A[149] = A[148] - 0.000820907487574183*G0_0_0 - 0.000410453743787093*G0_0_1 - 0.000410453743787093*G0_1_0 - 0.00246272246272256*G0_1_1 - 0.000410453743787093*G0_1_2 - 0.000410453743787093*G0_2_1 + 0.000410453743787091*G0_2_2; + A[186] = -A[149] + 0.00574635241301928*G0_0_0 + 0.000513067179733864*G0_0_1 + 0.00133397466730805*G0_0_2 + 0.000513067179733864*G0_1_0 - 0.000410453743787093*G0_1_1 + 0.00133397466730805*G0_2_0; + A[103] = A[149] + 0.000307840307840318*G0_0_1 - 0.000307840307840318*G0_0_2 + 0.000307840307840318*G0_1_0 + 0.000820907487574183*G0_1_1 - 0.000307840307840319*G0_2_0 - 0.000820907487574182*G0_2_2; + A[57] = A[103] + 0.00328362995029672*G0_0_0 + 0.000923520923520953*G0_0_2 - 0.00328362995029674*G0_1_1 - 0.000923520923520957*G0_1_2 + 0.000923520923520953*G0_2_0 - 0.000923520923520957*G0_2_1; + A[218] = A[186] - 0.009029982363316*G0_0_0 - 0.00143658810325482*G0_0_1 - 0.00143658810325482*G0_1_0 + 0.00143658810325482*G0_1_2 + 0.00143658810325482*G0_2_1 + 0.00902998236331601*G0_2_2; + A[89] = A[218] + 0.000410453743787091*G0_0_0 - 0.000513067179733864*G0_0_2 - 0.000410453743787091*G0_1_1 + 0.000513067179733865*G0_1_2 - 0.000513067179733864*G0_2_0 + 0.000513067179733864*G0_2_1; + A[215] = A[89]; + A[198] = A[186] - 0.00861952861952891*G0_0_0 - 0.00194965528298868*G0_0_2 + 0.00861952861952894*G0_1_1 + 0.00194965528298869*G0_1_2 - 0.00194965528298868*G0_2_0 + 0.00194965528298869*G0_2_1; + A[201] = A[103]; + A[85] = A[108] + 0.000218053551386891*G0_0_1 - 0.000218053551386891*G0_0_2 + 0.000218053551386891*G0_1_0 - 0.000782427449094149*G0_1_1 - 0.000218053551386891*G0_2_0 + 0.000782427449094144*G0_2_2; + A[66] = A[94]; + A[160] = A[191] + 0.00488696488696505*G0_0_0 + 0.00453743787077136*G0_0_1 + 0.000169953503286842*G0_0_2 + 0.00453743787077136*G0_1_0 + 0.00899150232483598*G0_1_1 + 0.00119608786275457*G0_1_2 + 0.000169953503286842*G0_2_0 + 0.00119608786275457*G0_2_1 - 6.41333974667289e-06*G0_2_2; + A[137] = A[21] - 5.34444978889442e-05*G0_0_1 + 5.34444978889443e-05*G0_0_2 - 5.34444978889442e-05*G0_1_0 - 0.000121853455186793*G0_1_1 + 5.34444978889443e-05*G0_2_0 + 0.000121853455186792*G0_2_2; + A[91] = A[21]; + A[82] = A[110]; + A[168] = A[56]; + A[109] = A[157] - 0.00199134199134206*G0_0_0 + 6.73400673400685e-05*G0_0_1 + 6.73400673400686e-05*G0_1_0 - 6.73400673400683e-05*G0_1_2 - 6.73400673400684e-05*G0_2_1 + 0.00199134199134206*G0_2_2; + A[212] = -A[109] + 9.62000962001069e-06*G0_0_0 + 0.000160333493666832*G0_0_1 - 9.29934263267624e-05*G0_0_2 + 0.000160333493666832*G0_1_0 + 9.62000962000944e-06*G0_1_1 - 9.29934263267619e-05*G0_1_2 - 9.29934263267626e-05*G0_2_0 - 9.29934263267619e-05*G0_2_1 + 0.00186628186628193*G0_2_2; + A[222] = A[193] - 0.00246272246272255*G0_0_1 + 0.00246272246272254*G0_0_2 - 0.00246272246272255*G0_1_0 + 0.00246272246272254*G0_2_0; + A[184] = A[72]; + A[213] = A[191] - 0.00205226871893546*G0_0_0 - 0.000102613435946773*G0_0_1 - 0.000102613435946773*G0_1_0 + 0.000102613435946774*G0_1_2 + 0.000102613435946774*G0_2_1 + 0.00205226871893546*G0_2_2; + A[204] = A[148]; + A[2] = -0.00010982844316178*G0_0_0 - 1.06888995777886e-06*G0_0_1 - 1.6300571856128e-05*G0_0_2 - 1.06888995777886e-06*G0_1_0 + 1.84383517716859e-05*G0_1_1 - 1.06888995777888e-06*G0_1_2 - 1.6300571856128e-05*G0_2_0 - 1.06888995777888e-06*G0_2_1 - 0.00010982844316178*G0_2_2; + A[18] = A[46]; + A[133] = A[103] + 0.00246272246272255*G0_0_0 + 0.000615680615680637*G0_0_1 + 0.000615680615680637*G0_1_0 - 0.000615680615680636*G0_1_2 - 0.000615680615680636*G0_2_1 - 0.00246272246272254*G0_2_2; + A[68] = A[100] + 0.00424563091229772*G0_0_0 + 0.000346320346320359*G0_0_1 + 0.000346320346320359*G0_1_0 - 0.000346320346320358*G0_1_2 - 0.000346320346320358*G0_2_1 - 0.00424563091229772*G0_2_2; + A[45] = A[195] + 7.05467372134072e-05*G0_0_0 - 1.06888995777887e-05*G0_0_1 - 1.06888995777887e-05*G0_1_0 + 0.000111164555609004*G0_1_1 + 0.000134680134680139*G0_1_2 + 0.000134680134680139*G0_2_1 - 6.41333974667339e-06*G0_2_2; + A[38] = A[122]; + A[143] = A[129]; + A[120] = A[8]; + A[88] = A[132] - 0.00205226871893545*G0_0_0 - 0.000102613435946771*G0_0_2 + 0.00205226871893546*G0_1_1 + 0.000102613435946774*G0_1_2 - 0.000102613435946771*G0_2_0 + 0.000102613435946774*G0_2_1; + A[92] = A[36]; + A[179] = A[149] + 0.00246272246272255*G0_0_0 + 0.000615680615680637*G0_0_2 - 0.00246272246272255*G0_1_1 - 0.000615680615680635*G0_1_2 + 0.000615680615680637*G0_2_0 - 0.000615680615680635*G0_2_1; + A[116] = A[108] - 0.0009363476030143*G0_0_0 - 6.4133397466733e-05*G0_0_1 - 6.4133397466733e-05*G0_1_0 + 6.41333974667325e-05*G0_1_2 + 6.41333974667325e-05*G0_2_1 + 0.000936347603014301*G0_2_2; + A[219] = A[149]; + A[189] = A[186] + 0.000513067179733866*G0_0_1 - 0.000513067179733863*G0_0_2 + 0.000513067179733866*G0_1_0 - 0.000410453743787093*G0_1_1 - 0.000513067179733863*G0_2_0 + 0.000410453743787092*G0_2_2; + A[207] = A[193]; + A[55] = A[153]; + A[29] = A[211]; + A[130] = A[158]; + A[43] = -A[35] - 0.000194537972315756*G0_0_0 - 0.000329218106995896*G0_0_1 + 2.1377799155579e-06*G0_0_2 - 0.000329218106995896*G0_1_0 - 0.000878627545294243*G0_1_1 - 2.13777991555783e-06*G0_1_2 + 2.1377799155579e-06*G0_2_0 - 2.13777991555785e-06*G0_2_1 + 0.00173160173160179*G0_2_2; + A[41] = A[43] - 6.41333974667342e-06*G0_0_0 + 0.000134680134680139*G0_0_1 + 0.000134680134680139*G0_1_0 + 0.000111164555609004*G0_1_1 - 1.06888995777889e-05*G0_1_2 - 1.06888995777888e-05*G0_2_1 + 7.05467372134058e-05*G0_2_2; + A[146] = A[174]; + A[75] = A[5]; + A[150] = A[10]; + A[183] = A[57]; + A[178] = -A[57] + 0.00133397466730805*G0_0_1 + 0.00133397466730805*G0_1_0 + 0.00574635241301928*G0_1_1 + 0.000513067179733864*G0_1_2 + 0.000513067179733863*G0_2_1 - 0.000410453743787093*G0_2_2; + A[119] = -A[117] + 0.000615680615680636*G0_0_0 + 0.00292448292448302*G0_0_2 - 0.000307840307840318*G0_1_1 + 0.00292448292448302*G0_2_0 + 0.000615680615680642*G0_2_2; + A[214] = A[119] - 0.00354016354016366*G0_0_0 - 0.00223184223184231*G0_0_2 + 0.00354016354016366*G0_1_1 + 0.0022318422318423*G0_1_2 - 0.00223184223184231*G0_2_0 + 0.0022318422318423*G0_2_1; + A[199] = -A[214] - 0.000307840307840318*G0_0_0 + 0.000615680615680634*G0_1_1 + 0.00292448292448302*G0_1_2 + 0.00292448292448302*G0_2_1 + 0.000615680615680634*G0_2_2; + A[163] = A[119] + 0.000692640692640716*G0_0_1 - 0.000692640692640717*G0_0_2 + 0.000692640692640715*G0_1_0 - 0.00261664261664272*G0_1_1 - 0.000692640692640717*G0_2_0 + 0.0026166426166427*G0_2_2; + A[205] = A[163]; + A[73] = A[199]; + A[220] = A[164]; + A[197] = A[43]; + A[194] = A[222]; + A[19] = A[61]; + A[12] = A[212] - 0.000134680134680139*G0_0_0 - 0.000185986852653526*G0_0_1 - 0.000185986852653526*G0_1_0 + 0.000185986852653526*G0_1_2 + 0.000185986852653526*G0_2_1 + 0.00013468013468014*G0_2_2; + A[54] = A[138]; + A[33] = A[47]; + A[24] = A[76] - 0.000427555983111554*G0_0_0 + 0.000427555983111553*G0_2_2; + A[127] = A[113]; + A[62] = A[107] - 0.000400833734167081*G0_0_0 + 0.000400833734167081*G0_1_1; + A[44] = A[212]; + A[141] = A[99]; + A[95] = A[108] - 4.27555983111488e-06*G0_0_0 + 2.56533589866927e-05*G0_0_1 - 4.27555983111466e-06*G0_0_2 + 2.56533589866927e-05*G0_1_0 + 1.28266794933428e-05*G0_1_1 + 0.00044893378226713*G0_1_2 - 4.27555983111472e-06*G0_2_0 + 0.00044893378226713*G0_2_1 + 0.0030014430014431*G0_2_2; + A[78] = A[50]; + A[172] = A[116]; + A[155] = A[85]; + A[105] = A[7]; + A[98] = A[126]; + A[180] = A[12]; + A[173] = A[51] + 5.13067179733855e-05*G0_0_0 + 5.13067179733864e-05*G0_0_1 + 5.13067179733864e-05*G0_1_0 - 5.13067179733865e-05*G0_1_2 - 5.13067179733866e-05*G0_2_1 - 5.13067179733859e-05*G0_2_2; + A[118] = A[202]; + A[217] = A[119]; + A[200] = A[88]; + A[6] = A[90]; + A[22] = A[106]; + A[9] = A[135]; + A[49] = A[97] + 0.00464325797659146*G0_0_0 + 0.000513067179733862*G0_0_2 - 0.00464325797659147*G0_1_1 - 0.000513067179733864*G0_1_2 + 0.000513067179733862*G0_2_0 - 0.000513067179733864*G0_2_1; + A[34] = A[62]; + A[147] = A[189]; + A[124] = A[68]; + A[84] = A[51] + 5.13067179733865e-05*G0_0_1 - 5.13067179733866e-05*G0_0_2 + 5.13067179733865e-05*G0_1_0 + 5.13067179733873e-05*G0_1_1 - 5.13067179733866e-05*G0_2_0 - 5.13067179733873e-05*G0_2_2; + A[67] = A[109]; + A[161] = A[175]; + A[136] = A[24]; + A[96] = A[144] - 0.00188124632569084*G0_0_1 + 0.00188124632569083*G0_0_2 - 0.00188124632569084*G0_1_0 - 0.0015392015392016*G0_1_1 + 0.00188124632569083*G0_2_0 + 0.00153920153920159*G0_2_2; + A[81] = A[95]; + A[167] = A[41]; + A[156] = A[100]; + A[112] = A[160] - 0.00344396344396357*G0_0_1 + 0.00344396344396356*G0_0_2 - 0.00344396344396357*G0_1_0 - 0.0069456469456472*G0_1_1 + 0.00344396344396356*G0_2_0 + 0.00694564694564717*G0_2_2; + A[223] = A[193] - 0.00246272246272255*G0_0_1 - 0.00246272246272255*G0_1_0 + 0.00246272246272255*G0_1_2 + 0.00246272246272255*G0_2_1; + A[185] = A[149] + 0.00328362995029673*G0_0_0 + 0.000923520923520955*G0_0_1 + 0.000923520923520955*G0_1_0 - 0.000923520923520956*G0_1_2 - 0.000923520923520956*G0_2_1 - 0.00328362995029673*G0_2_2; + A[210] = A[14]; + A[203] = A[133]; + A[3] = A[45]; + A[59] = A[213]; + A[17] = A[31]; + A[134] = A[218]; + A[69] = A[139]; + A[48] = A[176] - 0.00153920153920159*G0_0_0 - 0.00188124632569084*G0_0_1 - 0.00188124632569084*G0_1_0 + 0.00188124632569084*G0_1_2 + 0.00188124632569084*G0_2_1 + 0.00153920153920159*G0_2_2; + A[39] = A[137]; + A[121] = A[211] - 6.41333974667336e-06*G0_0_0 + 0.000134680134680139*G0_0_2 + 7.05467372134072e-05*G0_1_1 - 1.06888995777888e-05*G0_1_2 + 0.000134680134680139*G0_2_0 - 1.06888995777888e-05*G0_2_1 + 0.000111164555609004*G0_2_2; + A[87] = A[185]; + A[64] = A[160] - 0.00694564694564718*G0_0_0 - 0.00344396344396357*G0_0_1 - 0.00344396344396357*G0_1_0 + 0.00344396344396357*G0_1_2 + 0.00344396344396357*G0_2_1 + 0.00694564694564718*G0_2_2; + A[162] = -A[163] + 0.000615680615680635*G0_0_0 + 0.00292448292448302*G0_0_1 + 0.00292448292448302*G0_1_0 + 0.00061568061568063*G0_1_1 - 0.00030784030784032*G0_2_2; + A[93] = A[51]; + A[166] = A[26]; + A[115] = A[157]; + A[224] = A[192] - 0.0197017797017804*G0_0_0 - 0.0049254449254451*G0_0_1 - 0.0049254449254451*G0_1_0 + 0.00492544492544509*G0_1_2 + 0.00492544492544509*G0_2_1 + 0.0197017797017804*G0_2_2; + A[190] = A[162]; + A[206] = A[178]; + A[0] = A[16] + 0.00188926300037418*G0_0_0 + 6.680562236118e-05*G0_0_2 - 0.00188926300037418*G0_1_1 - 6.680562236118e-05*G0_1_2 + 6.680562236118e-05*G0_2_0 - 6.680562236118e-05*G0_2_1; + A[58] = A[198]; + A[28] = A[212] - 0.000185986852653525*G0_0_1 + 0.000185986852653526*G0_0_2 - 0.000185986852653525*G0_1_0 - 0.000134680134680135*G0_1_1 + 0.000185986852653526*G0_2_0 + 0.00013468013468014*G0_2_2; + A[131] = A[173]; + A[74] = A[214]; + A[40] = 6.57367324034013e-05*G0_0_0 - 0.000105820105820109*G0_0_1 - 8.01667468334159e-06*G0_0_2 - 0.000105820105820109*G0_1_0 + 6.57367324034021e-05*G0_1_1 - 8.0166746833415e-06*G0_1_2 - 8.01667468334159e-06*G0_2_0 - 8.0166746833415e-06*G0_2_1 + 6.41333974667344e-06*G0_2_2; + A[145] = A[159]; + A[151] = A[25]; + A[102] = A[186]; + A[177] = A[191]; + A[114] = A[142]; + A[221] = A[179]; + A[196] = A[28]; + A[209] = A[223]; + A[13] = A[195]; + A[53] = A[123]; + A[30] = A[2]; + A[23] = A[121]; + A[128] = A[176] - 0.00236010902677578*G0_0_1 + 0.00236010902677577*G0_0_2 - 0.00236010902677578*G0_1_0 - 0.0116637272192832*G0_1_1 + 0.00236010902677577*G0_2_0 + 0.0116637272192832*G0_2_2; + A[63] = A[49]; + A[140] = A[84]; + A[77] = A[35]; + A[171] = A[101]; + A[152] = A[40]; + } + + /// 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 mass_matrix_f2_p1_q4_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p1_q4_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p1_q4_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1))), 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 mass_matrix_f2_p1_q4_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p1_q4_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p1_q4_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p1_q4_tensor_finite_element_0(); + 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 mass_matrix_f2_p1_q4_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p1_q4_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p1_q4_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p1_q4_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f2_p2_q1_excafe.h b/mass_matrix_2d/mass_matrix_f2_p2_q1_excafe.h new file mode 100644 index 0000000..9af452a --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p2_q1_excafe.h @@ -0,0 +1,111 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 0.53 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[1][4] + w[1][5]; + const double var_1 = w[1][2] + w[1][1]; + const double var_2 = 0.3333333333333333148296163*w[1][3]; + const double var_3 = -0.0833333333333333287074041*var_1 + var_2 + 0.5000000000000000000000000*var_0; + const double var_4 = w[1][3] + w[1][5]; + const double var_5 = w[1][2] + w[1][0]; + const double var_6 = 0.3333333333333333148296163*w[1][4]; + const double var_7 = var_6 + 0.5000000000000000000000000*var_4 + -0.0833333333333333287074041*var_5; + const double var_8 = w[0][0]*w[1][0]; + const double var_9 = 0.1250000000000000000000000*var_8; + const double var_10 = w[0][1]*w[1][1]; + const double var_11 = 0.1250000000000000000000000*var_10; + const double var_12 = w[0][0] + w[0][2]; + const double var_13 = w[0][1] + w[0][2]; + const double var_14 = var_12*w[1][3] + var_13*w[1][4]; + const double var_15 = w[1][4] + w[1][3]; + const double var_16 = var_15 + -0.3333333333333333148296163*w[1][2]; + const double var_17 = w[0][1]*w[1][0] + w[0][0]*w[1][1]; + const double var_18 = w[0][2]*w[1][2]; + const double var_19 = var_18 + -1.0000000000000000000000000*var_17; + const double var_20 = var_7*w[0][3] + 0.5000000000000000000000000*var_16*w[0][5] + var_11 + -0.1666666666666666574148081*w[0][2]*w[1][5] + var_3*w[0][4] + var_9 + 0.0416666666666666643537020*var_19 + -0.0833333333333333287074041*var_14; + const double var_21 = -1.0000000000000000000000000*x[0][1]; + const double var_22 = var_21 + x[1][1]; + const double var_23 = w[1][0] + w[1][1]; + const double var_24 = -0.2500000000000000000000000*var_23; + const double var_25 = var_15 + var_24; + const double var_26 = 0.5000000000000000000000000*w[1][0]; + const double var_27 = -0.2500000000000000000000000*var_1; + const double var_28 = 0.5000000000000000000000000*w[1][3] + var_26 + var_27; + const double var_29 = -1.0000000000000000000000000*x[0][0]; + const double var_30 = x[1][0] + var_29; + const double var_31 = x[2][1] + var_21; + const double var_32 = x[2][0] + var_29; + const double var_33 = var_30*var_31 + -1.0000000000000000000000000*var_22*var_32; + const double var_34 = std::abs(var_33); + const double var_35 = 0.0833333333333333287074041*w[0][2]*w[1][2] + 2.0000000000000000000000000*w[0][5]*w[1][5]; + const double var_36 = 2.0000000000000000000000000*w[0][4]*w[1][4] + 0.0833333333333333287074041*w[0][1]*w[1][1]; + const double var_37 = w[0][1]*w[1][2] + w[0][2]*w[1][1]; + const double var_38 = var_26 + var_0 + var_2; + const double var_39 = w[1][4] + var_28; + const double var_40 = var_28 + w[1][5]; + const double var_41 = var_27 + var_0; + const double var_42 = var_35 + 0.5000000000000000000000000*var_41*w[0][0] + var_36 + var_8 + var_40*w[0][4] + 0.0416666666666666643537020*var_37 + var_39*w[0][5] + var_3*w[0][3] + -0.2500000000000000000000000*var_13*var_38; + A[0] = 0.0095238095238095246686250*var_34*var_42; + const double var_43 = 0.5000000000000000000000000*w[1][2]; + const double var_44 = var_43 + 0.5000000000000000000000000*w[1][5] + var_24; + const double var_45 = w[1][4] + var_44; + const double var_46 = 0.3333333333333333148296163*w[1][5]; + const double var_47 = -0.0833333333333333287074041*var_23 + 0.5000000000000000000000000*var_15 + var_46; + const double var_48 = 0.1250000000000000000000000*var_18; + const double var_49 = w[0][0] + w[0][1]; + const double var_50 = var_13*w[1][5] + var_49*w[1][3]; + const double var_51 = var_4 + -0.3333333333333333148296163*w[1][1]; + const double var_52 = w[0][2]*w[1][0] + w[0][0]*w[1][2]; + const double var_53 = -1.0000000000000000000000000*var_52 + var_10; + const double var_54 = -0.0833333333333333287074041*var_50 + -0.1666666666666666574148081*w[0][1]*w[1][4] + var_48 + 0.0416666666666666643537020*var_53 + 0.5000000000000000000000000*var_51*w[0][4] + var_47*w[0][3] + var_9 + var_3*w[0][5]; + const double var_55 = w[0][0]*w[1][3] + w[0][3]*w[1][0]; + A[1] = 0.0142857142857142852682140*var_34*w[0][5]*w[1][5] + 0.0095238095238095246686250*var_20*var_34; + const double var_56 = -1.0000000000000000000000000*var_37 + var_8; + const double var_57 = -0.2500000000000000000000000*var_5; + const double var_58 = 0.5000000000000000000000000*w[1][1]; + const double var_59 = 0.5000000000000000000000000*w[1][4] + var_58 + var_57; + const double var_60 = var_49*w[1][4] + var_12*w[1][5]; + const double var_61 = 0.0416666666666666643537020*var_56 + var_48 + var_47*w[0][4] + var_11 + var_7*w[0][5] + 0.5000000000000000000000000*var_0*w[0][3] + -0.0833333333333333287074041*var_60 + -0.1666666666666666574148081*var_55; + A[5] = 0.0142857142857142852682140*var_34*w[0][3]*w[1][3] + 0.0095238095238095246686250*var_34*var_61; + const double var_62 = 2.0000000000000000000000000*w[0][3]*w[1][3] + 0.0833333333333333287074041*w[0][0]*w[1][0]; + const double var_63 = var_15 + var_43 + var_46; + const double var_64 = w[1][3] + var_44; + const double var_65 = -0.2500000000000000000000000*var_49*var_63 + var_47*w[0][5] + 0.5000000000000000000000000*var_25*w[0][2] + var_62 + var_36 + var_64*w[0][4] + var_18 + var_45*w[0][3] + 0.0416666666666666643537020*var_17; + A[3] = A[1]; + const double var_66 = var_6 + var_4 + var_58; + const double var_67 = var_59 + w[1][5]; + const double var_68 = var_59 + w[1][3]; + const double var_69 = var_4 + var_57; + const double var_70 = -0.2500000000000000000000000*var_12*var_66 + var_35 + var_67*w[0][3] + var_62 + var_68*w[0][5] + 0.0416666666666666643537020*var_52 + var_10 + var_7*w[0][4] + 0.5000000000000000000000000*var_69*w[0][1]; + A[2] = 0.0142857142857142852682140*var_34*w[0][4]*w[1][4] + 0.0095238095238095246686250*var_34*var_54; + A[4] = 0.0095238095238095246686250*var_34*var_70; + A[7] = A[5]; + A[8] = 0.0095238095238095246686250*var_34*var_65; + A[6] = 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/mass_matrix_2d/mass_matrix_f2_p2_q1_quadrature.h b/mass_matrix_2d/mass_matrix_f2_p2_q1_quadrature.h new file mode 100644 index 0000000..82a3cee --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p2_q1_quadrature.h @@ -0,0 +1,3379 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P2_Q1_QUADRATURE_H +#define __MASS_MATRIX_F2_P2_Q1_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p2_q1_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p2_q1_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p2_q1_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p2_q1_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p2_q1_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p2_q1_quadrature_finite_element_1() + { + // 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 mass_matrix_f2_p2_q1_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p2_q1_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p2_q1_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f2_p2_q1_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p2_q1_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p2_q1_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_p2_q1_quadrature_dofmap_1() + { + // 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 mass_matrix_f2_p2_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 mass_matrix_f2_p2_q1_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p2_q1_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // 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[12][3] = \ + {{0.063089014491502, 0.873821971016996, 0.063089014491502}, + {0.063089014491502, 0.0630890144915021, 0.873821971016996}, + {0.873821971016996, 0.0630890144915021, 0.063089014491502}, + {0.249286745170911, 0.501426509658179, 0.24928674517091}, + {0.249286745170911, 0.24928674517091, 0.501426509658179}, + {0.50142650965818, 0.24928674517091, 0.24928674517091}, + {0.0531450498448159, 0.636502499121399, 0.310352451033785}, + {0.310352451033785, 0.636502499121399, 0.053145049844816}, + {0.053145049844816, 0.310352451033785, 0.636502499121399}, + {0.636502499121399, 0.310352451033785, 0.053145049844816}, + {0.310352451033785, 0.0531450498448161, 0.636502499121399}, + {0.636502499121399, 0.053145049844816, 0.310352451033785}}; + + static const double FE1[12][6] = \ + {{-0.0551285669924842, 0.65330770304706, -0.0551285669924841, 0.220514267969936, 0.0159208949980358, 0.220514267969937}, + {-0.0551285669924841, -0.055128566992484, 0.65330770304706, 0.220514267969936, 0.220514267969936, 0.0159208949980359}, + {0.653307703047059, -0.0551285669924842, -0.0551285669924842, 0.0159208949980359, 0.220514267969937, 0.220514267969937}, + {-0.124998982535098, 0.00143057951778881, -0.124998982535098, 0.499995930140389, 0.248575525271626, 0.499995930140391}, + {-0.124998982535098, -0.124998982535098, 0.00143057951778877, 0.499995930140389, 0.499995930140391, 0.248575525271626}, + {0.00143057951778977, -0.124998982535098, -0.124998982535098, 0.248575525271625, 0.49999593014039, 0.49999593014039}, + {-0.0474962571988001, 0.173768363654174, -0.117715163308429, 0.790160442765823, 0.0659747859186054, 0.135307828168627}, + {-0.117715163308429, 0.173768363654174, -0.0474962571988, 0.135307828168627, 0.0659747859186052, 0.790160442765823}, + {-0.0474962571988, -0.117715163308429, 0.173768363654174, 0.790160442765823, 0.135307828168627, 0.0659747859186053}, + {0.173768363654174, -0.117715163308429, -0.0474962571988, 0.0659747859186053, 0.135307828168627, 0.790160442765823}, + {-0.117715163308429, -0.0474962571988, 0.173768363654174, 0.135307828168627, 0.790160442765823, 0.0659747859186053}, + {0.173768363654174, -0.0474962571988001, -0.117715163308429, 0.0659747859186055, 0.790160442765823, 0.135307828168627}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 9; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 648 + for (unsigned int ip = 0; ip < 12; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + + // Total number of operations to compute function values = 24 + for (unsigned int r = 0; r < 6; r++) + { + F0 += FE1[ip][r]*w[0][r]; + F1 += FE1[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 3 + double I[1]; + // Number of operations: 3 + I[0] = F0*F1*W12[ip]*det; + + + // Number of operations for primary indices: 27 + for (unsigned int j = 0; j < 3; j++) + { + for (unsigned int k = 0; k < 3; k++) + { + // Number of operations to compute entry: 3 + A[j*3 + k] += FE0[ip][j]*FE0[ip][k]*I[0]; + }// 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 mass_matrix_f2_p2_q1_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p2_q1_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p2_q1_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1))), 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 mass_matrix_f2_p2_q1_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p2_q1_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p2_q1_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p2_q1_quadrature_finite_element_0(); + 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 mass_matrix_f2_p2_q1_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p2_q1_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p2_q1_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p2_q1_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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/mass_matrix_2d/mass_matrix_f2_p2_q1_tensor.h b/mass_matrix_2d/mass_matrix_f2_p2_q1_tensor.h new file mode 100644 index 0000000..dc82ea7 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p2_q1_tensor.h @@ -0,0 +1,3353 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P2_Q1_TENSOR_H +#define __MASS_MATRIX_F2_P2_Q1_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p2_q1_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p2_q1_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p2_q1_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p2_q1_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p2_q1_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p2_q1_tensor_finite_element_1() + { + // 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 mass_matrix_f2_p2_q1_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p2_q1_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p2_q1_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_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 mass_matrix_f2_p2_q1_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p2_q1_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p2_q1_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_p2_q1_tensor_dofmap_1() + { + // 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 mass_matrix_f2_p2_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 mass_matrix_f2_p2_q1_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p2_q1_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 54 + // Number of operations (multiply-add pairs) for tensor contraction: 158 + // Total number of operations (multiply-add pairs): 221 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0 = det*w[0][0]*w[1][0]*(1.0); + const double G0_0_1 = det*w[0][0]*w[1][1]*(1.0); + const double G0_0_2 = det*w[0][0]*w[1][2]*(1.0); + const double G0_0_3 = det*w[0][0]*w[1][3]*(1.0); + const double G0_0_4 = det*w[0][0]*w[1][4]*(1.0); + const double G0_0_5 = det*w[0][0]*w[1][5]*(1.0); + const double G0_1_0 = det*w[0][1]*w[1][0]*(1.0); + const double G0_1_1 = det*w[0][1]*w[1][1]*(1.0); + const double G0_1_2 = det*w[0][1]*w[1][2]*(1.0); + const double G0_1_3 = det*w[0][1]*w[1][3]*(1.0); + const double G0_1_4 = det*w[0][1]*w[1][4]*(1.0); + const double G0_1_5 = det*w[0][1]*w[1][5]*(1.0); + const double G0_2_0 = det*w[0][2]*w[1][0]*(1.0); + const double G0_2_1 = det*w[0][2]*w[1][1]*(1.0); + const double G0_2_2 = det*w[0][2]*w[1][2]*(1.0); + const double G0_2_3 = det*w[0][2]*w[1][3]*(1.0); + const double G0_2_4 = det*w[0][2]*w[1][4]*(1.0); + const double G0_2_5 = det*w[0][2]*w[1][5]*(1.0); + const double G0_3_0 = det*w[0][3]*w[1][0]*(1.0); + const double G0_3_1 = det*w[0][3]*w[1][1]*(1.0); + const double G0_3_2 = det*w[0][3]*w[1][2]*(1.0); + const double G0_3_3 = det*w[0][3]*w[1][3]*(1.0); + const double G0_3_4 = det*w[0][3]*w[1][4]*(1.0); + const double G0_3_5 = det*w[0][3]*w[1][5]*(1.0); + const double G0_4_0 = det*w[0][4]*w[1][0]*(1.0); + const double G0_4_1 = det*w[0][4]*w[1][1]*(1.0); + const double G0_4_2 = det*w[0][4]*w[1][2]*(1.0); + const double G0_4_3 = det*w[0][4]*w[1][3]*(1.0); + const double G0_4_4 = det*w[0][4]*w[1][4]*(1.0); + const double G0_4_5 = det*w[0][4]*w[1][5]*(1.0); + const double G0_5_0 = det*w[0][5]*w[1][0]*(1.0); + const double G0_5_1 = det*w[0][5]*w[1][1]*(1.0); + const double G0_5_2 = det*w[0][5]*w[1][2]*(1.0); + const double G0_5_3 = det*w[0][5]*w[1][3]*(1.0); + const double G0_5_4 = det*w[0][5]*w[1][4]*(1.0); + const double G0_5_5 = det*w[0][5]*w[1][5]*(1.0); + + // Compute element tensor + A[1] = 0.0011904761904762*G0_0_0 - 0.000396825396825401*G0_0_1 - 0.000793650793650787*G0_0_3 - 0.000396825396825401*G0_1_0 + 0.0011904761904762*G0_1_1 - 0.00079365079365079*G0_1_4 + 0.000396825396825395*G0_2_2 - 0.000793650793650788*G0_2_3 - 0.00079365079365079*G0_2_4 - 0.00158730158730158*G0_2_5 - 0.000793650793650787*G0_3_0 - 0.000793650793650788*G0_3_2 + 0.00476190476190473*G0_3_3 + 0.00317460317460315*G0_3_4 + 0.00476190476190474*G0_3_5 - 0.00079365079365079*G0_4_1 - 0.00079365079365079*G0_4_2 + 0.00317460317460315*G0_4_3 + 0.00476190476190474*G0_4_4 + 0.00476190476190474*G0_4_5 - 0.00158730158730158*G0_5_2 + 0.00476190476190474*G0_5_3 + 0.00476190476190474*G0_5_4 + 0.0142857142857144*G0_5_5; + A[5] = 0.000396825396825394*G0_0_0 - 0.00158730158730158*G0_0_3 - 0.000793650793650787*G0_0_4 - 0.000793650793650787*G0_0_5 + 0.0011904761904762*G0_1_1 - 0.0003968253968254*G0_1_2 - 0.000793650793650788*G0_1_4 - 0.0003968253968254*G0_2_1 + 0.0011904761904762*G0_2_2 - 0.000793650793650788*G0_2_5 - 0.00158730158730158*G0_3_0 + 0.0142857142857144*G0_3_3 + 0.00476190476190473*G0_3_4 + 0.00476190476190473*G0_3_5 - 0.000793650793650787*G0_4_0 - 0.000793650793650789*G0_4_1 + 0.00476190476190473*G0_4_3 + 0.00476190476190474*G0_4_4 + 0.00317460317460315*G0_4_5 - 0.000793650793650787*G0_5_0 - 0.000793650793650788*G0_5_2 + 0.00476190476190473*G0_5_3 + 0.00317460317460315*G0_5_4 + 0.00476190476190474*G0_5_5; + A[0] = A[1] + 0.0083333333333334*G0_0_0 - 0.000793650793650798*G0_0_1 - 0.0011904761904762*G0_0_2 + 0.000793650793650791*G0_0_3 + 0.0047619047619048*G0_0_4 + 0.00476190476190479*G0_0_5 - 0.000793650793650797*G0_1_0 - 0.000396825396825401*G0_1_1 + 0.000396825396825396*G0_1_2 - 0.000793650793650791*G0_1_3 - 0.00158730158730159*G0_1_4 - 0.00238095238095239*G0_1_5 - 0.0011904761904762*G0_2_0 + 0.000396825396825396*G0_2_1 + 0.000396825396825401*G0_2_2 - 0.00158730158730159*G0_2_4 - 0.000793650793650792*G0_2_5 + 0.000793650793650791*G0_3_0 - 0.000793650793650791*G0_3_1 - 0.00158730158730157*G0_3_3 + 0.00158730158730159*G0_3_4 + 0.0047619047619048*G0_4_0 - 0.00158730158730159*G0_4_1 - 0.00158730158730159*G0_4_2 + 0.00158730158730159*G0_4_3 + 0.0142857142857145*G0_4_4 + 0.00476190476190476*G0_4_5 + 0.00476190476190479*G0_5_0 - 0.00238095238095239*G0_5_1 - 0.000793650793650792*G0_5_2 + 0.00476190476190476*G0_5_4 + 0.00476190476190479*G0_5_5; + A[7] = A[5]; + A[6] = 0.0011904761904762*G0_0_0 - 0.0003968253968254*G0_0_2 - 0.000793650793650787*G0_0_3 + 0.000396825396825395*G0_1_1 - 0.000793650793650789*G0_1_3 - 0.00158730158730158*G0_1_4 - 0.00079365079365079*G0_1_5 - 0.0003968253968254*G0_2_0 + 0.0011904761904762*G0_2_2 - 0.00079365079365079*G0_2_5 - 0.000793650793650786*G0_3_0 - 0.000793650793650789*G0_3_1 + 0.00476190476190473*G0_3_3 + 0.00476190476190474*G0_3_4 + 0.00317460317460315*G0_3_5 - 0.00158730158730158*G0_4_1 + 0.00476190476190474*G0_4_3 + 0.0142857142857144*G0_4_4 + 0.00476190476190474*G0_4_5 - 0.00079365079365079*G0_5_1 - 0.00079365079365079*G0_5_2 + 0.00317460317460315*G0_5_3 + 0.00476190476190474*G0_5_4 + 0.00476190476190474*G0_5_5; + A[2] = A[6]; + A[8] = A[0] - 0.00873015873015881*G0_0_0 + 0.00158730158730159*G0_0_1 - 0.00238095238095237*G0_0_3 - 0.00714285714285718*G0_0_4 - 0.00555555555555559*G0_0_5 + 0.00158730158730159*G0_1_0 - 0.00158730158730159*G0_1_2 - 0.00158730158730159*G0_1_3 + 0.00158730158730159*G0_1_5 - 0.00158730158730159*G0_2_1 + 0.0087301587301588*G0_2_2 + 0.00555555555555558*G0_2_3 + 0.00714285714285717*G0_2_4 + 0.00238095238095238*G0_2_5 - 0.00238095238095237*G0_3_0 - 0.00158730158730159*G0_3_1 + 0.00555555555555558*G0_3_2 + 0.015873015873016*G0_3_3 + 0.00476190476190472*G0_3_4 - 0.00714285714285718*G0_4_0 + 0.00714285714285717*G0_4_2 + 0.00476190476190472*G0_4_3 - 0.00476190476190476*G0_4_5 - 0.00555555555555559*G0_5_0 + 0.00158730158730159*G0_5_1 + 0.00238095238095238*G0_5_2 - 0.00476190476190476*G0_5_4 - 0.015873015873016*G0_5_5; + A[3] = A[1]; + A[4] = A[0] - 0.00873015873015881*G0_0_0 + 0.00158730158730159*G0_0_2 - 0.00238095238095237*G0_0_3 - 0.00555555555555559*G0_0_4 - 0.00714285714285718*G0_0_5 + 0.00873015873015881*G0_1_1 - 0.00158730158730159*G0_1_2 + 0.00555555555555559*G0_1_3 + 0.00238095238095238*G0_1_4 + 0.00714285714285718*G0_1_5 + 0.00158730158730159*G0_2_0 - 0.00158730158730159*G0_2_1 - 0.00158730158730159*G0_2_3 + 0.0015873015873016*G0_2_4 - 0.00238095238095237*G0_3_0 + 0.00555555555555558*G0_3_1 - 0.00158730158730159*G0_3_2 + 0.015873015873016*G0_3_3 + 0.00476190476190473*G0_3_5 - 0.00555555555555559*G0_4_0 + 0.00238095238095238*G0_4_1 + 0.0015873015873016*G0_4_2 - 0.015873015873016*G0_4_4 - 0.00476190476190476*G0_4_5 - 0.00714285714285718*G0_5_0 + 0.00714285714285718*G0_5_1 + 0.00476190476190473*G0_5_3 - 0.00476190476190476*G0_5_4; + } + + /// 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 mass_matrix_f2_p2_q1_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p2_q1_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p2_q1_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1))), 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 mass_matrix_f2_p2_q1_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p2_q1_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p2_q1_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p2_q1_tensor_finite_element_0(); + 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 mass_matrix_f2_p2_q1_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p2_q1_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p2_q1_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p2_q1_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_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 diff --git a/mass_matrix_2d/mass_matrix_f2_p2_q2_excafe.h b/mass_matrix_2d/mass_matrix_f2_p2_q2_excafe.h new file mode 100644 index 0000000..67e8904 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p2_q2_excafe.h @@ -0,0 +1,219 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 8.25 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 = 3.2000000000000001776356839*w[0][3]*w[1][3]; + const double var_1 = w[0][5]*w[1][4] + w[0][4]*w[1][5]; + const double var_2 = w[0][3]*w[1][0] + w[0][0]*w[1][3]; + const double var_3 = -1.0000000000000000000000000*var_2; + const double var_4 = w[0][3]*w[1][3]; + const double var_5 = 0.5000000000000000000000000*var_3 + var_4 + -1.0000000000000000000000000*var_1; + const double var_6 = -1.0000000000000000000000000*x[0][0]; + const double var_7 = var_6 + x[1][0]; + const double var_8 = -1.0000000000000000000000000*x[0][1]; + const double var_9 = var_8 + x[2][1]; + const double var_10 = var_6 + x[2][0]; + const double var_11 = var_8 + x[1][1]; + const double var_12 = var_7*var_9 + -1.0000000000000000000000000*var_10*var_11; + const double var_13 = std::abs(var_12); + const double var_14 = w[0][5]*w[1][0] + w[0][0]*w[1][5]; + const double var_15 = w[0][2]*w[1][4] + w[0][4]*w[1][2]; + const double var_16 = w[0][5]*w[1][1] + w[0][1]*w[1][5]; + const double var_17 = w[0][3]*w[1][1] + w[0][1]*w[1][3]; + const double var_18 = w[0][0]*w[1][2] + w[0][2]*w[1][0]; + const double var_19 = w[0][0]*w[1][1] + w[0][1]*w[1][0]; + const double var_20 = w[0][1]*w[1][4] + w[0][4]*w[1][1]; + const double var_21 = w[0][2]*w[1][1] + w[0][1]*w[1][2]; + const double var_22 = -0.0833333333333333287074041*var_21; + const double var_23 = w[0][1]*w[1][1]; + const double var_24 = 0.5000000000000000000000000*var_23; + const double var_25 = 0.0333333333333333328707404*var_18 + var_24 + 0.1666666666666666574148081*var_20 + -0.5333333333333333259318465*w[0][4]*w[1][4] + -0.0833333333333333287074041*var_19 + var_22; + const double var_26 = w[0][2]*w[1][5] + w[0][5]*w[1][2]; + const double var_27 = w[0][4]*w[1][3] + w[0][3]*w[1][4]; + const double var_28 = 0.2500000000000000000000000*w[0][2]*w[1][2]; + const double var_29 = -1.0000000000000000000000000*var_28; + const double var_30 = 0.0666666666666666657414808*var_29 + -0.2666666666666666629659233*var_27 + 0.0333333333333333328707404*var_26; + const double var_31 = w[0][0]*w[1][0]; + const double var_32 = -0.0833333333333333287074041*var_31 + -0.4000000000000000222044605*var_1; + const double var_33 = w[0][4]*w[1][0] + w[0][0]*w[1][4]; + const double var_34 = -1.0000000000000000000000000*var_33; + const double var_35 = w[0][2]*w[1][3] + w[0][3]*w[1][2]; + const double var_36 = -1.0000000000000000000000000*var_35; + const double var_37 = var_36 + var_3; + const double var_38 = var_37 + var_34; + const double var_39 = var_25 + var_30 + 0.0666666666666666657414808*var_15 + var_32 + 0.3333333333333333148296163*var_17 + 0.6666666666666666296592325*var_16 + 0.0333333333333333328707404*var_38; + A[11] = 0.0031746031746031746004211*var_13*var_39 + -0.0009523809523809523801263*var_13*var_14; + A[31] = A[11]; + const double var_40 = 0.1666666666666666574148081*var_31; + const double var_41 = 1.6000000000000000888178420*var_1 + var_0 + -0.0333333333333333328707404*var_21 + -0.5333333333333333259318465*var_2 + var_40; + const double var_42 = 3.2000000000000001776356839*w[0][5]*w[1][5]; + const double var_43 = w[0][2]*w[1][2]; + const double var_44 = 0.5000000000000000000000000*var_43; + const double var_45 = 0.3333333333333333148296163*var_44 + -0.5333333333333333259318465*var_26 + var_42 + 1.6000000000000000888178420*var_27 + -0.0333333333333333328707404*var_19; + const double var_46 = -1.0000000000000000000000000*var_14; + const double var_47 = var_36 + var_46; + const double var_48 = w[0][3]*w[1][5] + w[0][5]*w[1][3]; + const double var_49 = w[0][4]*w[1][4]; + const double var_50 = 1.3333333333333332593184650*var_48 + var_49; + const double var_51 = var_23 + 0.2000000000000000111022302*var_18; + const double var_52 = -1.0000000000000000000000000*var_20; + const double var_53 = var_52 + var_34; + const double var_54 = -1.0000000000000000000000000*var_15; + const double var_55 = var_53 + var_54; + const double var_56 = var_41 + 1.6000000000000000888178420*var_50 + var_45 + 0.2666666666666666629659233*var_55 + 0.3333333333333333148296163*var_51 + 0.4000000000000000222044605*var_47; + A[23] = 0.0031746031746031746004211*var_13*var_56; + A[33] = A[23]; + const double var_57 = var_17 + var_16; + const double var_58 = 0.0027777777777777778837887*var_18; + const double var_59 = 0.2500000000000000000000000*w[0][1]*w[1][1]; + const double var_60 = -1.0000000000000000000000000*var_59; + const double var_61 = 0.5000000000000000000000000*var_52 + -1.0000000000000000000000000*var_48 + var_49; + const double var_62 = 0.0111111111111111115351546*var_61 + var_58 + -0.0277777777777777762358014*var_57 + 0.1666666666666666574148081*var_60; + const double var_63 = var_33 + var_14; + const double var_64 = 0.0027777777777777778837887*var_21; + const double var_65 = 0.2500000000000000000000000*w[0][0]*w[1][0]; + const double var_66 = -1.0000000000000000000000000*var_65; + const double var_67 = 0.0111111111111111115351546*var_5 + 0.1666666666666666574148081*var_66 + -0.0277777777777777762358014*var_63 + var_64; + const double var_68 = var_35 + var_15; + const double var_69 = var_68 + var_26; + const double var_70 = var_69 + var_28; + const double var_71 = -0.1000000000000000055511151*w[0][5]*w[1][5] + 0.0222222222222222230703093*var_27 + var_62 + 0.0166666666666666664353702*var_19 + 0.0111111111111111115351546*var_70 + var_67; + A[1] = 0.0095238095238095246686250*var_13*var_71; + A[6] = A[1]; + const double var_72 = -0.0277777777777777762358014*var_51 + -0.1333333333333333314829616*var_50 + 0.0222222222222222230703093*var_20; + const double var_73 = var_4 + 1.3333333333333332593184650*var_1; + const double var_74 = var_31 + 0.2000000000000000111022302*var_21; + const double var_75 = -0.1333333333333333314829616*var_73 + -0.0277777777777777762358014*var_74 + 0.0222222222222222230703093*var_2; + const double var_76 = w[0][5]*w[1][5]; + const double var_77 = -1.0000000000000000000000000*var_17; + const double var_78 = var_77 + var_34; + const double var_79 = var_78 + var_19 + var_16 + var_14; + const double var_80 = -0.4000000000000000222044605*var_76 + 0.0666666666666666657414808*var_26 + 0.0555555555555555524716027*var_68 + var_75 + -0.0888888888888888922812370*var_27 + var_72 + 0.0111111111111111115351546*var_79; + A[17] = 0.0095238095238095246686250*var_13*var_80; + const double var_81 = -1.0000000000000000000000000*var_26; + const double var_82 = var_42 + var_43; + const double var_83 = 0.2222222222222222098864108*var_82 + 0.0111111111111111115351546*var_19 + 1.0666666666666666518636930*var_27 + 0.1333333333333333314829616*var_81; + const double var_84 = var_19 + var_18; + const double var_85 = 0.0111111111111111115351546*var_21 + 0.0555555555555555524716027*var_2 + -0.0277777777777777762358014*var_84 + -0.1777777777777777845624740*w[0][3]*w[1][3] + var_40; + const double var_86 = -1.0000000000000000000000000*var_16; + const double var_87 = var_77 + var_52 + var_54; + const double var_88 = 0.4000000000000000222044605*var_48 + 0.0833333333333333287074041*var_23; + const double var_89 = -1.0000000000000000000000000*var_88; + const double var_90 = var_89 + var_30; + const double var_91 = 0.3333333333333333148296163*var_90 + 0.0222222222222222230703093*var_35 + 0.1000000000000000055511151*var_86 + 0.1111111111111111049432054*var_33 + 0.2222222222222222098864108*var_14 + var_85 + 0.0111111111111111115351546*var_87; + A[5] = 0.0095238095238095246686250*var_13*var_91; + const double var_92 = 1.3333333333333332593184650*var_27 + var_76; + const double var_93 = 0.2000000000000000111022302*var_19 + var_43; + const double var_94 = -0.1333333333333333314829616*var_92 + -0.0277777777777777762358014*var_93 + 0.0222222222222222230703093*var_26; + const double var_95 = var_86 + var_54; + const double var_96 = var_95 + var_17 + var_21 + var_35; + const double var_97 = -0.0888888888888888922812370*var_1 + var_94 + -0.4000000000000000222044605*var_4 + 0.0555555555555555524716027*var_63 + 0.0666666666666666657414808*var_2 + var_72 + 0.0111111111111111115351546*var_96; + A[3] = 0.0095238095238095246686250*var_13*var_97; + const double var_98 = 0.2500000000000000000000000*var_19 + -1.0000000000000000000000000*var_27 + 0.5000000000000000000000000*var_81 + var_76; + const double var_99 = 0.0333333333333333328707404*var_98 + 0.5000000000000000000000000*var_29 + -0.0833333333333333287074041*var_68; + const double var_100 = 0.3333333333333333148296163*var_99; + const double var_101 = var_63 + var_2; + const double var_102 = var_101 + var_65; + const double var_103 = 0.0222222222222222230703093*var_1 + 0.0166666666666666664353702*var_21 + 0.0111111111111111115351546*var_102 + var_62 + -0.1000000000000000055511151*w[0][3]*w[1][3] + var_100; + const double var_104 = var_47 + var_33 + var_15 + var_18; + const double var_105 = 0.0555555555555555524716027*var_57 + var_94 + 0.0666666666666666657414808*var_20 + 0.0111111111111111115351546*var_104 + -0.4000000000000000222044605*var_49 + var_75 + -0.0888888888888888922812370*var_48; + A[10] = 0.0095238095238095246686250*var_105*var_13; + const double var_106 = var_57 + var_20; + const double var_107 = var_59 + var_106; + const double var_108 = 0.0166666666666666664353702*var_18 + -0.1000000000000000055511151*w[0][4]*w[1][4] + 0.0222222222222222230703093*var_48 + var_100 + 0.0111111111111111115351546*var_107 + var_67; + const double var_109 = var_0 + var_31; + const double var_110 = 0.4000000000000000222044605*var_3; + const double var_111 = var_110 + 0.6666666666666666296592325*var_109 + 3.2000000000000001776356839*var_1 + 0.0333333333333333328707404*var_21; + const double var_112 = 0.3333333333333333148296163*var_111; + const double var_113 = 0.0666666666666666657414808*var_23 + -0.1000000000000000055511151*var_18 + -0.1777777777777777845624740*var_57 + 0.4000000000000000222044605*var_52 + 4.2666666666666666074547720*w[0][4]*w[1][4] + var_83 + 0.5333333333333333259318465*var_48 + var_112; + A[28] = 0.0095238095238095246686250*var_113*var_13; + const double var_114 = 3.2000000000000001776356839*w[0][4]*w[1][4]; + const double var_115 = -0.0333333333333333328707404*var_18 + 0.3333333333333333148296163*var_24 + -0.5333333333333333259318465*var_20 + var_114 + 1.6000000000000000888178420*var_48; + const double var_116 = var_3 + var_77; + const double var_117 = var_36 + var_116; + const double var_118 = 0.4000000000000000222044605*var_95 + 0.3333333333333333148296163*var_74 + 0.2666666666666666629659233*var_117 + var_115 + var_45 + 1.6000000000000000888178420*var_73; + const double var_119 = var_46 + var_86; + const double var_120 = var_44 + -0.5333333333333333259318465*w[0][5]*w[1][5] + -0.0833333333333333287074041*var_18 + 0.1666666666666666574148081*var_26 + 0.0333333333333333328707404*var_19 + var_22; + const double var_121 = 0.0666666666666666657414808*var_66 + -0.2666666666666666629659233*var_1 + 0.0333333333333333328707404*var_2; + const double var_122 = var_86 + var_53; + const double var_123 = var_120 + 0.3333333333333333148296163*var_15 + var_89 + 0.6666666666666666296592325*var_35 + 0.0666666666666666657414808*var_14 + 0.0333333333333333328707404*var_122 + var_121; + A[15] = -0.0009523809523809523801263*var_13*var_17 + 0.0031746031746031746004211*var_123*var_13; + const double var_124 = var_36 + var_86 + var_81; + const double var_125 = -0.2666666666666666629659233*var_48 + 0.0333333333333333328707404*var_20 + 0.0666666666666666657414808*var_60; + const double var_126 = 0.4000000000000000222044605*var_27 + 0.0833333333333333287074041*var_43; + const double var_127 = -1.0000000000000000000000000*var_126; + const double var_128 = var_125 + var_127; + const double var_129 = 0.1000000000000000055511151*var_54 + 0.0111111111111111115351546*var_124 + 0.2222222222222222098864108*var_33 + 0.1111111111111111049432054*var_14 + 0.0222222222222222230703093*var_17 + var_85 + 0.3333333333333333148296163*var_128; + A[4] = 0.0095238095238095246686250*var_129*var_13; + A[29] = 0.0031746031746031746004211*var_118*var_13; + A[34] = A[29]; + const double var_130 = 0.0166666666666666664353702*var_31 + 0.0555555555555555524716027*var_1 + -0.0416666666666666643537020*var_21 + 0.2222222222222222098864108*w[0][3]*w[1][3]; + const double var_131 = 0.2222222222222222098864108*w[0][5]*w[1][5] + -0.0416666666666666643537020*var_19 + 0.0555555555555555524716027*var_27 + 0.0166666666666666664353702*var_43; + const double var_132 = var_46 + var_81; + const double var_133 = var_132 + var_37; + const double var_134 = var_54 + var_34; + const double var_135 = var_24 + 0.1666666666666666574148081*var_57 + var_58 + var_131 + var_130 + 0.0666666666666666657414808*var_49 + 0.1111111111111111049432054*var_48 + 0.0055555555555555557675773*var_134 + 0.0277777777777777762358014*var_133; + A[7] = 0.0095238095238095246686250*var_13*var_135; + const double var_136 = 0.2222222222222222098864108*w[0][4]*w[1][4] + 0.0555555555555555524716027*var_48 + 0.0166666666666666664353702*var_23 + -0.0416666666666666643537020*var_18; + const double var_137 = var_95 + var_52 + var_81; + const double var_138 = var_36 + var_77; + const double var_139 = var_64 + 0.1111111111111111049432054*var_1 + 0.5000000000000000000000000*var_31 + 0.0055555555555555557675773*var_138 + var_131 + 0.1666666666666666574148081*var_63 + 0.0666666666666666657414808*var_4 + var_136 + 0.0277777777777777762358014*var_137; + A[0] = 0.0095238095238095246686250*var_13*var_139; + A[2] = 0.0095238095238095246686250*var_108*var_13; + A[12] = A[2]; + const double var_140 = var_116 + var_46; + const double var_141 = var_120 + 0.6666666666666666296592325*var_15 + 0.3333333333333333148296163*var_35 + 0.0333333333333333328707404*var_140 + var_125 + var_32 + 0.0666666666666666657414808*var_16; + const double var_142 = var_132 + var_86; + A[20] = A[15]; + A[8] = 0.0095238095238095246686250*var_103*var_13; + A[13] = A[8]; + const double var_143 = var_114 + var_23; + const double var_144 = 1.0666666666666666518636930*var_48 + 0.1333333333333333314829616*var_52 + 0.2222222222222222098864108*var_143 + 0.0111111111111111115351546*var_18; + const double var_145 = 4.2666666666666666074547720*w[0][5]*w[1][5] + -0.1777777777777777845624740*var_68 + 0.4000000000000000222044605*var_81 + 0.5333333333333333259318465*var_27 + -0.1000000000000000055511151*var_19 + 0.0666666666666666657414808*var_43 + var_144 + var_112; + A[35] = 0.0095238095238095246686250*var_13*var_145; + const double var_146 = 0.0666666666666666657414808*var_31 + 0.5333333333333333259318465*var_1 + -0.1000000000000000055511151*var_21 + -0.1777777777777777845624740*var_63 + var_83 + 4.2666666666666666074547720*w[0][3]*w[1][3] + var_110 + var_144; + A[21] = 0.0095238095238095246686250*var_13*var_146; + const double var_147 = var_116 + var_53; + const double var_148 = var_132 + var_54; + const double var_149 = var_25 + var_127 + 0.0666666666666666657414808*var_33 + 0.6666666666666666296592325*var_17 + 0.3333333333333333148296163*var_16 + 0.0333333333333333328707404*var_148 + var_121; + A[9] = -0.0009523809523809523801263*var_13*var_35 + 0.0031746031746031746004211*var_13*var_149; + A[19] = A[9]; + const double var_150 = 0.2666666666666666629659233*var_142 + var_115 + 0.3333333333333333148296163*var_93 + var_41 + 1.6000000000000000888178420*var_92 + 0.4000000000000000222044605*var_78; + A[22] = 0.0031746031746031746004211*var_13*var_150; + A[18] = A[3]; + A[32] = A[17]; + A[16] = 0.0031746031746031746004211*var_13*var_141 + -0.0009523809523809523801263*var_13*var_33; + A[26] = A[16]; + A[25] = A[10]; + const double var_151 = var_44 + 0.0666666666666666657414808*var_76 + var_130 + 0.1666666666666666574148081*var_68 + 0.1111111111111111049432054*var_27 + var_136 + 0.0027777777777777778837887*var_19 + 0.0277777777777777762358014*var_147 + 0.0055555555555555557675773*var_119; + A[30] = A[5]; + A[24] = A[4]; + A[14] = 0.0095238095238095246686250*var_13*var_151; + A[27] = A[22]; + } + + 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/mass_matrix_2d/mass_matrix_f2_p2_q2_quadrature.h b/mass_matrix_2d/mass_matrix_f2_p2_q2_quadrature.h new file mode 100644 index 0000000..96f298c --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p2_q2_quadrature.h @@ -0,0 +1,2234 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P2_Q2_QUADRATURE_H +#define __MASS_MATRIX_F2_P2_Q2_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p2_q2_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p2_q2_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p2_q2_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p2_q2_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p2_q2_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_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 mass_matrix_f2_p2_q2_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class mass_matrix_f2_p2_q2_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p2_q2_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // 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[25][6] = \ + {{0.759842524889053, -0.0409849230988147, -0.036640207614552, 0.00717255684496526, 0.145727572487076, 0.164882476492272}, + {0.404143384962011, -0.0347905350890822, -0.119594790557632, 0.0297980510461641, 0.605418365816316, 0.115025523822223}, + {0.03820389372017, -0.0249744559383749, -0.0543309414249184, 0.0461882014671776, 0.938423301877432, 0.0564900002985143}, + {-0.121759885907613, -0.0138776265525463, 0.271876837668966, 0.0397410384743821, 0.807433832894958, 0.0165858034218534}, + {-0.0762735703276687, -0.00457955736373819, 0.723813068870285, 0.0166673234982246, 0.338636367163553, 0.00173636815934475}, + {0.352482461135478, -0.123384449130048, -0.036640207614552, 0.0352840510877738, 0.117616078244268, 0.65464206627708}, + {0.144254514044104, -0.116568374669637, -0.119594790557632, 0.146585935553368, 0.488630481309112, 0.456692234320686}, + {-0.0585120870225412, -0.0960538647466012, -0.0543309414249184, 0.227214213208259, 0.75739729013635, 0.224285389849452}, + {-0.124504469204174, -0.0603987775714151, 0.271876837668966, 0.19549860142211, 0.65167626994723, 0.0658515377372835}, + {-0.0643063527627087, -0.0217044058396818, 0.723813068870285, 0.0819917787365635, 0.273311911925214, 0.00689399907032831}, + {-0.0191125161665053, -0.0191125161665052, -0.036640207614552, 0.0764500646660208, 0.0764500646660208, 0.921965110615521}, + {-0.0794020521078101, -0.07940205210781, -0.119594790557632, 0.31760820843124, 0.31760820843124, 0.643182477910772}, + {-0.123076437918076, -0.123076437918076, -0.0543309414249183, 0.492305751672305, 0.492305751672305, 0.315872313916462}, + {-0.105896858921168, -0.105896858921168, 0.271876837668966, 0.42358743568467, 0.42358743568467, 0.092742008804029}, + {-0.0444129613327222, -0.0444129613327222, 0.723813068870285, 0.177651845330889, 0.177651845330889, 0.00970916313338213}, + {-0.123384449130048, 0.352482461135478, -0.036640207614552, 0.117616078244268, 0.0352840510877737, 0.65464206627708}, + {-0.116568374669637, 0.144254514044104, -0.119594790557632, 0.488630481309112, 0.146585935553368, 0.456692234320686}, + {-0.0960538647466012, -0.0585120870225412, -0.0543309414249183, 0.75739729013635, 0.227214213208259, 0.224285389849452}, + {-0.0603987775714152, -0.124504469204174, 0.271876837668966, 0.65167626994723, 0.195498601422111, 0.0658515377372835}, + {-0.0217044058396819, -0.0643063527627086, 0.723813068870285, 0.273311911925214, 0.0819917787365634, 0.00689399907032831}, + {-0.0409849230988147, 0.759842524889054, -0.036640207614552, 0.145727572487076, 0.00717255684496518, 0.164882476492272}, + {-0.0347905350890822, 0.404143384962011, -0.119594790557632, 0.605418365816316, 0.0297980510461639, 0.115025523822223}, + {-0.024974455938375, 0.03820389372017, -0.0543309414249183, 0.938423301877431, 0.0461882014671776, 0.0564900002985144}, + {-0.0138776265525464, -0.121759885907613, 0.271876837668966, 0.807433832894958, 0.0397410384743823, 0.0165858034218536}, + {-0.00457955736373822, -0.0762735703276687, 0.723813068870285, 0.338636367163553, 0.0166673234982245, 0.00173636815934475}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 36; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 3375 + for (unsigned int ip = 0; ip < 25; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + + // Total number of operations to compute function values = 24 + for (unsigned int r = 0; r < 6; r++) + { + F0 += FE0[ip][r]*w[0][r]; + F1 += FE0[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 3 + double I[1]; + // Number of operations: 3 + I[0] = F0*F1*W25[ip]*det; + + + // Number of operations for primary indices: 108 + for (unsigned int j = 0; j < 6; j++) + { + for (unsigned int k = 0; k < 6; k++) + { + // Number of operations to compute entry: 3 + A[j*6 + k] += FE0[ip][j]*FE0[ip][k]*I[0]; + }// 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 mass_matrix_f2_p2_q2_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p2_q2_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p2_q2_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1))), 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 mass_matrix_f2_p2_q2_quadrature_finite_element_0(); + break; + } + case 1: + { + return new mass_matrix_f2_p2_q2_quadrature_finite_element_0(); + break; + } + case 2: + { + return new mass_matrix_f2_p2_q2_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p2_q2_quadrature_finite_element_0(); + 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 mass_matrix_f2_p2_q2_quadrature_dofmap_0(); + break; + } + case 1: + { + return new mass_matrix_f2_p2_q2_quadrature_dofmap_0(); + break; + } + case 2: + { + return new mass_matrix_f2_p2_q2_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p2_q2_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f2_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/mass_matrix_2d/mass_matrix_f2_p2_q2_tensor.h b/mass_matrix_2d/mass_matrix_f2_p2_q2_tensor.h new file mode 100644 index 0000000..5c6da97 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p2_q2_tensor.h @@ -0,0 +1,2236 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P2_Q2_TENSOR_H +#define __MASS_MATRIX_F2_P2_Q2_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p2_q2_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p2_q2_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p2_q2_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p2_q2_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p2_q2_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_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 mass_matrix_f2_p2_q2_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class mass_matrix_f2_p2_q2_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p2_q2_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 54 + // Number of operations (multiply-add pairs) for tensor contraction: 571 + // Total number of operations (multiply-add pairs): 634 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0 = det*w[0][0]*w[1][0]*(1.0); + const double G0_0_1 = det*w[0][0]*w[1][1]*(1.0); + const double G0_0_2 = det*w[0][0]*w[1][2]*(1.0); + const double G0_0_3 = det*w[0][0]*w[1][3]*(1.0); + const double G0_0_4 = det*w[0][0]*w[1][4]*(1.0); + const double G0_0_5 = det*w[0][0]*w[1][5]*(1.0); + const double G0_1_0 = det*w[0][1]*w[1][0]*(1.0); + const double G0_1_1 = det*w[0][1]*w[1][1]*(1.0); + const double G0_1_2 = det*w[0][1]*w[1][2]*(1.0); + const double G0_1_3 = det*w[0][1]*w[1][3]*(1.0); + const double G0_1_4 = det*w[0][1]*w[1][4]*(1.0); + const double G0_1_5 = det*w[0][1]*w[1][5]*(1.0); + const double G0_2_0 = det*w[0][2]*w[1][0]*(1.0); + const double G0_2_1 = det*w[0][2]*w[1][1]*(1.0); + const double G0_2_2 = det*w[0][2]*w[1][2]*(1.0); + const double G0_2_3 = det*w[0][2]*w[1][3]*(1.0); + const double G0_2_4 = det*w[0][2]*w[1][4]*(1.0); + const double G0_2_5 = det*w[0][2]*w[1][5]*(1.0); + const double G0_3_0 = det*w[0][3]*w[1][0]*(1.0); + const double G0_3_1 = det*w[0][3]*w[1][1]*(1.0); + const double G0_3_2 = det*w[0][3]*w[1][2]*(1.0); + const double G0_3_3 = det*w[0][3]*w[1][3]*(1.0); + const double G0_3_4 = det*w[0][3]*w[1][4]*(1.0); + const double G0_3_5 = det*w[0][3]*w[1][5]*(1.0); + const double G0_4_0 = det*w[0][4]*w[1][0]*(1.0); + const double G0_4_1 = det*w[0][4]*w[1][1]*(1.0); + const double G0_4_2 = det*w[0][4]*w[1][2]*(1.0); + const double G0_4_3 = det*w[0][4]*w[1][3]*(1.0); + const double G0_4_4 = det*w[0][4]*w[1][4]*(1.0); + const double G0_4_5 = det*w[0][4]*w[1][5]*(1.0); + const double G0_5_0 = det*w[0][5]*w[1][0]*(1.0); + const double G0_5_1 = det*w[0][5]*w[1][1]*(1.0); + const double G0_5_2 = det*w[0][5]*w[1][2]*(1.0); + const double G0_5_3 = det*w[0][5]*w[1][3]*(1.0); + const double G0_5_4 = det*w[0][5]*w[1][4]*(1.0); + const double G0_5_5 = det*w[0][5]*w[1][5]*(1.0); + + // Compute element tensor + A[9] = -5.29100529100527e-05*G0_0_0 - 0.000264550264550264*G0_0_1 + 0.000105820105820105*G0_0_2 + 0.000105820105820105*G0_0_3 + 0.000211640211640211*G0_0_4 - 0.000105820105820105*G0_0_5 - 0.000264550264550264*G0_1_0 + 0.00158730158730158*G0_1_1 - 0.000264550264550264*G0_1_2 + 0.00211640211640211*G0_1_3 + 0.000529100529100527*G0_1_4 + 0.00105820105820105*G0_1_5 + 0.000105820105820105*G0_2_0 - 0.000264550264550264*G0_2_1 - 0.000264550264550263*G0_2_2 - 0.000952380952380948*G0_2_3 - 0.000105820105820105*G0_2_4 - 0.000105820105820105*G0_2_5 + 0.000105820105820105*G0_3_0 + 0.00211640211640211*G0_3_1 - 0.000952380952380948*G0_3_2 - 0.00126984126984127*G0_3_4 + 0.000211640211640211*G0_4_0 + 0.000529100529100527*G0_4_1 - 0.000105820105820105*G0_4_2 - 0.00126984126984127*G0_4_3 - 0.00169312169312169*G0_4_4 - 0.000846560846560844*G0_4_5 - 0.000105820105820105*G0_5_0 + 0.00105820105820105*G0_5_1 - 0.000105820105820105*G0_5_2 - 0.000846560846560844*G0_5_4; + A[18] = A[9] + 5.29100529100533e-05*G0_0_0 + 0.000211640211640211*G0_0_1 - 0.000158730158730158*G0_0_2 + 0.000529100529100528*G0_0_3 + 0.000317460317460317*G0_0_4 + 0.000634920634920633*G0_0_5 + 0.000211640211640211*G0_1_0 - 0.00185185185185184*G0_1_1 + 0.000370370370370369*G0_1_2 - 0.002010582010582*G0_1_3 - 0.000317460317460317*G0_1_4 - 0.00116402116402116*G0_1_5 - 0.000158730158730158*G0_2_0 + 0.000370370370370369*G0_2_1 + 0.00105820105820105*G0_2_3 + 0.000317460317460316*G0_2_5 + 0.000529100529100528*G0_3_0 - 0.002010582010582*G0_3_1 + 0.00105820105820105*G0_3_2 - 0.0038095238095238*G0_3_3 - 0.000423280423280422*G0_3_4 - 0.00169312169312169*G0_3_5 + 0.000317460317460317*G0_4_0 - 0.000317460317460317*G0_4_1 - 0.000423280423280422*G0_4_3 + 0.000423280423280423*G0_4_4 + 0.000634920634920633*G0_5_0 - 0.00116402116402116*G0_5_1 + 0.000317460317460316*G0_5_2 - 0.00169312169312169*G0_5_3 - 0.00126984126984126*G0_5_5; + A[20] = A[9] + 0.000370370370370369*G0_0_1 - 0.000370370370370369*G0_0_2 - 0.000317460317460316*G0_0_4 + 0.000317460317460316*G0_0_5 + 0.000370370370370369*G0_1_0 - 0.00185185185185184*G0_1_1 - 0.00306878306878306*G0_1_3 - 0.000634920634920633*G0_1_4 - 0.00116402116402116*G0_1_5 - 0.000370370370370369*G0_2_0 + 0.00185185185185184*G0_2_2 + 0.00306878306878305*G0_2_3 + 0.00116402116402116*G0_2_4 + 0.000634920634920633*G0_2_5 - 0.00306878306878306*G0_3_1 + 0.00306878306878305*G0_3_2 + 0.00126984126984127*G0_3_4 - 0.00126984126984127*G0_3_5 - 0.000317460317460316*G0_4_0 - 0.000634920634920633*G0_4_1 + 0.00116402116402116*G0_4_2 + 0.00126984126984127*G0_4_3 + 0.00169312169312169*G0_4_4 + 0.000317460317460316*G0_5_0 - 0.00116402116402116*G0_5_1 + 0.000634920634920633*G0_5_2 - 0.00126984126984127*G0_5_3 - 0.00169312169312169*G0_5_5; + A[31] = A[9] - 0.00021164021164021*G0_0_0 - 0.000211640211640211*G0_0_3 - 0.000317460317460316*G0_0_4 - 0.000846560846560842*G0_0_5 - 0.00105820105820105*G0_1_3 + 0.00105820105820105*G0_1_5 + 0.00021164021164021*G0_2_2 + 0.000846560846560842*G0_2_3 + 0.000317460317460316*G0_2_4 + 0.000211640211640211*G0_2_5 - 0.00021164021164021*G0_3_0 - 0.00105820105820105*G0_3_1 + 0.000846560846560842*G0_3_2 + 0.000423280423280421*G0_3_4 - 0.000317460317460316*G0_4_0 + 0.000317460317460316*G0_4_2 + 0.000423280423280421*G0_4_3 - 0.000423280423280422*G0_4_5 - 0.000846560846560842*G0_5_0 + 0.00105820105820105*G0_5_1 + 0.000211640211640211*G0_5_2 - 0.000423280423280422*G0_5_4; + A[13] = -A[31] - 0.000238095238095237*G0_0_0 - 0.000238095238095237*G0_0_1 + 0.000132275132275132*G0_0_2 - 0.000846560846560842*G0_0_5 - 0.000238095238095237*G0_1_0 + 0.00119047619047618*G0_1_1 - 0.000105820105820106*G0_1_2 + 0.00079365079365079*G0_1_3 + 0.000476190476190474*G0_1_4 + 0.00185185185185184*G0_1_5 + 0.000132275132275132*G0_2_0 - 0.000105820105820106*G0_2_1 - 0.000449735449735447*G0_2_2 - 0.000370370370370368*G0_2_3 - 5.29100529100522e-05*G0_2_4 + 5.29100529100529e-05*G0_2_5 + 0.00079365079365079*G0_3_1 - 0.000370370370370368*G0_3_2 - 0.000952380952380948*G0_3_3 - 0.000952380952380949*G0_3_4 - 0.000105820105820106*G0_3_5 + 0.000476190476190474*G0_4_1 - 5.29100529100521e-05*G0_4_2 - 0.000952380952380949*G0_4_3 - 0.00158730158730158*G0_4_4 - 0.00105820105820105*G0_4_5 - 0.000846560846560842*G0_5_0 + 0.00185185185185184*G0_5_1 + 5.2910052910053e-05*G0_5_2 - 0.000105820105820106*G0_5_3 - 0.00105820105820105*G0_5_4 + 0.000105820105820105*G0_5_5; + A[3] = A[18]; + A[17] = A[18] - 0.000264550264550264*G0_0_0 + 0.000158730158730158*G0_0_1 - 0.000423280423280422*G0_0_3 - 0.000634920634920633*G0_0_4 - 0.000423280423280422*G0_0_5 + 0.000158730158730158*G0_1_0 - 0.000158730158730158*G0_1_2 - 0.00021164021164021*G0_1_3 + 0.000211640211640211*G0_1_5 - 0.000158730158730158*G0_2_1 + 0.000264550264550263*G0_2_2 + 0.000423280423280422*G0_2_3 + 0.000634920634920633*G0_2_4 + 0.000423280423280422*G0_2_5 - 0.000423280423280422*G0_3_0 - 0.00021164021164021*G0_3_1 + 0.000423280423280422*G0_3_2 + 0.00253968253968253*G0_3_3 + 0.000846560846560843*G0_3_4 - 0.000634920634920633*G0_4_0 + 0.000634920634920633*G0_4_2 + 0.000846560846560843*G0_4_3 - 0.000846560846560844*G0_4_5 - 0.000423280423280422*G0_5_0 + 0.000211640211640211*G0_5_1 + 0.000423280423280422*G0_5_2 - 0.000846560846560844*G0_5_4 - 0.00253968253968253*G0_5_5; + A[24] = A[9] + 0.00164021164021163*G0_0_0 - 0.000370370370370369*G0_0_2 + 0.000423280423280422*G0_0_3 + 0.0019047619047619*G0_0_4 + 0.00116402116402116*G0_0_5 - 0.00164021164021163*G0_1_1 + 0.000370370370370369*G0_1_2 - 0.0019047619047619*G0_1_3 - 0.000423280423280422*G0_1_4 - 0.00116402116402116*G0_1_5 - 0.000370370370370369*G0_2_0 + 0.000370370370370369*G0_2_1 + 0.000846560846560842*G0_2_3 - 0.000846560846560844*G0_2_4 + 0.000423280423280423*G0_3_0 - 0.0019047619047619*G0_3_1 + 0.000846560846560842*G0_3_2 - 0.00169312169312169*G0_3_3 - 0.000846560846560844*G0_3_5 + 0.0019047619047619*G0_4_0 - 0.000423280423280422*G0_4_1 - 0.000846560846560844*G0_4_2 + 0.00169312169312169*G0_4_4 + 0.000846560846560844*G0_4_5 + 0.00116402116402116*G0_5_0 - 0.00116402116402116*G0_5_1 - 0.000846560846560844*G0_5_3 + 0.000846560846560844*G0_5_4; + A[8] = A[13]; + A[21] = 0.000634920634920633*G0_0_0 + 0.000105820105820105*G0_0_1 + 0.000105820105820106*G0_0_2 - 0.0038095238095238*G0_0_3 - 0.00169312169312169*G0_0_4 - 0.00169312169312169*G0_0_5 + 0.000105820105820105*G0_1_0 + 0.00211640211640211*G0_1_1 - 0.000952380952380948*G0_1_2 - 0.00126984126984127*G0_1_4 + 0.000105820105820106*G0_2_0 - 0.000952380952380948*G0_2_1 + 0.00211640211640211*G0_2_2 - 0.00126984126984127*G0_2_5 - 0.0038095238095238*G0_3_0 + 0.0406349206349205*G0_3_3 + 0.0101587301587301*G0_3_4 + 0.0101587301587301*G0_3_5 - 0.00169312169312169*G0_4_0 - 0.00126984126984127*G0_4_1 + 0.0101587301587301*G0_4_3 + 0.00677248677248675*G0_4_4 + 0.00507936507936506*G0_4_5 - 0.00169312169312169*G0_5_0 - 0.00126984126984127*G0_5_2 + 0.0101587301587301*G0_5_3 + 0.00507936507936506*G0_5_4 + 0.00677248677248675*G0_5_5; + A[28] = A[21] + 0.00148148148148147*G0_0_0 - 0.00105820105820105*G0_0_2 + 0.00253968253968253*G0_0_3 + 0.00169312169312168*G0_0_4 + 0.00169312169312169*G0_0_5 - 0.00148148148148147*G0_1_1 + 0.00105820105820105*G0_1_2 - 0.00169312169312169*G0_1_3 - 0.00253968253968253*G0_1_4 - 0.00169312169312169*G0_1_5 - 0.00105820105820105*G0_2_0 + 0.00105820105820105*G0_2_1 + 0.00253968253968253*G0_3_0 - 0.00169312169312169*G0_3_1 - 0.0338624338624337*G0_3_3 - 0.00507936507936506*G0_3_5 + 0.00169312169312168*G0_4_0 - 0.00253968253968253*G0_4_1 + 0.0338624338624337*G0_4_4 + 0.00507936507936507*G0_4_5 + 0.00169312169312169*G0_5_0 - 0.00169312169312169*G0_5_1 - 0.00507936507936506*G0_5_3 + 0.00507936507936507*G0_5_4; + A[11] = A[31]; + A[30] = A[24] - 0.00105820105820105*G0_0_4 + 0.00105820105820105*G0_0_5 - 0.000211640211640211*G0_1_1 - 0.000317460317460316*G0_1_3 - 0.00021164021164021*G0_1_4 - 0.000846560846560842*G0_1_5 + 0.00021164021164021*G0_2_2 + 0.000317460317460317*G0_2_3 + 0.000846560846560844*G0_2_4 + 0.000211640211640211*G0_2_5 - 0.000317460317460316*G0_3_1 + 0.000317460317460317*G0_3_2 + 0.000423280423280421*G0_3_4 - 0.000423280423280422*G0_3_5 - 0.00105820105820105*G0_4_0 - 0.00021164021164021*G0_4_1 + 0.000846560846560844*G0_4_2 + 0.000423280423280421*G0_4_3 + 0.00105820105820105*G0_5_0 - 0.000846560846560842*G0_5_1 + 0.000211640211640211*G0_5_2 - 0.000423280423280422*G0_5_3; + A[4] = A[24]; + A[25] = A[18] - 0.000264550264550264*G0_0_0 + 0.000158730158730158*G0_0_2 - 0.000423280423280422*G0_0_3 - 0.000423280423280422*G0_0_4 - 0.000634920634920633*G0_0_5 + 0.000264550264550264*G0_1_1 - 0.000158730158730158*G0_1_2 + 0.000423280423280422*G0_1_3 + 0.000423280423280422*G0_1_4 + 0.000634920634920632*G0_1_5 + 0.000158730158730158*G0_2_0 - 0.000158730158730158*G0_2_1 - 0.000211640211640211*G0_2_3 + 0.000211640211640211*G0_2_4 - 0.000423280423280422*G0_3_0 + 0.000423280423280422*G0_3_1 - 0.000211640211640211*G0_3_2 + 0.00253968253968253*G0_3_3 + 0.000846560846560843*G0_3_5 - 0.000423280423280422*G0_4_0 + 0.000423280423280422*G0_4_1 + 0.000211640211640212*G0_4_2 - 0.00253968253968253*G0_4_4 - 0.000846560846560844*G0_4_5 - 0.000634920634920633*G0_5_0 + 0.000634920634920632*G0_5_1 + 0.000846560846560844*G0_5_3 - 0.000846560846560844*G0_5_4; + A[34] = 0.00105820105820105*G0_0_0 - 0.000105820105820105*G0_0_1 - 0.000105820105820105*G0_0_2 - 0.000846560846560844*G0_0_3 - 0.000105820105820105*G0_1_0 + 0.000529100529100527*G0_1_1 + 0.000211640211640211*G0_1_2 - 0.000846560846560844*G0_1_3 - 0.00169312169312169*G0_1_4 - 0.00126984126984127*G0_1_5 - 0.000105820105820105*G0_2_0 + 0.000211640211640211*G0_2_1 + 0.000529100529100528*G0_2_2 - 0.000846560846560844*G0_2_3 - 0.00126984126984127*G0_2_4 - 0.00169312169312169*G0_2_5 - 0.000846560846560844*G0_3_0 - 0.000846560846560844*G0_3_1 - 0.000846560846560844*G0_3_2 + 0.00507936507936506*G0_3_3 + 0.00507936507936507*G0_3_4 + 0.00507936507936506*G0_3_5 - 0.00169312169312169*G0_4_1 - 0.00126984126984127*G0_4_2 + 0.00507936507936506*G0_4_3 + 0.0101587301587301*G0_4_4 + 0.00677248677248675*G0_4_5 - 0.00126984126984127*G0_5_1 - 0.00169312169312169*G0_5_2 + 0.00507936507936506*G0_5_3 + 0.00677248677248675*G0_5_4 + 0.0101587301587301*G0_5_5; + A[29] = A[34]; + A[14] = A[13] + 0.000132275132275132*G0_0_0 - 0.000423280423280421*G0_0_2 - 0.000370370370370369*G0_0_3 - 0.000370370370370369*G0_0_4 - 0.000158730158730158*G0_0_5 + 0.000555555555555553*G0_1_1 - 0.000555555555555552*G0_1_2 - 0.00021164021164021*G0_1_4 + 0.000211640211640211*G0_1_5 - 0.000423280423280421*G0_2_0 - 0.000555555555555552*G0_2_1 + 0.00515873015873013*G0_2_2 + 0.00185185185185184*G0_2_3 + 0.00185185185185184*G0_2_4 + 5.29100529100528e-05*G0_2_5 - 0.000370370370370369*G0_3_0 + 0.00185185185185184*G0_3_2 + 0.00306878306878305*G0_3_3 + 0.00116402116402116*G0_3_4 + 0.000634920634920633*G0_3_5 - 0.000370370370370369*G0_4_0 - 0.00021164021164021*G0_4_1 + 0.00185185185185184*G0_4_2 + 0.00116402116402116*G0_4_3 + 0.002010582010582*G0_4_4 + 0.000317460317460317*G0_4_5 - 0.000158730158730158*G0_5_0 + 0.000211640211640211*G0_5_1 + 5.29100529100528e-05*G0_5_2 + 0.000634920634920633*G0_5_3 + 0.000317460317460317*G0_5_4 + 0.000529100529100527*G0_5_5; + A[7] = A[14] - 0.000423280423280422*G0_0_1 + 0.000423280423280421*G0_0_2 + 0.00021164021164021*G0_0_4 - 0.000211640211640211*G0_0_5 - 0.000423280423280422*G0_1_0 + 0.00460317460317458*G0_1_1 + 0.00185185185185184*G0_1_3 + 0.000264550264550263*G0_1_4 + 0.00164021164021163*G0_1_5 + 0.000423280423280421*G0_2_0 - 0.00460317460317458*G0_2_2 - 0.00185185185185184*G0_2_3 - 0.00164021164021163*G0_2_4 - 0.000264550264550263*G0_2_5 + 0.00185185185185184*G0_3_1 - 0.00185185185185184*G0_3_2 - 0.000529100529100526*G0_3_4 + 0.000529100529100526*G0_3_5 + 0.00021164021164021*G0_4_0 + 0.000264550264550263*G0_4_1 - 0.00164021164021163*G0_4_2 - 0.000529100529100526*G0_4_3 - 0.00148148148148147*G0_4_4 - 0.000211640211640211*G0_5_0 + 0.00164021164021163*G0_5_1 - 0.000264550264550263*G0_5_2 + 0.000529100529100526*G0_5_3 + 0.00148148148148147*G0_5_5; + A[0] = A[14] + 0.00460317460317457*G0_0_0 - 0.000423280423280421*G0_0_1 + 0.000264550264550264*G0_0_3 + 0.00185185185185184*G0_0_4 + 0.00164021164021163*G0_0_5 - 0.000423280423280421*G0_1_0 + 0.000423280423280421*G0_1_2 + 0.00021164021164021*G0_1_3 - 0.00021164021164021*G0_1_5 + 0.000423280423280421*G0_2_1 - 0.00460317460317458*G0_2_2 - 0.00164021164021163*G0_2_3 - 0.00185185185185184*G0_2_4 - 0.000264550264550264*G0_2_5 + 0.000264550264550264*G0_3_0 + 0.00021164021164021*G0_3_1 - 0.00164021164021163*G0_3_2 - 0.00148148148148147*G0_3_3 - 0.000529100529100526*G0_3_4 + 0.00185185185185184*G0_4_0 - 0.00185185185185184*G0_4_2 - 0.000529100529100526*G0_4_3 + 0.000529100529100526*G0_4_5 + 0.00164021164021163*G0_5_0 - 0.00021164021164021*G0_5_1 - 0.000264550264550264*G0_5_2 + 0.000529100529100526*G0_5_4 + 0.00148148148148147*G0_5_5; + A[10] = A[25]; + A[5] = A[30]; + A[26] = A[20] - 0.00021164021164021*G0_0_0 - 0.000211640211640211*G0_0_3 - 0.000846560846560844*G0_0_4 - 0.000317460317460316*G0_0_5 + 0.000211640211640211*G0_1_1 + 0.000846560846560843*G0_1_3 + 0.000211640211640211*G0_1_4 + 0.000317460317460316*G0_1_5 - 0.00105820105820105*G0_2_3 + 0.00105820105820105*G0_2_4 - 0.000211640211640211*G0_3_0 + 0.000846560846560843*G0_3_1 - 0.00105820105820105*G0_3_2 + 0.000423280423280422*G0_3_5 - 0.000846560846560844*G0_4_0 + 0.000211640211640211*G0_4_1 + 0.00105820105820105*G0_4_2 - 0.000423280423280422*G0_4_5 - 0.000317460317460316*G0_5_0 + 0.000317460317460316*G0_5_1 + 0.000423280423280421*G0_5_3 - 0.000423280423280422*G0_5_4; + A[6] = A[13] - 0.000423280423280421*G0_0_0 + 0.000132275132275132*G0_0_1 - 0.000158730158730158*G0_0_3 - 0.000370370370370369*G0_0_4 - 0.000370370370370369*G0_0_5 + 0.000132275132275132*G0_1_0 - 0.000132275132275132*G0_1_2 - 0.000132275132275132*G0_2_1 + 0.00042328042328042*G0_2_2 + 0.000370370370370368*G0_2_3 + 0.000370370370370369*G0_2_4 + 0.000158730158730158*G0_2_5 - 0.000158730158730158*G0_3_0 + 0.000370370370370368*G0_3_2 + 0.00105820105820105*G0_3_3 + 0.000317460317460316*G0_3_4 - 0.000370370370370369*G0_4_0 + 0.000370370370370369*G0_4_2 + 0.000317460317460316*G0_4_3 - 0.000317460317460316*G0_4_5 - 0.000370370370370369*G0_5_0 + 0.000158730158730158*G0_5_2 - 0.000317460317460316*G0_5_4 - 0.00105820105820105*G0_5_5; + A[1] = A[6]; + A[35] = A[21] + 0.00148148148148147*G0_0_0 - 0.00105820105820105*G0_0_1 + 0.00253968253968253*G0_0_3 + 0.00169312169312169*G0_0_4 + 0.00169312169312168*G0_0_5 - 0.00105820105820105*G0_1_0 + 0.00105820105820105*G0_1_2 + 0.00105820105820105*G0_2_1 - 0.00148148148148147*G0_2_2 - 0.00169312169312168*G0_2_3 - 0.00169312169312169*G0_2_4 - 0.00253968253968253*G0_2_5 + 0.00253968253968253*G0_3_0 - 0.00169312169312168*G0_3_2 - 0.0338624338624337*G0_3_3 - 0.00507936507936506*G0_3_4 + 0.00169312169312168*G0_4_0 - 0.00169312169312169*G0_4_2 - 0.00507936507936506*G0_4_3 + 0.00507936507936506*G0_4_5 + 0.00169312169312168*G0_5_0 - 0.00253968253968253*G0_5_2 + 0.00507936507936506*G0_5_4 + 0.0338624338624337*G0_5_5; + A[23] = A[34] - 0.000529100529100526*G0_0_0 + 0.000317460317460316*G0_0_2 - 0.000846560846560844*G0_0_3 - 0.000846560846560844*G0_0_4 - 0.00126984126984126*G0_0_5 + 0.000529100529100527*G0_1_1 - 0.000317460317460317*G0_1_2 + 0.000846560846560844*G0_1_3 + 0.000846560846560844*G0_1_4 + 0.00126984126984126*G0_1_5 + 0.000317460317460316*G0_2_0 - 0.000317460317460316*G0_2_1 - 0.000423280423280422*G0_2_3 + 0.000423280423280422*G0_2_4 - 0.000846560846560844*G0_3_0 + 0.000846560846560844*G0_3_1 - 0.000423280423280422*G0_3_2 + 0.00507936507936506*G0_3_3 + 0.00169312169312169*G0_3_5 - 0.000846560846560843*G0_4_0 + 0.000846560846560844*G0_4_1 + 0.000423280423280422*G0_4_2 - 0.00507936507936506*G0_4_4 - 0.00169312169312169*G0_4_5 - 0.00126984126984126*G0_5_0 + 0.00126984126984126*G0_5_1 + 0.00169312169312169*G0_5_3 - 0.00169312169312169*G0_5_4; + A[33] = A[23]; + A[19] = A[9]; + A[16] = A[26]; + A[27] = A[34] - 0.000529100529100526*G0_0_0 + 0.000317460317460316*G0_0_1 - 0.000846560846560843*G0_0_3 - 0.00126984126984126*G0_0_4 - 0.000846560846560842*G0_0_5 + 0.000317460317460316*G0_1_0 - 0.000317460317460316*G0_1_2 - 0.000423280423280421*G0_1_3 + 0.000423280423280422*G0_1_5 - 0.000317460317460316*G0_2_1 + 0.000529100529100526*G0_2_2 + 0.000846560846560844*G0_2_3 + 0.00126984126984127*G0_2_4 + 0.000846560846560844*G0_2_5 - 0.000846560846560843*G0_3_0 - 0.000423280423280421*G0_3_1 + 0.000846560846560844*G0_3_2 + 0.00507936507936506*G0_3_3 + 0.00169312169312169*G0_3_4 - 0.00126984126984126*G0_4_0 + 0.00126984126984127*G0_4_2 + 0.00169312169312169*G0_4_3 - 0.00169312169312169*G0_4_5 - 0.000846560846560842*G0_5_0 + 0.000423280423280422*G0_5_1 + 0.000846560846560844*G0_5_2 - 0.00169312169312169*G0_5_4 - 0.00507936507936506*G0_5_5; + A[22] = A[27]; + A[15] = A[20]; + A[32] = A[17]; + A[2] = A[13] - 0.000423280423280421*G0_0_0 + 0.000132275132275132*G0_0_2 - 0.000158730158730158*G0_0_3 - 0.000370370370370369*G0_0_4 - 0.000370370370370369*G0_0_5 + 0.000423280423280421*G0_1_1 - 0.000132275132275132*G0_1_2 + 0.000370370370370369*G0_1_3 + 0.000158730158730158*G0_1_4 + 0.000370370370370369*G0_1_5 + 0.000132275132275132*G0_2_0 - 0.000132275132275132*G0_2_1 - 0.000158730158730158*G0_3_0 + 0.000370370370370369*G0_3_1 + 0.00105820105820105*G0_3_3 + 0.000317460317460316*G0_3_5 - 0.000370370370370369*G0_4_0 + 0.000158730158730158*G0_4_1 - 0.00105820105820106*G0_4_4 - 0.000317460317460317*G0_4_5 - 0.000370370370370369*G0_5_0 + 0.000370370370370369*G0_5_1 + 0.000317460317460316*G0_5_3 - 0.000317460317460317*G0_5_4; + A[12] = A[2]; + } + + /// 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 mass_matrix_f2_p2_q2_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p2_q2_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p2_q2_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1))), 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 mass_matrix_f2_p2_q2_tensor_finite_element_0(); + break; + } + case 1: + { + return new mass_matrix_f2_p2_q2_tensor_finite_element_0(); + break; + } + case 2: + { + return new mass_matrix_f2_p2_q2_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p2_q2_tensor_finite_element_0(); + 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 mass_matrix_f2_p2_q2_tensor_dofmap_0(); + break; + } + case 1: + { + return new mass_matrix_f2_p2_q2_tensor_dofmap_0(); + break; + } + case 2: + { + return new mass_matrix_f2_p2_q2_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p2_q2_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f2_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/mass_matrix_2d/mass_matrix_f2_p2_q3_excafe.h b/mass_matrix_2d/mass_matrix_f2_p2_q3_excafe.h new file mode 100644 index 0000000..98a58a4 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p2_q3_excafe.h @@ -0,0 +1,403 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 1 minute and 16.46 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][4]*w[1][0] + w[0][0]*w[1][4]; + const double var_1 = w[0][2]*w[1][3] + w[0][3]*w[1][2]; + const double var_2 = -1.0000000000000000000000000*var_1; + const double var_3 = var_2 + var_0; + const double var_4 = -1.0000000000000000000000000*x[0][0]; + const double var_5 = x[1][0] + var_4; + const double var_6 = -1.0000000000000000000000000*x[0][1]; + const double var_7 = var_6 + x[2][1]; + const double var_8 = x[2][0] + var_4; + const double var_9 = var_6 + x[1][1]; + const double var_10 = var_5*var_7 + -1.0000000000000000000000000*var_8*var_9; + const double var_11 = std::abs(var_10); + const double var_12 = w[0][5]*w[1][0] + w[0][0]*w[1][5]; + const double var_13 = w[0][2]*w[1][4] + w[0][4]*w[1][2]; + const double var_14 = w[0][0]*w[1][1] + w[0][1]*w[1][0]; + const double var_15 = w[0][5]*w[1][5]; + const double var_16 = -1.0000000000000000000000000*var_15; + const double var_17 = -1.0000000000000000000000000*w[0][2]*w[1][2]; + const double var_18 = 0.0232142857142857150787307*var_14 + 0.0250000000000000013877788*var_17 + 0.4285714285714285476380780*var_16; + const double var_19 = w[0][2]*w[1][1] + w[0][1]*w[1][2]; + const double var_20 = w[0][0]*w[1][0]; + const double var_21 = w[0][3]*w[1][0] + w[0][0]*w[1][3]; + const double var_22 = w[0][5]*w[1][4] + w[0][4]*w[1][5]; + const double var_23 = 0.0357142857142857123031732*var_21 + var_22; + const double var_24 = w[0][3]*w[1][3]; + const double var_25 = w[0][3]*w[1][5] + w[0][5]*w[1][3]; + const double var_26 = w[0][4]*w[1][3] + w[0][3]*w[1][4]; + const double var_27 = var_26 + var_25; + const double var_28 = var_24 + var_27; + const double var_29 = 0.1250000000000000000000000*var_20 + 0.0089285714285714280757933*var_19 + 0.2000000000000000111022302*var_23 + 0.0857142857142857150787307*var_28; + const double var_30 = w[0][2]*w[1][5] + w[0][5]*w[1][2]; + const double var_31 = w[0][1]*w[1][4] + w[0][4]*w[1][1]; + const double var_32 = var_30 + var_31; + const double var_33 = -1.0000000000000000000000000*var_29 + 0.0500000000000000027755576*var_32; + const double var_34 = w[0][0]*w[1][2] + w[0][2]*w[1][0]; + const double var_35 = -1.0000000000000000000000000*w[0][1]*w[1][1]; + const double var_36 = 0.0285714285714285705364279*var_34 + 0.0089285714285714280757933*var_35; + const double var_37 = w[0][3]*w[1][1] + w[0][1]*w[1][3]; + const double var_38 = 0.0357142857142857123031732*var_37; + const double var_39 = w[0][5]*w[1][1] + w[0][1]*w[1][5]; + const double var_40 = -1.0000000000000000000000000*var_0; + const double var_41 = var_39 + var_40; + const double var_42 = 0.0214285714285714287696827*var_13 + var_33 + var_36 + var_18 + 0.0857142857142857150787307*var_41 + var_38 + -0.1285714285714285587403083*var_12 + 0.0071428571428571426341070*var_2; + const double var_43 = w[0][4]*w[1][4]; + const double var_44 = -1.0000000000000000000000000*var_43; + const double var_45 = 0.0011688311688311688301550*var_11*var_44; + A[67] = 0.0068181818181818178506437*var_11*var_42 + var_45; + const double var_46 = var_14 + var_34; + const double var_47 = var_12 + var_0; + const double var_48 = w[0][2]*w[1][2]; + const double var_49 = w[0][1]*w[1][1]; + const double var_50 = var_49 + var_48; + const double var_51 = var_44 + var_16; + const double var_52 = -1.0000000000000000000000000*var_24; + const double var_53 = -1.0000000000000000000000000*var_37; + const double var_54 = var_2 + var_53; + const double var_55 = -1.0000000000000000000000000*var_22; + const double var_56 = var_55 + 0.2500000000000000000000000*var_32; + const double var_57 = -1.0000000000000000000000000*var_39; + const double var_58 = -1.0000000000000000000000000*var_13; + const double var_59 = var_57 + var_58; + const double var_60 = var_59 + var_56; + const double var_61 = -0.0937500000000000000000000*w[0][0]*w[1][0] + 0.3750000000000000000000000*var_21 + var_52 + -1.0000000000000000000000000*var_27 + 0.5000000000000000000000000*var_60 + 0.7500000000000000000000000*var_54; + const double var_62 = 0.0022727272727272726168812*var_47 + 0.0090909090909090904675249*var_51 + 0.0077922077922077922010335*var_61 + 0.0006493506493506493500861*var_46 + -0.0089285714285714280757933*var_50 + 0.0036525974025974029466002*var_19; + A[34] = 0.1500000000000000222044605*var_11*var_62; + const double var_63 = var_43 + var_15; + const double var_64 = var_22 + -0.2500000000000000000000000*var_32; + const double var_65 = 0.1625000000000000055511151*w[0][0]*w[1][0]; + const double var_66 = -1.0000000000000000000000000*var_46; + const double var_67 = 0.0030952380952380953438308*var_50 + 0.0071428571428571426341070*var_27 + 0.0142857142857142852682140*var_64 + 0.0285714285714285705364279*var_63 + var_65 + 0.0035714285714285713170535*var_59 + 0.0001190476190476190475158*var_19 + 0.0123809523809523813753231*var_24 + 0.0002380952380952380950316*var_54 + 0.0357142857142857123031732*var_47 + 0.0089285714285714280757933*var_66; + const double var_68 = -0.0250000000000000013877788*var_14 + -0.0125000000000000006938894*var_48 + 0.3000000000000000444089210*var_15; + const double var_69 = var_34 + var_19; + const double var_70 = -1.0000000000000000000000000*var_69; + const double var_71 = -1.0000000000000000000000000*var_12; + const double var_72 = -1.0000000000000000000000000*var_21; + const double var_73 = -0.0758928571428571369095195*w[0][0]*w[1][0] + 0.0095238095238095246686250*var_72 + 0.0023809523809523811671562*var_22 + 0.0404761904761904781069326*var_24 + -0.0041666666666666666088426*var_19; + const double var_74 = 0.0293154761904761938795527*w[0][1]*w[1][1] + 0.0035714285714285713170535*var_31 + 0.0095238095238095246686250*var_43 + 0.0285714285714285705364279*var_25 + 0.0077380952380952392269386*var_34; + const double var_75 = -1.0000000000000000000000000*var_30; + const double var_76 = 0.0017857142857142856585267*var_14; + const double var_77 = 0.0001488095238095238229473*var_48 + 0.0047619047619047623343125*var_75 + var_76 + 0.0119047619047619041010577*var_26 + 0.0142857142857142852682140*var_16; + const double var_78 = 0.0357142857142857123031732*var_39; + const double var_79 = 0.0476190476190476164042309*var_71 + 0.0172619047619047630282019*var_37 + var_77 + 0.0238095238095238082021154*var_40 + 0.0035714285714285713170535*var_58 + var_74 + -0.0101190476190476195267332*var_1 + var_73 + var_78; + A[8] = 0.0090909090909090904675249*var_11*var_79; + const double var_80 = 0.0095238095238095246686250*var_75 + 0.0023809523809523811671562*var_26 + -0.0041666666666666666088426*var_14 + 0.0404761904761904781069326*var_15 + -0.0758928571428571369095195*w[0][2]*w[1][2]; + const double var_81 = 0.0047619047619047623343125*var_72 + 0.0119047619047619041010577*var_22 + 0.0142857142857142852682140*var_52 + 0.0001488095238095238229473*var_20 + 0.0017857142857142856585267*var_19; + const double var_82 = 0.0035714285714285713170535*var_40 + 0.0238095238095238082021154*var_58 + var_74 + var_80 + var_81 + -0.0101190476190476195267332*var_12 + var_38 + 0.0476190476190476164042309*var_2 + 0.0172619047619047630282019*var_39; + A[23] = 0.0090909090909090904675249*var_11*var_82; + const double var_83 = 0.0025974025974025974003445*var_43; + const double var_84 = var_26 + 0.0357142857142857123031732*var_30; + const double var_85 = var_25 + var_22; + const double var_86 = var_85 + var_15; + const double var_87 = 0.0089285714285714280757933*var_14 + 0.0857142857142857150787307*var_86 + 0.2000000000000000111022302*var_84 + 0.1250000000000000000000000*var_48; + const double var_88 = var_31 + var_21; + const double var_89 = var_20 + var_49; + const double var_90 = var_1 + var_13; + const double var_91 = var_24 + var_43; + const double var_92 = var_57 + var_71; + const double var_93 = var_0 + var_37; + const double var_94 = -0.0535714285714285684547598*var_93 + var_87 + 0.0142857142857142852682140*var_92 + 0.3000000000000000444089210*var_91 + 0.0169642857142857129970626*var_89 + 0.1071428571428571369095195*var_90 + -0.0500000000000000027755576*var_88 + -0.0258928571428571410728559*var_69; + A[46] = 0.0136363636363636357012874*var_11*var_94; + A[64] = A[46]; + const double var_95 = var_14 + var_19; + const double var_96 = var_39 + var_37; + const double var_97 = var_20 + var_48; + const double var_98 = var_52 + var_16; + const double var_99 = var_26 + var_22; + const double var_100 = var_40 + var_58; + const double var_101 = var_30 + var_21; + const double var_102 = -1.0000000000000000000000000*var_25; + const double var_103 = var_102 + 0.2500000000000000000000000*var_101; + const double var_104 = var_2 + var_71; + const double var_105 = var_104 + var_103; + const double var_106 = 0.3750000000000000000000000*var_31 + -0.0937500000000000000000000*w[0][1]*w[1][1] + -1.0000000000000000000000000*var_99 + var_44 + 0.5000000000000000000000000*var_105 + 0.7500000000000000000000000*var_100; + const double var_107 = 0.0077922077922077922010335*var_106 + -0.0089285714285714280757933*var_97 + 0.0036525974025974029466002*var_34 + 0.0090909090909090904675249*var_98 + 0.0006493506493506493500861*var_95 + 0.0022727272727272726168812*var_96; + const double var_108 = -1.0000000000000000000000000*var_26; + const double var_109 = var_30 + var_108; + const double var_110 = 0.0077110389610389618725295*w[0][2]*w[1][2] + 0.0001149891774891774958540*var_14 + 0.0005411255411255411250718*var_109 + 0.0023809523809523811671562*var_16; + const double var_111 = -1.0000000000000000000000000*w[0][0]*w[1][0]; + const double var_112 = -1.0000000000000000000000000*var_19; + const double var_113 = 0.0010822510822510822501435*var_55 + 0.0008116883116883117418178*var_112 + 0.0002705627705627705625359*var_21 + 0.0016233766233766234836355*var_52 + 0.0001149891774891774958540*var_111; + const double var_114 = -1.0000000000000000000000000*var_34; + const double var_115 = var_114 + var_44; + const double var_116 = -0.3291666666666666629659233*w[0][1]*w[1][1] + var_102 + 0.3333333333333333148296163*var_115; + const double var_117 = 0.0016233766233766234836355*var_116; + const double var_118 = 0.0001893939393939393937751*var_57 + var_117 + 0.0021645021645021645002871*var_13 + var_113 + var_110 + 0.0008116883116883117418178*var_53 + 0.0043290043290043290005742*var_1 + 0.0002705627705627705625359*var_12; + A[24] = 0.2000000000000000111022302*var_11*var_118; + A[42] = A[24]; + const double var_119 = 0.0045454545454545452337625*var_43 + 0.0015422077922077922877697*w[0][1]*w[1][1] + -0.0012175324675324677211469*var_31 + 0.0038961038961038961005168*var_25 + -0.0006290584415584415511197*var_34; + const double var_120 = 0.0003652597402597402729760*var_48 + -0.0021915584415584414210154*var_30 + 0.0019480519480519480502584*var_26 + -0.0016436688311688310657616*var_14 + 0.0272727272727272714025748*var_15; + const double var_121 = 0.0025974025974025974003445*var_24; + const double var_122 = 0.0056818181818181819758840*var_20 + 0.0002232142857142857073158*var_19 + 0.0068181818181818178506437*var_23 + var_121; + const double var_123 = var_120 + 0.0029220779220779221838078*var_57 + 0.0024350649350649354422937*var_0 + var_119 + 0.0011363636363636363084406*var_58 + var_122 + 0.0073051948051948058932004*var_12 + 0.0006493506493506493500861*var_2; + const double var_124 = var_58 + var_0; + const double var_125 = -0.0012175324675324677211469*var_30 + 0.0038961038961038961005168*var_26 + -0.0006290584415584415511197*var_14 + 0.0045454545454545452337625*var_15 + 0.0015422077922077922877697*w[0][2]*w[1][2]; + const double var_126 = 0.0019480519480519480502584*var_22 + -0.0021915584415584414210154*var_21 + 0.0272727272727272714025748*var_24 + 0.0003652597402597402729760*var_20 + -0.0016436688311688310657616*var_19; + const double var_127 = var_25 + 0.0357142857142857123031732*var_31; + const double var_128 = var_83 + 0.0002232142857142857073158*var_34 + 0.0056818181818181819758840*var_49 + 0.0068181818181818178506437*var_127; + const double var_129 = var_126 + 0.0011363636363636363084406*var_71 + 0.0073051948051948058932004*var_37 + 0.0006493506493506493500861*var_40 + var_125 + var_128 + 0.0029220779220779221838078*var_2 + 0.0024350649350649354422937*var_39; + const double var_130 = 0.0015422077922077922877697*w[0][0]*w[1][0] + 0.0038961038961038961005168*var_22 + -0.0012175324675324677211469*var_21 + 0.0045454545454545452337625*var_24 + -0.0006290584415584415511197*var_19; + const double var_131 = -1.0000000000000000000000000*var_31; + const double var_132 = 0.0404761904761904781069326*var_43 + -0.0758928571428571369095195*w[0][1]*w[1][1] + 0.0023809523809523811671562*var_25 + 0.0095238095238095246686250*var_131 + -0.0041666666666666666088426*var_34; + const double var_133 = 0.0035714285714285713170535*var_30 + 0.0285714285714285705364279*var_26 + 0.0077380952380952392269386*var_14 + 0.0095238095238095246686250*var_15 + 0.0293154761904761938795527*w[0][2]*w[1][2]; + const double var_134 = 0.0357142857142857123031732*var_1; + const double var_135 = 0.0238095238095238082021154*var_57 + 0.0035714285714285713170535*var_71 + var_134 + -0.0101190476190476195267332*var_0 + 0.0172619047619047630282019*var_13 + 0.0476190476190476164042309*var_53 + var_81 + var_132 + var_133; + A[14] = 0.0090909090909090904675249*var_11*var_135; + A[41] = A[14]; + const double var_136 = var_31 + var_102; + const double var_137 = 0.0005411255411255411250718*var_136 + 0.0001149891774891774958540*var_34 + 0.0023809523809523811671562*var_44 + 0.0077110389610389618725295*w[0][1]*w[1][1]; + const double var_138 = -1.0000000000000000000000000*var_14; + const double var_139 = 0.0001149891774891774958540*var_17 + 0.0010822510822510822501435*var_108 + 0.0002705627705627705625359*var_30 + 0.0008116883116883117418178*var_138 + 0.0016233766233766234836355*var_16; + const double var_140 = var_52 + var_112; + const double var_141 = var_55 + -0.3291666666666666629659233*w[0][0]*w[1][0] + 0.3333333333333333148296163*var_140; + const double var_142 = 0.0016233766233766234836355*var_141; + const double var_143 = 0.0008116883116883117418178*var_71 + 0.0021645021645021645002871*var_37 + 0.0002705627705627705625359*var_13 + var_142 + 0.0001893939393939393937751*var_40 + var_139 + var_137 + 0.0043290043290043290005742*var_39; + const double var_144 = var_16 + var_138; + const double var_145 = -0.3291666666666666629659233*w[0][2]*w[1][2] + 0.3333333333333333148296163*var_144 + var_108; + const double var_146 = 0.0016233766233766234836355*var_145; + const double var_147 = 0.0043290043290043290005742*var_37 + 0.0002705627705627705625359*var_0 + var_146 + 0.0001893939393939393937751*var_58 + var_113 + var_137 + 0.0008116883116883117418178*var_2 + 0.0021645021645021645002871*var_39; + const double var_148 = var_26 + -0.2500000000000000000000000*var_88; + const double var_149 = var_148 + var_16; + const double var_150 = 0.0312500000000000000000000*var_14 + 0.0750000000000000111022302*var_30 + 0.0625000000000000000000000*var_48 + 0.3000000000000000444089210*var_149; + const double var_151 = 0.3000000000000000444089210*var_24 + -0.0125000000000000006938894*var_20 + -0.0250000000000000013877788*var_19; + const double var_152 = 0.0062500000000000003469447*var_49 + -0.0187500000000000027755576*var_34 + 0.6000000000000000888178420*var_43; + const double var_153 = var_40 + var_13; + const double var_154 = 0.0500000000000000027755576*var_71 + var_151 + var_152 + var_150 + 0.1000000000000000055511151*var_1 + 0.0750000000000000111022302*var_53 + 0.1500000000000000222044605*var_153; + A[69] = 0.0116883116883116887352312*var_11*var_154; + A[96] = A[69]; + const double var_155 = var_64 + var_52; + const double var_156 = 0.0625000000000000000000000*var_20 + 0.3000000000000000444089210*var_155 + 0.0312500000000000000000000*var_19 + 0.0750000000000000111022302*var_21; + const double var_157 = 0.0750000000000000111022302*var_57 + var_68 + var_156 + var_152 + 0.1000000000000000055511151*var_12 + 0.1500000000000000222044605*var_124 + 0.0500000000000000027755576*var_2; + const double var_158 = var_39 + var_12; + const double var_159 = var_34 + var_95; + const double var_160 = var_89 + var_48; + const double var_161 = var_31 + var_101; + const double var_162 = -1.5000000000000000000000000*var_161 + 0.5000000000000000000000000*var_160 + var_92 + var_54 + 0.1250000000000000000000000*var_159 + var_100; + const double var_163 = var_85 + var_26; + const double var_164 = var_91 + var_15; + const double var_165 = 0.2500000000000000000000000*var_162 + 1.5000000000000000000000000*var_163 + 2.0000000000000000000000000*var_164; + A[99] = 0.0140259740259740268292221*var_11*var_165; + const double var_166 = var_96 + var_44; + const double var_167 = -0.0125000000000000006938894*var_49 + -0.0250000000000000013877788*var_34 + 0.3000000000000000444089210*var_43; + const double var_168 = var_25 + -0.2500000000000000000000000*var_101; + const double var_169 = var_168 + var_44; + const double var_170 = 0.0312500000000000000000000*var_34 + 0.0625000000000000000000000*var_49 + 0.0750000000000000111022302*var_31 + 0.3000000000000000444089210*var_169; + const double var_171 = 0.6000000000000000888178420*var_24 + 0.0062500000000000003469447*var_20 + -0.0187500000000000027755576*var_19; + const double var_172 = var_2 + var_37; + const double var_173 = 0.0750000000000000111022302*var_71 + var_68 + 0.0500000000000000027755576*var_58 + var_171 + var_170 + 0.1500000000000000222044605*var_172 + 0.1000000000000000055511151*var_39; + A[39] = 0.0116883116883116887352312*var_11*var_173; + const double var_174 = 0.0500000000000000027755576*var_88 + -1.0000000000000000000000000*var_87; + const double var_175 = 0.0002705627705627705625359*var_31 + 0.0001149891774891774958540*var_35 + 0.0010822510822510822501435*var_102 + 0.0016233766233766234836355*var_44 + 0.0008116883116883117418178*var_114; + const double var_176 = -0.0187500000000000027755576*var_14 + 0.0062500000000000003469447*var_48 + 0.6000000000000000888178420*var_15; + const double var_177 = var_39 + var_71; + const double var_178 = 0.1000000000000000055511151*var_37 + var_151 + var_176 + 0.0500000000000000027755576*var_40 + 0.1500000000000000222044605*var_177 + var_170 + 0.0750000000000000111022302*var_2; + A[89] = 0.0116883116883116887352312*var_11*var_178; + const double var_179 = 0.0293154761904761938795527*w[0][0]*w[1][0] + 0.0285714285714285705364279*var_22 + 0.0035714285714285713170535*var_21 + 0.0095238095238095246686250*var_24 + 0.0077380952380952392269386*var_19; + const double var_180 = 0.0357142857142857123031732*var_12; + const double var_181 = 0.0476190476190476164042309*var_57 + 0.0172619047619047630282019*var_0 + -0.0101190476190476195267332*var_13 + var_77 + var_179 + 0.0238095238095238082021154*var_53 + var_132 + var_180 + 0.0035714285714285713170535*var_2; + A[17] = 0.0090909090909090904675249*var_11*var_181; + const double var_182 = 0.0036796536796536798673285*var_64 + 0.0020021645021645021085555*w[0][0]*w[1][0] + 0.2500000000000000000000000*var_121 + 0.0003787878787878787875502*var_21 + 0.0010822510822510822501435*var_27 + 0.0004464285714285714146317*var_19; + const double var_183 = -0.0002705627705627705625359*var_49 + -0.0002840909090909090771102*var_34 + 0.0084415584415584409005984*w[0][4]*w[1][4]; + const double var_184 = 0.0025974025974025974003445*var_15; + const double var_185 = -0.0006358225108225107813018*w[0][2]*w[1][2] + -0.0004058441558441558709089*var_14 + var_184; + const double var_186 = 0.0008658008658008658001148*var_57 + -0.0023268398268398268920187*var_13 + 0.0025432900432900431252070*var_0 + var_185 + var_182 + 0.0002164502164502164500287*var_53 + var_183 + 0.0015692640692640692084980*var_12 + 0.0011904761904761905835781*var_2; + A[15] = 0.1000000000000000055511151*var_11*var_186; + A[51] = A[15]; + const double var_187 = -0.0002705627705627705625359*var_20 + -0.0002840909090909090771102*var_19 + 0.0084415584415584409005984*w[0][3]*w[1][3]; + const double var_188 = var_83 + -0.0004058441558441558709089*var_34 + -0.0006358225108225107813018*w[0][1]*w[1][1]; + const double var_189 = 0.0147186147186147194693140*var_148 + var_184 + var_76 + 0.0015151515151515151502010*var_30 + 0.0043290043290043290005742*var_85 + 0.0080086580086580084342218*w[0][2]*w[1][2]; + const double var_190 = 0.2500000000000000000000000*var_189; + const double var_191 = 0.0011904761904761905835781*var_57 + 0.0002164502164502164500287*var_71 + 0.0015692640692640692084980*var_13 + -0.0023268398268398268920187*var_37 + 0.0008658008658008658001148*var_40 + 0.0025432900432900431252070*var_1 + var_187 + var_190 + var_188; + A[98] = A[89]; + const double var_192 = var_53 + var_40; + const double var_193 = 0.1625000000000000055511151*w[0][2]*w[1][2]; + const double var_194 = 0.0001190476190476190475158*var_14 + 0.0123809523809523813753231*var_15 + 0.0357142857142857123031732*var_90 + 0.0002380952380952380950316*var_92 + 0.0089285714285714280757933*var_70 + 0.0142857142857142852682140*var_148 + 0.0035714285714285713170535*var_192 + 0.0071428571428571426341070*var_85 + var_193 + 0.0285714285714285705364279*var_91 + 0.0030952380952380953438308*var_89; + A[22] = 0.0151515151515151519356905*var_11*var_194; + const double var_195 = 0.0312500000000000000000000*var_89 + 0.1363636363636363812990027*var_85 + 0.0113636363636363639517679*var_158 + 0.0681818181818181906495013*var_93; + const double var_196 = 0.2500000000000000000000000*var_88 + var_108; + const double var_197 = var_75 + var_196; + const double var_198 = 0.0113636363636363639517679*var_48 + 0.1000000000000000055511151*var_195 + 0.0090909090909090904675249*var_197 + -0.0028409090909090909879420*var_14 + -0.0136363636363636357012874*var_91 + 0.0545454545454545428051496*var_15 + -0.0011363636363636363084406*var_69; + const double var_199 = 0.1625000000000000055511151*w[0][1]*w[1][1]; + const double var_200 = var_12 + var_1; + const double var_201 = var_0 + var_13; + const double var_202 = -1.0000000000000000000000000*var_95; + const double var_203 = 0.0051587301587301586172640*var_96 + 0.0015873015873015873002105*var_103 + 0.0285714285714285705364279*var_43 + 0.0142857142857142852682140*var_201 + 0.0048611111111111111882099*w[0][1]*w[1][1] + 0.0003968253968253968250526*var_131 + -0.0072420634920634923553662*var_34 + 0.0095238095238095246686250*var_200 + 0.0047619047619047623343125*var_98 + 0.0357142857142857123031732*var_97 + 0.0035714285714285713170535*var_202; + A[2] = 0.0045454545454545452337625*var_11*var_203; + A[20] = A[2]; + A[56] = 0.1500000000000000222044605*var_107*var_11; + const double var_204 = 0.0250000000000000013877788*var_111 + 0.4285714285714285476380780*var_52 + 0.0232142857142857150787307*var_19; + const double var_205 = var_99 + var_43; + const double var_206 = 0.0857142857142857150787307*var_205 + 0.1250000000000000000000000*var_49 + 0.0089285714285714280757933*var_34 + 0.2000000000000000111022302*var_127; + const double var_207 = -1.0000000000000000000000000*var_206 + 0.0500000000000000027755576*var_101; + const double var_208 = 0.0285714285714285705364279*var_14 + 0.0089285714285714280757933*var_17; + const double var_209 = 0.0357142857142857123031732*var_13; + const double var_210 = var_57 + var_1; + const double var_211 = var_209 + -0.1285714285714285587403083*var_37 + 0.0071428571428571426341070*var_40 + var_208 + 0.0857142857142857150787307*var_210 + var_207 + 0.0214285714285714287696827*var_12 + var_204; + const double var_212 = 0.0011688311688311688301550*var_11*var_16; + A[37] = var_212 + 0.0068181818181818178506437*var_11*var_211; + A[73] = A[37]; + const double var_213 = 0.0089285714285714280757933*var_111 + 0.0285714285714285705364279*var_19; + const double var_214 = 0.0357142857142857123031732*var_0; + const double var_215 = var_12 + var_53; + const double var_216 = var_213 + 0.0071428571428571426341070*var_58 + 0.0857142857142857150787307*var_215 + var_18 + 0.0214285714285714287696827*var_1 + var_207 + var_214 + -0.1285714285714285587403083*var_39; + const double var_217 = 0.0011688311688311688301550*var_11*var_52; + A[48] = var_217 + 0.0068181818181818178506437*var_11*var_216; + A[93] = A[39]; + const double var_218 = var_53 + var_1; + const double var_219 = 0.0500000000000000027755576*var_57 + 0.1000000000000000055511151*var_13 + 0.0750000000000000111022302*var_40 + 0.1500000000000000222044605*var_218 + var_150 + var_167 + var_171; + A[49] = 0.0116883116883116887352312*var_11*var_219; + const double var_220 = var_24 + var_15; + const double var_221 = 0.0357142857142857123031732*var_96 + var_199 + 0.0285714285714285705364279*var_220 + 0.0123809523809523813753231*var_43 + 0.0002380952380952380950316*var_100 + 0.0001190476190476190475158*var_34 + 0.0071428571428571426341070*var_99 + 0.0035714285714285713170535*var_104 + 0.0030952380952380953438308*var_97 + 0.0142857142857142852682140*var_168 + 0.0089285714285714280757933*var_202; + const double var_222 = 0.0119047619047619041010577*var_25 + 0.0047619047619047623343125*var_131 + 0.0001488095238095238229473*var_49 + 0.0017857142857142856585267*var_34 + 0.0142857142857142852682140*var_44; + const double var_223 = var_222 + 0.0035714285714285713170535*var_57 + 0.0238095238095238082021154*var_71 + var_209 + -0.0101190476190476195267332*var_37 + 0.0476190476190476164042309*var_40 + 0.0172619047619047630282019*var_1 + var_73 + var_133; + A[6] = 0.0090909090909090904675249*var_11*var_223; + A[60] = A[6]; + const double var_224 = var_120 + 0.0029220779220779221838078*var_71 + 0.0024350649350649354422937*var_37 + 0.0006493506493506493500861*var_58 + var_130 + var_128 + 0.0011363636363636363084406*var_2 + 0.0073051948051948058932004*var_39; + const double var_225 = 0.0001893939393939393937751*var_71 + 0.0043290043290043290005742*var_13 + var_142 + 0.0008116883116883117418178*var_40 + var_175 + 0.0021645021645021645002871*var_1 + var_110 + 0.0002705627705627705625359*var_39; + A[26] = 0.2000000000000000111022302*var_11*var_225; + const double var_226 = var_39 + var_13; + const double var_227 = var_1 + var_37; + const double var_228 = 0.0312500000000000000000000*var_50 + 0.0113636363636363639517679*var_227 + 0.1363636363636363812990027*var_27 + 0.0681818181818181906495013*var_226; + const double var_229 = var_72 + var_56; + const double var_230 = 0.0545454545454545428051496*var_24 + 0.0090909090909090904675249*var_229 + -0.0011363636363636363084406*var_46 + 0.0113636363636363639517679*var_20 + 0.1000000000000000055511151*var_228 + -0.0028409090909090909879420*var_19 + -0.0136363636363636357012874*var_63; + A[9] = 0.0285714285714285705364279*var_11*var_230; + A[59] = 0.0116883116883116887352312*var_11*var_157; + A[95] = A[59]; + const double var_231 = var_52 + var_44; + const double var_232 = 0.0232142857142857150787307*var_34 + 0.0250000000000000013877788*var_35 + 0.4285714285714285476380780*var_44; + const double var_233 = 0.0071428571428571426341070*var_57 + 0.0214285714285714287696827*var_37 + -0.1285714285714285587403083*var_13 + var_213 + var_232 + var_174 + var_180 + 0.0857142857142857150787307*var_3; + const double var_234 = var_196 + var_192; + const double var_235 = 0.3750000000000000000000000*var_30 + -1.0000000000000000000000000*var_85 + 0.7500000000000000000000000*var_92 + 0.5000000000000000000000000*var_234 + var_16 + -0.0937500000000000000000000*w[0][2]*w[1][2]; + const double var_236 = 0.0090909090909090904675249*var_231 + 0.0077922077922077922010335*var_235 + -0.0089285714285714280757933*var_89 + 0.0036525974025974029466002*var_14 + 0.0022727272727272726168812*var_90 + 0.0006493506493506493500861*var_69; + A[78] = 0.1500000000000000222044605*var_11*var_236; + A[87] = A[78]; + const double var_237 = var_90 + var_16; + const double var_238 = 0.0012987012987012987001723*var_196 + 0.0077922077922077922010335*var_231 + 0.0038961038961038961005168*var_237 + 0.0016233766233766234836355*var_30 + -0.0285714285714285705364279*var_195 + 0.0129870129870129878690843*var_193 + 0.0005681818181818181542203*var_14 + -0.0004058441558441558709089*var_69; + A[35] = 0.1500000000000000222044605*var_11*var_238; + A[65] = A[56]; + A[4] = 0.1000000000000000055511151*var_11*var_191; + A[29] = 0.0285714285714285705364279*var_11*var_198; + A[33] = 0.6000000000000000888178420*var_11*var_129; + const double var_239 = var_52 + var_47; + const double var_240 = 0.0129870129870129878690843*var_65 + 0.0077922077922077922010335*var_51 + 0.0038961038961038961005168*var_239 + 0.0016233766233766234836355*var_21 + -0.0004058441558441558709089*var_46 + 0.0012987012987012987001723*var_56 + -0.0285714285714285705364279*var_228 + 0.0005681818181818181542203*var_19; + const double var_241 = var_55 + var_21; + const double var_242 = 0.0023809523809523811671562*var_52 + 0.0001149891774891774958540*var_19 + 0.0077110389610389618725295*w[0][0]*w[1][0] + 0.0005411255411255411250718*var_241; + const double var_243 = 0.0008116883116883117418178*var_57 + var_242 + var_117 + 0.0021645021645021645002871*var_0 + var_139 + 0.0002705627705627705625359*var_1 + 0.0001893939393939393937751*var_53 + 0.0043290043290043290005742*var_12; + const double var_244 = -0.0002840909090909090771102*var_14 + 0.0084415584415584409005984*w[0][5]*w[1][5] + -0.0002705627705627705625359*var_48; + const double var_245 = 0.0015692640692640692084980*var_0 + 0.0008658008658008658001148*var_58 + var_244 + var_182 + 0.0011904761904761905835781*var_53 + 0.0025432900432900431252070*var_12 + 0.0002164502164502164500287*var_2 + -0.0023268398268398268920187*var_39 + var_188; + const double var_246 = -0.0072420634920634923553662*var_14 + 0.0142857142857142852682140*var_158 + 0.0051587301587301586172640*var_90 + 0.0285714285714285705364279*var_15 + 0.0035714285714285713170535*var_70 + 0.0003968253968253968250526*var_75 + 0.0048611111111111111882099*w[0][2]*w[1][2] + 0.0015873015873015873002105*var_196 + 0.0047619047619047623343125*var_231 + 0.0095238095238095246686250*var_93 + 0.0357142857142857123031732*var_89; + A[1] = 0.0045454545454545452337625*var_11*var_246; + A[10] = A[1]; + A[77] = 0.6000000000000000888178420*var_11*var_123; + const double var_247 = -0.0004058441558441558709089*var_19 + -0.0006358225108225107813018*w[0][0]*w[1][0] + var_121; + const double var_248 = 0.0011904761904761905835781*var_71 + 0.0002164502164502164500287*var_57 + -0.0023268398268398268920187*var_0 + 0.0025432900432900431252070*var_13 + var_247 + 0.0015692640692640692084980*var_1 + 0.0008658008658008658001148*var_53 + var_183 + var_190; + A[76] = A[67]; + const double var_249 = var_71 + var_13; + const double var_250 = var_134 + -0.1285714285714285587403083*var_0 + var_33 + var_208 + var_232 + 0.0071428571428571426341070*var_53 + 0.0857142857142857150787307*var_249 + 0.0214285714285714287696827*var_39; + A[58] = 0.0068181818181818178506437*var_11*var_250 + var_212; + A[53] = A[35]; + const double var_251 = 0.0272727272727272714025748*var_43 + -0.0021915584415584414210154*var_31 + 0.0019480519480519480502584*var_25 + 0.0003652597402597402729760*var_49 + -0.0016436688311688310657616*var_34; + const double var_252 = 0.0011363636363636363084406*var_57 + 0.0073051948051948058932004*var_0 + 0.0029220779220779221838078*var_58 + var_125 + var_122 + var_251 + 0.0006493506493506493500861*var_53 + 0.0024350649350649354422937*var_12; + A[55] = 0.6000000000000000888178420*var_11*var_252; + A[94] = A[49]; + A[7] = 0.2000000000000000111022302*var_11*var_243; + A[70] = A[7]; + const double var_253 = var_12 + var_57; + const double var_254 = 0.1000000000000000055511151*var_0 + 0.1500000000000000222044605*var_253 + var_176 + 0.0750000000000000111022302*var_58 + var_156 + var_167 + 0.0500000000000000027755576*var_53; + const double var_255 = -0.0535714285714285684547598*var_226 + 0.1071428571428571369095195*var_47 + -0.0500000000000000027755576*var_32 + -0.0258928571428571410728559*var_46 + 0.0169642857142857129970626*var_50 + 0.0142857142857142852682140*var_54 + var_29 + 0.3000000000000000444089210*var_63; + A[16] = 0.1000000000000000055511151*var_11*var_248; + A[61] = A[16]; + A[57] = 0.0136363636363636357012874*var_11*var_255; + const double var_256 = 0.0312500000000000000000000*var_97 + 0.1363636363636363812990027*var_99 + 0.0113636363636363639517679*var_201 + 0.0681818181818181906495013*var_200; + const double var_257 = 0.0016233766233766234836355*var_31 + 0.0012987012987012987001723*var_103 + 0.0038961038961038961005168*var_166 + 0.0129870129870129878690843*var_199 + -0.0285714285714285705364279*var_256 + 0.0005681818181818181542203*var_34 + 0.0077922077922077922010335*var_98 + -0.0004058441558441558709089*var_95; + A[47] = 0.1500000000000000222044605*var_11*var_257; + A[74] = A[47]; + const double var_258 = 0.0169642857142857129970626*var_97 + 0.3000000000000000444089210*var_220 + -0.0500000000000000027755576*var_101 + -0.0258928571428571410728559*var_95 + 0.1071428571428571369095195*var_96 + 0.0142857142857142852682140*var_100 + -0.0535714285714285684547598*var_200 + var_206; + A[40] = A[4]; + A[38] = 0.0136363636363636357012874*var_11*var_258; + const double var_259 = var_222 + 0.0476190476190476164042309*var_58 + var_179 + var_80 + 0.0035714285714285713170535*var_53 + 0.0172619047619047630282019*var_12 + var_214 + 0.0238095238095238082021154*var_2 + -0.0101190476190476195267332*var_39; + A[25] = 0.0090909090909090904675249*var_11*var_259; + A[52] = A[25]; + A[36] = var_217 + 0.0068181818181818178506437*var_11*var_233; + A[63] = A[36]; + const double var_260 = var_58 + var_37; + A[88] = 0.6000000000000000888178420*var_11*var_224; + const double var_261 = 0.0095238095238095246686250*var_226 + 0.0357142857142857123031732*var_50 + 0.0142857142857142852682140*var_227 + 0.0015873015873015873002105*var_56 + -0.0072420634920634923553662*var_19 + 0.0285714285714285705364279*var_24 + 0.0051587301587301586172640*var_47 + 0.0035714285714285713170535*var_66 + 0.0047619047619047623343125*var_51 + 0.0048611111111111111882099*w[0][0]*w[1][0] + 0.0003968253968253968250526*var_72; + const double var_262 = var_184 + 0.1250000000000000000000000*var_76 + 0.0068181818181818178506437*var_84 + 0.0056818181818181819758840*var_48; + const double var_263 = 0.0006493506493506493500861*var_57 + 0.0073051948051948058932004*var_13 + 0.0029220779220779221838078*var_40 + var_130 + var_251 + 0.0024350649350649354422937*var_1 + 0.0011363636363636363084406*var_53 + var_262; + A[66] = 0.6000000000000000888178420*var_11*var_263; + const double var_264 = 0.0071428571428571426341070*var_71 + 0.0214285714285714287696827*var_0 + 0.0857142857142857150787307*var_260 + var_36 + var_174 + -0.1285714285714285587403083*var_1 + var_78 + var_204; + A[90] = A[9]; + const double var_265 = var_242 + 0.0002705627705627705625359*var_37 + 0.0043290043290043290005742*var_0 + 0.0008116883116883117418178*var_58 + var_146 + var_175 + 0.0021645021645021645002871*var_12 + 0.0001893939393939393937751*var_2; + A[5] = 0.2000000000000000111022302*var_11*var_265; + const double var_266 = var_131 + var_103; + const double var_267 = 0.0545454545454545428051496*var_43 + 0.0090909090909090904675249*var_266 + -0.0136363636363636357012874*var_220 + 0.0113636363636363639517679*var_49 + 0.1000000000000000055511151*var_256 + -0.0028409090909090909879420*var_34 + -0.0011363636363636363084406*var_95; + A[19] = 0.0285714285714285705364279*var_11*var_267; + A[91] = A[19]; + A[43] = A[34]; + A[79] = 0.0116883116883116887352312*var_11*var_254; + A[75] = A[57]; + A[85] = A[58]; + A[68] = 0.1500000000000000222044605*var_11*var_240; + A[12] = 0.0045454545454545452337625*var_11*var_261; + A[13] = 0.2000000000000000111022302*var_11*var_147; + A[31] = A[13]; + A[71] = A[17]; + A[80] = A[8]; + A[45] = 0.0068181818181818178506437*var_11*var_264 + var_45; + A[0] = 0.0151515151515151519356905*var_11*var_67; + A[18] = 0.2000000000000000111022302*var_11*var_143; + A[32] = A[23]; + const double var_268 = 0.0020021645021645021085555*w[0][1]*w[1][1] + 0.0010822510822510822501435*var_99 + 0.0003787878787878787875502*var_31 + 0.2500000000000000000000000*var_83 + 0.0036796536796536798673285*var_168 + 0.0004464285714285714146317*var_34; + const double var_269 = 0.0015692640692640692084980*var_37 + 0.0011904761904761905835781*var_40 + 0.0002164502164502164500287*var_58 + var_244 + var_247 + var_268 + -0.0023268398268398268920187*var_12 + 0.0008658008658008658001148*var_2 + 0.0025432900432900431252070*var_39; + A[11] = 0.0151515151515151519356905*var_11*var_221; + const double var_270 = var_126 + 0.0006493506493506493500861*var_71 + 0.0024350649350649354422937*var_13 + 0.0011363636363636363084406*var_40 + var_119 + 0.0073051948051948058932004*var_1 + 0.0029220779220779221838078*var_53 + var_262; + A[54] = A[45]; + A[50] = A[5]; + A[44] = 0.6000000000000000888178420*var_11*var_270; + A[62] = A[26]; + A[92] = A[29]; + A[81] = A[18]; + A[27] = 0.1000000000000000055511151*var_11*var_245; + A[72] = A[27]; + A[28] = 0.1000000000000000055511151*var_11*var_269; + A[84] = A[48]; + const double var_271 = 0.0008658008658008658001148*var_71 + 0.0025432900432900431252070*var_37 + var_185 + 0.0002164502164502164500287*var_40 + 0.0011904761904761905835781*var_58 + -0.0023268398268398268920187*var_1 + var_268 + var_187 + 0.0015692640692640692084980*var_39; + A[3] = 0.1000000000000000055511151*var_11*var_271; + A[86] = A[68]; + A[83] = A[38]; + A[82] = A[28]; + A[21] = A[12]; + A[97] = A[79]; + A[30] = A[3]; + } + + 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/mass_matrix_2d/mass_matrix_f2_p2_q3_quadrature.h b/mass_matrix_2d/mass_matrix_f2_p2_q3_quadrature.h new file mode 100644 index 0000000..7ed2d2b --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p2_q3_quadrature.h @@ -0,0 +1,5391 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P2_Q3_QUADRATURE_H +#define __MASS_MATRIX_F2_P2_Q3_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p2_q3_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p2_q3_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p2_q3_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p2_q3_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p2_q3_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p2_q3_quadrature_finite_element_1() + { + // 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p2_q3_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p2_q3_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p2_q3_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_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 mass_matrix_f2_p2_q3_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p2_q3_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p2_q3_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_p2_q3_quadrature_dofmap_1() + { + // 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.0*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 mass_matrix_f2_p2_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 mass_matrix_f2_p2_q3_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p2_q3_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Array of quadrature weights. + static const double W36[36] = {0.00619426535265906, 0.0116108747669979, 0.0120606064042655, 0.0084515357969434, 0.0037652982126918, 0.000748542561236343, 0.0130433943300833, 0.0244492622580587, 0.0253962715890485, 0.0177965759970269, 0.00792866733379675, 0.00157622175402364, 0.0169175056800133, 0.0317111115907051, 0.0329393989007878, 0.023082463651359, 0.0102836172287667, 0.00204438659154493, 0.0169175056800133, 0.0317111115907051, 0.0329393989007878, 0.023082463651359, 0.0102836172287667, 0.00204438659154493, 0.0130433943300833, 0.0244492622580587, 0.0253962715890485, 0.0177965759970269, 0.00792866733379675, 0.00157622175402364, 0.00619426535265908, 0.0116108747669979, 0.0120606064042655, 0.00845153579694342, 0.00376529821269181, 0.000748542561236345}; + // Quadrature points on the UFC reference element: (0.0327753666144599, 0.0293164271597849), (0.0287653330125591, 0.148078599668484), (0.0223868729780306, 0.336984690281154), (0.0149015633666711, 0.55867151877155), (0.00779187470128645, 0.769233862030055), (0.00246669715267023, 0.926945671319741), (0.164429241594827, 0.0293164271597849), (0.144311486950417, 0.148078599668484), (0.112311681780954, 0.336984690281154), (0.0747589734626491, 0.55867151877155), (0.0390907007328242, 0.769233862030055), (0.01237506041744, 0.926945671319741), (0.369529924372377, 0.0293164271597849), (0.324318304588776, 0.148078599668484), (0.252403568076518, 0.336984690281154), (0.168009519121192, 0.55867151877155), (0.0878504549759972, 0.769233862030055), (0.0278110821153606, 0.926945671319741), (0.601153648467838, 0.0293164271597849), (0.52760309574274, 0.148078599668484), (0.410611741642328, 0.336984690281154), (0.273318962107258, 0.55867151877155), (0.142915682993948, 0.769233862030055), (0.0452432465648983, 0.926945671319741), (0.806254331245388, 0.0293164271597849), (0.707609913381099, 0.148078599668484), (0.550703627937892, 0.336984690281154), (0.366569507765801, 0.55867151877155), (0.191675437237121, 0.769233862030055), (0.0606792682628189, 0.926945671319741), (0.937908206225755, 0.0293164271597849), (0.823156067318956, 0.148078599668484), (0.640628436740815, 0.336984690281154), (0.426426917861779, 0.55867151877155), (0.222974263268659, 0.769233862030055), (0.0705876315275886, 0.926945671319741) + + // Value of basis functions at quadrature points. + static const double FE0[36][6] = \ + {{0.821435400385472, -0.0306269173010354, -0.027597521356955, 0.00384342659195225, 0.109984470441528, 0.122961141239038}, + {0.532015755009065, -0.0271104442459123, -0.104224056308926, 0.0170381209259896, 0.487567191028831, 0.0947134335909535}, + {0.180181151181146, -0.0213845288145617, -0.109867327313383, 0.0301761338274608, 0.863527901361615, 0.0573666697577237}, + {-0.0627470853075864, -0.0144574501851293, 0.0655562130014708, 0.0333003161525148, 0.952930295387644, 0.0254177109510863}, + {-0.123539219108257, -0.00767044807856534, 0.414207606957291, 0.0239750954756995, 0.686077414669827, 0.00694955008400423}, + {-0.0606224040782395, -0.0024545279629842, 0.79151088383707, 0.00914597699249764, 0.261723597972845, 0.00069647323881139}, + {0.493837762058507, -0.110355290611927, -0.027597521356955, 0.0192819115366138, 0.0945459854968659, 0.530287152876896}, + {0.293813665649314, -0.102659876418736, -0.104224056308926, 0.0854777716147778, 0.419127540340042, 0.408464955123528}, + {0.0558453437100203, -0.0870838540520213, -0.109867327313383, 0.151389269199641, 0.742314765989434, 0.247401802466309}, + {-0.0978230997184779, -0.0635811652362709, 0.0655562130014709, 0.167062836984721, 0.819167774555438, 0.109617440413119}, + {-0.118196490757038, -0.0360345349652578, 0.414207606957291, 0.120279562776686, 0.58977294736884, 0.0299709086194782}, + {-0.0533153210689967, -0.0120687761767694, 0.79151088383707, 0.0458840347450652, 0.224985540220277, 0.00300363844335377}, + {0.121617769664549, -0.0964251943590678, -0.027597521356955, 0.0433331884448944, 0.0704947085885853, 0.888577049017995}, + {0.0291269575319054, -0.1139535792061, -0.104224056308926, 0.192098401561452, 0.312506910393369, 0.6844453660283}, + {-0.0734077368932363, -0.124988445721003, -0.109867327313383, 0.340224552856495, 0.553479482332581, 0.414559474738547}, + {-0.123912452012481, -0.111555122090524, 0.0655562130014709, 0.375448532862056, 0.610782078678102, 0.183680749561375}, + {-0.102065898102695, -0.0724150500970178, 0.414207606957291, 0.270310179049135, 0.439742331096391, 0.050220831096895}, + {-0.041149343845434, -0.0262641695385059, 0.79151088383707, 0.103117448726206, 0.167752126239137, 0.00503305458152761}, + {-0.0964251943590678, 0.121617769664549, -0.027597521356955, 0.0704947085885853, 0.0433331884448943, 0.888577049017995}, + {-0.1139535792061, 0.0291269575319054, -0.104224056308926, 0.312506910393369, 0.192098401561452, 0.6844453660283}, + {-0.124988445721003, -0.0734077368932363, -0.109867327313383, 0.553479482332581, 0.340224552856495, 0.414559474738547}, + {-0.111555122090524, -0.123912452012481, 0.0655562130014709, 0.610782078678102, 0.375448532862056, 0.183680749561375}, + {-0.0724150500970178, -0.102065898102695, 0.414207606957291, 0.439742331096391, 0.270310179049135, 0.050220831096895}, + {-0.026264169538506, -0.0411493438454339, 0.79151088383707, 0.167752126239137, 0.103117448726206, 0.00503305458152761}, + {-0.110355290611927, 0.493837762058507, -0.027597521356955, 0.094545985496866, 0.0192819115366137, 0.530287152876895}, + {-0.102659876418736, 0.293813665649314, -0.104224056308926, 0.419127540340043, 0.0854777716147777, 0.408464955123527}, + {-0.0870838540520213, 0.0558453437100204, -0.109867327313383, 0.742314765989434, 0.151389269199641, 0.247401802466309}, + {-0.0635811652362708, -0.0978230997184778, 0.0655562130014709, 0.819167774555438, 0.16706283698472, 0.109617440413119}, + {-0.0360345349652578, -0.118196490757038, 0.414207606957291, 0.58977294736884, 0.120279562776686, 0.0299709086194782}, + {-0.0120687761767695, -0.0533153210689966, 0.79151088383707, 0.224985540220277, 0.0458840347450654, 0.00300363844335377}, + {-0.0306269173010354, 0.821435400385472, -0.027597521356955, 0.109984470441527, 0.00384342659195216, 0.122961141239039}, + {-0.0271104442459124, 0.532015755009064, -0.104224056308926, 0.487567191028831, 0.0170381209259896, 0.0947134335909537}, + {-0.0213845288145617, 0.180181151181146, -0.109867327313383, 0.863527901361614, 0.0301761338274608, 0.0573666697577238}, + {-0.0144574501851293, -0.0627470853075864, 0.0655562130014709, 0.952930295387644, 0.0333003161525146, 0.0254177109510863}, + {-0.00767044807856535, -0.123539219108256, 0.414207606957291, 0.686077414669827, 0.0239750954756995, 0.00694955008400424}, + {-0.00245452796298434, -0.0606224040782394, 0.79151088383707, 0.261723597972845, 0.00914597699249803, 0.000696473238811418}}; + + static const double FE1[36][10] = \ + {{0.692116405326339, 0.02809979214053, 0.0255622715011347, -0.00389870712577275, -0.00394357498286782, 0.224416734425978, -0.112850342203846, 0.250894855131633, -0.124729708262302, 0.0243322740491734}, + {0.283934759651154, 0.0251489409971642, 0.0640171956914923, -0.0175137741663261, -0.0106528248707412, 0.806022543976085, -0.304843939147456, 0.156575676330067, -0.0973575486190499, 0.0946689701576109}, + {-0.0230667189458806, 0.0201820871510281, -0.00182545940770507, -0.0316681717528919, 0.000371870446193849, 0.89558289813655, 0.0106415390326746, 0.0594961764142811, -0.0602031247994332, 0.130488903725183}, + {-0.042916247694867, 0.0139171991648146, -0.0611798040376018, -0.0357880903185195, 0.0253254357551023, 0.299401977386427, 0.724719094689676, 0.00798601215243768, -0.0273165975674619, 0.0958510204699925}, + {0.0491311892659461, 0.00752079361748066, 0.154762873078755, -0.026341495488006, 0.0352713041777646, -0.255537670979266, 1.00933258876242, -0.0025884423606554, -0.00763548751524317, 0.0360843474408066}, + {0.0497485688239403, 0.00243938401571425, 0.644479118812606, -0.0102130829170651, 0.0183234311516915, -0.232087782696187, 0.524347954533704, -0.000617609305981537, -0.000777734182289297, 0.00435775176386716}, + {0.239508104110957, 0.0627683640711487, 0.0255622715011347, -0.0109916789233747, -0.0197843414303476, 0.150905638607928, -0.0970095757563665, 0.846395762124882, -0.302290885970787, 0.104936341664825}, + {0.0487956775975465, 0.0641196764159749, 0.0640171956914923, -0.0545304359767136, -0.0534436711248166, 0.529434975607773, -0.26205309289338, 0.515966174346368, -0.260579700000555, 0.40827320033631}, + {-0.0624669400507792, 0.0619241738506681, -0.00182545940770509, -0.112928533782117, 0.00186561987722207, 0.544580480381976, 0.00914778960164644, 0.181500084071326, -0.18454889805122, 0.562751683508982}, + {-0.0164528736892738, 0.0514890982575726, -0.0611798040376018, -0.145793810693828, 0.127054023323504, 0.0918877602754595, 0.622990507121273, 0.0122960172501371, -0.0956618757635125, 0.413370957956269}, + {0.0580370533440932, 0.0324831299939718, 0.154762873078755, -0.119445891298145, 0.176950996894466, -0.281967732783221, 0.867652896045716, -0.0143289535245541, -0.0297631768059827, 0.1556188050549}, + {0.045115774663025, 0.0116944490193934, 0.644479118812606, -0.0497031543433876, 0.0919259858517786, -0.207033374665612, 0.450745399833617, -0.00276397053159101, -0.00325364379944372, 0.0187934151596152}, + {-0.0474645235382767, -0.0178848851455664, 0.0255622715011347, 0.00529373373938191, -0.044462323864076, 0.0637197133595963, -0.0723315933226381, 0.803179075351347, 0.108551677668697, 0.1758368542504}, + {-0.0641414000235847, 0.00450421741088884, 0.0640171956914923, -0.00584473256502761, -0.120106591488146, 0.204898420912783, -0.195390172530051, 0.448763755411812, -0.0208247444397816, 0.684124051619613}, + {-0.0365624407658455, 0.0380796136728451, -0.00182545940770511, -0.0929282395408237, 0.00419269933650997, 0.144355545313924, 0.00682071014235854, 0.108123175205576, -0.11323192829258, 0.94297632433574}, + {0.029034487004146, 0.062328097021337, -0.0611798040376018, -0.209488219289238, 0.285534757531946, -0.123712995627073, 0.464509772912832, -0.037204260833003, -0.102487957137557, 0.692666122454212}, + {0.0641393355313791, 0.0561718105163469, 0.154762873078755, -0.223953257707656, 0.397670681113729, -0.282604617367218, 0.646933211826454, -0.0322748977125214, -0.0416081953276764, 0.260763056048409}, + {0.0364487137089397, 0.024427326771013, 0.644479118812606, -0.106328278377059, 0.206589790661253, -0.163106070537901, 0.336081595024143, -0.00489365931747124, -0.00518977181109788, 0.0314912350655752}, + {-0.0178848851455664, -0.0474645235382767, 0.0255622715011347, 0.0637197133595962, -0.072331593322638, 0.00529373373938194, -0.044462323864076, 0.108551677668697, 0.803179075351347, 0.1758368542504}, + {0.00450421741088887, -0.0641414000235847, 0.0640171956914923, 0.204898420912783, -0.195390172530051, -0.00584473256502761, -0.120106591488146, -0.0208247444397817, 0.448763755411812, 0.684124051619613}, + {0.0380796136728452, -0.0365624407658455, -0.00182545940770511, 0.144355545313924, 0.00682071014235857, -0.0929282395408238, 0.00419269933651001, -0.11323192829258, 0.108123175205576, 0.94297632433574}, + {0.062328097021337, 0.029034487004146, -0.0611798040376018, -0.123712995627073, 0.464509772912832, -0.209488219289239, 0.285534757531946, -0.102487957137557, -0.0372042608330028, 0.692666122454212}, + {0.0561718105163469, 0.0641393355313791, 0.154762873078755, -0.282604617367218, 0.646933211826454, -0.223953257707657, 0.397670681113729, -0.0416081953276766, -0.0322748977125212, 0.260763056048409}, + {0.0244273267710131, 0.0364487137089397, 0.644479118812606, -0.163106070537901, 0.336081595024142, -0.106328278377059, 0.206589790661253, -0.00518977181109807, -0.00489365931747109, 0.0314912350655752}, + {0.0627683640711488, 0.239508104110958, 0.0255622715011347, 0.150905638607928, -0.0970095757563665, -0.0109916789233747, -0.0197843414303476, -0.302290885970787, 0.846395762124882, 0.104936341664825}, + {0.064119676415975, 0.0487956775975466, 0.0640171956914923, 0.529434975607773, -0.26205309289338, -0.0545304359767137, -0.0534436711248165, -0.260579700000555, 0.515966174346368, 0.40827320033631}, + {0.0619241738506681, -0.0624669400507792, -0.00182545940770511, 0.544580480381976, 0.00914778960164649, -0.112928533782117, 0.00186561987722211, -0.18454889805122, 0.181500084071326, 0.562751683508982}, + {0.0514890982575726, -0.0164528736892739, -0.0611798040376018, 0.0918877602754599, 0.622990507121273, -0.145793810693828, 0.127054023323504, -0.0956618757635126, 0.0122960172501373, 0.413370957956269}, + {0.0324831299939719, 0.0580370533440933, 0.154762873078755, -0.28196773278322, 0.867652896045716, -0.119445891298145, 0.176950996894467, -0.0297631768059829, -0.0143289535245539, 0.1556188050549}, + {0.0116944490193935, 0.0451157746630249, 0.644479118812606, -0.207033374665612, 0.450745399833616, -0.0497031543433881, 0.091925985851779, -0.00325364379944393, -0.0027639705315908, 0.0187934151596153}, + {0.02809979214053, 0.692116405326339, 0.0255622715011347, 0.224416734425978, -0.112850342203846, -0.00389870712577277, -0.00394357498286788, -0.124729708262302, 0.250894855131634, 0.0243322740491735}, + {0.0251489409971643, 0.283934759651153, 0.0640171956914923, 0.806022543976084, -0.304843939147455, -0.0175137741663261, -0.0106528248707413, -0.0973575486190503, 0.156575676330067, 0.0946689701576112}, + {0.0201820871510282, -0.0230667189458806, -0.0018254594077051, 0.89558289813655, 0.0106415390326748, -0.0316681717528918, 0.000371870446193856, -0.0602031247994334, 0.0594961764142812, 0.130488903725183}, + {0.0139171991648146, -0.042916247694867, -0.0611798040376018, 0.299401977386428, 0.724719094689675, -0.0357880903185195, 0.0253254357551024, -0.027316597567462, 0.00798601215243784, 0.0958510204699924}, + {0.00752079361748067, 0.0491311892659461, 0.154762873078755, -0.255537670979266, 1.00933258876242, -0.026341495488006, 0.0352713041777647, -0.00763548751524335, -0.00258844236065517, 0.0360843474408064}, + {0.00243938401571438, 0.0497485688239402, 0.644479118812606, -0.232087782696186, 0.524347954533703, -0.0102130829170658, 0.0183234311516924, -0.000777734182289533, -0.00061760930598137, 0.00435775176386732}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 100; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 11772 + for (unsigned int ip = 0; ip < 36; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + + // Total number of operations to compute function values = 24 + for (unsigned int r = 0; r < 6; r++) + { + F0 += FE0[ip][r]*w[0][r]; + F1 += FE0[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 3 + double I[1]; + // Number of operations: 3 + I[0] = F0*F1*W36[ip]*det; + + + // Number of operations for primary indices: 300 + for (unsigned int j = 0; j < 10; j++) + { + for (unsigned int k = 0; k < 10; k++) + { + // Number of operations to compute entry: 3 + A[j*10 + k] += FE1[ip][j]*FE1[ip][k]*I[0]; + }// 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 mass_matrix_f2_p2_q3_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p2_q3_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p2_q3_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1))), 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 mass_matrix_f2_p2_q3_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p2_q3_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p2_q3_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p2_q3_quadrature_finite_element_0(); + 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 mass_matrix_f2_p2_q3_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p2_q3_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p2_q3_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p2_q3_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f2_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/mass_matrix_2d/mass_matrix_f2_p2_q3_tensor.h b/mass_matrix_2d/mass_matrix_f2_p2_q3_tensor.h new file mode 100644 index 0000000..575deca --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p2_q3_tensor.h @@ -0,0 +1,5408 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P2_Q3_TENSOR_H +#define __MASS_MATRIX_F2_P2_Q3_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p2_q3_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p2_q3_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p2_q3_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p2_q3_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p2_q3_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p2_q3_tensor_finite_element_1() + { + // 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p2_q3_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p2_q3_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p2_q3_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_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 mass_matrix_f2_p2_q3_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p2_q3_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p2_q3_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_p2_q3_tensor_dofmap_1() + { + // 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.0*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 mass_matrix_f2_p2_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 mass_matrix_f2_p2_q3_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p2_q3_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 54 + // Number of operations (multiply-add pairs) for tensor contraction: 1498 + // Total number of operations (multiply-add pairs): 1561 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0 = det*w[0][0]*w[1][0]*(1.0); + const double G0_0_1 = det*w[0][0]*w[1][1]*(1.0); + const double G0_0_2 = det*w[0][0]*w[1][2]*(1.0); + const double G0_0_3 = det*w[0][0]*w[1][3]*(1.0); + const double G0_0_4 = det*w[0][0]*w[1][4]*(1.0); + const double G0_0_5 = det*w[0][0]*w[1][5]*(1.0); + const double G0_1_0 = det*w[0][1]*w[1][0]*(1.0); + const double G0_1_1 = det*w[0][1]*w[1][1]*(1.0); + const double G0_1_2 = det*w[0][1]*w[1][2]*(1.0); + const double G0_1_3 = det*w[0][1]*w[1][3]*(1.0); + const double G0_1_4 = det*w[0][1]*w[1][4]*(1.0); + const double G0_1_5 = det*w[0][1]*w[1][5]*(1.0); + const double G0_2_0 = det*w[0][2]*w[1][0]*(1.0); + const double G0_2_1 = det*w[0][2]*w[1][1]*(1.0); + const double G0_2_2 = det*w[0][2]*w[1][2]*(1.0); + const double G0_2_3 = det*w[0][2]*w[1][3]*(1.0); + const double G0_2_4 = det*w[0][2]*w[1][4]*(1.0); + const double G0_2_5 = det*w[0][2]*w[1][5]*(1.0); + const double G0_3_0 = det*w[0][3]*w[1][0]*(1.0); + const double G0_3_1 = det*w[0][3]*w[1][1]*(1.0); + const double G0_3_2 = det*w[0][3]*w[1][2]*(1.0); + const double G0_3_3 = det*w[0][3]*w[1][3]*(1.0); + const double G0_3_4 = det*w[0][3]*w[1][4]*(1.0); + const double G0_3_5 = det*w[0][3]*w[1][5]*(1.0); + const double G0_4_0 = det*w[0][4]*w[1][0]*(1.0); + const double G0_4_1 = det*w[0][4]*w[1][1]*(1.0); + const double G0_4_2 = det*w[0][4]*w[1][2]*(1.0); + const double G0_4_3 = det*w[0][4]*w[1][3]*(1.0); + const double G0_4_4 = det*w[0][4]*w[1][4]*(1.0); + const double G0_4_5 = det*w[0][4]*w[1][5]*(1.0); + const double G0_5_0 = det*w[0][5]*w[1][0]*(1.0); + const double G0_5_1 = det*w[0][5]*w[1][1]*(1.0); + const double G0_5_2 = det*w[0][5]*w[1][2]*(1.0); + const double G0_5_3 = det*w[0][5]*w[1][3]*(1.0); + const double G0_5_4 = det*w[0][5]*w[1][4]*(1.0); + const double G0_5_5 = det*w[0][5]*w[1][5]*(1.0); + + // Compute element tensor + A[73] = -0.000170454545454552*G0_0_0 + 0.000194805194805202*G0_0_1 - 6.08766233766256e-05*G0_0_2 + 0.000340909090909103*G0_0_3 - 4.87012987013005e-05*G0_0_4 + 0.000146103896103901*G0_0_5 + 0.000194805194805202*G0_1_0 - 0.000852272727272759*G0_1_1 + 0.000158279220779227*G0_1_2 - 0.000876623376623409*G0_1_3 - 4.87012987013005e-05*G0_1_4 - 0.000584415584415605*G0_1_5 - 6.08766233766256e-05*G0_2_0 + 0.000158279220779227*G0_2_1 - 6.08766233766253e-05*G0_2_2 + 0.000584415584415605*G0_2_3 + 0.000243506493506502*G0_2_4 + 0.000340909090909103*G0_2_5 + 0.000340909090909103*G0_3_0 - 0.000876623376623409*G0_3_1 + 0.000584415584415605*G0_3_2 - 0.00292207792207802*G0_3_3 - 0.000584415584415604*G0_3_4 - 0.00136363636363641*G0_3_5 - 4.87012987013005e-05*G0_4_0 - 4.87012987013005e-05*G0_4_1 + 0.000243506493506502*G0_4_2 - 0.000584415584415604*G0_4_3 - 0.000584415584415604*G0_4_4 - 0.000584415584415605*G0_4_5 + 0.000146103896103901*G0_5_0 - 0.000584415584415606*G0_5_1 + 0.000340909090909103*G0_5_2 - 0.00136363636363641*G0_5_3 - 0.000584415584415605*G0_5_4 - 0.00116883116883121*G0_5_5; + A[69] = -0.000146103896103901*G0_0_0 + 0.000365259740259753*G0_0_1 - 0.000219155844155852*G0_0_2 - 0.000876623376623407*G0_0_3 - 0.00175324675324681*G0_0_4 - 0.000584415584415605*G0_0_5 + 0.000365259740259753*G0_1_0 + 7.30519480519503e-05*G0_1_1 - 0.000292207792207802*G0_1_2 - 0.000876623376623407*G0_1_3 - 0.000876623376623406*G0_1_4 - 0.000219155844155852*G0_2_0 - 0.000292207792207802*G0_2_1 + 0.000730519480519506*G0_2_2 + 0.00116883116883121*G0_2_3 + 0.00175324675324681*G0_2_4 + 0.000876623376623407*G0_2_5 - 0.000876623376623407*G0_3_0 - 0.000876623376623407*G0_3_1 + 0.00116883116883121*G0_3_2 + 0.00350649350649363*G0_3_3 + 0.00350649350649363*G0_3_4 - 0.00175324675324681*G0_4_0 - 0.000876623376623406*G0_4_1 + 0.00175324675324681*G0_4_2 + 0.00350649350649363*G0_4_3 + 0.00701298701298725*G0_4_4 - 0.000584415584415605*G0_5_0 + 0.000876623376623407*G0_5_2 - 0.00350649350649363*G0_5_5; + A[7] = 0.00154220779220784*G0_0_0 - 0.000162337662337668*G0_0_1 - 0.000108225108225112*G0_0_2 + 0.000108225108225112*G0_0_3 + 0.000432900432900448*G0_0_4 + 0.000865800865800896*G0_0_5 - 0.000162337662337668*G0_1_0 - 0.000106872294372299*G0_1_1 + 2.29978354978364e-05*G0_1_2 - 3.78787878787894e-05*G0_1_3 - 0.000162337662337668*G0_1_5 - 0.000108225108225112*G0_2_0 + 2.29978354978364e-05*G0_2_1 - 2.29978354978364e-05*G0_2_2 + 5.4112554112556e-05*G0_2_3 + 5.4112554112556e-05*G0_2_5 + 0.000108225108225112*G0_3_0 - 3.78787878787894e-05*G0_3_1 + 5.4112554112556e-05*G0_3_2 - 0.000476190476190493*G0_3_3 - 0.000216450216450224*G0_3_4 - 0.000324675324675336*G0_3_5 + 0.000432900432900448*G0_4_0 - 0.000216450216450224*G0_4_3 - 0.000108225108225112*G0_4_4 - 0.000108225108225112*G0_4_5 + 0.000865800865800896*G0_5_0 - 0.000162337662337668*G0_5_1 + 5.4112554112556e-05*G0_5_2 - 0.000324675324675336*G0_5_3 - 0.000108225108225112*G0_5_4 - 0.000324675324675336*G0_5_5; + A[37] = A[73]; + A[85] = A[73] - 0.000681818181818204*G0_0_0 + 0.000219155844155852*G0_0_2 - 0.000389610389610403*G0_0_3 - 0.000827922077922105*G0_0_4 - 0.000730519480519504*G0_0_5 + 0.000681818181818207*G0_1_1 - 0.000219155844155852*G0_1_2 + 0.000827922077922108*G0_1_3 + 0.000389610389610403*G0_1_4 + 0.000730519480519506*G0_1_5 + 0.000219155844155852*G0_2_0 - 0.000219155844155852*G0_2_1 - 0.000340909090909103*G0_2_3 + 0.000340909090909102*G0_2_4 - 0.000389610389610403*G0_3_0 + 0.000827922077922108*G0_3_1 - 0.000340909090909103*G0_3_2 + 0.00233766233766242*G0_3_3 + 0.000779220779220806*G0_3_5 - 0.000827922077922105*G0_4_0 + 0.000389610389610403*G0_4_1 + 0.000340909090909102*G0_4_2 - 0.00233766233766241*G0_4_4 - 0.000779220779220805*G0_4_5 - 0.000730519480519505*G0_5_0 + 0.000730519480519506*G0_5_1 + 0.000779220779220806*G0_5_3 - 0.000779220779220805*G0_5_4; + A[58] = A[85]; + A[90] = 0.000324675324675336*G0_0_0 - 3.24675324675336e-05*G0_0_1 - 3.24675324675336e-05*G0_0_2 - 0.000259740259740269*G0_0_3 - 3.24675324675336e-05*G0_1_0 + 8.92857142857176e-05*G0_1_1 - 8.1168831168834e-05*G0_1_2 + 3.24675324675339e-05*G0_1_3 + 6.49350649350673e-05*G0_1_4 + 0.000194805194805202*G0_1_5 - 3.24675324675336e-05*G0_2_0 - 8.1168831168834e-05*G0_2_1 + 8.92857142857175e-05*G0_2_2 + 3.24675324675335e-05*G0_2_3 + 0.000194805194805202*G0_2_4 + 6.49350649350671e-05*G0_2_5 - 0.000259740259740269*G0_3_0 + 3.24675324675339e-05*G0_3_1 + 3.24675324675335e-05*G0_3_2 + 0.00155844155844161*G0_3_3 + 0.000389610389610403*G0_3_4 + 0.000389610389610403*G0_3_5 + 6.49350649350673e-05*G0_4_1 + 0.000194805194805202*G0_4_2 + 0.000389610389610403*G0_4_3 - 0.000389610389610403*G0_4_4 - 0.000259740259740269*G0_4_5 + 0.000194805194805202*G0_5_1 + 6.49350649350671e-05*G0_5_2 + 0.000389610389610403*G0_5_3 - 0.000259740259740269*G0_5_4 - 0.000389610389610403*G0_5_5; + A[67] = A[85] - 3.65259740259753e-05*G0_0_1 + 3.65259740259758e-05*G0_0_2 + 0.000292207792207801*G0_0_4 - 0.000292207792207804*G0_0_5 - 3.65259740259753e-05*G0_1_0 + 0.000109577922077927*G0_1_1 + 0.000292207792207803*G0_1_3 + 0.000438311688311705*G0_1_5 + 3.65259740259758e-05*G0_2_0 - 0.000109577922077927*G0_2_2 - 0.000292207792207803*G0_2_3 - 0.000438311688311704*G0_2_4 + 0.000292207792207803*G0_3_1 - 0.000292207792207803*G0_3_2 + 0.000292207792207801*G0_4_0 - 0.000438311688311704*G0_4_2 + 0.00175324675324681*G0_4_4 - 0.000292207792207804*G0_5_0 + 0.000438311688311705*G0_5_1 - 0.00175324675324681*G0_5_5; + A[76] = A[67]; + A[11] = -A[7] + 0.00158910533910539*G0_0_0 - 0.000297619047619058*G0_0_1 - 0.00010642135642136*G0_0_2 + 5.4112554112556e-05*G0_0_3 + 0.000429292929292944*G0_0_4 + 0.00081168831168834*G0_0_5 - 0.000297619047619058*G0_1_0 + 0.002355248917749*G0_1_1 - 0.000112283549783554*G0_1_2 + 0.000503246753246771*G0_1_3 + 0.000378787878787894*G0_1_5 - 0.00010642135642136*G0_2_0 - 0.000112283549783554*G0_2_1 + 2.38997113997121e-05*G0_2_2 + 5.4112554112556e-05*G0_3_0 + 0.000503246753246771*G0_3_1 - 4.32900432900455e-05*G0_3_3 - 0.000108225108225112*G0_3_4 - 0.000108225108225112*G0_3_5 + 0.000429292929292944*G0_4_0 - 0.000108225108225112*G0_4_3 + 7.93650793650819e-05*G0_4_4 + 0.00081168831168834*G0_5_0 + 0.000378787878787894*G0_5_1 - 0.000108225108225112*G0_5_3 + 0.000108225108225113*G0_5_5; + A[45] = A[73] - 0.000255681818181827*G0_0_1 + 0.000255681818181827*G0_0_2 + 0.000194805194805202*G0_0_4 - 0.000194805194805201*G0_0_5 - 0.000255681818181827*G0_1_0 + 0.000791396103896134*G0_1_1 + 0.00146103896103901*G0_1_3 + 0.000389610389610403*G0_1_4 + 0.000827922077922107*G0_1_5 + 0.000255681818181827*G0_2_0 - 0.000791396103896132*G0_2_2 - 0.00146103896103901*G0_2_3 - 0.000827922077922107*G0_2_4 - 0.000389610389610404*G0_2_5 + 0.00146103896103901*G0_3_1 - 0.00146103896103901*G0_3_2 - 0.000779220779220807*G0_3_4 + 0.000779220779220807*G0_3_5 + 0.000194805194805202*G0_4_0 + 0.000389610389610403*G0_4_1 - 0.000827922077922107*G0_4_2 - 0.000779220779220807*G0_4_3 - 0.000584415584415606*G0_4_4 - 0.000194805194805201*G0_5_0 + 0.000827922077922108*G0_5_1 - 0.000389610389610404*G0_5_2 + 0.000779220779220807*G0_5_3 + 0.000584415584415608*G0_5_5; + A[1] = 0.000162337662337668*G0_0_0 - 3.29184704184716e-05*G0_0_1 - 1.62337662337668e-05*G0_0_2 + 1.80375180375185e-06*G0_0_3 + 4.32900432900448e-05*G0_0_4 + 6.49350649350672e-05*G0_0_5 - 3.29184704184716e-05*G0_1_0 + 0.000162337662337669*G0_1_1 - 1.62337662337668e-05*G0_1_2 + 4.3290043290045e-05*G0_1_3 + 1.80375180375187e-06*G0_1_4 + 6.49350649350675e-05*G0_1_5 - 1.62337662337668e-05*G0_2_0 - 1.62337662337668e-05*G0_2_1 + 2.20959595959604e-05*G0_2_2 + 2.34487734487742e-05*G0_2_3 + 2.34487734487743e-05*G0_2_4 - 1.80375180375188e-06*G0_2_5 + 1.80375180375185e-06*G0_3_0 + 4.3290043290045e-05*G0_3_1 + 2.34487734487742e-05*G0_3_2 - 2.16450216450223e-05*G0_3_3 - 7.21500721500744e-06*G0_3_4 + 4.32900432900448e-05*G0_4_0 + 1.80375180375187e-06*G0_4_1 + 2.34487734487743e-05*G0_4_2 - 7.21500721500744e-06*G0_4_3 - 2.16450216450224e-05*G0_4_4 + 6.49350649350672e-05*G0_5_0 + 6.49350649350675e-05*G0_5_1 - 1.80375180375189e-06*G0_5_2 + 0.000129870129870134*G0_5_5; + A[99] = 0.00175324675324681*G0_0_0 + 0.000438311688311703*G0_0_1 + 0.000438311688311703*G0_0_2 - 0.00525974025974044*G0_0_3 - 0.00350649350649363*G0_0_4 - 0.00350649350649363*G0_0_5 + 0.000438311688311703*G0_1_0 + 0.00175324675324681*G0_1_1 + 0.000438311688311704*G0_1_2 - 0.00350649350649362*G0_1_3 - 0.00525974025974044*G0_1_4 - 0.00350649350649363*G0_1_5 + 0.000438311688311703*G0_2_0 + 0.000438311688311704*G0_2_1 + 0.00175324675324681*G0_2_2 - 0.00350649350649363*G0_2_3 - 0.00350649350649363*G0_2_4 - 0.00525974025974044*G0_2_5 - 0.00525974025974044*G0_3_0 - 0.00350649350649362*G0_3_1 - 0.00350649350649363*G0_3_2 + 0.028051948051949*G0_3_3 + 0.0210389610389618*G0_3_4 + 0.0210389610389618*G0_3_5 - 0.00350649350649363*G0_4_0 - 0.00525974025974044*G0_4_1 - 0.00350649350649363*G0_4_2 + 0.0210389610389618*G0_4_3 + 0.028051948051949*G0_4_4 + 0.0210389610389618*G0_4_5 - 0.00350649350649363*G0_5_0 - 0.00350649350649363*G0_5_1 - 0.00525974025974044*G0_5_2 + 0.0210389610389618*G0_5_3 + 0.0210389610389618*G0_5_4 + 0.028051948051949*G0_5_5; + A[21] = A[1] - 0.000140241702741708*G0_0_0 + 1.66847041847048e-05*G0_0_1 - 1.98412698412705e-05*G0_0_4 - 4.14862914862929e-05*G0_0_5 + 1.66847041847048e-05*G0_1_0 - 1.66847041847047e-05*G0_1_2 + 2.16450216450223e-05*G0_1_3 - 2.16450216450226e-05*G0_1_5 - 1.66847041847047e-05*G0_2_1 + 0.000140241702741707*G0_2_2 + 4.14862914862929e-05*G0_2_3 + 1.98412698412705e-05*G0_2_4 + 2.16450216450223e-05*G0_3_1 + 4.14862914862929e-05*G0_3_2 + 0.000151515151515157*G0_3_3 - 1.98412698412705e-05*G0_4_0 + 1.98412698412705e-05*G0_4_2 - 4.14862914862929e-05*G0_5_0 - 2.16450216450226e-05*G0_5_1 - 0.000151515151515157*G0_5_5; + A[94] = A[69] + 0.000219155844155852*G0_0_0 - 7.30519480519504e-05*G0_0_2 + 0.000876623376623407*G0_0_4 + 0.000584415584415605*G0_0_5 - 0.000219155844155852*G0_1_1 + 7.30519480519508e-05*G0_1_2 - 0.000876623376623407*G0_1_3 - 0.000584415584415605*G0_1_5 - 7.30519480519504e-05*G0_2_0 + 7.30519480519507e-05*G0_2_1 + 0.000584415584415605*G0_2_3 - 0.000584415584415606*G0_2_4 - 0.000876623376623407*G0_3_1 + 0.000584415584415605*G0_3_2 + 0.00350649350649362*G0_3_3 + 0.000876623376623407*G0_4_0 - 0.000584415584415606*G0_4_2 - 0.00350649350649363*G0_4_4 + 0.000584415584415605*G0_5_0 - 0.000584415584415605*G0_5_1; + A[93] = -A[94] + 0.000146103896103901*G0_0_0 + 7.30519480519503e-05*G0_0_1 + 7.30519480519506e-05*G0_0_2 - 0.00175324675324681*G0_0_3 - 0.000876623376623406*G0_0_4 - 0.000876623376623406*G0_0_5 + 7.30519480519503e-05*G0_1_0 + 0.000584415584415605*G0_1_1 - 0.000438311688311704*G0_1_2 + 0.000584415584415606*G0_1_5 + 7.30519480519506e-05*G0_2_0 - 0.000438311688311704*G0_2_1 + 0.000584415584415604*G0_2_2 + 0.000584415584415605*G0_2_4 - 0.00175324675324681*G0_3_0 + 0.0140259740259745*G0_3_3 + 0.00350649350649362*G0_3_4 + 0.00350649350649362*G0_3_5 - 0.000876623376623406*G0_4_0 + 0.000584415584415605*G0_4_2 + 0.00350649350649362*G0_4_3 - 0.000876623376623406*G0_5_0 + 0.000584415584415606*G0_5_1 + 0.00350649350649362*G0_5_3; + A[89] = A[93] - 0.000219155844155851*G0_0_0 + 7.30519480519507e-05*G0_0_1 - 0.000584415584415605*G0_0_4 - 0.000876623376623407*G0_0_5 + 7.30519480519507e-05*G0_1_0 - 7.30519480519502e-05*G0_1_2 - 0.000584415584415606*G0_1_3 + 0.000584415584415604*G0_1_5 - 7.30519480519502e-05*G0_2_1 + 0.000219155844155852*G0_2_2 + 0.000876623376623407*G0_2_3 + 0.000584415584415604*G0_2_4 - 0.000584415584415606*G0_3_1 + 0.000876623376623407*G0_3_2 - 0.00350649350649362*G0_3_3 - 0.000584415584415605*G0_4_0 + 0.000584415584415604*G0_4_2 - 0.000876623376623407*G0_5_0 + 0.000584415584415604*G0_5_1 + 0.00350649350649363*G0_5_5; + A[36] = A[45] + 0.000109577922077926*G0_0_0 - 3.65259740259754e-05*G0_0_2 + 0.000438311688311703*G0_0_4 + 0.000292207792207803*G0_0_5 - 0.000109577922077927*G0_1_1 + 3.65259740259753e-05*G0_1_2 - 0.000438311688311704*G0_1_3 - 0.000292207792207803*G0_1_5 - 3.65259740259754e-05*G0_2_0 + 3.65259740259753e-05*G0_2_1 + 0.000292207792207803*G0_2_3 - 0.000292207792207802*G0_2_4 - 0.000438311688311704*G0_3_1 + 0.000292207792207803*G0_3_2 + 0.00175324675324681*G0_3_3 + 0.000438311688311703*G0_4_0 - 0.000292207792207802*G0_4_2 - 0.00175324675324681*G0_4_4 + 0.000292207792207803*G0_5_0 - 0.000292207792207803*G0_5_1; + A[86] = A[85] + 0.00116883116883121*G0_0_0 - 0.000255681818181827*G0_0_1 - 0.000219155844155852*G0_0_2 + 0.000292207792207802*G0_0_3 + 0.00146103896103901*G0_0_4 + 0.00116883116883121*G0_0_5 - 0.000255681818181827*G0_1_0 + 3.65259740259755e-05*G0_1_1 + 0.000146103896103901*G0_1_2 - 0.000292207792207802*G0_1_4 - 0.000438311688311703*G0_1_5 - 0.000219155844155852*G0_2_0 + 0.000146103896103901*G0_2_1 - 7.305194805195e-05*G0_2_2 - 0.000292207792207802*G0_2_3 - 0.000876623376623406*G0_2_4 - 0.000292207792207802*G0_2_5 + 0.000292207792207802*G0_3_0 - 0.000292207792207802*G0_3_2 + 0.00146103896103901*G0_4_0 - 0.000292207792207802*G0_4_1 - 0.000876623376623406*G0_4_2 + 0.00175324675324681*G0_4_4 + 0.00116883116883121*G0_4_5 + 0.00116883116883121*G0_5_0 - 0.000438311688311703*G0_5_1 - 0.000292207792207802*G0_5_2 + 0.00116883116883121*G0_5_4; + A[97] = -A[89] + 0.000584415584415605*G0_0_0 - 0.000438311688311703*G0_0_1 + 7.30519480519506e-05*G0_0_2 + 0.000584415584415604*G0_0_4 - 0.000438311688311703*G0_1_0 + 0.000584415584415605*G0_1_1 + 7.30519480519507e-05*G0_1_2 + 0.000584415584415604*G0_1_3 + 7.30519480519505e-05*G0_2_0 + 7.30519480519507e-05*G0_2_1 + 0.000146103896103901*G0_2_2 - 0.000876623376623407*G0_2_3 - 0.000876623376623407*G0_2_4 - 0.00175324675324681*G0_2_5 + 0.000584415584415604*G0_3_1 - 0.000876623376623407*G0_3_2 + 0.00350649350649363*G0_3_5 + 0.000584415584415604*G0_4_0 - 0.000876623376623407*G0_4_2 + 0.00350649350649363*G0_4_5 - 0.00175324675324681*G0_5_2 + 0.00350649350649363*G0_5_3 + 0.00350649350649363*G0_5_4 + 0.0140259740259745*G0_5_5; + A[54] = A[45]; + A[10] = A[1]; + A[35] = A[45] + 3.65259740259753e-05*G0_0_0 + 0.000146103896103901*G0_0_1 - 0.000255681818181827*G0_0_2 - 0.000292207792207802*G0_0_3 - 0.000438311688311704*G0_0_4 + 0.000146103896103901*G0_1_0 - 7.30519480519513e-05*G0_1_1 - 0.000219155844155852*G0_1_2 - 0.000876623376623408*G0_1_3 - 0.000292207792207803*G0_1_4 - 0.000292207792207803*G0_1_5 - 0.000255681818181827*G0_2_0 - 0.000219155844155852*G0_2_1 + 0.00116883116883121*G0_2_2 + 0.00146103896103901*G0_2_3 + 0.00116883116883121*G0_2_4 + 0.000292207792207803*G0_2_5 - 0.000292207792207802*G0_3_0 - 0.000876623376623408*G0_3_1 + 0.00146103896103901*G0_3_2 + 0.00175324675324681*G0_3_3 + 0.00116883116883121*G0_3_4 - 0.000438311688311704*G0_4_0 - 0.000292207792207803*G0_4_1 + 0.00116883116883121*G0_4_2 + 0.00116883116883121*G0_4_3 - 0.000292207792207803*G0_5_1 + 0.000292207792207803*G0_5_2; + A[92] = A[90] - 0.000235389610389618*G0_0_0 - 4.87012987013003e-05*G0_0_1 + 0.000324675324675336*G0_0_3 + 0.000194805194805202*G0_0_4 + 3.24675324675339e-05*G0_0_5 - 4.87012987013003e-05*G0_1_0 + 4.87012987013004e-05*G0_1_2 + 0.000162337662337668*G0_1_3 - 0.000162337662337668*G0_1_5 + 4.87012987013004e-05*G0_2_1 + 0.000235389610389619*G0_2_2 - 3.24675324675332e-05*G0_2_3 - 0.000194805194805201*G0_2_4 - 0.000324675324675336*G0_2_5 + 0.000324675324675336*G0_3_0 + 0.000162337662337668*G0_3_1 - 3.24675324675332e-05*G0_3_2 - 0.00194805194805201*G0_3_3 - 0.000649350649350671*G0_3_4 + 0.000194805194805201*G0_4_0 - 0.000194805194805201*G0_4_2 - 0.000649350649350671*G0_4_3 + 0.000649350649350672*G0_4_5 + 3.24675324675339e-05*G0_5_0 - 0.000162337662337668*G0_5_1 - 0.000324675324675336*G0_5_2 + 0.000649350649350672*G0_5_4 + 0.00194805194805201*G0_5_5; + A[74] = A[73] + 3.65259740259755e-05*G0_0_0 - 0.000255681818181828*G0_0_1 + 0.000146103896103901*G0_0_2 - 0.000292207792207803*G0_0_3 - 0.000438311688311703*G0_0_5 - 0.000255681818181828*G0_1_0 + 0.00116883116883121*G0_1_1 - 0.000219155844155852*G0_1_2 + 0.00146103896103901*G0_1_3 + 0.000292207792207803*G0_1_4 + 0.00116883116883121*G0_1_5 + 0.000146103896103901*G0_2_0 - 0.000219155844155852*G0_2_1 - 7.30519480519515e-05*G0_2_2 - 0.000876623376623408*G0_2_3 - 0.000292207792207803*G0_2_4 - 0.000292207792207803*G0_2_5 - 0.000292207792207803*G0_3_0 + 0.00146103896103901*G0_3_1 - 0.000876623376623408*G0_3_2 + 0.00175324675324682*G0_3_3 + 0.00116883116883121*G0_3_5 + 0.000292207792207803*G0_4_1 - 0.000292207792207803*G0_4_2 - 0.000438311688311703*G0_5_0 + 0.00116883116883121*G0_5_1 - 0.000292207792207803*G0_5_2 + 0.00116883116883121*G0_5_3; + A[2] = A[1] + 1.66847041847048e-05*G0_0_1 - 1.66847041847048e-05*G0_0_2 + 2.16450216450223e-05*G0_0_4 - 2.16450216450224e-05*G0_0_5 + 1.66847041847048e-05*G0_1_0 - 0.000140241702741708*G0_1_1 - 1.98412698412707e-05*G0_1_3 - 4.14862914862932e-05*G0_1_5 - 1.66847041847048e-05*G0_2_0 + 0.000140241702741708*G0_2_2 + 1.98412698412706e-05*G0_2_3 + 4.14862914862929e-05*G0_2_4 - 1.98412698412707e-05*G0_3_1 + 1.98412698412706e-05*G0_3_2 + 2.16450216450223e-05*G0_4_0 + 4.14862914862929e-05*G0_4_2 + 0.000151515151515157*G0_4_4 - 2.16450216450224e-05*G0_5_0 - 4.14862914862932e-05*G0_5_1 - 0.000151515151515157*G0_5_5; + A[48] = A[73] + 0.000109577922077926*G0_0_0 - 3.65259740259755e-05*G0_0_1 + 0.000292207792207802*G0_0_4 + 0.000438311688311704*G0_0_5 - 3.65259740259755e-05*G0_1_0 + 3.6525974025975e-05*G0_1_2 + 0.000292207792207803*G0_1_3 - 0.000292207792207802*G0_1_5 + 3.6525974025975e-05*G0_2_1 - 0.000109577922077926*G0_2_2 - 0.000438311688311703*G0_2_3 - 0.000292207792207802*G0_2_4 + 0.000292207792207803*G0_3_1 - 0.000438311688311703*G0_3_2 + 0.00175324675324682*G0_3_3 + 0.000292207792207802*G0_4_0 - 0.000292207792207802*G0_4_2 + 0.000438311688311704*G0_5_0 - 0.000292207792207802*G0_5_1 - 0.00175324675324681*G0_5_5; + A[78] = A[48] - 0.00127840909090913*G0_0_0 + 0.000389610389610403*G0_0_1 + 0.000158279220779226*G0_0_2 - 0.000194805194805201*G0_0_3 - 0.000827922077922106*G0_0_4 - 0.00146103896103901*G0_0_5 + 0.000389610389610403*G0_1_0 - 0.000487012987013006*G0_1_1 - 9.74025974026007e-05*G0_1_2 + 0.000194805194805202*G0_1_4 + 0.000158279220779226*G0_2_0 - 9.74025974026007e-05*G0_2_1 + 6.08766233766252e-05*G0_2_2 + 0.000194805194805201*G0_2_3 + 0.000389610389610403*G0_2_4 + 9.74025974026009e-05*G0_2_5 - 0.000194805194805201*G0_3_0 + 0.000194805194805201*G0_3_2 - 0.000194805194805203*G0_3_3 + 0.0001948051948052*G0_3_5 - 0.000827922077922106*G0_4_0 + 0.000194805194805202*G0_4_1 + 0.000389610389610403*G0_4_2 - 0.000779220779220806*G0_4_4 - 0.000584415584415605*G0_4_5 - 0.00146103896103901*G0_5_0 + 9.74025974026009e-05*G0_5_2 + 0.0001948051948052*G0_5_3 - 0.000584415584415605*G0_5_4 + 0.00175324675324681*G0_5_5; + A[98] = A[89]; + A[39] = A[93]; + A[19] = A[90] - 0.000235389610389618*G0_0_0 - 4.87012987013004e-05*G0_0_2 + 0.000324675324675336*G0_0_3 + 3.24675324675336e-05*G0_0_4 + 0.000194805194805202*G0_0_5 + 0.000235389610389619*G0_1_1 + 4.87012987013003e-05*G0_1_2 - 3.24675324675334e-05*G0_1_3 - 0.000324675324675336*G0_1_4 - 0.000194805194805201*G0_1_5 - 4.87012987013004e-05*G0_2_0 + 4.87012987013003e-05*G0_2_1 + 0.000162337662337668*G0_2_3 - 0.000162337662337668*G0_2_4 + 0.000324675324675336*G0_3_0 - 3.24675324675334e-05*G0_3_1 + 0.000162337662337668*G0_3_2 - 0.00194805194805201*G0_3_3 - 0.000649350649350672*G0_3_5 + 3.24675324675336e-05*G0_4_0 - 0.000324675324675336*G0_4_1 - 0.000162337662337668*G0_4_2 + 0.00194805194805201*G0_4_4 + 0.000649350649350672*G0_4_5 + 0.000194805194805202*G0_5_0 - 0.000194805194805201*G0_5_1 - 0.000649350649350672*G0_5_3 + 0.000649350649350672*G0_5_4; + A[87] = A[78]; + A[42] = -A[11] + 2.38997113997123e-05*G0_0_0 - 0.000112283549783554*G0_0_1 - 0.00010642135642136*G0_0_2 - 0.000112283549783554*G0_1_0 + 0.002355248917749*G0_1_1 - 0.000297619047619058*G0_1_2 + 0.000378787878787892*G0_1_3 + 0.000503246753246773*G0_1_5 - 0.00010642135642136*G0_2_0 - 0.000297619047619058*G0_2_1 + 0.00158910533910539*G0_2_2 + 0.00081168831168834*G0_2_3 + 0.000429292929292944*G0_2_4 + 5.4112554112556e-05*G0_2_5 + 0.000378787878787892*G0_3_1 + 0.00081168831168834*G0_3_2 + 0.000108225108225112*G0_3_3 - 0.000108225108225111*G0_3_5 + 0.000429292929292944*G0_4_2 + 7.93650793650823e-05*G0_4_4 - 0.000108225108225112*G0_4_5 + 0.000503246753246773*G0_5_1 + 5.4112554112556e-05*G0_5_2 - 0.000108225108225111*G0_5_3 - 0.000108225108225112*G0_5_4 - 4.32900432900436e-05*G0_5_5; + A[26] = A[42] - 8.38744588744617e-05*G0_0_0 - 5.41125541125561e-05*G0_0_2 - 5.4112554112556e-05*G0_0_3 - 0.000162337662337668*G0_0_4 - 9.19913419913452e-05*G0_0_5 + 8.38744588744618e-05*G0_1_1 + 5.41125541125558e-05*G0_1_2 + 0.000162337662337668*G0_1_3 + 5.4112554112556e-05*G0_1_4 + 9.19913419913453e-05*G0_1_5 - 5.41125541125561e-05*G0_2_0 + 5.41125541125558e-05*G0_2_1 - 0.000432900432900447*G0_2_3 + 0.000432900432900448*G0_2_4 - 5.4112554112556e-05*G0_3_0 + 0.000162337662337668*G0_3_1 - 0.000432900432900447*G0_3_2 + 0.000216450216450224*G0_3_3 + 0.000108225108225112*G0_3_5 - 0.000162337662337668*G0_4_0 + 5.4112554112556e-05*G0_4_1 + 0.000432900432900448*G0_4_2 - 0.000216450216450223*G0_4_4 - 0.000108225108225112*G0_4_5 - 9.19913419913452e-05*G0_5_0 + 9.19913419913453e-05*G0_5_1 + 0.000108225108225112*G0_5_3 - 0.000108225108225112*G0_5_4; + A[31] = A[42] - 0.000131222943722949*G0_0_1 + 0.000131222943722948*G0_0_2 + 5.41125541125561e-05*G0_0_4 - 5.41125541125561e-05*G0_0_5 - 0.000131222943722949*G0_1_0 + 0.00164908008658014*G0_1_1 + 0.00102813852813856*G0_1_3 + 0.000108225108225112*G0_1_4 + 0.000470779220779239*G0_1_5 + 0.000131222943722948*G0_2_0 - 0.00164908008658014*G0_2_2 - 0.00102813852813856*G0_2_3 - 0.000470779220779237*G0_2_4 - 0.000108225108225112*G0_2_5 + 0.00102813852813856*G0_3_1 - 0.00102813852813856*G0_3_2 - 0.000216450216450224*G0_3_4 + 0.000216450216450225*G0_3_5 + 5.41125541125561e-05*G0_4_0 + 0.000108225108225112*G0_4_1 - 0.000470779220779237*G0_4_2 - 0.000216450216450224*G0_4_3 - 0.000367965367965381*G0_4_4 - 5.41125541125561e-05*G0_5_0 + 0.000470779220779239*G0_5_1 - 0.000108225108225112*G0_5_2 + 0.000216450216450225*G0_5_3 + 0.000367965367965382*G0_5_5; + A[16] = -A[31] - 8.65800865800896e-05*G0_0_0 - 6.35822510822536e-05*G0_0_1 - 5.41125541125553e-06*G0_0_2 - 3.78787878787895e-05*G0_0_3 - 0.000178571428571435*G0_0_4 - 0.000119047619047623*G0_0_5 - 6.35822510822536e-05*G0_1_0 + 0.00151515151515157*G0_1_1 - 0.000202922077922085*G0_1_2 + 0.000779220779220806*G0_1_3 + 1.62337662337668e-05*G0_1_4 + 0.000411255411255427*G0_1_5 - 5.41125541125552e-06*G0_2_0 - 0.000202922077922085*G0_2_1 + 9.33441558441591e-05*G0_2_2 - 5.41125541125568e-06*G0_2_3 + 0.000216450216450224*G0_2_4 + 3.78787878787889e-05*G0_2_5 - 3.78787878787895e-05*G0_3_0 + 0.000779220779220806*G0_3_1 - 5.41125541125563e-06*G0_3_2 - 6.49350649350673e-05*G0_3_3 + 4.32900432900451e-05*G0_3_4 - 0.000178571428571435*G0_4_0 + 1.62337662337668e-05*G0_4_1 + 0.000216450216450224*G0_4_2 + 4.32900432900451e-05*G0_4_3 + 0.000367965367965381*G0_4_4 - 0.000108225108225112*G0_4_5 - 0.000119047619047623*G0_5_0 + 0.000411255411255427*G0_5_1 + 3.78787878787889e-05*G0_5_2 - 0.000108225108225112*G0_5_4 - 4.32900432900438e-05*G0_5_5; + A[40] = A[16] + 3.65259740259752e-05*G0_0_0 - 1.21753246753251e-05*G0_0_2 + 0.000146103896103901*G0_0_4 + 9.74025974026008e-05*G0_0_5 - 3.65259740259752e-05*G0_1_1 + 1.21753246753251e-05*G0_1_2 - 0.000146103896103901*G0_1_3 - 9.74025974026008e-05*G0_1_5 - 1.21753246753251e-05*G0_2_0 + 1.21753246753251e-05*G0_2_1 + 9.74025974026007e-05*G0_2_3 - 9.74025974026007e-05*G0_2_4 - 0.000146103896103901*G0_3_1 + 9.74025974026007e-05*G0_3_2 + 0.000584415584415605*G0_3_3 + 0.000146103896103901*G0_4_0 - 9.74025974026007e-05*G0_4_2 - 0.000584415584415605*G0_4_4 + 9.74025974026008e-05*G0_5_0 - 9.74025974026008e-05*G0_5_1; + A[4] = A[40]; + A[60] = A[16] - 0.000626352813852835*G0_0_0 + 2.57034632034641e-05*G0_0_1 + 4.46428571428586e-05*G0_0_2 + 5.41125541125555e-06*G0_0_3 - 0.000200216450216457*G0_0_4 - 9.7402597402601e-05*G0_0_5 + 2.57034632034641e-05*G0_1_0 + 2.84090909090922e-05*G0_1_1 + 2.70562770562777e-06*G0_1_2 - 5.41125541125549e-06*G0_1_3 + 4.87012987013004e-05*G0_1_4 - 1.08225108225111e-05*G0_1_5 + 4.46428571428586e-05*G0_2_0 + 2.70562770562777e-06*G0_2_1 + 6.62878787878811e-05*G0_2_2 + 7.03463203463229e-05*G0_2_4 - 5.4112554112556e-06*G0_2_5 + 5.41125541125555e-06*G0_3_0 - 5.41125541125549e-06*G0_3_1 + 0.000108225108225112*G0_3_3 - 0.000108225108225112*G0_3_4 - 0.000200216450216457*G0_4_0 + 4.87012987013003e-05*G0_4_1 + 7.03463203463229e-05*G0_4_2 - 0.000108225108225112*G0_4_3 - 0.000974025974026006*G0_4_4 - 8.65800865800894e-05*G0_4_5 - 9.74025974026009e-05*G0_5_0 - 1.08225108225111e-05*G0_5_1 - 5.4112554112556e-06*G0_5_2 - 8.65800865800894e-05*G0_5_4 + 2.16450216450225e-05*G0_5_5; + A[25] = A[60] + 0.000956439393939426*G0_0_0 - 0.000108225108225112*G0_0_1 + 0.000119047619047623*G0_0_3 + 0.000757575757575784*G0_0_4 + 0.000373376623376636*G0_0_5 - 0.000108225108225112*G0_1_0 + 0.000108225108225112*G0_1_2 + 5.95238095238116e-05*G0_1_3 - 5.95238095238116e-05*G0_1_5 + 0.000108225108225112*G0_2_1 - 0.000956439393939428*G0_2_2 - 0.000373376623376637*G0_2_3 - 0.000757575757575784*G0_2_4 - 0.000119047619047623*G0_2_5 + 0.000119047619047623*G0_3_0 + 5.95238095238116e-05*G0_3_1 - 0.000373376623376637*G0_3_2 - 0.000281385281385291*G0_3_3 - 0.000238095238095246*G0_3_4 + 0.000757575757575784*G0_4_0 - 0.000757575757575784*G0_4_2 - 0.000238095238095247*G0_4_3 + 0.000238095238095246*G0_4_5 + 0.000373376623376636*G0_5_0 - 5.95238095238115e-05*G0_5_1 - 0.000119047619047623*G0_5_2 + 0.000238095238095246*G0_5_4 + 0.000281385281385291*G0_5_5; + A[51] = A[25] - 6.6287878787881e-05*G0_0_0 - 2.70562770562773e-06*G0_0_1 - 4.46428571428587e-05*G0_0_2 + 5.41125541125555e-06*G0_0_3 - 7.03463203463228e-05*G0_0_4 - 2.70562770562773e-06*G0_1_0 - 2.84090909090924e-05*G0_1_1 - 2.57034632034641e-05*G0_1_2 + 1.08225108225111e-05*G0_1_3 - 4.87012987013003e-05*G0_1_4 + 5.41125541125549e-06*G0_1_5 - 4.46428571428587e-05*G0_2_0 - 2.57034632034641e-05*G0_2_1 + 0.000626352813852836*G0_2_2 + 9.7402597402601e-05*G0_2_3 + 0.000200216450216457*G0_2_4 - 5.41125541125561e-06*G0_2_5 + 5.41125541125555e-06*G0_3_0 + 1.08225108225111e-05*G0_3_1 + 9.7402597402601e-05*G0_3_2 - 2.16450216450223e-05*G0_3_3 + 8.65800865800895e-05*G0_3_4 - 7.03463203463228e-05*G0_4_0 - 4.87012987013003e-05*G0_4_1 + 0.000200216450216457*G0_4_2 + 8.65800865800895e-05*G0_4_3 + 0.000974025974026006*G0_4_4 + 0.000108225108225112*G0_4_5 + 5.41125541125547e-06*G0_5_1 - 5.41125541125561e-06*G0_5_2 + 0.000108225108225112*G0_5_4 - 0.000108225108225112*G0_5_5; + A[72] = A[51] + 1.21753246753251e-05*G0_0_1 - 1.21753246753251e-05*G0_0_2 - 9.74025974026007e-05*G0_0_4 + 9.74025974026009e-05*G0_0_5 + 1.21753246753251e-05*G0_1_0 - 3.6525974025975e-05*G0_1_1 - 9.74025974026008e-05*G0_1_3 - 0.000146103896103901*G0_1_5 - 1.21753246753251e-05*G0_2_0 + 3.65259740259747e-05*G0_2_2 + 9.74025974026006e-05*G0_2_3 + 0.000146103896103901*G0_2_4 - 9.74025974026008e-05*G0_3_1 + 9.74025974026006e-05*G0_3_2 - 9.74025974026007e-05*G0_4_0 + 0.000146103896103901*G0_4_2 - 0.000584415584415604*G0_4_4 + 9.74025974026009e-05*G0_5_0 - 0.000146103896103901*G0_5_1 + 0.000584415584415605*G0_5_5; + A[15] = A[51]; + A[22] = -A[31] + 2.38997113997122e-05*G0_0_0 - 0.00010642135642136*G0_0_1 - 0.000112283549783554*G0_0_2 - 0.00010642135642136*G0_1_0 + 0.00158910533910539*G0_1_1 - 0.000297619047619058*G0_1_2 + 0.00081168831168834*G0_1_3 + 5.4112554112556e-05*G0_1_4 + 0.000429292929292946*G0_1_5 - 0.000112283549783554*G0_2_0 - 0.000297619047619058*G0_2_1 + 0.00235524891774899*G0_2_2 + 0.000378787878787891*G0_2_3 + 0.000503246753246771*G0_2_4 + 0.00081168831168834*G0_3_1 + 0.000378787878787891*G0_3_2 + 0.000108225108225112*G0_3_3 - 0.000108225108225112*G0_3_4 + 5.41125541125561e-05*G0_4_1 + 0.000503246753246771*G0_4_2 - 0.000108225108225112*G0_4_3 - 4.32900432900449e-05*G0_4_4 - 0.000108225108225112*G0_4_5 + 0.000429292929292946*G0_5_1 - 0.000108225108225112*G0_5_4 + 7.93650793650831e-05*G0_5_5; + A[41] = A[40] + 2.84090909090919e-05*G0_0_0 + 2.57034632034642e-05*G0_0_1 + 2.70562770562776e-06*G0_0_2 + 4.87012987013004e-05*G0_0_3 - 5.41125541125557e-06*G0_0_4 - 1.08225108225111e-05*G0_0_5 + 2.57034632034642e-05*G0_1_0 - 0.000626352813852835*G0_1_1 + 4.46428571428587e-05*G0_1_2 - 0.000200216450216457*G0_1_3 + 5.4112554112556e-06*G0_1_4 - 9.74025974026013e-05*G0_1_5 + 2.70562770562776e-06*G0_2_0 + 4.46428571428587e-05*G0_2_1 + 6.62878787878812e-05*G0_2_2 + 7.03463203463228e-05*G0_2_3 - 5.41125541125551e-06*G0_2_5 + 4.87012987013004e-05*G0_3_0 - 0.000200216450216457*G0_3_1 + 7.03463203463228e-05*G0_3_2 - 0.000974025974026008*G0_3_3 - 0.000108225108225112*G0_3_4 - 8.65800865800898e-05*G0_3_5 - 5.41125541125559e-06*G0_4_0 + 5.41125541125559e-06*G0_4_1 - 0.000108225108225112*G0_4_3 + 0.000108225108225112*G0_4_4 - 1.08225108225111e-05*G0_5_0 - 9.74025974026013e-05*G0_5_1 - 5.41125541125551e-06*G0_5_2 - 8.65800865800898e-05*G0_5_3 + 2.16450216450221e-05*G0_5_5; + A[32] = A[41] - 0.000108225108225112*G0_0_1 + 0.000108225108225112*G0_0_2 + 5.95238095238116e-05*G0_0_4 - 5.95238095238117e-05*G0_0_5 - 0.000108225108225112*G0_1_0 + 0.000956439393939427*G0_1_1 + 0.000757575757575784*G0_1_3 + 0.000119047619047623*G0_1_4 + 0.000373376623376637*G0_1_5 + 0.000108225108225112*G0_2_0 - 0.000956439393939426*G0_2_2 - 0.000757575757575784*G0_2_3 - 0.000373376623376636*G0_2_4 - 0.000119047619047623*G0_2_5 + 0.000757575757575784*G0_3_1 - 0.000757575757575784*G0_3_2 - 0.000238095238095247*G0_3_4 + 0.000238095238095247*G0_3_5 + 5.95238095238116e-05*G0_4_0 + 0.000119047619047623*G0_4_1 - 0.000373376623376636*G0_4_2 - 0.000238095238095246*G0_4_3 - 0.000281385281385291*G0_4_4 - 5.95238095238117e-05*G0_5_0 + 0.000373376623376637*G0_5_1 - 0.000119047619047623*G0_5_2 + 0.000238095238095247*G0_5_3 + 0.000281385281385291*G0_5_5; + A[71] = A[72] + 6.62878787878811e-05*G0_0_0 + 4.4642857142859e-05*G0_0_1 + 2.70562770562778e-06*G0_0_2 - 5.41125541125554e-06*G0_0_3 + 7.03463203463226e-05*G0_0_5 + 4.4642857142859e-05*G0_1_0 - 0.000626352813852838*G0_1_1 + 2.57034632034643e-05*G0_1_2 - 9.74025974026014e-05*G0_1_3 + 5.41125541125563e-06*G0_1_4 - 0.000200216450216458*G0_1_5 + 2.70562770562778e-06*G0_2_0 + 2.57034632034643e-05*G0_2_1 + 2.84090909090925e-05*G0_2_2 - 1.08225108225109e-05*G0_2_3 - 5.41125541125541e-06*G0_2_4 + 4.87012987013005e-05*G0_2_5 - 5.41125541125552e-06*G0_3_0 - 9.74025974026014e-05*G0_3_1 - 1.08225108225109e-05*G0_3_2 + 2.1645021645022e-05*G0_3_3 - 8.658008658009e-05*G0_3_5 + 5.41125541125566e-06*G0_4_1 - 5.41125541125541e-06*G0_4_2 + 0.000108225108225111*G0_4_4 - 0.000108225108225112*G0_4_5 + 7.03463203463226e-05*G0_5_0 - 0.000200216450216458*G0_5_1 + 4.87012987013005e-05*G0_5_2 - 8.658008658009e-05*G0_5_3 - 0.000108225108225112*G0_5_4 - 0.000974025974026009*G0_5_5; + A[5] = -A[22] + 0.00158910533910539*G0_0_0 - 0.00010642135642136*G0_0_1 - 0.000297619047619058*G0_0_2 + 5.41125541125562e-05*G0_0_3 + 0.000811688311688339*G0_0_4 + 0.000429292929292944*G0_0_5 - 0.00010642135642136*G0_1_0 + 2.38997113997122e-05*G0_1_1 - 0.000112283549783553*G0_1_2 - 0.000297619047619058*G0_2_0 - 0.000112283549783553*G0_2_1 + 0.00235524891774899*G0_2_2 + 0.00050324675324677*G0_2_3 + 0.000378787878787892*G0_2_4 + 5.41125541125562e-05*G0_3_0 + 0.00050324675324677*G0_3_2 - 4.3290043290045e-05*G0_3_3 - 0.000108225108225112*G0_3_4 - 0.000108225108225112*G0_3_5 + 0.000811688311688339*G0_4_0 + 0.000378787878787892*G0_4_2 - 0.000108225108225112*G0_4_3 + 0.000108225108225112*G0_4_4 + 0.000429292929292944*G0_5_0 - 0.000108225108225112*G0_5_3 + 7.9365079365082e-05*G0_5_5; + A[27] = A[72]; + A[61] = A[16]; + A[13] = A[31]; + A[30] = A[32] - 2.84090909090922e-05*G0_0_0 - 2.70562770562779e-06*G0_0_1 - 2.57034632034641e-05*G0_0_2 - 4.87012987013004e-05*G0_0_3 + 1.08225108225111e-05*G0_0_4 + 5.4112554112554e-06*G0_0_5 - 2.70562770562779e-06*G0_1_0 - 6.62878787878808e-05*G0_1_1 - 4.46428571428587e-05*G0_1_2 - 7.03463203463224e-05*G0_1_3 + 5.4112554112556e-06*G0_1_4 - 2.57034632034641e-05*G0_2_0 - 4.46428571428587e-05*G0_2_1 + 0.000626352813852835*G0_2_2 + 0.000200216450216457*G0_2_3 + 9.74025974026008e-05*G0_2_4 - 5.41125541125561e-06*G0_2_5 - 4.87012987013004e-05*G0_3_0 - 7.03463203463224e-05*G0_3_1 + 0.000200216450216457*G0_3_2 + 0.000974025974026009*G0_3_3 + 8.65800865800897e-05*G0_3_4 + 0.000108225108225112*G0_3_5 + 1.08225108225111e-05*G0_4_0 + 5.41125541125559e-06*G0_4_1 + 9.74025974026007e-05*G0_4_2 + 8.65800865800897e-05*G0_4_3 - 2.16450216450223e-05*G0_4_4 + 5.41125541125542e-06*G0_5_0 - 5.41125541125561e-06*G0_5_2 + 0.000108225108225112*G0_5_3 - 0.000108225108225111*G0_5_5; + A[82] = A[30] - 3.65259740259748e-05*G0_0_0 + 1.21753246753251e-05*G0_0_1 - 9.74025974026006e-05*G0_0_4 - 0.000146103896103901*G0_0_5 + 1.21753246753251e-05*G0_1_0 - 1.21753246753251e-05*G0_1_2 - 9.74025974026011e-05*G0_1_3 + 9.74025974026006e-05*G0_1_5 - 1.21753246753251e-05*G0_2_1 + 3.65259740259755e-05*G0_2_2 + 0.000146103896103901*G0_2_3 + 9.74025974026009e-05*G0_2_4 - 9.74025974026011e-05*G0_3_1 + 0.000146103896103901*G0_3_2 - 0.000584415584415606*G0_3_3 - 9.74025974026006e-05*G0_4_0 + 9.7402597402601e-05*G0_4_2 - 0.000146103896103901*G0_5_0 + 9.74025974026006e-05*G0_5_1 + 0.000584415584415604*G0_5_5; + A[8] = A[82] - 0.000626352813852835*G0_0_0 + 4.46428571428587e-05*G0_0_1 + 2.57034632034641e-05*G0_0_2 + 5.41125541125544e-06*G0_0_3 - 9.74025974026007e-05*G0_0_4 - 0.000200216450216458*G0_0_5 + 4.46428571428587e-05*G0_1_0 + 6.62878787878815e-05*G0_1_1 + 2.70562770562779e-06*G0_1_2 - 5.41125541125562e-06*G0_1_4 + 7.03463203463229e-05*G0_1_5 + 2.57034632034641e-05*G0_2_0 + 2.70562770562779e-06*G0_2_1 + 2.84090909090917e-05*G0_2_2 - 5.41125541125571e-06*G0_2_3 - 1.08225108225113e-05*G0_2_4 + 4.87012987013003e-05*G0_2_5 + 5.41125541125547e-06*G0_3_0 - 5.41125541125571e-06*G0_3_2 + 0.000108225108225112*G0_3_3 - 0.000108225108225112*G0_3_5 - 9.74025974026007e-05*G0_4_0 - 5.41125541125563e-06*G0_4_1 - 1.08225108225113e-05*G0_4_2 + 2.16450216450226e-05*G0_4_4 - 8.65800865800893e-05*G0_4_5 - 0.000200216450216457*G0_5_0 + 7.03463203463229e-05*G0_5_1 + 4.87012987013003e-05*G0_5_2 - 0.000108225108225112*G0_5_3 - 8.65800865800893e-05*G0_5_4 - 0.000974025974026007*G0_5_5; + A[28] = A[82]; + A[80] = A[8]; + A[62] = A[26]; + A[50] = A[5]; + A[14] = A[41]; + A[23] = A[32]; + A[96] = A[69]; + A[65] = A[78] - 0.000450487012987029*G0_0_1 + 0.000450487012987029*G0_0_2 - 0.000292207792207801*G0_0_4 + 0.000292207792207802*G0_0_5 - 0.000450487012987029*G0_1_0 + 0.00122970779220784*G0_1_1 + 0.000925324675324709*G0_1_3 + 0.000292207792207803*G0_1_4 + 0.00121753246753251*G0_1_5 + 0.000450487012987029*G0_2_0 - 0.00122970779220784*G0_2_2 - 0.000925324675324708*G0_2_3 - 0.00121753246753251*G0_2_4 - 0.000292207792207802*G0_2_5 + 0.000925324675324709*G0_3_1 - 0.000925324675324708*G0_3_2 - 0.000584415584415606*G0_3_4 + 0.000584415584415605*G0_3_5 - 0.000292207792207801*G0_4_0 + 0.000292207792207803*G0_4_1 - 0.00121753246753251*G0_4_2 - 0.000584415584415606*G0_4_3 + 0.000194805194805191*G0_4_4 + 0.000292207792207801*G0_5_0 + 0.00121753246753251*G0_5_1 - 0.000292207792207803*G0_5_2 + 0.000584415584415605*G0_5_3 - 0.000194805194805202*G0_5_5; + A[53] = A[35]; + A[70] = A[7]; + A[68] = A[86]; + A[6] = A[60]; + A[17] = A[71]; + A[9] = A[90]; + A[34] = A[78] + 0.00122970779220783*G0_0_0 - 0.000450487012987029*G0_0_1 + 0.000292207792207803*G0_0_3 + 0.000925324675324707*G0_0_4 + 0.00121753246753251*G0_0_5 - 0.000450487012987029*G0_1_0 + 0.000450487012987029*G0_1_2 - 0.000292207792207802*G0_1_3 + 0.000292207792207802*G0_1_5 + 0.000450487012987029*G0_2_1 - 0.00122970779220783*G0_2_2 - 0.00121753246753251*G0_2_3 - 0.000925324675324708*G0_2_4 - 0.000292207792207802*G0_2_5 + 0.000292207792207803*G0_3_0 - 0.000292207792207802*G0_3_1 - 0.00121753246753251*G0_3_2 + 0.000194805194805202*G0_3_3 - 0.000584415584415605*G0_3_4 + 0.000925324675324707*G0_4_0 - 0.000925324675324708*G0_4_2 - 0.000584415584415605*G0_4_3 + 0.000584415584415605*G0_4_5 + 0.00121753246753251*G0_5_0 + 0.000292207792207803*G0_5_1 - 0.000292207792207802*G0_5_2 + 0.000584415584415605*G0_5_4 - 0.000194805194805199*G0_5_5; + A[75] = -A[34] + 0.00159496753246759*G0_0_0 - 0.000255681818181826*G0_0_1 - 0.000255681818181827*G0_0_2 + 0.000535714285714305*G0_0_3 + 0.00180194805194811*G0_0_4 + 0.00180194805194811*G0_0_5 - 0.000255681818181826*G0_1_0 - 0.00110795454545458*G0_1_1 + 0.00066964285714288*G0_1_2 - 0.00107142857142861*G0_1_3 - 0.000535714285714304*G0_1_4 - 0.00131493506493511*G0_1_5 - 0.000255681818181827*G0_2_0 + 0.00066964285714288*G0_2_1 - 0.00110795454545458*G0_2_2 - 0.00107142857142861*G0_2_3 - 0.00131493506493511*G0_2_4 - 0.000535714285714304*G0_2_5 + 0.000535714285714305*G0_3_0 - 0.00107142857142861*G0_3_1 - 0.00107142857142861*G0_3_2 + 0.00180194805194811*G0_4_0 - 0.000535714285714304*G0_4_1 - 0.00131493506493511*G0_4_2 + 0.00272727272727282*G0_4_4 + 0.00214285714285721*G0_4_5 + 0.00180194805194811*G0_5_0 - 0.00131493506493511*G0_5_1 - 0.000535714285714304*G0_5_2 + 0.00214285714285721*G0_5_4 + 0.00272727272727282*G0_5_5; + A[55] = A[75] + 0.00170454545454551*G0_0_0 - 2.43506493506504e-05*G0_0_1 - 0.000633116883116905*G0_0_2 + 4.87012987013004e-05*G0_0_3 + 0.00292207792207802*G0_0_4 - 2.43506493506504e-05*G0_1_0 - 1.21753246753253e-05*G0_1_1 + 1.21753246753251e-05*G0_1_2 - 0.000194805194805202*G0_1_3 - 0.000633116883116904*G0_1_4 + 4.87012987013001e-05*G0_1_5 - 0.000633116883116905*G0_2_0 + 1.21753246753252e-05*G0_2_1 + 0.00069399350649353*G0_2_2 + 0.000194805194805202*G0_2_3 - 0.00102272727272731*G0_2_4 - 4.87012987013004e-05*G0_2_5 + 4.87012987013004e-05*G0_3_0 - 0.000194805194805202*G0_3_1 + 0.000194805194805202*G0_3_2 + 0.000389610389610403*G0_3_3 + 0.00116883116883121*G0_3_4 + 0.00292207792207802*G0_4_0 - 0.000633116883116905*G0_4_1 - 0.00102272727272731*G0_4_2 + 0.00116883116883121*G0_4_3 + 0.0122727272727277*G0_4_4 + 0.00136363636363641*G0_4_5 + 4.87012987013001e-05*G0_5_1 - 4.87012987013004e-05*G0_5_2 + 0.00136363636363641*G0_5_4 - 0.00136363636363641*G0_5_5; + A[64] = A[75] - 0.00147321428571433*G0_0_0 + 0.000474837662337678*G0_0_1 - 0.000779220779220806*G0_0_3 - 0.00219155844155852*G0_0_4 - 0.00165584415584421*G0_0_5 + 0.000474837662337678*G0_1_0 - 0.000474837662337679*G0_1_2 - 0.000535714285714304*G0_1_3 + 0.000535714285714304*G0_1_5 - 0.000474837662337679*G0_2_1 + 0.00147321428571434*G0_2_2 + 0.00165584415584421*G0_2_3 + 0.00219155844155852*G0_2_4 + 0.000779220779220806*G0_2_5 - 0.000779220779220806*G0_3_0 - 0.000535714285714304*G0_3_1 + 0.00165584415584421*G0_3_2 + 0.00292207792207802*G0_3_3 + 0.00155844155844161*G0_3_4 - 0.00219155844155852*G0_4_0 + 0.00219155844155852*G0_4_2 + 0.00155844155844161*G0_4_3 - 0.00155844155844161*G0_4_5 - 0.00165584415584421*G0_5_0 + 0.000535714285714304*G0_5_1 + 0.000779220779220806*G0_5_2 - 0.00155844155844161*G0_5_4 - 0.00292207792207802*G0_5_5; + A[83] = A[75] - 0.00147321428571433*G0_0_0 + 0.000474837662337679*G0_0_2 - 0.000779220779220806*G0_0_3 - 0.00165584415584421*G0_0_4 - 0.00219155844155852*G0_0_5 + 0.00147321428571434*G0_1_1 - 0.000474837662337679*G0_1_2 + 0.00165584415584422*G0_1_3 + 0.000779220779220806*G0_1_4 + 0.00219155844155852*G0_1_5 + 0.000474837662337679*G0_2_0 - 0.000474837662337679*G0_2_1 - 0.000535714285714305*G0_2_3 + 0.000535714285714303*G0_2_4 - 0.000779220779220806*G0_3_0 + 0.00165584415584422*G0_3_1 - 0.000535714285714305*G0_3_2 + 0.00292207792207802*G0_3_3 + 0.00155844155844161*G0_3_5 - 0.00165584415584421*G0_4_0 + 0.000779220779220806*G0_4_1 + 0.000535714285714303*G0_4_2 - 0.00292207792207802*G0_4_4 - 0.00155844155844161*G0_4_5 - 0.00219155844155852*G0_5_0 + 0.00219155844155852*G0_5_1 + 0.00155844155844161*G0_5_3 - 0.00155844155844161*G0_5_4; + A[46] = A[64]; + A[57] = A[75]; + A[24] = A[42]; + A[84] = A[48]; + A[59] = A[97] - 7.30519480519506e-05*G0_0_1 + 7.30519480519508e-05*G0_0_2 + 0.000584415584415604*G0_0_4 - 0.000584415584415605*G0_0_5 - 7.30519480519506e-05*G0_1_0 + 0.000219155844155852*G0_1_1 + 0.000584415584415606*G0_1_3 + 0.000876623376623408*G0_1_5 + 7.30519480519508e-05*G0_2_0 - 0.000219155844155852*G0_2_2 - 0.000584415584415604*G0_2_3 - 0.000876623376623406*G0_2_4 + 0.000584415584415606*G0_3_1 - 0.000584415584415604*G0_3_2 + 0.000584415584415604*G0_4_0 - 0.000876623376623406*G0_4_2 + 0.00350649350649362*G0_4_4 - 0.000584415584415605*G0_5_0 + 0.000876623376623408*G0_5_1 - 0.00350649350649364*G0_5_5; + A[47] = A[74]; + A[91] = A[19]; + A[66] = A[55] - 0.00248376623376631*G0_0_0 + 0.000511363636363654*G0_0_1 - 0.000876623376623407*G0_0_3 - 0.00613636363636384*G0_0_4 - 0.00146103896103901*G0_0_5 + 0.000511363636363654*G0_1_0 - 0.000511363636363654*G0_1_2 - 0.000292207792207803*G0_1_3 + 0.000292207792207802*G0_1_5 - 0.000511363636363654*G0_2_1 + 0.00248376623376632*G0_2_2 + 0.00146103896103901*G0_2_3 + 0.00613636363636385*G0_2_4 + 0.000876623376623406*G0_2_5 - 0.000876623376623407*G0_3_0 - 0.000292207792207803*G0_3_1 + 0.00146103896103901*G0_3_2 + 0.00116883116883121*G0_3_3 + 0.00175324675324682*G0_3_4 - 0.00613636363636384*G0_4_0 + 0.00613636363636385*G0_4_2 + 0.00175324675324682*G0_4_3 - 0.00175324675324681*G0_4_5 - 0.00146103896103901*G0_5_0 + 0.000292207792207802*G0_5_1 + 0.000876623376623406*G0_5_2 - 0.00175324675324681*G0_5_4 - 0.00116883116883121*G0_5_5; + A[56] = A[65]; + A[77] = A[55] - 0.000608766233766256*G0_0_1 + 0.000608766233766255*G0_0_2 - 0.00292207792207802*G0_0_4 + 0.00292207792207803*G0_0_5 - 0.000608766233766256*G0_1_0 + 0.000706168831168858*G0_1_1 + 0.000389610389610404*G0_1_3 + 0.000584415584415604*G0_1_4 - 0.00107142857142861*G0_1_5 + 0.000608766233766255*G0_2_0 - 0.000706168831168856*G0_2_2 - 0.000389610389610404*G0_2_3 + 0.00107142857142861*G0_2_4 - 0.000584415584415606*G0_2_5 + 0.000389610389610404*G0_3_1 - 0.000389610389610404*G0_3_2 - 0.00116883116883121*G0_3_4 + 0.00116883116883121*G0_3_5 - 0.00292207792207802*G0_4_0 + 0.000584415584415604*G0_4_1 + 0.00107142857142861*G0_4_2 - 0.00116883116883121*G0_4_3 - 0.0136363636363641*G0_4_4 + 0.00292207792207803*G0_5_0 - 0.00107142857142861*G0_5_1 - 0.000584415584415606*G0_5_2 + 0.00116883116883121*G0_5_3 + 0.0136363636363641*G0_5_5; + A[3] = A[30]; + A[12] = A[21]; + A[49] = A[94]; + A[33] = A[55] - 0.00318993506493517*G0_0_0 + 0.00112012987012991*G0_0_2 - 0.00146103896103901*G0_0_3 - 0.00477272727272743*G0_0_4 - 0.00214285714285722*G0_0_5 + 0.00318993506493518*G0_1_1 - 0.00112012987012991*G0_1_2 + 0.00477272727272744*G0_1_3 + 0.00146103896103901*G0_1_4 + 0.00214285714285722*G0_1_5 + 0.00112012987012991*G0_2_0 - 0.00112012987012991*G0_2_1 - 0.00175324675324681*G0_2_3 + 0.00175324675324681*G0_2_4 - 0.00146103896103901*G0_3_0 + 0.00477272727272744*G0_3_1 - 0.00175324675324681*G0_3_2 + 0.0148051948051953*G0_3_3 + 0.00292207792207803*G0_3_5 - 0.00477272727272743*G0_4_0 + 0.00146103896103901*G0_4_1 + 0.00175324675324681*G0_4_2 - 0.0148051948051953*G0_4_4 - 0.00292207792207802*G0_4_5 - 0.00214285714285722*G0_5_0 + 0.00214285714285722*G0_5_1 + 0.00292207792207803*G0_5_3 - 0.00292207792207802*G0_5_4; + A[29] = A[92]; + A[44] = A[66] - 0.000706168831168856*G0_0_0 + 0.000608766233766255*G0_0_2 - 0.000584415584415603*G0_0_3 + 0.00107142857142861*G0_0_4 - 0.000389610389610403*G0_0_5 + 0.000706168831168856*G0_1_1 - 0.000608766233766255*G0_1_2 - 0.00107142857142861*G0_1_3 + 0.000584415584415605*G0_1_4 + 0.000389610389610404*G0_1_5 + 0.000608766233766255*G0_2_0 - 0.000608766233766255*G0_2_1 + 0.00292207792207802*G0_2_3 - 0.00292207792207802*G0_2_4 - 0.000584415584415603*G0_3_0 - 0.00107142857142861*G0_3_1 + 0.00292207792207802*G0_3_2 + 0.0136363636363641*G0_3_3 + 0.00116883116883121*G0_3_5 + 0.00107142857142861*G0_4_0 + 0.000584415584415605*G0_4_1 - 0.00292207792207802*G0_4_2 - 0.0136363636363641*G0_4_4 - 0.00116883116883121*G0_4_5 - 0.000389610389610403*G0_5_0 + 0.000389610389610404*G0_5_1 + 0.00116883116883121*G0_5_3 - 0.00116883116883121*G0_5_4; + A[63] = A[36]; + A[0] = -A[26] + 0.002355248917749*G0_0_0 - 0.000112283549783554*G0_0_1 - 0.000297619047619058*G0_0_2 + 0.000378787878787891*G0_0_4 + 0.000503246753246771*G0_0_5 - 0.000112283549783554*G0_1_0 + 2.38997113997123e-05*G0_1_1 - 0.00010642135642136*G0_1_2 - 0.000297619047619058*G0_2_0 - 0.00010642135642136*G0_2_1 + 0.00158910533910539*G0_2_2 + 0.000429292929292945*G0_2_3 + 0.00081168831168834*G0_2_4 + 5.41125541125561e-05*G0_2_5 + 0.000429292929292945*G0_3_2 + 7.93650793650826e-05*G0_3_3 - 0.000108225108225112*G0_3_5 + 0.000378787878787891*G0_4_0 + 0.00081168831168834*G0_4_2 + 0.000108225108225112*G0_4_4 - 0.000108225108225112*G0_4_5 + 0.000503246753246771*G0_5_0 + 5.41125541125561e-05*G0_5_2 - 0.000108225108225112*G0_5_3 - 0.000108225108225112*G0_5_4 - 4.32900432900444e-05*G0_5_5; + A[81] = -A[0] + 0.002355248917749*G0_0_0 - 0.000297619047619058*G0_0_1 - 0.000112283549783554*G0_0_2 + 0.00050324675324677*G0_0_4 + 0.000378787878787892*G0_0_5 - 0.000297619047619058*G0_1_0 + 0.0015891053391054*G0_1_1 - 0.000106421356421361*G0_1_2 + 0.000429292929292945*G0_1_3 + 5.4112554112556e-05*G0_1_4 + 0.000811688311688342*G0_1_5 - 0.000112283549783554*G0_2_0 - 0.000106421356421361*G0_2_1 + 2.38997113997123e-05*G0_2_2 + 0.000429292929292946*G0_3_1 + 7.93650793650832e-05*G0_3_3 - 0.000108225108225112*G0_3_4 + 0.00050324675324677*G0_4_0 + 5.4112554112556e-05*G0_4_1 - 0.000108225108225112*G0_4_3 - 4.32900432900449e-05*G0_4_4 - 0.000108225108225112*G0_4_5 + 0.000378787878787892*G0_5_0 + 0.000811688311688342*G0_5_1 - 0.000108225108225112*G0_5_4 + 0.000108225108225113*G0_5_5; + A[79] = A[97]; + A[38] = A[83]; + A[20] = A[2]; + A[18] = A[81]; + A[88] = A[66] - 0.00112012987012991*G0_0_1 + 0.00112012987012991*G0_0_2 + 0.00175324675324681*G0_0_4 - 0.00175324675324682*G0_0_5 - 0.00112012987012991*G0_1_0 + 0.00318993506493518*G0_1_1 + 0.00214285714285722*G0_1_3 + 0.00146103896103901*G0_1_4 + 0.00477272727272744*G0_1_5 + 0.00112012987012991*G0_2_0 - 0.00318993506493518*G0_2_2 - 0.00214285714285722*G0_2_3 - 0.00477272727272744*G0_2_4 - 0.00146103896103901*G0_2_5 + 0.00214285714285722*G0_3_1 - 0.00214285714285722*G0_3_2 - 0.00292207792207803*G0_3_4 + 0.00292207792207802*G0_3_5 + 0.00175324675324681*G0_4_0 + 0.00146103896103901*G0_4_1 - 0.00477272727272744*G0_4_2 - 0.00292207792207803*G0_4_3 - 0.0148051948051953*G0_4_4 - 0.00175324675324682*G0_5_0 + 0.00477272727272744*G0_5_1 - 0.00146103896103901*G0_5_2 + 0.00292207792207802*G0_5_3 + 0.0148051948051953*G0_5_5; + A[43] = A[34]; + A[95] = A[59]; + A[52] = A[25]; + } + + /// 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 mass_matrix_f2_p2_q3_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p2_q3_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p2_q3_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1))), 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 mass_matrix_f2_p2_q3_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p2_q3_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p2_q3_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p2_q3_tensor_finite_element_0(); + 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 mass_matrix_f2_p2_q3_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p2_q3_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p2_q3_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p2_q3_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f2_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/mass_matrix_2d/mass_matrix_f2_p2_q4_excafe.h b/mass_matrix_2d/mass_matrix_f2_p2_q4_excafe.h new file mode 100644 index 0000000..ba37205 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p2_q4_excafe.h @@ -0,0 +1,631 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 13 minutes and 16.68 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][0]*w[1][3] + w[0][3]*w[1][0]; + const double var_1 = 32.0000000000000000000000000*w[0][3]*w[1][3]; + const double var_2 = w[0][4]*w[1][5] + w[0][5]*w[1][4]; + const double var_3 = -0.0004871319157033442820946*var_2; + const double var_4 = var_3 + 0.0003869146726289583661414*var_0 + -0.0002695716981431267220658*w[0][0]*w[1][0] + 0.0000177600177600177600024*var_1; + const double var_5 = -1.0000000000000000000000000*x[0][0]; + const double var_6 = var_5 + x[1][0]; + const double var_7 = -1.0000000000000000000000000*x[0][1]; + const double var_8 = var_7 + x[2][1]; + const double var_9 = var_5 + x[2][0]; + const double var_10 = var_7 + x[1][1]; + const double var_11 = -1.0000000000000000000000000*var_10*var_9 + var_6*var_8; + const double var_12 = std::abs(var_11); + const double var_13 = w[0][2]*w[1][0] + w[0][0]*w[1][2]; + const double var_14 = w[0][3]*w[1][3]; + const double var_15 = w[0][5]*w[1][5]; + const double var_16 = var_14 + var_15; + const double var_17 = w[0][1]*w[1][2] + w[0][2]*w[1][1]; + const double var_18 = w[0][1]*w[1][0] + w[0][0]*w[1][1]; + const double var_19 = var_18 + var_17; + const double var_20 = w[0][3]*w[1][2] + w[0][2]*w[1][3]; + const double var_21 = w[0][0]*w[1][5] + w[0][5]*w[1][0]; + const double var_22 = var_20 + var_21; + const double var_23 = w[0][3]*w[1][4] + w[0][4]*w[1][3]; + const double var_24 = var_23 + var_2; + const double var_25 = w[0][0]*w[1][0]; + const double var_26 = w[0][2]*w[1][2]; + const double var_27 = var_25 + var_26; + const double var_28 = w[0][1]*w[1][5] + w[0][5]*w[1][1]; + const double var_29 = w[0][1]*w[1][3] + w[0][3]*w[1][1]; + const double var_30 = var_28 + var_29; + const double var_31 = w[0][4]*w[1][2] + w[0][2]*w[1][4]; + const double var_32 = w[0][0]*w[1][4] + w[0][4]*w[1][0]; + const double var_33 = var_31 + var_32; + const double var_34 = w[0][4]*w[1][4]; + const double var_35 = w[0][5]*w[1][3] + w[0][3]*w[1][5]; + const double var_36 = w[0][5]*w[1][2] + w[0][2]*w[1][5]; + const double var_37 = var_36 + var_0; + const double var_38 = var_35 + -0.2500000000000000000000000*var_37; + const double var_39 = 0.2277777777777777734602438*var_33 + 30.5000000000000000000000000*var_30 + 15.7777777777777767909128670*var_16 + -1.9722222222222220988641084*var_22 + 191.5000000000000000000000000*w[0][1]*w[1][1] + 9.7111111111111121374506183*var_34 + -7.6250000000000000000000000*var_19 + -0.1138888888888888867301219*var_13 + 2.4277777777777780343626546*var_27 + 3.9444444444444441977282167*var_24 + 7.8888888888888883954564335*var_38; + A[16] = 0.0000074000074000073997186*var_12*var_39; + const double var_40 = -1.0000000000000000000000000*var_20; + const double var_41 = w[0][4]*w[1][1] + w[0][1]*w[1][4]; + const double var_42 = -0.0030946830946830946804105*w[0][1]*w[1][1] + 0.0062515262515262515208292*var_41 + -0.0527117327117327116869916*w[0][4]*w[1][4] + -0.0088800088800088800011778*var_35 + 0.0077389277389277389210265*var_13; + const double var_43 = -1.0000000000000000000000000*var_1; + const double var_44 = -0.0021711621711621711602880*w[0][0]*w[1][0] + 0.0066200466200466200408781*var_17 + -0.0080275280275280275210648*var_2 + 0.0007770007770007770001031*var_43 + 0.0066777666777666777608857*var_0; + const double var_45 = -1.0000000000000000000000000*var_36; + const double var_46 = 0.5555555555555555802271783*var_18 + 6.0800000000000000710542736*w[0][5]*w[1][5]; + const double var_47 = 0.0022377622377622377602968*var_45 + -0.0494172494172494189412781*var_26 + -0.0258585858585858585634298*var_23 + -0.0019980019980019980002650*var_46; + const double var_48 = -1.0000000000000000000000000*var_28; + const double var_49 = 0.0009235209235209235201225*var_48; + const double var_50 = var_42 + var_49 + var_44 + -0.0363014763014763014448150*var_31 + 0.0035697635697635697604735*var_29 + 0.0233721833721833721631000*var_40 + var_47 + 0.0115972915972915972815382*var_32 + 0.0031257631257631257604146*var_21; + A[68] = 0.0317460317460317442694873*var_12*var_50; + const double var_51 = -1.0000000000000000000000000*var_18; + const double var_52 = -0.0002587888302174016380043*w[0][5]*w[1][5] + 0.0000158571587143015728827*var_51 + -0.0003272917558631844420734*var_36 + -0.0025371453942882515528168*var_23 + -0.0043822843822843822805813*w[0][2]*w[1][2]; + const double var_53 = var_31 + var_20; + const double var_54 = -1.0000000000000000000000000*var_17; + const double var_55 = -0.0043822843822843822805813*w[0][0]*w[1][0] + -0.0025371453942882515528168*var_2 + -0.0002587888302174016380043*w[0][3]*w[1][3] + -0.0003272917558631844420734*var_0 + 0.0000158571587143015728827*var_54; + const double var_56 = 0.4259740259740259493703718*w[0][1]*w[1][1] + -0.0092352092352092352012249*var_35 + -0.0711111111111111110494321*w[0][4]*w[1][4] + 0.0121212121212121212016077*var_41 + 0.0038672438672438672405129*var_13; + const double var_57 = -0.0092352092352092352012249*var_14 + -0.0198556998556998556826336*w[0][0]*w[1][0] + -0.0346320346320346320045935*var_2 + -0.0005772005772005772000766*var_0 + 0.0181818181818181809350499*var_54; + const double var_58 = 16.0000000000000000000000000*w[0][5]*w[1][5]; + const double var_59 = 0.0303030303030303038713811*var_51 + 0.0051948051948051948006890*var_36 + -0.0230880230880230880030624*var_23 + -0.0017316017316017316002297*var_58 + -0.0035786435786435786404747*w[0][2]*w[1][2]; + const double var_60 = var_57 + 0.1454545454545454474803989*var_28 + var_59 + 0.0057720057720057720007656*var_31 + 0.0727272727272727237401995*var_29 + -0.0005772005772005772000766*var_20 + -0.0091197691197691197612096*var_32 + var_56 + -0.0190476190476190493372499*var_21; + A[26] = 0.0028490028490028491449382*var_12*var_60; + const double var_61 = -1.0000000000000000000000000*var_13; + const double var_62 = -0.0043822843822843822805813*w[0][1]*w[1][1] + -0.0025371453942882515528168*var_35 + -0.0003272917558631844420734*var_41 + -0.0002587888302174016380043*w[0][4]*w[1][4] + 0.0000158571587143015728827*var_61; + const double var_63 = -1.0000000000000000000000000*var_31; + const double var_64 = 0.0031257631257631257604146*var_25 + 0.0082539682539682548284565*var_17 + 0.0117216117216117216015547*var_2 + -0.0531379731379731379270481*w[0][3]*w[1][3] + 0.0072283272283272283209588*var_0; + const double var_65 = -1.0000000000000000000000000*var_26; + const double var_66 = 0.0640781440781440780884992*w[0][5]*w[1][5] + 0.0024420024420024420003239*var_51 + 0.0246153846153846153632649*var_65 + -0.0103540903540903540813733*var_36 + -0.0234432234432234432031095*var_23; + const double var_67 = w[0][1]*w[1][1]; + const double var_68 = -1.0000000000000000000000000*var_67; + const double var_69 = 0.0078144078144078144010365*var_68 + 0.0062515262515262515208292*var_35 + 0.0044932844932844932805960*var_41 + -0.0203174603174603174426949*var_34 + 0.0031257631257631257604146*var_13; + const double var_70 = 0.0164102564102564102421766*var_63 + 0.0078144078144078144010365*var_48 + 0.0097680097680097680012956*var_29 + var_64 + 0.0355555555555555555247160*var_40 + var_69 + 0.0084004884004884004811142*var_32 + 0.0072283272283272283209588*var_21 + var_66; + A[87] = 0.0230880230880230880030624*var_12*var_70; + A[185] = A[87]; + const double var_71 = -1.0000000000000000000000000*var_21; + const double var_72 = -1.0000000000000000000000000*var_32; + const double var_73 = -0.0098568098568098568013074*w[0][0]*w[1][0] + 0.0001871144728287585390098*var_17 + -0.0035520035520035520004711*var_2 + -0.0035317063888492461129487*w[0][3]*w[1][3] + 0.0001243201243201243200165*var_0; + const double var_74 = 8.0000000000000000000000000*w[0][5]*w[1][5]; + const double var_75 = -0.0007814407814407814401036*var_74 + 0.0012660355517498376488883*var_36 + -0.0012685726971441257764084*var_23 + 0.0018159618159618159602409*var_18 + -0.0003184117469831755620722*w[0][2]*w[1][2]; + const double var_76 = 32.0000000000000000000000000*w[0][4]*w[1][4]; + const double var_77 = -1.0000000000000000000000000*var_76; + const double var_78 = -0.0031790431790431790404217*w[0][1]*w[1][1] + -0.0027807113521399239378096*var_35 + 0.0005099662242519385681877*var_41 + 0.0001154401154401154400153*var_77 + 0.0007237207237207237200960*var_13; + const double var_79 = var_75 + 0.0015222872365729508883220*var_48 + 0.0009539666682523825682466*var_31 + 0.0044755244755244755205936*var_71 + -0.0013903556760699619689048*var_29 + 0.0033388833388833388804429*var_72 + var_73 + 0.0007662179090750520244618*var_20 + var_78; + A[145] = 0.2222222222222222098864108*var_12*var_79; + const double var_80 = 0.0090931290931290931212061*w[0][5]*w[1][5] + 0.0005860805860805860800777*var_51 + -0.0022200022200022200002945*var_36 + 0.0002841602841602841600377*var_23 + -0.0058430458430458430407750*w[0][2]*w[1][2]; + const double var_81 = -1.0000000000000000000000000*var_0; + const double var_82 = 0.0020424020424020424002709*var_81 + -0.0000266400266400266400035*w[0][0]*w[1][0] + 0.0009235209235209235201225*var_1 + 0.0006393606393606393600848*var_2 + 0.0008924408924408924401184*var_17; + const double var_83 = 0.0016161616161616161602144*var_67 + 0.0085248085248085248011307*var_35 + 0.0019003219003219003202521*var_41 + 0.0004440004440004440000589*var_77 + 0.0016694416694416694402214*var_13; + const double var_84 = 0.0016339216339216339202167*var_28 + 0.0064646464646464646408575*var_63 + 0.0015096015096015096002002*var_71 + var_82 + var_80 + 0.0006038406038406038400801*var_29 + 0.0062160062160062160008245*var_40 + var_83 + 0.0016872016872016872002238*var_32; + A[74] = 0.1904761904761904656169236*var_12*var_84; + A[214] = A[74]; + const double var_85 = 0.0022732822732822732803015*var_35 + 0.0007636807636807636801013*var_41 + 0.0022377622377622377602968*var_67 + 0.0000666000666000666000088*var_77 + 0.0004617604617604617600612*var_13; + const double var_86 = 0.0031257631257631257604146*var_67 + 0.0117216117216117216015547*var_35 + -0.0531379731379731379270481*w[0][4]*w[1][4] + 0.0072283272283272283209588*var_41 + 0.0082539682539682548284565*var_13; + const double var_87 = -1.0000000000000000000000000*var_25; + const double var_88 = -0.0203174603174603174426949*var_14 + 0.0078144078144078144010365*var_87 + 0.0031257631257631257604146*var_17 + 0.0062515262515262515208292*var_2 + 0.0044932844932844932805960*var_0; + const double var_89 = 0.0072283272283272283209588*var_28 + 0.0355555555555555555247160*var_63 + var_86 + 0.0078144078144078144010365*var_71 + 0.0084004884004884004811142*var_29 + 0.0164102564102564102421766*var_40 + var_88 + 0.0097680097680097680012956*var_32 + var_66; + A[133] = 0.0230880230880230880030624*var_12*var_89; + A[203] = A[133]; + const double var_90 = -4.0000000000000000000000000*var_35 + var_37; + const double var_91 = -1.0000000000000000000000000*var_41; + const double var_92 = -1.0000000000000000000000000*var_19; + const double var_93 = -1.0000000000000000000000000*var_30; + const double var_94 = 0.0507936507936507936067372*var_93 + 0.0058049886621315193932502*var_33 + 0.1269841269841269770779490*var_91 + -0.0609523809523809523280846*var_16 + 0.0736507936507936472603220*var_22 + 0.0031746031746031746004211*var_92 + 0.0101587301587301587213474*var_90 + -0.0346485260770975078692402*var_13 + 0.0472562358276644028931557*var_27 + 0.2336507936507936644687788*var_24 + 0.7706122448979592087781043*w[0][4]*w[1][4] + 0.4000000000000000222044605*var_67; + const double var_95 = var_3 + 0.0002797202797202797200371*var_25 + 0.0009825095539381255207306*var_17 + -0.0059622916765773911057513*w[0][3]*w[1][3] + 0.0006977149834292691119725*var_0; + const double var_96 = 0.0028889628889628891049435*w[0][5]*w[1][5] + 0.0008761608761608762323964*var_23 + 0.0008880008880008880001178*var_45 + -0.0009042809042809043162600*var_18 + 0.0005609205609205609923545*w[0][2]*w[1][2]; + const double var_97 = var_28 + var_21; + const double var_98 = -0.0527117327117327116869916*w[0][5]*w[1][5] + 0.0062515262515262515208292*var_36 + -0.0088800088800088800011778*var_23 + 0.0077389277389277389210265*var_18 + -0.0030946830946830946804105*w[0][2]*w[1][2]; + const double var_99 = -0.0021711621711621711602880*w[0][1]*w[1][1] + -0.0080275280275280275210648*var_35 + 0.0066777666777666777608857*var_41 + 0.0007770007770007770001031*var_77 + 0.0066200466200466200408781*var_13; + const double var_100 = 6.0800000000000000710542736*w[0][3]*w[1][3] + 0.5555555555555555802271783*var_17; + const double var_101 = -0.0494172494172494189412781*var_25 + -0.0019980019980019980002650*var_100 + -0.0258585858585858585634298*var_2 + 0.0022377622377622377602968*var_81; + const double var_102 = 0.0009235209235209235201225*var_40; + const double var_103 = var_101 + 0.0115972915972915972815382*var_28 + 0.0035697635697635697604735*var_31 + 0.0031257631257631257604146*var_29 + 0.0233721833721833721631000*var_72 + var_102 + var_99 + -0.0363014763014763014448150*var_21 + var_98; + const double var_104 = 0.0000126328697757269193798*var_25 + 0.0001480001480001479909846*var_2 + 0.0000643800643800643800085*var_81; + const double var_105 = var_14 + var_34; + const double var_106 = 8.0000000000000000000000000*var_105 + var_74; + const double var_107 = var_2 + var_1; + const double var_108 = 0.0000407000407000407022642*var_41 + 0.0003581603581603581419775*var_35 + 0.0003663532234960806721787*w[0][1]*w[1][1]; + const double var_109 = 0.0000643800643800643800085*var_45 + 0.0000126328697757269193798*var_26 + 0.0001480001480001479909846*var_23; + const double var_110 = var_34 + var_15; + const double var_111 = var_18 + var_13; + const double var_112 = 0.0007814407814407814401036*var_110 + -0.0274725274725274755394100*w[0][0]*w[1][0] + 0.0005209605209605209239290*var_2 + -0.0005895691609977324722583*var_17 + 0.0066608523751380899549646*w[0][3]*w[1][3] + -0.0012617012617012618447276*var_0 + 0.0014855514855514856224772*var_111; + const double var_113 = 0.0909090909090909116141432*var_112; + const double var_114 = 0.0003870203870203870561914*var_28 + 0.0000333000333000333000044*var_63 + var_108 + var_109 + 0.0004662004662004662000618*var_72 + 0.0002115344972487829861181*var_29 + var_113 + -0.0001118458261315404255474*var_20 + -0.0009916009916009914555712*var_21; + const double var_115 = -0.0030946830946830946804105*w[0][0]*w[1][0] + -0.0088800088800088800011778*var_2 + 0.0077389277389277389210265*var_17 + -0.0527117327117327116869916*w[0][3]*w[1][3] + 0.0062515262515262515208292*var_0; + const double var_116 = 0.0009235209235209235201225*var_71; + const double var_117 = 0.0031257631257631257604146*var_28 + var_116 + 0.0233721833721833721631000*var_63 + 0.0115972915972915972815382*var_29 + var_115 + var_47 + -0.0363014763014763014448150*var_20 + 0.0035697635697635697604735*var_32 + var_99; + A[82] = 0.0317460317460317442694873*var_117*var_12; + A[110] = A[82]; + const double var_118 = -0.0015438529724244010564449*w[0][1]*w[1][1] + -0.0007408464551321694482183*var_35 + 0.0005708577137148565560157*var_41 + -0.0018927104641390357208514*w[0][4]*w[1][4] + 0.0005569034140462712041339*var_13; + const double var_119 = -1.0000000000000000000000000*var_58; + const double var_120 = 0.0066777666777666777608857*var_36 + -0.0080275280275280275210648*var_23 + 0.0015540015540015540002061*var_119 + 0.0066200466200466200408781*var_18 + -0.0021711621711621711602880*w[0][2]*w[1][2]; + const double var_121 = -1.0000000000000000000000000*var_29; + const double var_122 = 0.0009235209235209235201225*var_121; + const double var_123 = var_101 + var_42 + 0.0035697635697635697604735*var_28 + var_122 + 0.0115972915972915972815382*var_31 + 0.0233721833721833721631000*var_71 + 0.0031257631257631257604146*var_20 + var_120 + -0.0363014763014763014448150*var_32; + A[100] = 0.0317460317460317442694873*var_12*var_123; + const double var_124 = 0.0000177600177600177600024*var_25 + 0.0010656010656010656001413*var_2 + -0.0031257631257631257604146*w[0][3]*w[1][3] + 0.0001909201909201909200253*var_54 + 0.0001598401598401598400212*var_0; + const double var_125 = 0.0011899211899211899201578*var_74 + 0.0006660006660006660000883*var_51 + -0.0012964812964812964801720*var_36 + -0.0018470418470418470402450*var_23 + -0.0014918414918414918401979*var_26; + const double var_126 = 0.0025574425574425574403392*var_28 + 0.0014918414918414918401979*var_63 + var_125 + 0.0011899211899211899201578*var_71 + 0.0021667221667221667202874*var_29 + 0.0012432012432012432001649*var_40 + var_124 + 0.0004084804084804084800542*var_32 + var_85; + A[88] = 0.2539682539682539541558981*var_12*var_126; + const double var_127 = 0.0002308802308802308800306*var_74 + 0.0012121212121212121201608*var_51 + -0.0031663574520717379691404*var_36 + -0.0220325706039991783824483*var_23 + -0.0144052772624201196743909*w[0][2]*w[1][2]; + const double var_128 = 0.0121212121212121212016077*var_87 + 0.0036940836940836940804900*var_2 + 0.0037105751391465677767323*var_17 + -0.0835126777983920820513930*w[0][3]*w[1][3] + 0.0096969696969696969612862*var_0; + const double var_129 = 0.0020861678004535149852372*var_67 + -0.0130612244897959188516534*var_35 + 0.0013193156050298907120549*var_41 + 0.0036363636363636363604823*var_13 + 0.0002886002886002886000383*var_76; + const double var_130 = 0.0009235209235209235201225*var_72; + const double var_131 = 0.0007586064728921872082207*var_28 + -0.0123026180169037314265923*var_31 + var_127 + 0.0113461142032570613813469*var_29 + var_129 + var_130 + -0.0164914450628736337922664*var_20 + var_128 + 0.0009235209235209235201225*var_21; + A[14] = 0.0085470085470085478684954*var_12*var_131; + A[210] = A[14]; + const double var_132 = -0.0001420801420801420800188*var_35 + 0.0005594405594405594400742*var_41 + -0.0025371453942882515528168*w[0][4]*w[1][4] + 0.0099900099900099900013251*var_67 + 0.0005511948369091225919530*var_13; + const double var_133 = -0.0000355200355200355200047*var_74 + 0.0005594405594405594400742*var_51 + -0.0003158746015888873261319*var_36 + -0.0018927104641390357208514*var_23 + -0.0049950049950049950006625*var_26; + const double var_134 = -0.0022161965019107878090143*var_31; + const double var_135 = 0.0017937617937617937602379*var_28 + var_132 + var_133 + 0.0038006438006438006405041*var_29 + var_4 + -0.0034137291280148421117324*var_20 + 0.0005708577137148565560157*var_32 + var_134 + 0.0001281258424115567010320*var_21; + const double var_136 = var_13 + var_17; + const double var_137 = var_25 + var_67; + const double var_138 = var_35 + var_2; + const double var_139 = var_41 + var_0; + const double var_140 = -4.0000000000000000000000000*var_23 + var_139; + const double var_141 = var_32 + var_29; + const double var_142 = -1.0000000000000000000000000*var_141; + const double var_143 = 0.0000532800532800532800071*var_97 + 0.0343123543123543123245511*var_53 + -0.0505094905094905094466995*var_105 + 0.0009723609723609723601290*var_18 + 0.0644289044289044349200779*w[0][2]*w[1][2] + -0.0012987012987012987001723*var_137 + 0.0014652014652014652001943*var_142 + -0.0079187479187479183073695*var_136 + 0.0039960039960039960005300*var_36 + 0.0020246420246420246402685*w[0][5]*w[1][5] + -0.0103363303363303363213710*var_138 + 0.0011721611721611721601555*var_140; + A[67] = 0.0158730158730158721347436*var_12*var_143; + const double var_144 = -0.0098568098568098568013074*w[0][1]*w[1][1] + -0.0035520035520035520004711*var_35 + -0.0035317063888492461129487*w[0][4]*w[1][4] + 0.0001243201243201243200165*var_41 + 0.0001871144728287585390098*var_13; + const double var_145 = 0.0005099662242519385681877*var_36 + -0.0002308802308802308800306*var_58 + -0.0027807113521399239378096*var_23 + 0.0007237207237207237200960*var_18 + -0.0031790431790431790404217*w[0][2]*w[1][2]; + const double var_146 = -0.0003184117469831755620722*w[0][0]*w[1][0] + -0.0012685726971441257764084*var_2 + 0.0001953601953601953600259*var_43 + 0.0018159618159618159602409*var_17 + 0.0012660355517498376488883*var_0; + const double var_147 = var_146 + -0.0013903556760699619689048*var_31 + 0.0033388833388833388804429*var_48 + 0.0044755244755244755205936*var_121 + 0.0015222872365729508883220*var_40 + 0.0007662179090750520244618*var_32 + var_144 + 0.0009539666682523825682466*var_21 + var_145; + const double var_148 = -0.0025371453942882515528168*w[0][5]*w[1][5] + 0.0005594405594405594400742*var_36 + -0.0001420801420801420800188*var_23 + 0.0005511948369091225919530*var_18 + 0.0099900099900099900013251*var_26; + const double var_149 = -0.0049950049950049950006625*var_25 + -0.0018927104641390357208514*var_2 + 0.0000088800088800088800012*var_43 + -0.0003158746015888873261319*var_0 + 0.0005594405594405594400742*var_54; + const double var_150 = -0.0004871319157033442820946*var_35; + const double var_151 = 0.0003869146726289583661414*var_41 + 0.0000177600177600177600024*var_76 + -0.0002695716981431267220658*w[0][1]*w[1][1] + var_150; + const double var_152 = -0.0022161965019107878090143*var_21; + const double var_153 = 0.0005708577137148565560157*var_28 + 0.0038006438006438006405041*var_31 + var_148 + 0.0001281258424115567010320*var_29 + var_149 + 0.0017937617937617937602379*var_20 + -0.0034137291280148421117324*var_32 + var_152 + var_151; + const double var_154 = var_58 + var_36; + const double var_155 = var_31 + var_28; + const double var_156 = var_23 + var_35; + const double var_157 = var_26 + var_67; + const double var_158 = var_20 + var_29; + const double var_159 = var_32 + var_21; + const double var_160 = var_41 + var_36; + const double var_161 = -0.2500000000000000000000000*var_160 + var_2; + const double var_162 = 9.7111111111111121374506183*var_14 + -1.9722222222222220988641084*var_155 + 7.8888888888888883954564335*var_161 + 3.9444444444444441977282167*var_156 + 0.2277777777777777734602438*var_158 + -0.1138888888888888867301219*var_17 + 15.7777777777777767909128670*var_110 + -7.6250000000000000000000000*var_111 + 30.5000000000000000000000000*var_159 + 2.4277777777777780343626546*var_157 + 191.5000000000000000000000000*w[0][0]*w[1][0]; + const double var_163 = 0.0036940836940836940804900*var_74 + 0.0006393606393606393600848*var_23 + 0.0020424020424020424002709*var_45 + 0.0008924408924408924401184*var_18 + -0.0000266400266400266400035*w[0][2]*w[1][2]; + const double var_164 = 0.0008880008880008880001178*var_81 + 0.0005609205609205609923545*w[0][0]*w[1][0] + -0.0009042809042809043162600*var_17 + 0.0008761608761608762323964*var_2 + 0.0028889628889628891049435*w[0][3]*w[1][3]; + const double var_165 = 0.0007148407148407148400948*var_67 + -0.0008169608169608169601084*var_41 + 0.0075302475302475302409988*w[0][4]*w[1][4] + 0.0010182410182410183124152*var_35 + -0.0010907610907610906878645*var_13; + const double var_166 = 0.0008761608761608762323964*w[0][5]*w[1][5] + 0.0003788803788803788981203*var_36 + 0.0034099234099234099204523*var_23 + 0.0000740000740000739954923*var_18 + 0.0061538461538461538408162*var_26; + const double var_167 = var_165 + 0.0003788803788803788981203*var_28 + var_164 + 0.0051385651385651379824404*var_31 + 0.0002960002960002959819692*var_71 + 0.0002545602545602545781038*var_121 + var_166 + 0.0029836829836829836803958*var_20 + -0.0015924815924815926247715*var_32; + A[53] = 0.1269841269841269770779490*var_12*var_167; + const double var_168 = 0.0005609205609205609923545*w[0][1]*w[1][1] + 0.0028889628889628891049435*w[0][4]*w[1][4] + 0.0008761608761608762323964*var_35 + 0.0008880008880008880001178*var_91 + -0.0009042809042809043162600*var_13; + const double var_169 = 0.0075302475302475302409988*w[0][5]*w[1][5] + -0.0008169608169608169601084*var_36 + 0.0010182410182410183124152*var_23 + -0.0010907610907610906878645*var_18 + 0.0007148407148407148400948*var_26; + const double var_170 = 0.0008761608761608762323964*var_14 + 0.0061538461538461538408162*var_25 + 0.0000740000740000739954923*var_17 + 0.0034099234099234099204523*var_2 + 0.0003788803788803788981203*var_0; + const double var_171 = -0.0015924815924815926247715*var_28 + 0.0002545602545602545781038*var_63 + var_170 + var_169 + 0.0002960002960002959819692*var_121 + 0.0003788803788803788981203*var_20 + 0.0029836829836829836803958*var_32 + var_168 + 0.0051385651385651379824404*var_21; + const double var_172 = 0.1647241647241647344301896*w[0][0]*w[1][0] + 0.0646464646464646464085746*var_2 + 0.0019314019314019314002562*var_17 + 0.0269952269952269952035806*w[0][3]*w[1][3] + 0.0055944055944055944007420*var_0; + const double var_173 = -1.0000000000000000000000000*var_2; + const double var_174 = 0.4259740259740259493703718*w[0][0]*w[1][0] + 0.0038672438672438672405129*var_17 + -0.0092352092352092352012249*var_2 + -0.0711111111111111110494321*w[0][3]*w[1][3] + 0.0121212121212121212016077*var_0; + const double var_175 = -0.0198556998556998556826336*w[0][2]*w[1][2] + 0.0181818181818181809350499*var_51 + -0.0346320346320346320045935*var_23 + -0.0005772005772005772000766*var_154; + const double var_176 = -0.0035786435786435786404747*w[0][1]*w[1][1] + -0.0230880230880230880030624*var_35 + 0.0051948051948051948006890*var_41 + 0.0303030303030303038713811*var_61 + -0.0277056277056277056036748*var_34; + const double var_177 = -0.0005772005772005772000766*var_28 + var_176 + -0.0190476190476190493372499*var_31 + 0.0057720057720057720007656*var_29 + var_175 + -0.0091197691197691197612096*var_20 + 0.1454545454545454474803989*var_32 + var_174 + 0.0727272727272727237401995*var_21; + A[6] = 0.0028490028490028491449382*var_12*var_177; + A[90] = A[6]; + const double var_178 = 0.1647241647241647344301896*w[0][1]*w[1][1] + 0.0646464646464646464085746*var_35 + 0.0055944055944055944007420*var_41 + 0.0269952269952269952035806*w[0][4]*w[1][4] + 0.0019314019314019314002562*var_13; + const double var_179 = 0.0323232323232323232042873*var_74 + -0.0196840196840196851590932*var_36 + 0.0140896140896140907583511*var_23 + -0.0331002331002330993370286*var_18 + 0.0035372035372035369113486*w[0][2]*w[1][2]; + const double var_180 = 0.0206312206312206300462542*w[0][0]*w[1][0] + 0.0281792281792281815167023*var_2 + -0.0128982128982128990690725*var_17 + 0.0013468013468013468724588*var_1 + -0.0126392126392126397799176*var_0; + const double var_181 = 0.1491841491841491840197875*var_28 + var_178 + -0.0052096052096052098898116*var_31 + 0.0497280497280497280065958*var_29 + var_179 + 0.0107744107744107749796703*var_40 + 0.0030784030784030782558480*var_32 + var_180 + -0.0364672364672364648918723*var_21; + A[176] = 0.0253968253968253968033686*var_12*var_181; + const double var_182 = 0.0099900099900099900013251*var_25 + -0.0001420801420801420800188*var_2 + 0.0005511948369091225919530*var_17 + -0.0025371453942882515528168*w[0][3]*w[1][3] + 0.0005594405594405594400742*var_0; + const double var_183 = 0.0005594405594405594400742*var_61 + -0.0049950049950049950006625*var_67 + -0.0018927104641390357208514*var_35 + -0.0003158746015888873261319*var_41 + 0.0000088800088800088800012*var_77; + const double var_184 = -0.0004871319157033442820946*var_23; + const double var_185 = -0.0002695716981431267220658*w[0][2]*w[1][2] + 0.0003869146726289583661414*var_36 + 0.0000355200355200355200047*var_58 + var_184; + const double var_186 = -0.0022161965019107878090143*var_29; + const double var_187 = -0.0034137291280148421117324*var_28 + var_182 + 0.0001281258424115567010320*var_31 + var_183 + var_186 + 0.0005708577137148565560157*var_20 + 0.0017937617937617937602379*var_32 + var_185 + 0.0038006438006438006405041*var_21; + A[11] = 0.0370370370370370349810685*var_12*var_187; + A[165] = A[11]; + const double var_188 = -0.0088888888888888888811790*var_74 + 0.0121212121212121212016077*var_36 + -0.0092352092352092352012249*var_23 + 0.0038672438672438672405129*var_18 + 0.4259740259740259493703718*w[0][2]*w[1][2]; + const double var_189 = var_57 + 0.0057720057720057720007656*var_28 + var_176 + 0.1454545454545454474803989*var_31 + -0.0005772005772005772000766*var_29 + 0.0727272727272727237401995*var_20 + -0.0190476190476190493372499*var_32 + var_188 + -0.0091197691197691197612096*var_21; + A[38] = 0.0028490028490028491449382*var_12*var_189; + const double var_190 = var_165 + var_96 + var_170 + -0.0015924815924815926247715*var_31 + 0.0002545602545602545781038*var_48 + 0.0003788803788803788981203*var_29 + 0.0002960002960002959819692*var_40 + 0.0051385651385651379824404*var_32 + 0.0029836829836829836803958*var_21; + A[101] = 0.1269841269841269770779490*var_12*var_190; + const double var_191 = -0.0015438529724244010564449*w[0][0]*w[1][0] + 0.0005569034140462712041339*var_17 + -0.0007408464551321694482183*var_2 + -0.0018927104641390357208514*w[0][3]*w[1][3] + 0.0005708577137148565560157*var_0; + const double var_192 = -0.0059622916765773911057513*w[0][5]*w[1][5] + 0.0006977149834292691119725*var_36 + var_184 + 0.0009825095539381255207306*var_18 + 0.0002797202797202797200371*var_26; + const double var_193 = -0.0039642896785753931054863*var_28 + 0.0001154401154401154400153*var_31 + var_186 + var_192 + var_62 + var_191 + 0.0005594405594405594400742*var_20 + -0.0003793032364460936041103*var_32 + 0.0007319664462521605682171*var_21; + const double var_194 = var_160 + -4.0000000000000000000000000*var_2; + const double var_195 = -0.0022161965019107878090143*var_20; + const double var_196 = -1.0000000000000000000000000*var_136; + const double var_197 = var_140 + var_53; + const double var_198 = var_105 + var_138; + const double var_199 = 0.0103896103896103896013781*var_197 + -0.3495171495171495168463593*w[0][5]*w[1][5] + 0.0282384282384282384037455*var_97 + 0.0001332001332001332000177*var_65 + 0.0258408258408258408034275*var_36 + 0.0205128205128205128027208*var_137 + -0.0076590076590076590010159*var_18 + 0.0050616050616050616006714*var_196 + -0.0724608724608724608096111*var_198 + 0.0202464202464202464026854*var_141; + A[164] = 0.0126984126984126984016843*var_12*var_199; + A[220] = A[164]; + A[49] = 0.2222222222222222098864108*var_12*var_147; + A[63] = A[49]; + const double var_200 = var_45 + var_91 + 4.0000000000000000000000000*var_2; + const double var_201 = -1.0000000000000000000000000*var_155; + const double var_202 = 0.0000837257980115123010261*var_81 + 0.0030141287284144425116794*var_156 + -0.0005767777196348625482966*var_158 + 0.0002674574103145531921155*var_17 + 0.0013954299668585382239450*var_201 + 0.0008465608465608465962524*var_25 + 0.0075911390197104479035661*var_110 + 0.0014233385661957091445490*var_200 + -0.0002348973777545206411462*var_111 + 0.0028280713994999710086953*w[0][3]*w[1][3] + 0.0009116809116809116439809*var_159 + 0.0004000232571661143602532*var_157; + A[192] = 2.9090909090909091716525836*var_12*var_202; + const double var_203 = -1.0000000000000000000000000*var_35; + const double var_204 = 0.0246153846153846153632649*var_68 + 0.0024420024420024420003239*var_61 + -0.0103540903540903540813733*var_41 + 0.0640781440781440780884992*w[0][4]*w[1][4] + 0.0234432234432234432031095*var_203; + const double var_205 = -0.0531379731379731379270481*w[0][5]*w[1][5] + 0.0072283272283272283209588*var_36 + 0.0117216117216117216015547*var_23 + 0.0082539682539682548284565*var_18 + 0.0031257631257631257604146*var_26; + const double var_206 = 0.0072283272283272283209588*var_31 + 0.0355555555555555555247160*var_48 + 0.0078144078144078144010365*var_72 + 0.0164102564102564102421766*var_121 + var_204 + var_205 + var_88 + 0.0084004884004884004811142*var_20 + 0.0097680097680097680012956*var_21; + A[179] = 0.0230880230880230880030624*var_12*var_206; + const double var_207 = var_23 + -0.2500000000000000000000000*var_139; + const double var_208 = 9.7111111111111121374506183*var_15 + 0.2277777777777777734602438*var_97 + 30.5000000000000000000000000*var_53 + 15.7777777777777767909128670*var_105 + -0.1138888888888888867301219*var_18 + 191.5000000000000000000000000*w[0][2]*w[1][2] + 2.4277777777777780343626546*var_137 + -1.9722222222222220988641084*var_141 + -7.6250000000000000000000000*var_136 + 3.9444444444444441977282167*var_138 + 7.8888888888888883954564335*var_207; + const double var_209 = -0.0035317063888492461129487*w[0][5]*w[1][5] + 0.0001243201243201243200165*var_36 + -0.0035520035520035520004711*var_23 + 0.0001871144728287585390098*var_18 + -0.0098568098568098568013074*w[0][2]*w[1][2]; + const double var_210 = -0.0003184117469831755620722*w[0][1]*w[1][1] + -0.0012685726971441257764084*var_35 + 0.0012660355517498376488883*var_41 + 0.0001953601953601953600259*var_77 + 0.0018159618159618159602409*var_13; + const double var_211 = -0.0031790431790431790404217*w[0][0]*w[1][0] + 0.0007237207237207237200960*var_17 + -0.0027807113521399239378096*var_2 + 0.0001154401154401154400153*var_43 + 0.0005099662242519385681877*var_0; + const double var_212 = 0.0007662179090750520244618*var_28 + 0.0044755244755244755205936*var_63 + var_209 + 0.0015222872365729508883220*var_72 + 0.0009539666682523825682466*var_29 + var_211 + 0.0033388833388833388804429*var_40 + var_210 + -0.0013903556760699619689048*var_21; + A[113] = 0.2222222222222222098864108*var_12*var_212; + A[127] = A[113]; + const double var_213 = 0.0001484230055658626969747*var_74 + -0.0005784691498977213722568*var_36 + 0.0018267446838875409358821*var_23 + 0.0000038057180914323772039*var_18 + -0.0065268065268065268008657*w[0][2]*w[1][2]; + const double var_214 = 0.0000152228723657295088155*var_81 + -0.0006602920888635174963277*w[0][0]*w[1][0] + 0.0000285428856857428271232*var_1 + 0.0008011036582465154041663*var_17 + 0.0029532372389515248491121*var_2; + const double var_215 = 0.0005194805194805194800689*var_67 + 0.0011873840445269015757973*var_35 + -0.0008981494695780410522992*var_41 + 0.0009495266638123781282460*var_13 + 0.0005232862375719518881895*var_76; + const double var_216 = -0.0039579468150896723530052*var_31 + 0.0000152228723657295088155*var_48 + var_214 + 0.0007383093097378812122780*var_72 + 0.0002816231387659959240974*var_29 + var_213 + -0.0035012606441177868479842*var_20 + var_215 + -0.0005784691498977213722568*var_21; + const double var_217 = -1.0000000000000000000000000*var_111; + const double var_218 = -1.0000000000000000000000000*var_159; + const double var_219 = 0.0736507936507936472603220*var_155 + 0.1269841269841269770779490*var_81 + 0.2336507936507936644687788*var_156 + 0.0058049886621315193932502*var_158 + -0.0346485260770975078692402*var_17 + 0.4000000000000000222044605*var_25 + 0.0101587301587301587213474*var_194 + -0.0609523809523809523280846*var_110 + 0.0507936507936507936067372*var_218 + 0.7706122448979592087781043*w[0][3]*w[1][3] + 0.0031746031746031746004211*var_217 + 0.0472562358276644028931557*var_157; + const double var_220 = 0.0003663532234960806721787*w[0][2]*w[1][2] + 0.0003581603581603581419775*var_23 + 0.0000407000407000407022642*var_36; + const double var_221 = -0.0274725274725274755394100*w[0][1]*w[1][1] + 0.0066608523751380899549646*w[0][4]*w[1][4] + 0.0005209605209605209239290*var_35 + -0.0012617012617012618447276*var_41 + 0.0007814407814407814401036*var_16 + -0.0005895691609977324722583*var_13 + 0.0014855514855514856224772*var_19; + const double var_222 = 0.0909090909090909116141432*var_221; + const double var_223 = 0.0004662004662004662000618*var_48 + 0.0002115344972487829861181*var_31 + 0.0000333000333000333000044*var_71 + var_220 + -0.0009916009916009914555712*var_29 + var_104 + 0.0003870203870203870561914*var_20 + -0.0001118458261315404255474*var_32 + var_222; + const double var_224 = 0.0020931449502878075527579*var_74 + -0.0008981494695780410522992*var_36 + 0.0011873840445269015757973*var_23 + 0.0009495266638123781282460*var_18 + 0.0005194805194805194800689*var_26; + const double var_225 = -0.0022161965019107878090143*var_28; + const double var_226 = 0.0017937617937617937602379*var_31 + var_148 + var_183 + -0.0034137291280148421117324*var_29 + var_4 + 0.0038006438006438006405041*var_20 + 0.0001281258424115567010320*var_32 + var_225 + 0.0005708577137148565560157*var_21; + A[33] = 0.0370370370370370349810685*var_12*var_226; + A[47] = A[33]; + const double var_227 = 0.5555555555555555802271783*var_13 + 6.0800000000000000710542736*w[0][4]*w[1][4]; + const double var_228 = 0.0022377622377622377602968*var_91 + -0.0258585858585858585634298*var_35 + -0.0494172494172494189412781*var_67 + -0.0019980019980019980002650*var_227; + const double var_229 = 0.0009235209235209235201225*var_63; + const double var_230 = -0.0363014763014763014448150*var_28 + var_44 + 0.0233721833721833721631000*var_121 + 0.0035697635697635697604735*var_20 + var_229 + 0.0031257631257631257604146*var_32 + var_228 + 0.0115972915972915972815382*var_21 + var_98; + const double var_231 = -0.0018927104641390357208514*w[0][5]*w[1][5] + 0.0005708577137148565560157*var_36 + -0.0007408464551321694482183*var_23 + 0.0005569034140462712041339*var_18 + -0.0015438529724244010564449*w[0][2]*w[1][2]; + const double var_232 = 0.0002797202797202797200371*var_67 + 0.0006977149834292691119725*var_41 + -0.0059622916765773911057513*w[0][4]*w[1][4] + var_150 + 0.0009825095539381255207306*var_13; + const double var_233 = 0.0005594405594405594400742*var_28 + var_232 + 0.0007319664462521605682171*var_31 + 0.0001154401154401154400153*var_29 + -0.0003793032364460936041103*var_20 + -0.0039642896785753931054863*var_32 + var_231 + var_152 + var_55; + const double var_234 = var_30 + var_90; + const double var_235 = var_16 + var_24; + const double var_236 = -0.0724608724608724608096111*var_235 + 0.0001332001332001332000177*var_68 + 0.0205128205128205128027208*var_27 + 0.0258408258408258408034275*var_41 + -0.3495171495171495168463593*w[0][4]*w[1][4] + 0.0103896103896103896013781*var_234 + 0.0282384282384282384037455*var_33 + 0.0050616050616050616006714*var_92 + -0.0076590076590076590010159*var_13 + 0.0202464202464202464026854*var_22; + A[118] = 0.0126984126984126984016843*var_12*var_236; + const double var_237 = -1.0000000000000000000000000*var_53; + const double var_238 = 0.0058049886621315193932502*var_97 + 0.0031746031746031746004211*var_196 + 0.4000000000000000222044605*var_26 + 0.0507936507936507936067372*var_237 + -0.0609523809523809523280846*var_105 + -0.0346485260770975078692402*var_18 + 0.0472562358276644028931557*var_137 + 0.0736507936507936472603220*var_141 + 0.7706122448979592087781043*w[0][5]*w[1][5] + 0.2336507936507936644687788*var_138 + 0.1269841269841269770779490*var_45 + 0.0101587301587301587213474*var_140; + A[44] = 0.0007770007770007770001031*var_12*var_238; + A[212] = A[44]; + const double var_239 = -0.0038150738150738152873465*var_33 + 0.0005794205794205794200769*var_30 + 0.0004995004995004995000663*var_16 + -0.0022610722610722612871403*var_22 + 0.0018253968253968255036623*w[0][1]*w[1][1] + 0.0003890553890553890550516*var_19 + 0.0019391719391719391702572*var_13 + -0.0136013986013986017120647*var_27 + -0.0000022200022200022200003*var_24 + 0.0005017205017205017200665*var_38 + 0.0001265401265401265400168*var_41 + -0.0048151848151848156143195*w[0][4]*w[1][4]; + A[2] = 0.0052910052910052907115812*var_12*var_239; + A[30] = A[2]; + const double var_240 = -0.0022161965019107878090143*var_32; + const double var_241 = 0.0007319664462521605682171*var_28 + 0.0005594405594405594400742*var_31 + var_240 + var_192 + -0.0003793032364460936041103*var_29 + 0.0001154401154401154400153*var_20 + var_118 + var_55 + -0.0039642896785753931054863*var_21; + A[39] = 0.0370370370370370349810685*var_12*var_241; + const double var_242 = var_91 + 4.0000000000000000000000000*var_23 + var_81; + const double var_243 = -0.0001573030144458716040809*var_97 + 0.0010256410256410256401360*var_196 + 0.0002854288568574282780078*var_46 + 0.0042624042624042624005654*var_53 + 0.0055411255411255411207350*var_105 + 0.0070596070596070596009364*w[0][2]*w[1][2] + 0.0003761318047032332820799*var_137 + 0.0009235209235209235201225*var_242 + -0.0010833610833610833601437*var_141 + 0.0003196803196803196800424*var_36 + 0.0012076812076812076801602*var_138; + A[83] = 0.2962962962962962798485478*var_12*var_243; + A[125] = A[83]; + const double var_244 = var_45 + 4.0000000000000000000000000*var_35 + var_81; + const double var_245 = -0.0001573030144458716040809*var_33 + 0.0002854288568574282780078*var_227 + 0.0042624042624042624005654*var_30 + 0.0055411255411255411207350*var_16 + -0.0010833610833610833601437*var_22 + 0.0070596070596070596009364*w[0][1]*w[1][1] + 0.0010256410256410256401360*var_92 + 0.0009235209235209235201225*var_244 + 0.0003761318047032332820799*var_27 + 0.0012076812076812076801602*var_24 + 0.0003196803196803196800424*var_41; + const double var_246 = 0.0234432234432234432031095*var_173 + 0.0246153846153846153632649*var_87 + 0.0640781440781440780884992*w[0][3]*w[1][3] + -0.0103540903540903540813733*var_0 + 0.0024420024420024420003239*var_54; + const double var_247 = -1.0000000000000000000000000*var_74; + const double var_248 = 0.0078144078144078144010365*var_65 + 0.0044932844932844932805960*var_36 + 0.0062515262515262515208292*var_23 + 0.0025396825396825396803369*var_247 + 0.0031257631257631257604146*var_18; + const double var_249 = 0.0084004884004884004811142*var_28 + 0.0097680097680097680012956*var_31 + var_86 + 0.0164102564102564102421766*var_71 + var_248 + 0.0355555555555555555247160*var_72 + 0.0072283272283272283209588*var_29 + 0.0078144078144078144010365*var_40 + var_246; + A[103] = 0.0230880230880230880030624*var_12*var_249; + A[201] = A[103]; + const double var_250 = -0.0277056277056277056036748*var_14 + -0.0035786435786435786404747*w[0][0]*w[1][0] + -0.0230880230880230880030624*var_2 + 0.0303030303030303038713811*var_54 + 0.0051948051948051948006890*var_0; + const double var_251 = 0.0727272727272727237401995*var_28 + var_250 + -0.0091197691197691197612096*var_31 + 0.1454545454545454474803989*var_29 + var_175 + -0.0190476190476190493372499*var_20 + 0.0057720057720057720007656*var_32 + var_56 + -0.0005772005772005772000766*var_21; + const double var_252 = var_35 + var_76; + const double var_253 = -0.0022200022200022200002945*var_41 + 0.0002841602841602841600377*var_252 + -0.0058430458430458430407750*w[0][1]*w[1][1] + 0.0005860805860805860800777*var_61; + A[18] = 0.0028490028490028491449382*var_12*var_251; + A[46] = A[18]; + const double var_254 = 0.0001909201909201909200253*var_61 + 0.0010656010656010656001413*var_35 + -0.0031257631257631257604146*w[0][4]*w[1][4] + 0.0001598401598401598400212*var_41 + 0.0000177600177600177600024*var_67; + const double var_255 = 0.0018470418470418470402450*var_173 + 0.0014918414918414918401979*var_87 + 0.0095193695193695193612626*w[0][3]*w[1][3] + -0.0012964812964812964801720*var_0 + 0.0006660006660006660000883*var_54; + const double var_256 = 0.0007636807636807636801013*var_36 + 0.0022732822732822732803015*var_23 + 0.0002664002664002664000353*var_247 + 0.0004617604617604617600612*var_18 + 0.0022377622377622377602968*var_26; + const double var_257 = 0.0004084804084804084800542*var_28 + 0.0021667221667221667202874*var_31 + 0.0014918414918414918401979*var_71 + 0.0012432012432012432001649*var_72 + 0.0011899211899211899201578*var_121 + var_256 + var_254 + 0.0025574425574425574403392*var_20 + var_255; + A[104] = 0.2539682539682539541558981*var_12*var_257; + const double var_258 = var_159 + var_194; + const double var_259 = var_156 + var_110; + const double var_260 = -0.0724608724608724608096111*var_259 + 0.0282384282384282384037455*var_158 + 0.0205128205128205128027208*var_157 + 0.0001332001332001332000177*var_87 + -0.0076590076590076590010159*var_17 + 0.0050616050616050616006714*var_217 + -0.3495171495171495168463593*w[0][3]*w[1][3] + 0.0202464202464202464026854*var_155 + 0.0103896103896103896013781*var_258 + 0.0258408258408258408034275*var_0; + A[72] = 0.0126984126984126984016843*var_12*var_260; + A[184] = A[72]; + const double var_261 = -0.0000253714539428825152571*var_25 + -0.0006089148946291803119607*var_2 + 0.0001554001554001554000206*var_1 + -0.0012812584241155670645301*var_0 + 0.0011544011544011544001531*var_54; + const double var_262 = 0.0269952269952269952035806*w[0][5]*w[1][5] + 0.0055944055944055944007420*var_36 + 0.0646464646464646464085746*var_23 + 0.0019314019314019314002562*var_18 + 0.1647241647241647344301896*w[0][2]*w[1][2]; + const double var_263 = 0.0206312206312206300462542*w[0][1]*w[1][1] + 0.0281792281792281815167023*var_35 + -0.0126392126392126397799176*var_41 + -0.0128982128982128990690725*var_13 + 0.0013468013468013468724588*var_76; + const double var_264 = 0.0035372035372035369113486*w[0][0]*w[1][0] + 0.0080808080808080808010718*var_1 + 0.0140896140896140907583511*var_2 + -0.0331002331002330993370286*var_17 + -0.0196840196840196851590932*var_0; + const double var_265 = 0.0030784030784030782558480*var_28 + var_262 + var_264 + 0.0497280497280497280065958*var_31 + var_263 + -0.0364672364672364648918723*var_29 + 0.0107744107744107749796703*var_72 + 0.1491841491841491840197875*var_20 + -0.0052096052096052098898116*var_21; + A[36] = 0.0370370370370370349810685*var_12*var_153; + A[92] = A[36]; + const double var_266 = 0.0053280053280053280007067*var_67 + 0.0049728049728049728006596*var_35 + 0.0015096015096015096002002*var_41 + -0.0045668617097188524481255*var_34 + 0.0005010862153719296881865*var_13; + const double var_267 = 0.0012432012432012432001649*var_74 + -0.0012051440622869195526401*var_36 + -0.0004566861709718852339705*var_23 + -0.0013542013542013542001796*var_18 + 0.0001395429966858538169735*var_26; + const double var_268 = 0.0069264069264069264009187*var_28 + 0.0001141715427429713084926*var_31 + var_267 + 0.0046176046176046176006125*var_29 + var_266 + var_261 + -0.0012812584241155670645301*var_20 + -0.0006089148946291803119607*var_32 + -0.0027147455718884291528403*var_21; + A[178] = 0.3555555555555555691249481*var_12*var_268; + const double var_269 = 0.0031257631257631257604146*var_31 + 0.0233721833721833721631000*var_48 + -0.0363014763014763014448150*var_29 + var_130 + var_115 + var_120 + 0.0115972915972915972815382*var_20 + var_228 + 0.0035697635697635697604735*var_21; + A[55] = 0.0317460317460317442694873*var_12*var_269; + A[153] = A[55]; + const double var_270 = 0.0336019536019536019244569*var_15 + 0.0125030525030525030416584*var_97 + 0.0117216117216117216015547*var_53 + 0.0672039072039072038489138*var_105 + -0.0086935286935286935211531*var_18 + 0.0669108669108669090741515*w[0][2]*w[1][2] + 0.0297435897435897426965834*var_137 + 0.0046886446886446886406219*var_242 + 0.0380952380952380986744998*var_141 + -0.0136263736263736272291691*var_136 + 0.0289133089133089132838350*var_138 + 0.0097680097680097680012956*var_45; + A[51] = 0.0038480038480038481450707*var_12*var_270; + const double var_271 = -0.0144052772624201196743909*w[0][0]*w[1][0] + 0.0000577200577200577200077*var_1 + -0.0220325706039991783824483*var_2 + -0.0031663574520717379691404*var_0 + 0.0012121212121212121201608*var_54; + const double var_272 = 0.0121212121212121212016077*var_68 + 0.0036940836940836940804900*var_35 + 0.0096969696969696969612862*var_41 + -0.0835126777983920820513930*w[0][4]*w[1][4] + 0.0037105751391465677767323*var_13; + const double var_273 = 0.0011544011544011544001531*var_74 + 0.0013193156050298907120549*var_36 + -0.0130612244897959188516534*var_23 + 0.0036363636363636363604823*var_18 + 0.0020861678004535149852372*var_26; + const double var_274 = var_49 + 0.0113461142032570613813469*var_31 + var_273 + var_272 + 0.0009235209235209235201225*var_29 + var_271 + 0.0007586064728921872082207*var_20 + -0.0164914450628736337922664*var_32 + -0.0123026180169037314265923*var_21; + A[27] = 0.0085470085470085478684954*var_12*var_274; + A[52] = 0.0740740740740740699621369*var_12*var_216; + A[108] = A[52]; + const double var_275 = 0.0225699168556311412225934*var_155 + 0.0268329554043839763055601*var_158 + -0.0261224489795918377033068*var_156 + -0.0107482993197278910851855*var_17 + 0.0044444444444444444405895*var_25 + 0.0023885109599395314486370*var_194 + -0.0061073318216175358566500*var_110 + -0.0058125472411186696747309*var_111 + 0.0106727135298563865356547*var_0 + -0.1936810279667422474147997*w[0][3]*w[1][3] + 0.0030687830687830689249673*var_159 + 0.0418065003779289484642234*var_157; + A[4] = 0.0023310023310023310003092*var_12*var_275; + const double var_276 = -0.0045668617097188524481255*var_14 + 0.0053280053280053280007067*var_25 + 0.0049728049728049728006596*var_2 + 0.0005010862153719296881865*var_17 + 0.0015096015096015096002002*var_0; + const double var_277 = 0.0011544011544011544001531*var_51 + 0.0006216006216006216000824*var_74 + -0.0012812584241155670645301*var_36 + -0.0006089148946291803119607*var_23 + -0.0000253714539428825152571*var_26; + const double var_278 = 0.0001395429966858538169735*var_67 + -0.0004566861709718852339705*var_35 + -0.0012051440622869195526401*var_41 + -0.0013542013542013542001796*var_13 + 0.0003108003108003108000412*var_76; + const double var_279 = -0.0012812584241155670645301*var_28 + -0.0027147455718884291528403*var_31 + var_278 + 0.0001141715427429713084926*var_29 + -0.0006089148946291803119607*var_20 + var_277 + 0.0069264069264069264009187*var_32 + 0.0046176046176046176006125*var_21 + var_276; + A[41] = 0.0370370370370370349810685*var_12*var_193; + A[167] = A[41]; + const double var_280 = var_182 + 0.0001281258424115567010320*var_28 + -0.0034137291280148421117324*var_31 + var_133 + 0.0005708577137148565560157*var_29 + var_195 + 0.0038006438006438006405041*var_32 + var_151 + 0.0017937617937617937602379*var_21; + A[8] = 0.0370370370370370349810685*var_12*var_280; + const double var_281 = 0.0014918414918414918401979*var_68 + 0.0006660006660006660000883*var_61 + -0.0012964812964812964801720*var_41 + 0.0095193695193695193612626*w[0][4]*w[1][4] + 0.0018470418470418470402450*var_203; + const double var_282 = var_281 + 0.0014918414918414918401979*var_48 + 0.0025574425574425574403392*var_31 + 0.0011899211899211899201578*var_72 + 0.0012432012432012432001649*var_121 + var_256 + 0.0021667221667221667202874*var_20 + var_124 + 0.0004084804084804084800542*var_21; + const double var_283 = 0.0009539666682523825682466*var_28 + 0.0015222872365729508883220*var_63 + 0.0033388833388833388804429*var_71 + 0.0044755244755244755205936*var_72 + 0.0007662179090750520244618*var_29 + var_73 + -0.0013903556760699619689048*var_20 + var_210 + var_145; + A[56] = 0.2962962962962962798485478*var_12*var_245; + const double var_284 = 0.0000643800643800643800085*var_91 + 0.0001480001480001479909846*var_35 + 0.0000126328697757269193798*var_67; + const double var_285 = 0.0003870203870203870561914*var_31 + 0.0000333000333000333000044*var_48 + 0.0004662004662004662000618*var_71 + var_220 + -0.0001118458261315404255474*var_29 + var_284 + var_113 + 0.0002115344972487829861181*var_20 + -0.0009916009916009914555712*var_32; + const double var_286 = -0.0000253714539428825152571*var_67 + -0.0006089148946291803119607*var_35 + -0.0012812584241155670645301*var_41 + 0.0011544011544011544001531*var_61 + 0.0001554001554001554000206*var_76; + const double var_287 = -0.0027147455718884291528403*var_28 + -0.0012812584241155670645301*var_31 + var_267 + var_286 + -0.0006089148946291803119607*var_29 + 0.0001141715427429713084926*var_20 + 0.0046176046176046176006125*var_32 + 0.0069264069264069264009187*var_21 + var_276; + A[147] = 0.3555555555555555691249481*var_12*var_287; + A[181] = A[27]; + const double var_288 = 0.0022377622377622377602968*var_25 + 0.0022732822732822732803015*var_2 + 0.0000666000666000666000088*var_43 + 0.0004617604617604617600612*var_17 + 0.0007636807636807636801013*var_0; + const double var_289 = 0.0012432012432012432001649*var_63 + var_125 + 0.0011899211899211899201578*var_48 + 0.0004084804084804084800542*var_29 + 0.0014918414918414918401979*var_40 + var_254 + var_288 + 0.0021667221667221667202874*var_32 + 0.0025574425574425574403392*var_21; + const double var_290 = 0.0011873840445269015757973*var_14 + -0.0065268065268065268008657*w[0][0]*w[1][0] + 0.0000038057180914323772039*var_17 + 0.0018267446838875409358821*var_2 + -0.0005784691498977213722568*var_0; + const double var_291 = 0.0001141715427429713084926*var_74 + 0.0029532372389515248491121*var_23 + 0.0000152228723657295088155*var_45 + 0.0008011036582465154041663*var_18 + -0.0006602920888635174963277*w[0][2]*w[1][2]; + const double var_292 = 0.0002816231387659959240974*var_28 + 0.0007383093097378812122780*var_63 + var_291 + 0.0000152228723657295088155*var_121 + var_215 + var_290 + -0.0005784691498977213722568*var_20 + -0.0039579468150896723530052*var_32 + -0.0035012606441177868479842*var_21; + A[116] = 0.0740740740740740699621369*var_12*var_292; + const double var_293 = -0.0835126777983920820513930*w[0][5]*w[1][5] + 0.0121212121212121212016077*var_65 + 0.0096969696969696969612862*var_36 + 0.0036940836940836940804900*var_23 + 0.0037105751391465677767323*var_18; + const double var_294 = 0.0113461142032570613813469*var_28 + var_129 + 0.0007586064728921872082207*var_29 + var_271 + var_293 + 0.0009235209235209235201225*var_20 + -0.0123026180169037314265923*var_32 + var_229 + -0.0164914450628736337922664*var_21; + const double var_295 = -0.0364672364672364648918723*var_28 + var_172 + 0.0107744107744107749796703*var_63 + var_263 + 0.0030784030784030782558480*var_29 + var_179 + -0.0052096052096052098898116*var_20 + 0.0497280497280497280065958*var_32 + 0.1491841491841491840197875*var_21; + const double var_296 = 0.0007148407148407148400948*var_25 + -0.0010907610907610906878645*var_17 + 0.0010182410182410183124152*var_2 + 0.0075302475302475302409988*w[0][3]*w[1][3] + -0.0008169608169608169601084*var_0; + const double var_297 = 0.0061538461538461538408162*var_67 + 0.0003788803788803788981203*var_41 + 0.0034099234099234099204523*var_35 + 0.0008761608761608762323964*var_34 + 0.0000740000740000739954923*var_13; + const double var_298 = 0.0029836829836829836803958*var_28 + 0.0002960002960002959819692*var_63 + var_96 + var_297 + 0.0002545602545602545781038*var_71 + 0.0051385651385651379824404*var_29 + -0.0015924815924815926247715*var_20 + 0.0003788803788803788981203*var_32 + var_296; + A[32] = 0.0000074000074000073997186*var_12*var_208; + const double var_299 = 0.0000407000407000407022642*var_0 + 0.0003663532234960806721787*w[0][0]*w[1][0] + 0.0003581603581603581419775*var_2; + const double var_300 = 0.0005194805194805194800689*var_25 + 0.0011873840445269015757973*var_2 + 0.0009495266638123781282460*var_17 + 0.0005232862375719518881895*var_1 + -0.0008981494695780410522992*var_0; + const double var_301 = -0.0005708577137148565560157*var_74 + 0.0015096015096015096002002*var_36 + 0.0049728049728049728006596*var_23 + 0.0005010862153719296881865*var_18 + 0.0053280053280053280007067*var_26; + const double var_302 = -0.0000266400266400266400035*w[0][1]*w[1][1] + 0.0006393606393606393600848*var_35 + 0.0020424020424020424002709*var_91 + 0.0008924408924408924401184*var_13 + 0.0009235209235209235201225*var_76; + const double var_303 = 0.0016161616161616161602144*var_25 + 0.0085248085248085248011307*var_2 + 0.0016694416694416694402214*var_17 + 0.0004440004440004440000589*var_43 + 0.0019003219003219003202521*var_0; + const double var_304 = 0.0062160062160062160008245*var_63 + var_302 + 0.0015096015096015096002002*var_48 + var_303 + var_80 + 0.0016872016872016872002238*var_29 + 0.0064646464646464646408575*var_40 + 0.0006038406038406038400801*var_32 + 0.0016339216339216339202167*var_21; + const double var_305 = 0.0012121212121212121201608*var_61 + -0.0144052772624201196743909*w[0][1]*w[1][1] + -0.0031663574520717379691404*var_41 + -0.0220325706039991783824483*var_35 + 0.0000577200577200577200077*var_76; + const double var_306 = 0.0020861678004535149852372*var_25 + 0.0002886002886002886000383*var_1 + 0.0036363636363636363604823*var_17 + -0.0130612244897959188516534*var_2 + 0.0013193156050298907120549*var_0; + const double var_307 = -0.0164914450628736337922664*var_28 + 0.0009235209235209235201225*var_31 + var_305 + -0.0123026180169037314265923*var_29 + var_293 + var_102 + 0.0007586064728921872082207*var_32 + var_306 + 0.0113461142032570613813469*var_21; + const double var_308 = -0.0142080142080142080018845*w[0][5]*w[1][5] + 0.0019003219003219003202521*var_36 + 0.0085248085248085248011307*var_23 + 0.0016694416694416694402214*var_18 + 0.0016161616161616161602144*var_26; + const double var_309 = 0.0016339216339216339202167*var_31 + 0.0064646464646464646408575*var_48 + var_253 + var_82 + var_308 + 0.0062160062160062160008245*var_121 + 0.0015096015096015096002002*var_72 + 0.0006038406038406038400801*var_20 + 0.0016872016872016872002238*var_21; + A[73] = 0.1904761904761904656169236*var_12*var_309; + const double var_310 = -0.0065268065268065268008657*w[0][1]*w[1][1] + 0.0018267446838875409358821*var_35 + -0.0005784691498977213722568*var_41 + 0.0011873840445269015757973*var_34 + 0.0000038057180914323772039*var_13; + const double var_311 = -0.0039579468150896723530052*var_28 + 0.0000152228723657295088155*var_63 + var_224 + var_310 + var_214 + 0.0007383093097378812122780*var_71 + -0.0035012606441177868479842*var_29 + 0.0002816231387659959240974*var_20 + -0.0005784691498977213722568*var_32; + const double var_312 = -0.0023088023088023088003062*var_33 + 0.0019536019536019536002591*var_30 + -0.0184704184704184704024499*var_16 + -0.0026640026640026640003533*var_22 + -0.0000888000888000888000118*w[0][1]*w[1][1] + 0.0013320013320013320001767*var_90 + 0.0005106005106005106000677*var_19 + 0.0009546009546009546001266*var_13 + -0.0018648018648018648002473*var_27 + -0.0010656010656010656001413*var_24 + -0.0007992007992007992001060*var_41 + 0.0156288156288156288020730*w[0][4]*w[1][4]; + A[194] = 0.3047619047619047893959987*var_12*var_312; + A[59] = 0.2539682539682539541558981*var_12*var_282; + A[213] = A[59]; + const double var_313 = -0.0026640026640026640003533*var_155 + -0.0010656010656010656001413*var_156 + -0.0023088023088023088003062*var_158 + 0.0009546009546009546001266*var_17 + 0.0013320013320013320001767*var_194 + -0.0184704184704184704024499*var_110 + 0.0005106005106005106000677*var_111 + -0.0007992007992007992001060*var_0 + 0.0156288156288156288020730*w[0][3]*w[1][3] + 0.0019536019536019536002591*var_159 + -0.0018648018648018648002473*var_157 + -0.0000888000888000888000118*w[0][0]*w[1][0]; + const double var_314 = -0.0006602920888635174963277*w[0][1]*w[1][1] + 0.0029532372389515248491121*var_35 + 0.0000152228723657295088155*var_91 + 0.0008011036582465154041663*var_13 + 0.0000285428856857428271232*var_76; + const double var_315 = var_314 + var_224 + 0.0007383093097378812122780*var_48 + 0.0002816231387659959240974*var_31 + -0.0005784691498977213722568*var_29 + 0.0000152228723657295088155*var_40 + var_290 + -0.0035012606441177868479842*var_32 + -0.0039579468150896723530052*var_21; + A[130] = 0.0740740740740740699621369*var_12*var_315; + A[158] = A[130]; + const double var_316 = -0.0009916009916009914555712*var_28 + -0.0001118458261315404255474*var_31 + var_109 + var_299 + 0.0004662004662004662000618*var_121 + 0.0000333000333000333000044*var_40 + 0.0002115344972487829861181*var_32 + var_222 + 0.0003870203870203870561914*var_21; + A[25] = 0.3333333333333333148296163*var_12*var_316; + A[151] = A[25]; + const double var_317 = 0.0001395429966858538169735*var_25 + 0.0003108003108003108000412*var_1 + -0.0004566861709718852339705*var_2 + -0.0013542013542013542001796*var_17 + -0.0012051440622869195526401*var_0; + const double var_318 = -0.0006089148946291803119607*var_28 + 0.0046176046176046176006125*var_31 + var_317 + var_286 + -0.0027147455718884291528403*var_29 + var_301 + 0.0069264069264069264009187*var_20 + -0.0012812584241155670645301*var_32 + 0.0001141715427429713084926*var_21; + A[89] = 0.3555555555555555691249481*var_12*var_318; + A[215] = A[89]; + const double var_319 = -0.0005784691498977213722568*var_28 + var_314 + -0.0035012606441177868479842*var_31 + 0.0000152228723657295088155*var_71 + var_300 + 0.0007383093097378812122780*var_121 + var_213 + -0.0039579468150896723530052*var_20 + 0.0002816231387659959240974*var_32; + A[66] = 0.0740740740740740699621369*var_12*var_319; + const double var_320 = -0.0010833610833610833601437*var_155 + 0.0002854288568574282780078*var_100 + 0.0012076812076812076801602*var_156 + -0.0001573030144458716040809*var_158 + 0.0055411255411255411207350*var_110 + 0.0009235209235209235201225*var_200 + 0.0003196803196803196800424*var_0 + 0.0010256410256410256401360*var_217 + 0.0042624042624042624005654*var_159 + 0.0003761318047032332820799*var_157 + 0.0070596070596070596009364*w[0][0]*w[1][0]; + A[99] = 0.2962962962962962798485478*var_12*var_320; + const double var_321 = -0.0022610722610722612871403*var_155 + 0.0005017205017205017200665*var_161 + -0.0000022200022200022200003*var_156 + -0.0038150738150738152873465*var_158 + 0.0019391719391719391702572*var_17 + 0.0004995004995004995000663*var_110 + 0.0003890553890553890550516*var_111 + 0.0001265401265401265400168*var_0 + -0.0048151848151848156143195*w[0][3]*w[1][3] + 0.0005794205794205794200769*var_159 + -0.0136013986013986017120647*var_157 + 0.0018253968253968255036623*w[0][0]*w[1][0]; + A[17] = 0.0052910052910052907115812*var_12*var_321; + const double var_322 = 0.0000541257684114826987634*var_106*var_12; + const double var_323 = 0.0778835978835978881562596*var_158 + 0.0052003023431594855990889*var_200 + 0.0075585789871504159218030*w[0][0]*w[1][0] + 0.1600000000000000033306691*var_157 + 0.0590173847316704455745473*var_156 + -0.0450188964474678710026012*var_17 + 0.0181405895691609982123271*var_218 + 0.0609523809523809523280846*var_155 + -0.0243083900226757389229082*var_0 + -0.0120030234315948603623925*var_111; + A[50] = var_322 + 0.0062160062160062160008245*var_12*var_323; + A[78] = A[50]; + const double var_324 = 0.0066608523751380899549646*w[0][5]*w[1][5] + -0.0012617012617012618447276*var_36 + 0.0005209605209605209239290*var_23 + 0.0014855514855514856224772*var_136 + -0.0005895691609977324722583*var_18 + 0.0007814407814407814401036*var_105 + -0.0274725274725274755394100*w[0][2]*w[1][2]; + const double var_325 = 0.0909090909090909116141432*var_324; + const double var_326 = 0.0002115344972487829861181*var_28 + 0.0004662004662004662000618*var_63 + var_108 + 0.0000333000333000333000044*var_72 + 0.0003870203870203870561914*var_29 + var_104 + -0.0009916009916009914555712*var_20 + var_325 + -0.0001118458261315404255474*var_21; + A[123] = A[53]; + A[85] = 0.0740740740740740699621369*var_12*var_311; + const double var_327 = 0.0000532800532800532800071*var_158 + -0.0103363303363303363213710*var_156 + 0.0009723609723609723601290*var_17 + 0.0014652014652014652001943*var_201 + 0.0011721611721611721601555*var_194 + -0.0505094905094905094466995*var_110 + -0.0079187479187479183073695*var_111 + 0.0039960039960039960005300*var_0 + 0.0020246420246420246402685*w[0][3]*w[1][3] + 0.0343123543123543123245511*var_159 + -0.0012987012987012987001723*var_157 + 0.0644289044289044349200779*w[0][0]*w[1][0]; + A[115] = 0.0158730158730158721347436*var_12*var_327; + const double var_328 = 0.0097680097680097680012956*var_28 + 0.0084004884004884004811142*var_31 + 0.0355555555555555555247160*var_71 + 0.0164102564102564102421766*var_72 + 0.0078144078144078144010365*var_121 + var_246 + var_205 + 0.0072283272283272283209588*var_20 + var_69; + A[149] = 0.0230880230880230880030624*var_12*var_328; + A[219] = A[149]; + const double var_329 = 2.1333333333333333037273860*var_97 + -1.3783549783549784439884434*var_53 + 5.3471861471861474868205732*var_105 + -1.9329004329004328965879722*var_18 + 0.5359307359307359241995528*w[0][2]*w[1][2] + 6.3393939393939398030397570*var_137 + 0.6008658008658008808922091*var_242 + 2.3272727272727271596863829*var_141 + -0.3874458874458874269031128*var_136 + -3.4649350649350649788971168*var_36 + 55.5774891774891770523936430*w[0][5]*w[1][5] + 8.1316017316017319416232567*var_138; + const double var_330 = 0.0035372035372035369113486*w[0][1]*w[1][1] + 0.0140896140896140907583511*var_35 + -0.0196840196840196851590932*var_41 + -0.0331002331002330993370286*var_13 + 0.0080808080808080808010718*var_76; + const double var_331 = -0.0052096052096052098898116*var_28 + var_262 + 0.1491841491841491840197875*var_31 + 0.0107744107744107749796703*var_121 + 0.0497280497280497280065958*var_20 + -0.0364672364672364648918723*var_32 + var_330 + var_180 + 0.0030784030784030782558480*var_21; + const double var_332 = 0.0078144078144078144010365*var_63 + 0.0164102564102564102421766*var_48 + var_248 + var_64 + var_204 + 0.0355555555555555555247160*var_121 + 0.0097680097680097680012956*var_20 + 0.0072283272283272283209588*var_32 + 0.0084004884004884004811142*var_21; + A[7] = 0.3333333333333333148296163*var_12*var_285; + A[105] = A[7]; + const double var_333 = 0.0268329554043839763055601*var_33 + 0.0030687830687830689249673*var_30 + -0.0061073318216175358566500*var_16 + 0.0225699168556311412225934*var_22 + 0.0023885109599395314486370*var_90 + -0.0058125472411186696747309*var_19 + -0.0107482993197278910851855*var_13 + 0.0418065003779289484642234*var_27 + -0.0261224489795918377033068*var_24 + 0.0106727135298563865356547*var_41 + -0.1936810279667422474147997*w[0][4]*w[1][4] + 0.0044444444444444444405895*var_67; + A[22] = 0.0023310023310023310003092*var_12*var_333; + A[106] = A[22]; + const double var_334 = -0.0123026180169037314265923*var_28 + var_116 + 0.0007586064728921872082207*var_31 + var_305 + var_273 + -0.0164914450628736337922664*var_29 + 0.0113461142032570613813469*var_20 + var_128 + 0.0009235209235209235201225*var_32; + A[13] = 0.0085470085470085478684954*var_12*var_334; + A[195] = A[13]; + A[10] = 0.3333333333333333148296163*var_114*var_12; + const double var_335 = var_53 + var_74; + const double var_336 = -0.0023088023088023088003062*var_97 + -0.0184704184704184704024499*var_105 + 0.0009546009546009546001266*var_18 + 0.0019536019536019536002591*var_335 + -0.0000888000888000888000118*w[0][2]*w[1][2] + -0.0018648018648018648002473*var_137 + -0.0026640026640026640003533*var_141 + 0.0005106005106005106000677*var_136 + -0.0007992007992007992001060*var_36 + -0.0010656010656010656001413*var_138 + 0.0013320013320013320001767*var_140; + A[193] = 0.3047619047619047893959987*var_12*var_336; + const double var_337 = -0.0126392126392126397799176*var_36 + 0.0026936026936026937449176*var_58 + 0.0281792281792281815167023*var_23 + -0.0128982128982128990690725*var_18 + 0.0206312206312206300462542*w[0][2]*w[1][2]; + const double var_338 = 0.0181818181818181809350499*var_61 + -0.0198556998556998556826336*w[0][1]*w[1][1] + -0.0346320346320346320045935*var_35 + -0.0005772005772005772000766*var_41 + -0.0092352092352092352012249*var_34; + const double var_339 = -0.0190476190476190493372499*var_28 + var_59 + -0.0005772005772005772000766*var_31 + var_338 + -0.0091197691197691197612096*var_29 + 0.0057720057720057720007656*var_20 + 0.0727272727272727237401995*var_32 + var_174 + 0.1454545454545454474803989*var_21; + A[9] = 0.0028490028490028491449382*var_12*var_339; + A[34] = 0.3333333333333333148296163*var_12*var_326; + A[62] = A[34]; + A[94] = A[66]; + A[160] = 0.0002442002442002442000324*var_12*var_329; + const double var_340 = -1.0000000000000000000000000*var_22; + const double var_341 = 0.0000532800532800532800071*var_33 + 0.0014652014652014652001943*var_340 + 0.0343123543123543123245511*var_30 + -0.0505094905094905094466995*var_16 + 0.0644289044289044349200779*w[0][1]*w[1][1] + 0.0011721611721611721601555*var_90 + -0.0079187479187479183073695*var_19 + 0.0009723609723609723601290*var_13 + -0.0012987012987012987001723*var_27 + -0.0103363303363303363213710*var_24 + 0.0039960039960039960005300*var_41 + 0.0020246420246420246402685*w[0][4]*w[1][4]; + A[70] = 0.0158730158730158721347436*var_12*var_341; + A[154] = A[70]; + A[209] = 0.3047619047619047893959987*var_12*var_313; + A[114] = 0.0317460317460317442694873*var_103*var_12; + A[142] = A[114]; + const double var_342 = 0.0125030525030525030416584*var_33 + 0.0097680097680097680012956*var_91 + 0.0672039072039072038489138*var_16 + 0.0117216117216117216015547*var_30 + 0.0380952380952380986744998*var_22 + 0.0669108669108669090741515*w[0][1]*w[1][1] + 0.0336019536019536019244569*var_34 + -0.0136263736263736272291691*var_19 + 0.0046886446886446886406219*var_244 + -0.0086935286935286935211531*var_13 + 0.0297435897435897426965834*var_27 + 0.0289133089133089132838350*var_24; + A[144] = 0.0253968253968253968033686*var_12*var_295; + A[20] = 0.0370370370370370349810685*var_12*var_135; + A[199] = A[73]; + const double var_343 = -0.0005767777196348625482966*var_97 + 0.0008465608465608465962524*var_26 + 0.0009116809116809116439809*var_53 + 0.0075911390197104479035661*var_105 + 0.0002674574103145531921155*var_18 + 0.0004000232571661143602532*var_137 + 0.0013954299668585382239450*var_142 + 0.0014233385661957091445490*var_242 + -0.0002348973777545206411462*var_136 + 0.0028280713994999710086953*w[0][5]*w[1][5] + 0.0030141287284144425116794*var_138 + 0.0000837257980115123010261*var_45; + A[224] = 2.9090909090909091716525836*var_12*var_343; + const double var_344 = 0.0001909201909201909200253*var_51 + 0.0001598401598401598400212*var_36 + 0.0010656010656010656001413*var_23 + 0.0001953601953601953600259*var_119 + 0.0000177600177600177600024*var_26; + const double var_345 = 0.0021667221667221667202874*var_28 + 0.0004084804084804084800542*var_31 + 0.0012432012432012432001649*var_71 + var_344 + 0.0025574425574425574403392*var_29 + 0.0014918414918414918401979*var_72 + 0.0011899211899211899201578*var_40 + var_85 + var_255; + A[148] = 0.2539682539682539541558981*var_12*var_345; + A[204] = A[148]; + const double var_346 = -0.0013903556760699619689048*var_28 + var_146 + 0.0033388833388833388804429*var_63 + var_209 + 0.0015222872365729508883220*var_121 + 0.0044755244755244755205936*var_40 + 0.0009539666682523825682466*var_32 + var_78 + 0.0007662179090750520244618*var_21; + const double var_347 = 0.0046176046176046176006125*var_28 + -0.0006089148946291803119607*var_31 + var_317 + var_266 + 0.0069264069264069264009187*var_29 + -0.0027147455718884291528403*var_20 + var_277 + 0.0001141715427429713084926*var_32 + -0.0012812584241155670645301*var_21; + A[42] = 0.0085470085470085478684954*var_12*var_294; + A[182] = A[42]; + const double var_348 = var_281 + 0.0011899211899211899201578*var_63 + 0.0012432012432012432001649*var_48 + 0.0014918414918414918401979*var_121 + var_344 + 0.0004084804084804084800542*var_20 + var_288 + 0.0025574425574425574403392*var_32 + 0.0021667221667221667202874*var_21; + A[177] = 0.2539682539682539541558981*var_12*var_348; + A[191] = A[177]; + A[31] = A[17]; + A[65] = 0.2222222222222222098864108*var_12*var_346; + A[79] = A[65]; + const double var_349 = 0.0336019536019536019244569*var_14 + 0.0380952380952380986744998*var_155 + 0.0097680097680097680012956*var_81 + 0.0289133089133089132838350*var_156 + 0.0125030525030525030416584*var_158 + -0.0086935286935286935211531*var_17 + 0.0672039072039072038489138*var_110 + 0.0046886446886446886406219*var_200 + -0.0136263736263736272291691*var_111 + 0.0117216117216117216015547*var_159 + 0.0297435897435897426965834*var_157 + 0.0669108669108669090741515*w[0][0]*w[1][0]; + A[131] = 0.0038480038480038481450707*var_12*var_349; + A[173] = A[131]; + const double var_350 = 0.0029836829836829836803958*var_31 + 0.0002960002960002959819692*var_48 + 0.0002545602545602545781038*var_72 + -0.0015924815924815926247715*var_29 + 0.0051385651385651379824404*var_20 + var_166 + var_168 + 0.0003788803788803788981203*var_21 + var_296; + A[81] = 0.1269841269841269770779490*var_12*var_350; + A[95] = A[81]; + const double var_351 = 2.1333333333333333037273860*var_33 + -1.3783549783549784439884434*var_30 + 5.3471861471861474868205732*var_16 + 2.3272727272727271596863829*var_22 + 0.5359307359307359241995528*w[0][1]*w[1][1] + -0.3874458874458874269031128*var_19 + 0.6008658008658008808922091*var_244 + -1.9329004329004328965879722*var_13 + 6.3393939393939398030397570*var_27 + 8.1316017316017319416232567*var_24 + -3.4649350649350649788971168*var_41 + 55.5774891774891770523936430*w[0][4]*w[1][4]; + const double var_352 = 0.0001141715427429713084926*var_28 + var_278 + 0.0069264069264069264009187*var_31 + -0.0012812584241155670645301*var_29 + var_301 + var_261 + 0.0046176046176046176006125*var_20 + -0.0027147455718884291528403*var_32 + -0.0006089148946291803119607*var_21; + A[119] = 0.1904761904761904656169236*var_12*var_304; + A[217] = A[119]; + const double var_353 = -0.0003793032364460936041103*var_28 + 0.0007319664462521605682171*var_29 + var_52 + var_95 + -0.0039642896785753931054863*var_20 + 0.0005594405594405594400742*var_32 + var_118 + var_134 + 0.0001154401154401154400153*var_21; + A[5] = 0.0370370370370370349810685*var_12*var_353; + A[75] = A[5]; + const double var_354 = -0.0003793032364460936041103*var_31 + -0.0039642896785753931054863*var_29 + var_62 + 0.0007319664462521605682171*var_20 + var_95 + 0.0001154401154401154400153*var_32 + var_231 + var_225 + 0.0005594405594405594400742*var_21; + A[71] = 0.0317460317460317442694873*var_12*var_230; + A[221] = A[179]; + A[28] = 0.0007770007770007770001031*var_12*var_94; + A[196] = A[28]; + A[189] = A[147]; + const double var_355 = 0.0001154401154401154400153*var_28 + var_232 + -0.0039642896785753931054863*var_31 + var_195 + 0.0005594405594405594400742*var_29 + var_52 + var_191 + 0.0007319664462521605682171*var_32 + -0.0003793032364460936041103*var_21; + A[23] = 0.0370370370370370349810685*var_12*var_355; + const double var_356 = 0.0009235209235209235201225*var_28 + var_122 + var_127 + -0.0164914450628736337922664*var_31 + var_272 + -0.0123026180169037314265923*var_20 + 0.0113461142032570613813469*var_32 + var_306 + 0.0007586064728921872082207*var_21; + A[29] = 0.0085470085470085478684954*var_12*var_356; + A[211] = A[29]; + const double var_357 = 0.0002841602841602841600377*var_107 + 0.0005860805860805860800777*var_54 + -0.0022200022200022200002945*var_0 + -0.0058430458430458430407750*w[0][0]*w[1][0]; + const double var_358 = 0.0006038406038406038400801*var_28 + 0.0016872016872016872002238*var_31 + 0.0062160062160062160008245*var_71 + 0.0016339216339216339202167*var_29 + 0.0064646464646464646408575*var_72 + 0.0015096015096015096002002*var_40 + var_83 + var_357 + var_163; + A[162] = 0.1904761904761904656169236*var_12*var_358; + const double var_359 = var_172 + var_337 + -0.0364672364672364648918723*var_31 + 0.0107744107744107749796703*var_48 + -0.0052096052096052098898116*var_29 + 0.0030784030784030782558480*var_20 + 0.1491841491841491840197875*var_32 + var_330 + 0.0497280497280497280065958*var_21; + A[129] = 0.1269841269841269770779490*var_12*var_171; + A[143] = A[129]; + A[102] = 0.3555555555555555691249481*var_12*var_279; + A[121] = A[23]; + A[60] = A[4]; + const double var_360 = 0.0268329554043839763055601*var_97 + 0.0044444444444444444405895*var_26 + 0.0030687830687830689249673*var_53 + -0.0061073318216175358566500*var_105 + -0.0107482993197278910851855*var_18 + 0.0418065003779289484642234*var_137 + 0.0225699168556311412225934*var_141 + -0.0058125472411186696747309*var_136 + 0.0106727135298563865356547*var_36 + -0.1936810279667422474147997*w[0][5]*w[1][5] + -0.0261224489795918377033068*var_138 + 0.0023885109599395314486370*var_140; + const double var_361 = var_75 + 0.0044755244755244755205936*var_48 + 0.0007662179090750520244618*var_31 + 0.0015222872365729508883220*var_71 + 0.0033388833388833388804429*var_121 + var_211 + 0.0009539666682523825682466*var_20 + -0.0013903556760699619689048*var_32 + var_144; + A[161] = 0.2222222222222222098864108*var_12*var_361; + A[175] = A[161]; + A[12] = 0.0007770007770007770001031*var_12*var_219; + A[180] = A[12]; + A[58] = 0.3555555555555555691249481*var_12*var_347; + A[84] = 0.0038480038480038481450707*var_12*var_342; + A[54] = 0.1269841269841269770779490*var_12*var_298; + A[122] = A[38]; + const double var_362 = -0.0035012606441177868479842*var_28 + -0.0005784691498977213722568*var_31 + var_310 + 0.0000152228723657295088155*var_72 + -0.0039579468150896723530052*var_29 + var_291 + var_300 + 0.0007383093097378812122780*var_40 + 0.0002816231387659959240974*var_21; + A[93] = A[51]; + A[202] = A[118]; + const double var_363 = 0.0016872016872016872002238*var_28 + var_302 + 0.0006038406038406038400801*var_31 + 0.0064646464646464646408575*var_71 + var_308 + 0.0015096015096015096002002*var_121 + 0.0062160062160062160008245*var_72 + var_357 + 0.0016339216339216339202167*var_20; + A[117] = 0.1904761904761904656169236*var_12*var_363; + const double var_364 = 0.0590173847316704455745473*var_138 + 0.0778835978835978881562596*var_97 + -0.0243083900226757389229082*var_36 + 0.1600000000000000033306691*var_137 + -0.0120030234315948603623925*var_136 + -0.0450188964474678710026012*var_18 + 0.0181405895691609982123271*var_237 + 0.0609523809523809523280846*var_141 + 0.0075585789871504159218030*w[0][2]*w[1][2] + 0.0052003023431594855990889*var_242; + A[146] = var_322 + 0.0062160062160062160008245*var_12*var_364; + A[141] = A[99]; + A[76] = A[20]; + A[109] = A[67]; + const double var_365 = 0.0051385651385651379824404*var_28 + var_297 + 0.0003788803788803788981203*var_31 + var_164 + var_169 + 0.0002960002960002959819692*var_72 + 0.0029836829836829836803958*var_29 + 0.0002545602545602545781038*var_40 + -0.0015924815924815926247715*var_21; + A[86] = 0.1269841269841269770779490*var_12*var_365; + A[170] = A[86]; + A[150] = A[10]; + const double var_366 = 0.0015096015096015096002002*var_63 + 0.0062160062160062160008245*var_48 + var_253 + var_303 + 0.0064646464646464646408575*var_121 + 0.0016872016872016872002238*var_20 + 0.0016339216339216339202167*var_32 + var_163 + 0.0006038406038406038400801*var_21; + A[163] = 0.1904761904761904656169236*var_12*var_366; + const double var_367 = -0.0091197691197691197612096*var_28 + var_250 + 0.0727272727272727237401995*var_31 + var_338 + -0.0190476190476190493372499*var_29 + 0.1454545454545454474803989*var_20 + -0.0005772005772005772000766*var_32 + var_188 + 0.0057720057720057720007656*var_21; + A[35] = 0.0028490028490028491449382*var_12*var_367; + A[77] = A[35]; + A[40] = 0.0023310023310023310003092*var_12*var_360; + A[152] = A[40]; + const double var_368 = -0.0001118458261315404255474*var_28 + -0.0009916009916009914555712*var_31 + var_299 + 0.0000333000333000333000044*var_121 + var_284 + 0.0004662004662004662000618*var_40 + 0.0003870203870203870561914*var_32 + var_325 + 0.0002115344972487829861181*var_21; + A[124] = A[68]; + A[198] = A[58]; + A[140] = A[84]; + const double var_369 = 0.0038006438006438006405041*var_28 + var_132 + 0.0005708577137148565560157*var_31 + var_240 + 0.0017937617937617937602379*var_29 + var_149 + 0.0001281258424115567010320*var_20 + var_185 + -0.0034137291280148421117324*var_21; + A[24] = 0.0370370370370370349810685*var_12*var_369; + A[136] = A[24]; + const double var_370 = -0.0005767777196348625482966*var_33 + 0.0000837257980115123010261*var_91 + 0.0013954299668585382239450*var_340 + 0.0009116809116809116439809*var_30 + 0.0075911390197104479035661*var_16 + -0.0002348973777545206411462*var_19 + 0.0014233385661957091445490*var_244 + 0.0002674574103145531921155*var_13 + 0.0004000232571661143602532*var_27 + 0.0030141287284144425116794*var_24 + 0.0028280713994999710086953*w[0][4]*w[1][4] + 0.0008465608465608465962524*var_67; + A[208] = 2.9090909090909091716525836*var_12*var_370; + A[200] = A[88]; + A[187] = A[117]; + A[206] = A[178]; + const double var_371 = 0.0497280497280497280065958*var_28 + var_337 + var_178 + var_264 + 0.0030784030784030782558480*var_31 + 0.0107744107744107749796703*var_71 + 0.1491841491841491840197875*var_29 + -0.0364672364672364648918723*var_20 + -0.0052096052096052098898116*var_32; + A[48] = 0.0253968253968253968033686*var_12*var_371; + A[134] = 0.3555555555555555691249481*var_12*var_352; + A[19] = 0.3333333333333333148296163*var_12*var_223; + A[61] = A[19]; + A[69] = 0.0740740740740740699621369*var_12*var_362; + A[128] = 0.0253968253968253968033686*var_12*var_331; + A[137] = A[39]; + A[171] = A[101]; + A[97] = 0.2222222222222222098864108*var_12*var_283; + A[111] = A[97]; + A[218] = A[134]; + const double var_372 = 0.1600000000000000033306691*var_27 + 0.0075585789871504159218030*w[0][1]*w[1][1] + -0.0243083900226757389229082*var_41 + 0.0778835978835978881562596*var_33 + -0.0450188964474678710026012*var_13 + 0.0181405895691609982123271*var_93 + -0.0120030234315948603623925*var_19 + 0.0052003023431594855990889*var_244 + 0.0590173847316704455745473*var_24 + 0.0609523809523809523280846*var_22; + A[37] = 0.3333333333333333148296163*var_12*var_368; + A[21] = 0.0370370370370370349810685*var_12*var_233; + A[91] = A[21]; + const double var_373 = -0.0038150738150738152873465*var_97 + 0.0005794205794205794200769*var_53 + 0.0004995004995004995000663*var_105 + 0.0019391719391719391702572*var_18 + 0.0018253968253968255036623*w[0][2]*w[1][2] + -0.0136013986013986017120647*var_137 + -0.0022610722610722612871403*var_141 + 0.0003890553890553890550516*var_136 + 0.0001265401265401265400168*var_36 + -0.0048151848151848156143195*w[0][5]*w[1][5] + -0.0000022200022200022200003*var_138 + 0.0005017205017205017200665*var_207; + A[1] = 0.0052910052910052907115812*var_12*var_373; + A[174] = A[146]; + A[190] = A[162]; + A[169] = A[71]; + A[132] = 0.2539682539682539541558981*var_12*var_289; + A[186] = A[102]; + A[3] = 0.0370370370370370349810685*var_12*var_354; + A[45] = A[3]; + A[57] = 0.0230880230880230880030624*var_12*var_332; + A[43] = 0.0085470085470085478684954*var_12*var_307; + const double var_374 = 2.3272727272727271596863829*var_155 + 8.1316017316017319416232567*var_156 + 2.1333333333333333037273860*var_158 + -1.9329004329004328965879722*var_17 + 5.3471861471861474868205732*var_110 + 0.6008658008658008808922091*var_200 + -0.3874458874458874269031128*var_111 + -3.4649350649350649788971168*var_0 + 55.5774891774891770523936430*w[0][3]*w[1][3] + -1.3783549783549784439884434*var_159 + 6.3393939393939398030397570*var_157 + 0.5359307359307359241995528*w[0][0]*w[1][0]; + A[64] = 0.0002442002442002442000324*var_12*var_374; + A[207] = A[193]; + A[205] = A[163]; + A[168] = A[56]; + A[135] = A[9]; + A[15] = A[1]; + A[188] = A[132]; + A[96] = 0.0253968253968253968033686*var_12*var_359; + A[172] = A[116]; + A[80] = 0.0253968253968253968033686*var_12*var_265; + A[216] = A[104]; + A[166] = A[26]; + A[223] = A[209]; + A[197] = A[43]; + A[156] = A[100]; + A[222] = A[194]; + A[107] = A[37]; + A[0] = 0.0000074000074000073997186*var_12*var_162; + A[98] = var_322 + 0.0062160062160062160008245*var_12*var_372; + A[126] = A[98]; + A[112] = 0.0002442002442002442000324*var_12*var_351; + A[139] = A[69]; + A[159] = A[145]; + A[183] = A[57]; + A[120] = A[8]; + A[155] = A[85]; + A[157] = A[115]; + A[138] = A[54]; + } + + 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/mass_matrix_2d/mass_matrix_f2_p2_q4_quadrature.h b/mass_matrix_2d/mass_matrix_f2_p2_q4_quadrature.h new file mode 100644 index 0000000..d1e1b02 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p2_q4_quadrature.h @@ -0,0 +1,7270 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P2_Q4_QUADRATURE_H +#define __MASS_MATRIX_F2_P2_Q4_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p2_q4_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p2_q4_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p2_q4_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p2_q4_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p2_q4_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p2_q4_quadrature_finite_element_1() + { + // 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.0224478343233824, 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.0412393049421162, -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.0388807895679869, 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.0439885919382571, 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.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 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.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.00927360943924092, 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.0535412090610519}; + + // 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.0622092633087791, -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.251415744421884, 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.0224478343233824, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0412393049421162, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0388807895679869, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0439885919382571, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.00927360943924092, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0622092633087791, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.251415744421884, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p2_q4_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p2_q4_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p2_q4_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_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 mass_matrix_f2_p2_q4_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p2_q4_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p2_q4_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_p2_q4_quadrature_dofmap_1() + { + // 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.0*m.num_entities[1] + 3.0*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 mass_matrix_f2_p2_q4_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 mass_matrix_f2_p2_q4_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p2_q4_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Array of quadrature weights. + static const double W49[49] = {0.0036234660797264, 0.00715464377909735, 0.00824760301353097, 0.00693554275373524, 0.00429791008798315, 0.00177448507143835, 0.000337590756711431, 0.00782718664849641, 0.0154550176627367, 0.0178159604006788, 0.0149817292193919, 0.0092840787568901, 0.00383313257348533, 0.000729242610651687, 0.0106850106013168, 0.021097877818156, 0.0243208363749012, 0.0204517846225132, 0.0126738360020949, 0.00523266711568851, 0.000995500091625133, 0.0116960367644213, 0.0230941796709132, 0.0266220977213878, 0.0223869525046108, 0.0138730467715663, 0.00572778720065371, 0.00108969528483177, 0.0106850106013168, 0.021097877818156, 0.0243208363749012, 0.0204517846225133, 0.0126738360020949, 0.00523266711568852, 0.000995500091625133, 0.00782718664849641, 0.0154550176627367, 0.0178159604006788, 0.0149817292193919, 0.0092840787568901, 0.00383313257348533, 0.000729242610651687, 0.00362346607972641, 0.00715464377909737, 0.00824760301353099, 0.00693554275373526, 0.00429791008798316, 0.00177448507143835, 0.000337590756711432}; + // Quadrature points on the UFC reference element: (0.0248740323760607, 0.0224793864387125), (0.0225279156156636, 0.114679053160904), (0.0186827443488427, 0.265789822784589), (0.0139228951565961, 0.452846373669445), (0.00897290400671669, 0.64737528288683), (0.00458641254163789, 0.819759308263108), (0.00143165958133296, 0.943737439463078), (0.126329297019669, 0.0224793864387125), (0.114413927746761, 0.114679053160904), (0.0948852170128628, 0.265789822784589), (0.0707110745463253, 0.452846373669445), (0.045571246280295, 0.64737528288683), (0.0232932989499898, 0.819759308263108), (0.00727105865856026, 0.943737439463078), (0.29039930608799, 0.0224793864387125), (0.263008866575801, 0.114679053160904), (0.218117268350298, 0.265789822784589), (0.16254699001287, 0.452846373669445), (0.104756842708482, 0.64737528288683), (0.0535454404572833, 0.819759308263108), (0.0167143365694675, 0.943737439463078), (0.488760306780644, 0.0224793864387125), (0.442660473419548, 0.114679053160904), (0.367105088607705, 0.265789822784589), (0.273576813165278, 0.452846373669445), (0.176312358556585, 0.64737528288683), (0.0901203458684462, 0.819759308263108), (0.0281312802684611, 0.943737439463078), (0.687121307473297, 0.0224793864387125), (0.622312080263294, 0.114679053160904), (0.516092908865112, 0.265789822784589), (0.384606636317686, 0.452846373669445), (0.247867874404688, 0.64737528288683), (0.126695251279609, 0.819759308263108), (0.0395482239674546, 0.943737439463078), (0.851191316541618, 0.0224793864387125), (0.770907019092334, 0.114679053160904), (0.639324960202548, 0.265789822784589), (0.47644255178423, 0.452846373669445), (0.307053470832875, 0.64737528288683), (0.156947392786903, 0.819759308263108), (0.0489915018783619, 0.943737439463078), (0.952646581185227, 0.0224793864387125), (0.862793031223432, 0.114679053160904), (0.715527432866568, 0.265789822784589), (0.533230731173959, 0.452846373669445), (0.343651813106453, 0.64737528288683), (0.175654279195255, 0.819759308263108), (0.0548309009555892, 0.943737439463078) + + // Value of basis functions at quadrature points. + static const double FE0[49][6] = \ + {{0.862424436102575, -0.0236365974027701, -0.0214687408093905, 0.00223661194428196, 0.0856596425519242, 0.0947846476133797}, + {0.626030598232005, -0.0215129016516906, -0.0883764826931413, 0.0103339201299722, 0.395777151578119, 0.0777477144047362}, + {0.308431581502673, -0.0179846544760344, -0.124501362992863, 0.019862733238435, 0.760719638316469, 0.0534720644113193}, + {0.0354392941626712, -0.0135352011375129, -0.0427066973783121, 0.0252197303305777, 0.965886411764936, 0.0296964622576404}, + {-0.107458675803748, -0.00881187799408917, 0.190814230898777, 0.0232353450786585, 0.889886758897449, 0.0123342189229534}, + {-0.113945427596046, -0.0045443421816336, 0.52425133870491, 0.0150390174901693, 0.575976921626226, 0.00322249195637399}, + {-0.0488180455563859, -0.00142756028301924, 0.837543269825575, 0.00540444298987969, 0.206983896285125, 0.000313996738824818}, + {0.597861998170088, -0.0944111144487016, -0.0214687408093905, 0.0113592203449441, 0.0765370341512621, 0.430121602591798}, + {0.417688245079323, -0.0882328340218791, -0.0883764826931413, 0.0524835236096748, 0.353627548098416, 0.352809999927606}, + {0.178147849273431, -0.0768788081977068, -0.124501362992863, 0.100878100058905, 0.679704271496, 0.242649950362235}, + {-0.0224475414828926, -0.0607109624193334, -0.0427066973783121, 0.128085014746293, 0.863021127349221, 0.134759059185025}, + {-0.118489802931845, -0.0414177693052164, 0.190814230898777, 0.118006793808846, 0.795115310167261, 0.0559712373621772}, + {-0.10768242458169, -0.0222081433980425, 0.52425133870491, 0.0763795945376376, 0.514636344578758, 0.0146232901584272}, + {-0.0441911673657668, -0.00716532207052775, 0.837543269825575, 0.027447881122462, 0.184940458152543, 0.00142488033571425}, + {0.25715007489433, -0.121735792135218, -0.0214687408093906, 0.0261119928923436, 0.0617842616038626, 0.798158203554073}, + {0.152232570219964, -0.124661538780826, -0.0883764826931413, 0.120646431167342, 0.285464640540749, 0.654694379545912}, + {0.0166108722965938, -0.122966982845106, -0.124501362992863, 0.231893400404338, 0.548688971150566, 0.450275101986471}, + {-0.0887621069184766, -0.109703942088382, -0.0427066973783121, 0.294435259912846, 0.696670882182668, 0.250066604289657}, + {-0.124990908080892, -0.0828088505199825, 0.190814230898777, 0.271267962730938, 0.641854141245169, 0.10386342372599}, + {-0.0945918778860025, -0.0478112120697543, 0.52425133870491, 0.175577492919624, 0.415438446196772, 0.0271358121344515}, + {-0.0364200999294947, -0.0161555984755526, 0.837543269825575, 0.0630957807855735, 0.149292558489432, 0.00264408930446697}, + {-0.0109870318120258, -0.0109870318120257, -0.0214687408093905, 0.0439481272481031, 0.043948127248103, 0.955546549937236}, + {-0.0507638839635114, -0.0507638839635114, -0.0883764826931413, 0.203055535854046, 0.203055535854046, 0.783793178912073}, + {-0.097572796444363, -0.097572796444363, -0.124501362992863, 0.390291185777452, 0.390291185777452, 0.539064584326685}, + {-0.123888267761939, -0.123888267761939, -0.0427066973783121, 0.495553071047757, 0.495553071047757, 0.299377090806677}, + {-0.114140262997013, -0.114140262997013, 0.190814230898777, 0.456561051988053, 0.456561051988053, 0.124344191119143}, + {-0.0738769923895495, -0.0738769923895494, 0.52425133870491, 0.295507969558198, 0.295507969558198, 0.0324867069577935}, + {-0.0265485424093757, -0.0265485424093756, 0.837543269825575, 0.106194169637503, 0.106194169637503, 0.00316547571817094}, + {-0.121735792135218, 0.25715007489433, -0.0214687408093905, 0.0617842616038626, 0.0261119928923435, 0.798158203554073}, + {-0.124661538780826, 0.152232570219964, -0.0883764826931413, 0.285464640540749, 0.120646431167342, 0.654694379545913}, + {-0.122966982845106, 0.0166108722965939, -0.124501362992863, 0.548688971150566, 0.231893400404338, 0.450275101986471}, + {-0.109703942088382, -0.0887621069184766, -0.0427066973783121, 0.696670882182668, 0.294435259912846, 0.250066604289657}, + {-0.0828088505199825, -0.124990908080892, 0.190814230898777, 0.641854141245169, 0.271267962730938, 0.10386342372599}, + {-0.0478112120697543, -0.0945918778860025, 0.52425133870491, 0.415438446196772, 0.175577492919624, 0.0271358121344515}, + {-0.0161555984755526, -0.0364200999294947, 0.837543269825575, 0.149292558489432, 0.0630957807855734, 0.00264408930446697}, + {-0.0944111144487017, 0.597861998170089, -0.0214687408093906, 0.076537034151262, 0.011359220344944, 0.430121602591798}, + {-0.0882328340218791, 0.417688245079323, -0.0883764826931413, 0.353627548098416, 0.0524835236096748, 0.352809999927606}, + {-0.0768788081977066, 0.178147849273431, -0.124501362992863, 0.679704271496, 0.100878100058904, 0.242649950362234}, + {-0.0607109624193333, -0.0224475414828925, -0.0427066973783121, 0.863021127349221, 0.128085014746293, 0.134759059185025}, + {-0.0414177693052163, -0.118489802931845, 0.190814230898777, 0.795115310167261, 0.118006793808845, 0.0559712373621772}, + {-0.0222081433980425, -0.10768242458169, 0.52425133870491, 0.514636344578758, 0.0763795945376375, 0.0146232901584272}, + {-0.00716532207052781, -0.0441911673657667, 0.837543269825575, 0.184940458152543, 0.0274478811224619, 0.00142488033571425}, + {-0.0236365974027702, 0.862424436102575, -0.0214687408093906, 0.0856596425519241, 0.00223661194428187, 0.09478464761338}, + {-0.0215129016516907, 0.626030598232004, -0.0883764826931413, 0.395777151578119, 0.0103339201299722, 0.0777477144047368}, + {-0.0179846544760343, 0.308431581502674, -0.124501362992863, 0.760719638316469, 0.0198627332384348, 0.0534720644113193}, + {-0.013535201137513, 0.0354392941626711, -0.0427066973783121, 0.965886411764936, 0.0252197303305778, 0.0296964622576406}, + {-0.00881187799408919, -0.107458675803748, 0.190814230898777, 0.889886758897448, 0.0232353450786585, 0.0123342189229534}, + {-0.00454434218163365, -0.113945427596046, 0.52425133870491, 0.575976921626226, 0.0150390174901692, 0.00322249195637399}, + {-0.0014275602830193, -0.0488180455563859, 0.837543269825575, 0.206983896285125, 0.00540444298987969, 0.000313996738824845}}; + + static const double FE1[49][15] = \ + {{0.65493168251092, -0.0205789274672045, -0.0189527116015302, 0.00255184165887925, 0.00183297678774451, 0.00259198352982953, 0.290603716006681, -0.219105827318645, 0.0992699619767751, 0.321560655592687, -0.239894622258735, 0.108143664805332, 0.0479081464945106, -0.0153496339773736, -0.0155129067398702}, + {0.230775858060036, -0.0189863795969369, -0.0405222585594037, 0.0119720884518775, 0.00508953632453206, 0.00574753296534107, 0.938538723808041, -0.525109102795761, 0.220123844292779, 0.184369512907595, -0.173400177740129, 0.0900725476951516, 0.174837877403648, -0.0649007648193047, -0.0386088383974671}, + {-0.0263983311889084, -0.0162261198136333, 0.00507672925618625, 0.0235888732361831, -0.0011607649332568, -0.000783521200376718, 0.814143923932396, 0.0894678796271941, -0.0300079529342198, 0.0572273333667857, -0.0921298244490819, 0.0635031309102465, 0.211719351801624, -0.105201833381602, 0.00718112577046323}, + {-0.0116043782850671, -0.0125441321876623, 0.0137291293953672, 0.0308694006898722, -0.0193233108232087, -0.00257306944590875, 0.0969694764122356, 0.887878747410501, -0.0985455745067013, 0.00298135511727236, -0.0317701263137074, 0.0363490005835354, 0.121883793023689, -0.101591987794192, 0.0872916767239754}, + {0.0218099529415095, -0.00839396511637563, -0.0415013584170549, 0.0293325065770879, -0.0356070363345375, 0.0145145425273689, -0.138986464423005, 0.529872971809418, 0.555890139046101, -0.00192641306591023, -0.00445465108536265, 0.0155708278252808, 0.0239295170915481, -0.0615862290518757, 0.101535659675808}, + {-0.0259492611373146, -0.00443369345139607, 0.11113014233463, 0.0195035965961387, -0.0336456931740674, 0.0292255580651792, 0.148148737523861, -0.39036643678642, 1.11930496644439, 0.000828866742906425, 0.00094073305667583, 0.00417914156908884, -0.00628469424034395, -0.0207456373131733, 0.0481636737698413}, + {-0.0353248749092046, -0.00141667572643594, 0.600364037626626, 0.0071441435627288, -0.0149111750403232, 0.0177460160336165, 0.191823296185013, -0.448397033656697, 0.679651825184295, 0.000290997949665299, 0.000243726072526582, 0.000415072891802891, -0.00185070567900358, -0.00235706800659374, 0.00657841751198318}, + {0.19397940489897, -0.038836852447118, -0.0189527116015302, 0.00559929212675889, 0.00511394539374506, 0.0131640681438155, 0.172368070814931, -0.167503953185903, 0.0886978773627891, 0.968671332469604, -0.51167095682965, 0.212019525091192, 0.186010896531717, -0.0382641892907092, -0.0703957494786129}, + {0.0242606988218174, -0.0405525724320025, -0.0405222585594037, 0.0292676684575813, 0.0154071771225109, 0.0291903535434691, 0.532298546745573, -0.398833206249272, 0.196681023714651, 0.531067930789444, -0.398690748637562, 0.196746052784021, 0.674427347852841, -0.175545638211733, -0.175202375741935}, + {-0.0409393785829868, -0.0416654387325616, 0.00507672925618626, 0.067617155738567, -0.00395318666886515, -0.00397931790660805, 0.393269167046055, 0.0668543214935021, -0.0268121562279885, 0.140394503704814, -0.234458308221653, 0.162644810657797, 0.803490563472283, -0.320126570668304, 0.0325871056397637}, + {0.0074160746878218, -0.0394342734932151, 0.0137291293953672, 0.105155064836454, -0.0745313551444684, -0.013068008008114, -0.0491062122584641, 0.634259088040995, -0.088050635944496, -0.00766783889105522, -0.0875365563411642, 0.110634312951984, 0.442198111258687, -0.350116281505072, 0.396119380414741}, + {0.015970300127765, -0.0318100600262602, -0.0415013584170549, 0.116934730443109, -0.153380385402901, 0.0737159108874248, -0.0933636624938861, 0.288425077831199, 0.496688770686045, -0.00657222876685419, -0.0104450119556573, 0.0554627521201485, 0.0661535370784604, -0.237035274833928, 0.460756902722391}, + {-0.0316931436460637, -0.0195134699140883, 0.11113014233463, 0.0880484441685923, -0.157853100866765, 0.148429661486447, 0.175234029467102, -0.436556452191517, 1.00010086302313, 0.00497924036170683, 0.00493580488416056, 0.0168573550942449, -0.0356952130556438, -0.0869652580135685, 0.218561096867636}, + {-0.0332102315466837, -0.00688947855730999, 0.600364037626627, 0.0350160522419851, -0.0739512469766622, 0.0901277965925672, 0.178837996787906, -0.412630630532666, 0.607270044625344, 0.00137786370514668, 0.00111233180701457, 0.00181776087018662, -0.00864955917974902, -0.0104448237879977, 0.029852086324292}, + {-0.0376956175325737, 0.0120551215952569, -0.0189527116015302, -0.00235849719545761, -0.00384020719810918, 0.0302608844064402, 0.0539053418262965, -0.098315178096167, 0.0716010611001644, 0.696374605395548, 0.225519887728122, -0.0720915440033548, 0.250972068421866, 0.0231951571299926, -0.130630371976494}, + {-0.0385978618377363, 0.00421203260995719, -0.0405222585594037, -0.00396748013210338, -0.00339812186399732, 0.0671012869814887, 0.138662020924587, -0.230114751401647, 0.158770090276632, 0.318012225905947, 0.0507347100226551, -0.0215297453751059, 0.894498913320254, 0.0312544707315248, -0.325115531603051}, + {-0.00551401390042556, -0.0111213794704897, 0.00507672925618628, 0.0222300842098284, -0.00186784636347934, -0.00914745182665401, 0.0250624086737194, 0.0368855930425567, -0.0216440223079426, 0.0205671686783165, -0.0611204778385174, 0.0431648913565248, 1.01905954305901, -0.122101720353953, 0.0604704937853235}, + {0.0232837784121718, -0.0300586074517321, 0.0137291293953672, 0.0926843927984531, -0.0835702709051445, -0.030040066295293, -0.115426011167977, 0.304355645490315, -0.0710785776573171, -0.0414316019194668, -0.0470995668315187, 0.0787177167049168, 0.48777893509197, -0.316906634390842, 0.735061738726097}, + {-0.000713687257402987, -0.0413899186446951, -0.0415013584170549, 0.166106745889389, -0.250504204511209, 0.169454353616954, 0.00368049337298404, -0.00870101593638279, 0.400950327956515, 0.000595569332897621, 0.0005146252391984, 0.0635991628291439, -0.00458755739023296, -0.312510351678385, 0.85500681559828}, + {-0.0387733042865956, -0.0348885869800194, 0.11113014233463, 0.164261938052622, -0.314443316341127, 0.341202489964212, 0.203975837927158, -0.466979589938781, 0.807328034545362, 0.0133233937990828, 0.0105173111354129, 0.0253869731120797, -0.0877725996405723, -0.139843173772725, 0.405574450089261}, + {-0.0290420360686864, -0.0147395092155397, 0.600364037626627, 0.075878896205005, -0.163381727865319, 0.207181154389279, 0.154313397085524, -0.348743299107376, 0.490216686828632, 0.00273301232759478, 0.00207700119923646, 0.00317977803574914, -0.016804665702167, -0.0186279615262171, 0.0553952357876583}, + {0.00365494127355517, 0.00365494127355519, -0.0189527116015302, -0.0012580146039302, -0.0381982295649768, 0.0509309727533025, -0.00125801460393015, -0.0381982295649767, 0.0509309727533024, -0.0273525082825465, 0.871557587200981, -0.0273525082825465, 0.164115049695279, 0.164115049695279, -0.156389298140817}, + {0.016031147564392, 0.016031147564392, -0.0405222585594037, -0.0239271120668688, -0.0847017664717951, 0.11293568862906, -0.0239271120668687, -0.0847017664717951, 0.11293568862906, -0.0923585124148332, 0.465486091026599, -0.0923585124148333, 0.554151074489, 0.554151074489, -0.389224871925106}, + {0.0233336587299905, 0.0233336587299905, 0.00507672925618628, -0.0647890461245245, 0.0115468028004737, -0.0153957370672982, -0.0647890461245244, 0.0115468028004738, -0.0153957370672983, -0.0894857006531375, 0.118280272671703, -0.0894857006531375, 0.536914203918825, 0.536914203918825, 0.0723946348634534}, + {0.00742175989654578, 0.00742175989654581, 0.0137291293953672, -0.0282179133868397, 0.0379194914822288, -0.050559321976305, -0.0282179133868396, 0.0379194914822289, -0.0505593219763051, -0.0170472090921069, 0.00266261730549322, -0.0170472090921069, 0.102283254552641, 0.102283254552642, 0.88000813034681}, + {-0.0257340266975475, -0.0257340266975475, -0.0415013584170549, 0.116157794657916, -0.213901755590051, 0.285202340786735, 0.116157794657916, -0.213901755590051, 0.285202340786735, 0.0316355215935064, 0.0108027617072241, 0.0316355215935064, -0.189813129561038, -0.189813129561038, 1.02360510633079}, + {-0.0415686454285033, -0.0415686454285033, 0.11113014233463, 0.20656059818514, -0.43069894669109, 0.574265262254787, 0.20656059818514, -0.43069894669109, 0.574265262254787, 0.0227082661503164, 0.0132865453363341, 0.0227082661503164, -0.136249596901899, -0.136249596901899, 0.485549437191533}, + {-0.0226774234992432, -0.0226774234992431, 0.600364037626627, 0.118589616099474, -0.261524190456717, 0.348698920608956, 0.118589616099474, -0.261524190456716, 0.348698920608955, 0.00353496384473364, 0.00249316558737318, 0.00353496384473372, -0.021209783068402, -0.0212097830684018, 0.0663185897283966}, + {0.0120551215952569, -0.0376956175325737, -0.0189527116015302, 0.0539053418262964, -0.0983151780961671, 0.0716010611001645, -0.00235849719545759, -0.00384020719810907, 0.0302608844064402, -0.0720915440033548, 0.225519887728122, 0.696374605395548, 0.0231951571299925, 0.250972068421866, -0.130630371976494}, + {0.00421203260995724, -0.0385978618377362, -0.0405222585594037, 0.138662020924586, -0.230114751401647, 0.158770090276632, -0.00396748013210343, -0.00339812186399724, 0.0671012869814887, -0.0215297453751062, 0.0507347100226559, 0.318012225905946, 0.0312544707315252, 0.894498913320254, -0.325115531603052}, + {-0.0111213794704897, -0.00551401390042553, 0.00507672925618627, 0.0250624086737194, 0.0368855930425567, -0.0216440223079425, 0.0222300842098284, -0.00186784636347918, -0.009147451826654, 0.0431648913565248, -0.0611204778385175, 0.0205671686783165, -0.122101720353954, 1.01905954305901, 0.0604704937853235}, + {-0.0300586074517321, 0.0232837784121718, 0.0137291293953672, -0.115426011167977, 0.304355645490315, -0.0710785776573171, 0.0926843927984532, -0.0835702709051443, -0.030040066295293, 0.0787177167049168, -0.0470995668315187, -0.0414316019194668, -0.316906634390842, 0.48777893509197, 0.735061738726097}, + {-0.0413899186446951, -0.000713687257402966, -0.0415013584170549, 0.00368049337298409, -0.00870101593638315, 0.400950327956515, 0.166106745889389, -0.250504204511208, 0.169454353616954, 0.0635991628291438, 0.000514625239198445, 0.000595569332897648, -0.312510351678385, -0.00458755739023278, 0.85500681559828}, + {-0.0348885869800194, -0.0387733042865956, 0.11113014233463, 0.203975837927158, -0.466979589938781, 0.807328034545362, 0.164261938052622, -0.314443316341127, 0.341202489964212, 0.0253869731120796, 0.010517311135413, 0.0133233937990828, -0.139843173772725, -0.087772599640572, 0.405574450089261}, + {-0.0147395092155398, -0.0290420360686864, 0.600364037626627, 0.154313397085524, -0.348743299107376, 0.490216686828632, 0.0758788962050049, -0.163381727865318, 0.207181154389279, 0.00317977803574904, 0.0020770011992365, 0.00273301232759483, -0.0186279615262173, -0.0168046657021668, 0.0553952357876583}, + {-0.038836852447118, 0.19397940489897, -0.0189527116015302, 0.172368070814931, -0.167503953185903, 0.0886978773627892, 0.00559929212675891, 0.00511394539374516, 0.0131640681438155, 0.212019525091193, -0.51167095682965, 0.968671332469604, -0.0382641892907092, 0.186010896531717, -0.0703957494786129}, + {-0.0405525724320025, 0.0242606988218175, -0.0405222585594037, 0.532298546745573, -0.398833206249271, 0.196681023714651, 0.0292676684575813, 0.0154071771225112, 0.0291903535434692, 0.196746052784021, -0.398690748637562, 0.531067930789443, -0.175545638211733, 0.674427347852841, -0.175202375741935}, + {-0.0416654387325616, -0.0409393785829868, 0.00507672925618626, 0.393269167046056, 0.0668543214935022, -0.0268121562279884, 0.067617155738567, -0.00395318666886488, -0.00397931790660801, 0.162644810657797, -0.234458308221653, 0.140394503704814, -0.320126570668304, 0.803490563472282, 0.0325871056397638}, + {-0.0394342734932151, 0.00741607468782182, 0.0137291293953672, -0.0491062122584641, 0.634259088040995, -0.088050635944496, 0.105155064836454, -0.0745313551444681, -0.013068008008114, 0.110634312951984, -0.0875365563411642, -0.00766783889105526, -0.350116281505072, 0.442198111258687, 0.396119380414741}, + {-0.0318100600262602, 0.015970300127765, -0.0415013584170549, -0.0933636624938861, 0.288425077831199, 0.496688770686045, 0.116934730443109, -0.153380385402901, 0.0737159108874249, 0.0554627521201484, -0.0104450119556572, -0.00657222876685418, -0.237035274833928, 0.0661535370784606, 0.46075690272239}, + {-0.0195134699140883, -0.0316931436460637, 0.11113014233463, 0.175234029467102, -0.436556452191517, 1.00010086302313, 0.0880484441685923, -0.157853100866765, 0.148429661486447, 0.0168573550942448, 0.0049358048841607, 0.00497924036170686, -0.0869652580135687, -0.0356952130556437, 0.218561096867636}, + {-0.00688947855731001, -0.0332102315466836, 0.600364037626627, 0.178837996787906, -0.412630630532667, 0.607270044625344, 0.035016052241985, -0.0739512469766618, 0.090127796592567, 0.00181776087018654, 0.00111233180701465, 0.00137786370514674, -0.0104448237879978, -0.00864955917974874, 0.0298520863242919}, + {-0.0205789274672046, 0.654931682510919, -0.0189527116015302, 0.290603716006681, -0.219105827318645, 0.0992699619767752, 0.00255184165887931, 0.00183297678774468, 0.00259198352982953, 0.108143664805332, -0.239894622258736, 0.321560655592688, -0.0153496339773739, 0.0479081464945108, -0.0155129067398701}, + {-0.018986379596937, 0.230775858060035, -0.0405222585594037, 0.938538723808041, -0.525109102795761, 0.220123844292779, 0.0119720884518774, 0.0050895363245325, 0.00574753296534108, 0.090072547695152, -0.17340017774013, 0.184369512907596, -0.0649007648193052, 0.17483787740365, -0.0386088383974673}, + {-0.0162261198136334, -0.0263983311889083, 0.00507672925618625, 0.814143923932396, 0.0894678796271942, -0.0300079529342197, 0.0235888732361831, -0.00116076493325639, -0.000783521200376745, 0.0635031309102465, -0.0921298244490819, 0.0572273333667858, -0.105201833381602, 0.211719351801625, 0.00718112577046345}, + {-0.0125441321876624, -0.011604378285067, 0.0137291293953672, 0.0969694764122352, 0.887878747410501, -0.0985455745067012, 0.0308694006898726, -0.0193233108232086, -0.00257306944590875, 0.0363490005835357, -0.0317701263137077, 0.00298135511727235, -0.101591987794193, 0.12188379302369, 0.087291676723976}, + {-0.00839396511637566, 0.0218099529415095, -0.0415013584170549, -0.138986464423005, 0.529872971809417, 0.555890139046101, 0.0293325065770882, -0.0356070363345374, 0.014514542527369, 0.0155708278252808, -0.00445465108536261, -0.00192641306591026, -0.0615862290518763, 0.0239295170915484, 0.101535659675808}, + {-0.00443369345139607, -0.0259492611373146, 0.11113014233463, 0.148148737523861, -0.39036643678642, 1.11930496644439, 0.0195035965961387, -0.033645693174067, 0.0292255580651793, 0.00417914156908869, 0.000940733056676031, 0.000828866742906418, -0.0207456373131734, -0.00628469424034378, 0.0481636737698411}, + {-0.00141667572643595, -0.0353248749092046, 0.600364037626627, 0.191823296185013, -0.448397033656697, 0.679651825184295, 0.00714414356272866, -0.0149111750403226, 0.0177460160336164, 0.000415072891802759, 0.000243726072526686, 0.000290997949665306, -0.00235706800659391, -0.00185070567900331, 0.00657841751198318}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 225; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 34398 + for (unsigned int ip = 0; ip < 49; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + + // Total number of operations to compute function values = 24 + for (unsigned int r = 0; r < 6; r++) + { + F0 += FE0[ip][r]*w[0][r]; + F1 += FE0[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 3 + double I[1]; + // Number of operations: 3 + I[0] = F0*F1*W49[ip]*det; + + + // Number of operations for primary indices: 675 + for (unsigned int j = 0; j < 15; j++) + { + for (unsigned int k = 0; k < 15; k++) + { + // Number of operations to compute entry: 3 + A[j*15 + k] += FE1[ip][j]*FE1[ip][k]*I[0]; + }// 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 mass_matrix_f2_p2_q4_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p2_q4_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p2_q4_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1))), 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 mass_matrix_f2_p2_q4_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p2_q4_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p2_q4_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p2_q4_quadrature_finite_element_0(); + 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 mass_matrix_f2_p2_q4_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p2_q4_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p2_q4_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p2_q4_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f2_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/mass_matrix_2d/mass_matrix_f2_p2_q4_tensor.h b/mass_matrix_2d/mass_matrix_f2_p2_q4_tensor.h new file mode 100644 index 0000000..a9edd60 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p2_q4_tensor.h @@ -0,0 +1,7386 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P2_Q4_TENSOR_H +#define __MASS_MATRIX_F2_P2_Q4_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p2_q4_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p2_q4_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p2_q4_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p2_q4_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p2_q4_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p2_q4_tensor_finite_element_1() + { + // 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.0224478343233824, 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.0412393049421162, -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.0388807895679869, 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.0439885919382571, 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.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 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.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.00927360943924092, 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.0535412090610519}; + + // 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.0622092633087791, -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.251415744421884, 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.0224478343233824, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0412393049421162, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0388807895679869, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0439885919382571, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.00927360943924092, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0622092633087791, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.251415744421884, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p2_q4_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p2_q4_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p2_q4_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_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 mass_matrix_f2_p2_q4_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p2_q4_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p2_q4_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_p2_q4_tensor_dofmap_1() + { + // 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.0*m.num_entities[1] + 3.0*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 mass_matrix_f2_p2_q4_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 mass_matrix_f2_p2_q4_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p2_q4_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 54 + // Number of operations (multiply-add pairs) for tensor contraction: 3571 + // Total number of operations (multiply-add pairs): 3634 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0 = det*w[0][0]*w[1][0]*(1.0); + const double G0_0_1 = det*w[0][0]*w[1][1]*(1.0); + const double G0_0_2 = det*w[0][0]*w[1][2]*(1.0); + const double G0_0_3 = det*w[0][0]*w[1][3]*(1.0); + const double G0_0_4 = det*w[0][0]*w[1][4]*(1.0); + const double G0_0_5 = det*w[0][0]*w[1][5]*(1.0); + const double G0_1_0 = det*w[0][1]*w[1][0]*(1.0); + const double G0_1_1 = det*w[0][1]*w[1][1]*(1.0); + const double G0_1_2 = det*w[0][1]*w[1][2]*(1.0); + const double G0_1_3 = det*w[0][1]*w[1][3]*(1.0); + const double G0_1_4 = det*w[0][1]*w[1][4]*(1.0); + const double G0_1_5 = det*w[0][1]*w[1][5]*(1.0); + const double G0_2_0 = det*w[0][2]*w[1][0]*(1.0); + const double G0_2_1 = det*w[0][2]*w[1][1]*(1.0); + const double G0_2_2 = det*w[0][2]*w[1][2]*(1.0); + const double G0_2_3 = det*w[0][2]*w[1][3]*(1.0); + const double G0_2_4 = det*w[0][2]*w[1][4]*(1.0); + const double G0_2_5 = det*w[0][2]*w[1][5]*(1.0); + const double G0_3_0 = det*w[0][3]*w[1][0]*(1.0); + const double G0_3_1 = det*w[0][3]*w[1][1]*(1.0); + const double G0_3_2 = det*w[0][3]*w[1][2]*(1.0); + const double G0_3_3 = det*w[0][3]*w[1][3]*(1.0); + const double G0_3_4 = det*w[0][3]*w[1][4]*(1.0); + const double G0_3_5 = det*w[0][3]*w[1][5]*(1.0); + const double G0_4_0 = det*w[0][4]*w[1][0]*(1.0); + const double G0_4_1 = det*w[0][4]*w[1][1]*(1.0); + const double G0_4_2 = det*w[0][4]*w[1][2]*(1.0); + const double G0_4_3 = det*w[0][4]*w[1][3]*(1.0); + const double G0_4_4 = det*w[0][4]*w[1][4]*(1.0); + const double G0_4_5 = det*w[0][4]*w[1][5]*(1.0); + const double G0_5_0 = det*w[0][5]*w[1][0]*(1.0); + const double G0_5_1 = det*w[0][5]*w[1][1]*(1.0); + const double G0_5_2 = det*w[0][5]*w[1][2]*(1.0); + const double G0_5_3 = det*w[0][5]*w[1][3]*(1.0); + const double G0_5_4 = det*w[0][5]*w[1][4]*(1.0); + const double G0_5_5 = det*w[0][5]*w[1][5]*(1.0); + + // Compute element tensor + A[108] = -4.89105251010091e-05*G0_0_0 + 7.03353084305582e-05*G0_0_2 - 1.12762017523968e-06*G0_0_3 - 5.46895784991116e-05*G0_0_4 - 4.28495666590976e-05*G0_0_5 + 3.84800384800466e-05*G0_1_1 + 5.93410117219736e-05*G0_1_2 + 2.08609732419305e-05*G0_1_3 - 6.65295903391254e-05*G0_1_4 - 1.12762017523885e-06*G0_1_5 + 7.03353084305582e-05*G0_2_0 + 5.93410117219736e-05*G0_2_1 - 0.000483467150133897*G0_2_2 - 0.000259352640305065*G0_2_3 - 0.000293181245562247*G0_2_4 - 4.28495666590978e-05*G0_2_5 - 1.12762017523967e-06*G0_3_0 + 2.08609732419305e-05*G0_3_1 - 0.000259352640305065*G0_3_2 + 6.76572105143674e-05*G0_3_3 + 0.00013531442102873*G0_3_4 + 8.79543736686748e-05*G0_3_5 - 5.46895784991116e-05*G0_4_0 - 6.65295903391254e-05*G0_4_1 - 0.000293181245562247*G0_4_2 + 0.00013531442102873*G0_4_3 + 0.00124038219276335*G0_4_4 + 0.000218758313996446*G0_4_5 - 4.28495666590976e-05*G0_5_0 - 1.12762017523885e-06*G0_5_1 - 4.28495666590978e-05*G0_5_2 + 8.79543736686748e-05*G0_5_3 + 0.000218758313996446*G0_5_4 + 8.7954373668675e-05*G0_5_5; + A[52] = A[108]; + A[202] = -A[108] + 0.000211569735379295*G0_0_0 - 6.3992444944837e-05*G0_0_1 - 2.69219316838406e-05*G0_0_2 + 0.000130803940327771*G0_0_3 + 0.000303893637227021*G0_0_4 + 0.000214247833295488*G0_0_5 - 6.3992444944837e-05*G0_1_0 + 3.67886082171883e-05*G0_1_1 - 4.93333826667295e-06*G0_1_2 + 0.000152792533744943*G0_1_3 + 0.000261607880655544*G0_1_4 + 0.000130803940327773*G0_1_5 - 2.69219316838406e-05*G0_2_0 - 4.93333826667294e-06*G0_2_1 - 0.000222986889653594*G0_2_2 - 2.25524035048035e-06*G0_2_3 + 6.54019701638855e-05*G0_2_4 + 8.90819938439125e-05*G0_2_5 + 0.000130803940327771*G0_3_0 + 0.000152792533744943*G0_3_1 - 2.25524035048035e-06*G0_3_2 - 0.000852480852480988*G0_3_3 - 0.00078482364196663*G0_3_4 - 0.000439771868343366*G0_3_5 + 0.000303893637227021*G0_4_0 + 0.000261607880655544*G0_4_1 + 6.54019701638855e-05*G0_4_2 - 0.00078482364196663*G0_4_3 - 0.00319793081697897*G0_4_4 - 0.000701379748998913*G0_4_5 + 0.000214247833295488*G0_5_0 + 0.000130803940327773*G0_5_1 + 8.90819938439125e-05*G0_5_2 - 0.000439771868343366*G0_5_3 - 0.000701379748998913*G0_5_4 - 0.00083218368932668*G0_5_5; + A[212] = 3.67181319562333e-05*G0_0_0 - 2.69219316838409e-05*G0_0_1 - 2.46666913333619e-06*G0_0_2 + 7.89334122667585e-06*G0_0_3 + 5.72267238934001e-05*G0_0_4 + 4.51048070095757e-06*G0_0_5 - 2.69219316838409e-05*G0_1_0 + 3.67181319562333e-05*G0_1_1 - 2.46666913333616e-06*G0_1_2 + 5.72267238934002e-05*G0_1_3 + 7.89334122667588e-06*G0_1_4 + 4.51048070095763e-06*G0_1_5 - 2.4666691333362e-06*G0_2_0 - 2.46666913333616e-06*G0_2_1 + 0.000310800310800362*G0_2_2 - 3.94667061333796e-05*G0_2_3 - 3.94667061333795e-05*G0_2_4 - 9.86667653334486e-05*G0_2_5 + 7.89334122667585e-06*G0_3_0 + 5.72267238934002e-05*G0_3_1 - 3.94667061333796e-05*G0_3_2 - 4.73600473600551e-05*G0_3_3 - 3.15733649067034e-05*G0_3_4 + 0.000181546848213546*G0_3_5 + 5.72267238934001e-05*G0_4_0 + 7.89334122667587e-06*G0_4_1 - 3.94667061333795e-05*G0_4_2 - 3.15733649067034e-05*G0_4_3 - 4.73600473600551e-05*G0_4_4 + 0.000181546848213546*G0_4_5 + 4.51048070095757e-06*G0_5_0 + 4.51048070095763e-06*G0_5_1 - 9.86667653334486e-05*G0_5_2 + 0.000181546848213546*G0_5_3 + 0.000181546848213546*G0_5_4 + 0.000598766313052128*G0_5_5; + A[1] = -7.1965071965084e-05*G0_0_0 + 1.02601689903294e-05*G0_0_1 + 2.05849412198652e-06*G0_0_2 - 1.19633452966806e-05*G0_0_4 - 2.01855757411346e-05*G0_0_5 + 1.02601689903294e-05*G0_1_0 - 7.19650719650842e-05*G0_1_1 + 2.05849412198655e-06*G0_1_2 - 1.19633452966807e-05*G0_1_3 - 2.01855757411347e-05*G0_1_5 + 2.05849412198652e-06*G0_2_0 + 2.05849412198655e-06*G0_2_1 + 9.65818426136049e-06*G0_2_2 + 3.06571735143216e-06*G0_2_3 + 3.06571735143215e-06*G0_2_4 - 1.19633452966807e-05*G0_3_1 + 3.06571735143216e-06*G0_3_2 + 2.6428597857173e-06*G0_3_3 + 2.65460582920944e-06*G0_3_4 - 1.19633452966806e-05*G0_4_0 + 3.06571735143215e-06*G0_4_2 + 2.65460582920944e-06*G0_4_3 + 2.64285978571737e-06*G0_4_4 - 2.01855757411346e-05*G0_5_0 - 2.01855757411347e-05*G0_5_1 - 2.54771683343155e-05*G0_5_5; + A[164] = A[202] - 3.29828901257524e-05*G0_0_1 + 3.29828901257522e-05*G0_0_2 - 0.000101485815771547*G0_0_4 + 0.000101485815771548*G0_0_5 - 3.29828901257524e-05*G0_1_0 + 0.000262171690743162*G0_1_1 + 0.000125165839451573*G0_1_3 - 0.000196205910491659*G0_1_4 + 0.00022665165522312*G0_1_5 + 3.29828901257522e-05*G0_2_0 - 0.000262171690743162*G0_2_2 - 0.000125165839451573*G0_2_3 - 0.000226651655223121*G0_2_4 + 0.000196205910491659*G0_2_5 + 0.000125165839451573*G0_3_1 - 0.000125165839451573*G0_3_2 + 0.000392411820983316*G0_3_4 - 0.000392411820983319*G0_3_5 - 0.000101485815771547*G0_4_0 - 0.000196205910491659*G0_4_1 - 0.000226651655223121*G0_4_2 + 0.000392411820983316*G0_4_3 + 0.00351817494674696*G0_4_4 + 0.000101485815771548*G0_5_0 + 0.00022665165522312*G0_5_1 + 0.000196205910491659*G0_5_2 - 0.00039241182098332*G0_5_3 - 0.00351817494674697*G0_5_5; + A[31] = 9.65818426136048e-06*G0_0_0 + 2.05849412198654e-06*G0_0_1 + 2.05849412198653e-06*G0_0_2 + 3.06571735143216e-06*G0_0_4 + 3.06571735143216e-06*G0_0_5 + 2.05849412198654e-06*G0_1_0 - 7.19650719650842e-05*G0_1_1 + 1.02601689903295e-05*G0_1_2 - 2.01855757411347e-05*G0_1_3 - 1.19633452966807e-05*G0_1_5 + 2.05849412198653e-06*G0_2_0 + 1.02601689903295e-05*G0_2_1 - 7.1965071965084e-05*G0_2_2 - 2.01855757411347e-05*G0_2_3 - 1.19633452966806e-05*G0_2_4 - 2.01855757411347e-05*G0_3_1 - 2.01855757411347e-05*G0_3_2 - 2.54771683343155e-05*G0_3_3 + 3.06571735143216e-06*G0_4_0 - 1.19633452966806e-05*G0_4_2 + 2.64285978571737e-06*G0_4_4 + 2.65460582920946e-06*G0_4_5 + 3.06571735143216e-06*G0_5_0 - 1.19633452966807e-05*G0_5_1 + 2.65460582920946e-06*G0_5_4 + 2.6428597857174e-06*G0_5_5; + A[72] = A[202] - 0.000262171690743163*G0_0_0 + 3.29828901257523e-05*G0_0_2 + 0.000196205910491659*G0_0_3 - 0.000226651655223122*G0_0_4 - 0.000125165839451574*G0_0_5 + 0.000262171690743163*G0_1_1 - 3.29828901257527e-05*G0_1_2 + 0.000226651655223121*G0_1_3 - 0.000196205910491658*G0_1_4 + 0.000125165839451574*G0_1_5 + 3.29828901257523e-05*G0_2_0 - 3.29828901257527e-05*G0_2_1 + 0.000101485815771549*G0_2_3 - 0.000101485815771546*G0_2_4 + 0.000196205910491659*G0_3_0 + 0.000226651655223121*G0_3_1 + 0.000101485815771549*G0_3_2 - 0.00351817494674698*G0_3_3 - 0.00039241182098332*G0_3_5 - 0.000226651655223122*G0_4_0 - 0.000196205910491658*G0_4_1 - 0.000101485815771546*G0_4_2 + 0.00351817494674696*G0_4_4 + 0.000392411820983315*G0_4_5 - 0.000125165839451574*G0_5_0 + 0.000125165839451574*G0_5_1 - 0.00039241182098332*G0_5_3 + 0.000392411820983315*G0_5_4; + A[32] = 1.79655735211321e-05*G0_0_0 - 5.64250564250659e-05*G0_0_2 - 1.45944590389059e-05*G0_0_3 - 1.45944590389059e-05*G0_0_4 + 1.68555724111306e-06*G0_0_5 + 1.79655735211321e-05*G0_1_1 - 5.64250564250658e-05*G0_1_2 - 1.45944590389059e-05*G0_1_3 - 1.45944590389059e-05*G0_1_4 + 1.68555724111308e-06*G0_1_5 - 5.64250564250659e-05*G0_2_0 - 5.64250564250658e-05*G0_2_1 + 0.00141710141710165*G0_2_2 + 0.000225700225700264*G0_2_3 + 0.000225700225700263*G0_2_4 - 1.45944590389059e-05*G0_3_0 - 1.45944590389059e-05*G0_3_1 + 0.000225700225700264*G0_3_2 + 0.000116755672311248*G0_3_3 + 5.83778361556237e-05*G0_3_4 + 2.91889180778119e-05*G0_3_5 - 1.45944590389059e-05*G0_4_0 - 1.45944590389059e-05*G0_4_1 + 0.000225700225700263*G0_4_2 + 5.83778361556237e-05*G0_4_3 + 0.000116755672311247*G0_4_4 + 2.91889180778119e-05*G0_4_5 + 1.68555724111306e-06*G0_5_0 + 1.68555724111308e-06*G0_5_1 + 2.91889180778119e-05*G0_5_3 + 2.91889180778119e-05*G0_5_4 + 7.18622940845284e-05*G0_5_5; + A[90] = -A[32] + 0.00123156678712255*G0_0_0 - 5.2642830420617e-05*G0_0_1 - 0.000142758476091834*G0_0_2 + 1.9938908827801e-05*G0_0_3 + 0.000399805955361579*G0_0_4 + 0.000208885764441355*G0_0_5 - 5.2642830420617e-05*G0_1_0 + 7.7700077700091e-06*G0_1_1 - 4.54072676294974e-05*G0_1_2 + 1.85000185000218e-06*G0_1_3 + 2.05555761111435e-07*G0_1_4 - 0.000142758476091834*G0_2_0 - 4.54072676294974e-05*G0_2_1 + 0.00136053247164381*G0_2_2 + 0.000199717977495789*G0_2_3 + 0.000171433504766866*G0_2_4 + 1.9938908827801e-05*G0_3_0 + 1.85000185000219e-06*G0_3_1 + 0.000199717977495789*G0_3_2 - 8.58400858401003e-05*G0_3_3 - 4.0288929177825e-05*G0_3_4 - 3.65889254778206e-05*G0_3_5 + 0.000399805955361579*G0_4_0 + 2.05555761111442e-07*G0_4_1 + 0.000171433504766867*G0_4_2 - 4.0288929177825e-05*G0_4_3 + 3.78222600444889e-05*G0_4_4 + 2.87778065555877e-06*G0_4_5 + 0.000208885764441355*G0_5_0 - 3.65889254778205e-05*G0_5_3 + 2.87778065555875e-06*G0_5_4 + 4.55511566622753e-05*G0_5_5; + A[7] = -A[90] + 0.000381100381100447*G0_0_0 - 6.78334011667458e-06*G0_0_1 - 4.13167079833818e-05*G0_0_2 - 3.70000370000429e-06*G0_0_3 + 8.38667505334319e-05*G0_0_4 + 5.18000518000607e-05*G0_0_5 - 6.78334011667457e-06*G0_1_0 - 5.98460915921341e-06*G0_1_1 - 6.84794335588097e-06*G0_1_2 - 2.0837481154945e-05*G0_1_3 - 6.66000666000776e-06*G0_1_4 - 1.27444571889038e-05*G0_1_5 - 4.13167079833818e-05*G0_2_0 - 6.84794335588097e-06*G0_2_1 + 6.55487957075368e-05*G0_2_2 + 4.45292508784647e-05*G0_2_3 + 7.47400747400873e-05*G0_2_4 + 1.19222341444584e-05*G0_2_5 - 3.70000370000429e-06*G0_3_0 - 2.0837481154945e-05*G0_3_1 + 4.45292508784647e-05*G0_3_2 - 7.51746783493341e-07*G0_3_3 + 2.07200207200241e-05*G0_3_4 - 1.64444608889082e-05*G0_3_5 + 8.3866750533432e-05*G0_4_0 - 6.66000666000776e-06*G0_4_1 + 7.47400747400872e-05*G0_4_2 + 2.07200207200241e-05*G0_4_3 - 5.52533885867306e-05*G0_4_4 - 1.05244549689012e-05*G0_4_5 + 5.18000518000607e-05*G0_5_0 - 1.27444571889038e-05*G0_5_1 + 1.19222341444584e-05*G0_5_2 - 1.64444608889082e-05*G0_5_3 - 1.05244549689012e-05*G0_5_4 - 2.63111374222536e-06*G0_5_5; + A[10] = A[7] + 0.000175133508466872*G0_0_4 - 0.000175133508466872*G0_0_5 + 0.000117906784573471*G0_1_1 + 0.000107793441126793*G0_1_3 + 3.50267016933743e-05*G0_1_4 + 0.000140106806773497*G0_1_5 - 0.000117906784573471*G0_2_2 - 0.000107793441126793*G0_2_3 - 0.000140106806773497*G0_2_4 - 3.50267016933743e-05*G0_2_5 + 0.000107793441126793*G0_3_1 - 0.000107793441126793*G0_3_2 - 7.00534033867484e-05*G0_3_4 + 7.00534033867486e-05*G0_3_5 + 0.000175133508466872*G0_4_0 + 3.50267016933743e-05*G0_4_1 - 0.000140106806773497*G0_4_2 - 7.00534033867484e-05*G0_4_3 - 0.000175133508466872*G0_5_0 + 0.000140106806773497*G0_5_1 - 3.50267016933743e-05*G0_5_2 + 7.00534033867486e-05*G0_5_3; + A[135] = -A[10] + 0.000381100381100445*G0_0_0 - 4.13167079833817e-05*G0_0_1 - 6.78334011667454e-06*G0_0_2 - 3.70000370000438e-06*G0_0_3 + 5.18000518000606e-05*G0_0_4 + 8.38667505334312e-05*G0_0_5 - 4.13167079833817e-05*G0_1_0 + 6.55487957075369e-05*G0_1_1 - 6.84794335588104e-06*G0_1_2 + 4.45292508784648e-05*G0_1_3 + 1.19222341444584e-05*G0_1_4 + 7.47400747400873e-05*G0_1_5 - 6.78334011667454e-06*G0_2_0 - 6.84794335588103e-06*G0_2_1 - 5.98460915921335e-06*G0_2_2 - 2.0837481154945e-05*G0_2_3 - 1.27444571889038e-05*G0_2_4 - 6.66000666000776e-06*G0_2_5 - 3.70000370000438e-06*G0_3_0 + 4.45292508784648e-05*G0_3_1 - 2.0837481154945e-05*G0_3_2 - 7.51746783492988e-07*G0_3_3 - 1.64444608889081e-05*G0_3_4 + 2.07200207200242e-05*G0_3_5 + 5.18000518000606e-05*G0_4_0 + 1.19222341444584e-05*G0_4_1 - 1.27444571889038e-05*G0_4_2 - 1.64444608889081e-05*G0_4_3 - 2.63111374222534e-06*G0_4_4 - 1.05244549689012e-05*G0_4_5 + 8.38667505334312e-05*G0_5_0 + 7.47400747400873e-05*G0_5_1 - 6.66000666000776e-06*G0_5_2 + 2.07200207200242e-05*G0_5_3 - 1.05244549689012e-05*G0_5_4 - 5.52533885867318e-05*G0_5_5; + A[16] = -A[135] + 0.00123156678712255*G0_0_0 - 0.000142758476091834*G0_0_1 - 5.2642830420617e-05*G0_0_2 + 1.99389088278009e-05*G0_0_3 + 0.000208885764441355*G0_0_4 + 0.000399805955361578*G0_0_5 - 0.000142758476091834*G0_1_0 + 0.00136053247164381*G0_1_1 - 4.54072676294976e-05*G0_1_2 + 0.000199717977495789*G0_1_3 + 0.000171433504766868*G0_1_5 - 5.2642830420617e-05*G0_2_0 - 4.54072676294976e-05*G0_2_1 + 7.77000777000907e-06*G0_2_2 + 1.85000185000219e-06*G0_2_3 + 2.05555761111372e-07*G0_2_5 + 1.99389088278009e-05*G0_3_0 + 0.000199717977495789*G0_3_1 + 1.85000185000219e-06*G0_3_2 - 8.58400858401004e-05*G0_3_3 - 3.65889254778206e-05*G0_3_4 - 4.02889291778248e-05*G0_3_5 + 0.000208885764441355*G0_4_0 - 3.65889254778206e-05*G0_4_3 + 4.55511566622754e-05*G0_4_4 + 2.87778065555886e-06*G0_4_5 + 0.000399805955361578*G0_5_0 + 0.000171433504766868*G0_5_1 + 2.05555761111374e-07*G0_5_2 - 4.02889291778248e-05*G0_5_3 + 2.87778065555885e-06*G0_5_4 + 3.78222600444888e-05*G0_5_5; + A[35] = -A[16] + 7.77000777000911e-06*G0_0_0 - 4.54072676294977e-05*G0_0_1 - 5.2642830420617e-05*G0_0_2 + 2.05555761111333e-07*G0_0_3 + 1.85000185000212e-06*G0_0_5 - 4.54072676294977e-05*G0_1_0 + 0.00136053247164382*G0_1_1 - 0.000142758476091833*G0_1_2 + 0.000171433504766867*G0_1_3 + 0.00019971797749579*G0_1_5 - 5.2642830420617e-05*G0_2_0 - 0.000142758476091833*G0_2_1 + 0.00123156678712255*G0_2_2 + 0.000399805955361578*G0_2_3 + 0.000208885764441355*G0_2_4 + 1.99389088278012e-05*G0_2_5 + 2.05555761111337e-07*G0_3_0 + 0.000171433504766867*G0_3_1 + 0.000399805955361578*G0_3_2 + 3.78222600444889e-05*G0_3_3 + 2.87778065555888e-06*G0_3_4 - 4.02889291778246e-05*G0_3_5 + 0.000208885764441355*G0_4_2 + 2.87778065555889e-06*G0_4_3 + 4.55511566622755e-05*G0_4_4 - 3.65889254778205e-05*G0_4_5 + 1.85000185000212e-06*G0_5_0 + 0.00019971797749579*G0_5_1 + 1.99389088278012e-05*G0_5_2 - 4.02889291778246e-05*G0_5_3 - 3.65889254778205e-05*G0_5_4 - 8.58400858401e-05*G0_5_5; + A[70] = -A[16] - 2.64873280746348e-06*G0_0_0 - 0.000182119467833784*G0_0_1 + 1.45915225280329e-05*G0_0_2 + 4.01127385254447e-06*G0_0_3 - 3.78516251532187e-05*G0_0_5 - 0.000182119467833784*G0_1_0 + 0.00243978243978285*G0_1_1 - 0.000182119467833784*G0_1_2 + 0.000770340770340901*G0_1_3 + 6.34286348572165e-05*G0_1_4 + 0.0007703407703409*G0_1_5 + 1.45915225280329e-05*G0_2_0 - 0.000182119467833784*G0_2_1 - 2.64873280746369e-06*G0_2_2 - 3.7851625153219e-05*G0_2_3 + 4.01127385254433e-06*G0_2_5 + 4.01127385254447e-06*G0_3_0 + 0.000770340770340901*G0_3_1 - 3.7851625153219e-05*G0_3_2 - 0.000684982272283977*G0_3_3 - 0.000134879817419523*G0_3_4 - 1.60450954101777e-05*G0_3_5 + 6.34286348572165e-05*G0_4_1 - 0.000134879817419523*G0_4_3 + 0.000103999469078852*G0_4_4 - 0.000134879817419523*G0_4_5 - 3.78516251532187e-05*G0_5_0 + 0.0007703407703409*G0_5_1 + 4.01127385254433e-06*G0_5_2 - 1.60450954101777e-05*G0_5_3 - 0.000134879817419523*G0_5_4 - 0.000684982272283974*G0_5_5; + A[149] = A[16] - 0.000586286141841794*G0_0_0 + 0.000246992866040527*G0_0_1 + 7.30104698358789e-05*G0_0_2 - 0.00022446101811185*G0_0_3 - 0.000380565936121556*G0_0_4 - 0.000806313028535385*G0_0_5 + 0.000246992866040527*G0_1_0 - 0.00159752064513996*G0_1_1 + 4.40476630955044e-08*G0_1_2 - 0.00040611945373857*G0_1_3 + 0.000103741056122026*G0_1_4 - 1.7619065238256e-07*G0_1_5 + 7.30104698358789e-05*G0_2_0 + 4.40476630955044e-08*G0_2_1 + 5.42021176941901e-05*G0_2_2 + 0.000181482244974339*G0_2_3 + 0.000192265112900066*G0_2_4 + 0.000181482244974339*G0_2_5 - 0.00022446101811185*G0_3_0 - 0.00040611945373857*G0_3_1 + 0.000181482244974339*G0_3_2 + 0.00136268199760286*G0_3_3 + 0.000241439923979647*G0_3_4 + 8.59575462750214e-05*G0_3_5 - 0.000380565936121556*G0_4_0 + 0.000103741056122026*G0_4_1 + 0.000192265112900066*G0_4_2 + 0.000241439923979647*G0_4_3 - 0.000540952286984123*G0_4_4 - 0.000570446602192729*G0_4_5 - 0.000806313028535385*G0_5_0 - 1.7619065238256e-07*G0_5_1 + 0.000181482244974339*G0_5_2 + 8.59575462750213e-05*G0_5_3 - 0.000570446602192729*G0_5_4 - 0.00134360642297173*G0_5_5; + A[192] = A[149] + 0.00303104303104354*G0_0_0 - 0.000873905635810545*G0_0_1 - 0.000755505517410406*G0_0_2 - 4.5104807009575e-06*G0_0_3 + 0.00303104303104354*G0_0_4 + 0.00347307013973739*G0_0_5 - 0.000873905635810545*G0_1_0 + 0.00134412324888538*G0_1_1 + 0.000834438929677165*G0_1_2 - 0.00149747959271794*G0_1_3 - 0.00424436233960115*G0_1_4 - 0.00428495666590977*G0_1_5 - 0.000755505517410406*G0_2_0 + 0.000834438929677165*G0_2_1 + 0.00109153632963175*G0_2_2 - 0.00184478660669168*G0_2_3 - 0.00425338330100307*G0_2_4 - 0.00430750906941456*G0_2_5 - 4.51048070095744e-06*G0_3_0 - 0.00149747959271794*G0_3_1 - 0.00184478660669168*G0_3_2 + 0.00674767912863265*G0_3_3 + 0.00849774564060422*G0_3_4 + 0.00862403910023103*G0_3_5 + 0.00303104303104354*G0_4_0 - 0.00424436233960115*G0_4_1 - 0.00425338330100307*G0_4_2 + 0.00849774564060422*G0_4_3 + 0.0225524035047883*G0_4_4 + 0.0171037428180314*G0_4_5 + 0.00347307013973739*G0_5_0 - 0.00428495666590977*G0_5_1 - 0.00430750906941456*G0_5_2 + 0.00862403910023103*G0_5_3 + 0.0171037428180314*G0_5_4 + 0.0233101642625491*G0_5_5; + A[46] = -A[32] + 7.77000777000913e-06*G0_0_0 - 5.26428304206172e-05*G0_0_1 - 4.54072676294974e-05*G0_0_2 + 2.05555761111294e-07*G0_0_3 + 1.85000185000219e-06*G0_0_4 - 5.26428304206172e-05*G0_1_0 + 0.00123156678712255*G0_1_1 - 0.000142758476091834*G0_1_2 + 0.000399805955361579*G0_1_3 + 1.9938908827801e-05*G0_1_4 + 0.000208885764441356*G0_1_5 - 4.54072676294974e-05*G0_2_0 - 0.000142758476091834*G0_2_1 + 0.00136053247164381*G0_2_2 + 0.000171433504766867*G0_2_3 + 0.000199717977495789*G0_2_4 + 2.05555761111286e-07*G0_3_0 + 0.000399805955361579*G0_3_1 + 0.000171433504766867*G0_3_2 + 3.78222600444892e-05*G0_3_3 - 4.02889291778249e-05*G0_3_4 + 2.87778065555931e-06*G0_3_5 + 1.85000185000219e-06*G0_4_0 + 1.9938908827801e-05*G0_4_1 + 0.000199717977495789*G0_4_2 - 4.02889291778249e-05*G0_4_3 - 8.58400858401003e-05*G0_4_4 - 3.65889254778205e-05*G0_4_5 + 0.000208885764441356*G0_5_1 + 2.87778065555931e-06*G0_5_3 - 3.65889254778205e-05*G0_5_4 + 4.55511566622757e-05*G0_5_5; + A[60] = -A[46] + 1.6444460888925e-07*G0_0_0 - 6.53491129681718e-05*G0_0_1 - 2.53127237254262e-06*G0_0_2 + 3.96781349162368e-05*G0_0_3 + 2.35978013755831e-05*G0_0_4 - 6.53491129681717e-05*G0_1_0 + 0.00131105226343344*G0_1_1 - 0.000111387730435368*G0_1_2 + 0.000476948095995796*G0_1_3 + 4.01009924819515e-05*G0_1_4 + 0.000259810736001257*G0_1_5 - 2.53127237254262e-06*G0_2_0 - 0.000111387730435368*G0_2_1 + 4.08821043741748e-05*G0_2_2 + 8.2809606619143e-06*G0_2_3 + 2.66282805965391e-05*G0_2_4 + 3.96781349162368e-05*G0_3_0 + 0.000476948095995796*G0_3_1 + 8.2809606619143e-06*G0_3_2 - 0.000530404339928239*G0_3_3 - 0.000159558254796377*G0_3_4 - 8.72026268851809e-05*G0_3_5 + 2.35978013755831e-05*G0_4_0 + 4.01009924819515e-05*G0_4_1 + 2.66282805965391e-05*G0_4_2 - 0.000159558254796377*G0_4_3 - 0.000216831962863745*G0_4_4 - 8.80483420166108e-05*G0_4_5 + 0.000259810736001257*G0_5_1 - 8.72026268851809e-05*G0_5_3 - 8.80483420166108e-05*G0_5_4 - 4.05473421346502e-05*G0_5_5; + A[4] = A[60]; + A[41] = A[135] - 0.00127078095332085*G0_0_0 + 0.000122722662405223*G0_0_1 + 5.12127496254566e-05*G0_0_2 - 1.33904895809679e-05*G0_0_3 - 0.000221248475216766*G0_0_4 - 0.00038729054602077*G0_0_5 + 0.000122722662405223*G0_1_0 - 0.000105737883515679*G0_1_1 + 9.60826357651914e-06*G0_1_2 - 5.60991037181607e-05*G0_1_3 - 1.04774707949329e-05*G0_1_4 - 9.25588227175682e-05*G0_1_5 + 5.12127496254566e-05*G0_2_0 + 9.60826357651915e-06*G0_2_1 + 2.05555761111353e-05*G0_2_2 + 4.27555983111605e-06*G0_2_3 + 1.10412808825525e-05*G0_2_5 - 1.33904895809679e-05*G0_3_0 - 5.60991037181607e-05*G0_3_1 + 4.27555983111604e-06*G0_3_2 + 0.000132495370590631*G0_3_3 + 4.77359207518019e-05*G0_3_4 + 4.69841739683112e-06*G0_3_5 - 0.000221248475216766*G0_4_0 - 1.04774707949329e-05*G0_4_1 + 4.77359207518019e-05*G0_4_3 + 1.67263659327181e-05*G0_4_4 - 1.12762017523933e-06*G0_4_5 - 0.00038729054602077*G0_5_0 - 9.25588227175683e-05*G0_5_1 + 1.10412808825525e-05*G0_5_2 + 4.69841739683112e-06*G0_5_3 - 1.12762017523932e-06*G0_5_4 - 0.000141892205384293*G0_5_5; + A[165] = A[41] + 0.000427180109719864*G0_0_0 - 3.63892427384551e-05*G0_0_1 - 2.01327185454203e-05*G0_0_2 - 4.22857565714781e-07*G0_0_3 + 8.0483890007713e-05*G0_0_4 + 0.000113654716829339*G0_0_5 - 3.63892427384551e-05*G0_1_0 - 2.26933560266934e-05*G0_1_1 - 2.11428782857353e-07*G0_1_2 + 4.22857565714772e-07*G0_1_4 + 2.03911315022459e-05*G0_1_5 - 2.01327185454203e-05*G0_2_0 - 2.11428782857356e-07*G0_2_1 - 2.03441473282779e-05*G0_2_2 + 4.22857565714808e-07*G0_2_3 - 1.15111226222356e-05*G0_2_5 - 4.22857565714781e-07*G0_3_0 + 4.22857565714808e-07*G0_3_2 - 2.38679603759011e-05*G0_3_3 + 2.38679603759007e-05*G0_3_5 + 8.0483890007713e-05*G0_4_0 + 4.22857565714772e-07*G0_4_1 - 9.39683479366149e-07*G0_4_4 + 2.21765301130417e-05*G0_4_5 + 0.000113654716829339*G0_5_0 + 2.03911315022459e-05*G0_5_1 - 1.15111226222356e-05*G0_5_2 + 2.38679603759008e-05*G0_5_3 + 2.21765301130417e-05*G0_5_4 + 0.000241874527588854*G0_5_5; + A[103] = A[149] - 0.000118400118400138*G0_0_1 + 0.000118400118400138*G0_0_2 - 0.000442027108693849*G0_0_4 + 0.000442027108693849*G0_0_5 - 0.000118400118400138*G0_1_0 + 0.000252586919253628*G0_1_1 + 0.000347307013973739*G0_1_3 + 6.31467298134073e-05*G0_1_4 - 3.15733649067034e-05*G0_1_5 + 0.000118400118400138*G0_2_0 - 0.000252586919253628*G0_2_2 - 0.000347307013973738*G0_2_3 + 3.15733649067035e-05*G0_2_4 - 6.31467298134067e-05*G0_2_5 + 0.000347307013973739*G0_3_1 - 0.000347307013973738*G0_3_2 - 0.000126293459626815*G0_3_4 + 0.000126293459626813*G0_3_5 - 0.000442027108693849*G0_4_0 + 6.31467298134073e-05*G0_4_1 + 3.15733649067036e-05*G0_4_2 - 0.000126293459626815*G0_4_3 - 0.000757760757760885*G0_4_4 + 0.000442027108693849*G0_5_0 - 3.15733649067034e-05*G0_5_1 - 6.31467298134067e-05*G0_5_2 + 0.000126293459626813*G0_5_3 + 0.00075776075776088*G0_5_5; + A[57] = A[103] + 0.000640488259535985*G0_0_0 - 0.000246948818377431*G0_0_2 + 0.000405943263086189*G0_0_3 + 0.000987795273509724*G0_0_4 + 0.000572831049021621*G0_0_5 - 0.000640488259535987*G0_1_1 + 0.000246948818377432*G0_1_2 - 0.000987795273509727*G0_1_3 - 0.000405943263086188*G0_1_4 - 0.000572831049021621*G0_1_5 - 0.000246948818377431*G0_2_0 + 0.000246948818377432*G0_2_1 + 0.000405943263086189*G0_2_3 - 0.000405943263086188*G0_2_4 + 0.000405943263086189*G0_3_0 - 0.000987795273509727*G0_3_1 + 0.000405943263086189*G0_3_2 - 0.00270628842057459*G0_3_3 - 0.000811886526172377*G0_3_5 + 0.000987795273509724*G0_4_0 - 0.000405943263086188*G0_4_1 - 0.000405943263086188*G0_4_2 + 0.00270628842057459*G0_4_4 + 0.000811886526172376*G0_4_5 + 0.000572831049021621*G0_5_0 - 0.000572831049021621*G0_5_1 - 0.000811886526172377*G0_5_3 + 0.000811886526172376*G0_5_4; + A[208] = A[192] - 0.0012990184418758*G0_0_0 + 0.00146139574711028*G0_0_2 - 0.00389705532562741*G0_0_3 - 0.00433006147291935*G0_0_4 - 0.00671159528302499*G0_0_5 + 0.0012990184418758*G0_1_1 - 0.00146139574711028*G0_1_2 + 0.00433006147291935*G0_1_3 + 0.00389705532562741*G0_1_4 + 0.00671159528302499*G0_1_5 + 0.00146139574711028*G0_2_0 - 0.00146139574711028*G0_2_1 - 0.00238153381010564*G0_2_3 + 0.00238153381010564*G0_2_4 - 0.00389705532562741*G0_3_0 + 0.00433006147291935*G0_3_1 - 0.00238153381010564*G0_3_2 + 0.0138561967133419*G0_3_3 + 0.00779411065125483*G0_3_5 - 0.00433006147291935*G0_4_0 + 0.00389705532562741*G0_4_1 + 0.00238153381010564*G0_4_2 - 0.0138561967133419*G0_4_4 - 0.00779411065125482*G0_4_5 - 0.00671159528302499*G0_5_0 + 0.00671159528302499*G0_5_1 + 0.00779411065125483*G0_5_3 - 0.00779411065125482*G0_5_4; + A[139] = -A[16] + 5.64456120011774e-05*G0_0_0 + 2.9159552969079e-06*G0_0_1 - 8.11240493780314e-05*G0_0_3 + 6.26651420302346e-06*G0_0_5 + 2.91595529690789e-06*G0_1_0 + 0.00093363426696776*G0_1_1 + 1.39102520054923e-05*G0_1_2 - 6.74810198619832e-05*G0_1_3 - 4.28495666590979e-05*G0_1_4 - 3.36524146048004e-05*G0_1_5 + 1.39102520054923e-05*G0_2_1 - 3.09449515798772e-05*G0_2_2 - 6.92840375380174e-05*G0_2_3 - 4.11640094179845e-05*G0_2_4 - 1.57220792141454e-05*G0_2_5 - 8.11240493780314e-05*G0_3_0 - 6.74810198619832e-05*G0_3_1 - 6.92840375380174e-05*G0_3_2 + 0.0013571378650746*G0_3_3 + 0.000247947232074258*G0_3_4 + 0.000193692257184354*G0_3_5 - 4.28495666590979e-05*G0_4_1 - 4.11640094179845e-05*G0_4_2 + 0.000247947232074258*G0_4_3 + 0.000159816667753202*G0_4_4 + 0.000117143291746486*G0_4_5 + 6.26651420302346e-06*G0_5_0 - 3.36524146048004e-05*G0_5_1 - 1.57220792141454e-05*G0_5_2 + 0.000193692257184354*G0_5_3 + 0.000117143291746486*G0_5_4 + 0.000184412882825613*G0_5_5; + A[11] = A[165]; + A[51] = A[32] + 9.64878742656678e-05*G0_0_0 - 3.26099532448793e-05*G0_0_1 + 3.99071827643325e-06*G0_0_2 - 3.44746376492463e-06*G0_0_3 + 0.00016118508182003*G0_0_4 + 4.6426236902435e-05*G0_0_5 - 3.26099532448793e-05*G0_1_0 + 9.64878742656678e-05*G0_1_1 + 3.99071827643318e-06*G0_1_2 + 0.000161185081820029*G0_1_3 - 3.44746376492467e-06*G0_1_4 + 4.6426236902435e-05*G0_1_5 + 3.99071827643325e-06*G0_2_0 + 3.99071827643317e-06*G0_2_1 - 0.00115962814375532*G0_2_2 - 0.000180595418690687*G0_2_3 - 0.000180595418690687*G0_2_4 - 3.75873391746472e-05*G0_2_5 - 3.44746376492463e-06*G0_3_0 + 0.000161185081820029*G0_3_1 - 0.000180595418690687*G0_3_2 + 0.000141845221210324*G0_3_3 + 1.37898550596987e-05*G0_3_4 + 8.20696058791434e-05*G0_3_5 + 0.00016118508182003*G0_4_0 - 3.44746376492466e-06*G0_4_1 - 0.000180595418690687*G0_4_2 + 1.37898550596987e-05*G0_4_3 + 0.000141845221210324*G0_4_4 + 8.20696058791434e-05*G0_4_5 + 4.6426236902435e-05*G0_5_0 + 4.6426236902435e-05*G0_5_1 - 3.75873391746472e-05*G0_5_2 + 8.20696058791434e-05*G0_5_3 + 8.20696058791434e-05*G0_5_4 + 5.74381526762572e-05*G0_5_5; + A[126] = A[10] + 0.00182706182706213*G0_0_0 - 0.00011962757994506*G0_0_1 - 0.000324854451838633*G0_0_2 + 5.90825987651483e-06*G0_0_3 + 0.000639525083969636*G0_0_4 + 0.000709414042747495*G0_0_5 - 0.00011962757994506*G0_1_0 - 7.51335671970721e-05*G0_1_1 - 5.67451361102248e-05*G0_1_2 - 0.000183273516606881*G0_1_3 - 0.00016466778371543*G0_1_4 - 0.000241768813197425*G0_1_5 - 0.000324854451838633*G0_2_0 - 5.67451361102248e-05*G0_2_1 + 0.000990350037969251*G0_2_2 + 0.000416162320924295*G0_2_3 + 0.000495224939669467*G0_2_4 - 1.08650902301712e-05*G0_2_5 + 5.90825987651483e-06*G0_3_0 - 0.000183273516606881*G0_3_1 + 0.000416162320924295*G0_3_2 + 0.000231162135924079*G0_3_3 + 0.000317519047677831*G0_3_4 + 9.91366070731298e-06*G0_3_5 + 0.000639525083969636*G0_4_0 - 0.00016466778371543*G0_4_1 + 0.000495224939669467*G0_4_2 + 0.000317519047677831*G0_4_3 + 0.000409326123611905*G0_4_4 + 0.000351065747891203*G0_4_5 + 0.000709414042747495*G0_5_0 - 0.000241768813197425*G0_5_1 - 1.08650902301712e-05*G0_5_2 + 9.91366070731298e-06*G0_5_3 + 0.000351065747891203*G0_5_4 + 0.000409326123611907*G0_5_5; + A[94] = A[108] + 8.73905635810536e-05*G0_0_0 - 1.09942967085841e-05*G0_0_2 - 6.54019701638858e-05*G0_0_3 + 7.55505517410402e-05*G0_0_4 + 4.17219464838581e-05*G0_0_5 - 8.73905635810556e-05*G0_1_1 + 1.09942967085846e-05*G0_1_2 - 7.55505517410418e-05*G0_1_3 + 6.5401970163886e-05*G0_1_4 - 4.17219464838586e-05*G0_1_5 - 1.09942967085841e-05*G0_2_0 + 1.09942967085845e-05*G0_2_1 - 3.38286052571823e-05*G0_2_3 + 3.38286052571824e-05*G0_2_4 - 6.54019701638858e-05*G0_3_0 - 7.55505517410418e-05*G0_3_1 - 3.38286052571823e-05*G0_3_2 + 0.00117272498224899*G0_3_3 + 0.000130803940327771*G0_3_5 + 7.55505517410402e-05*G0_4_0 + 6.54019701638859e-05*G0_4_1 + 3.38286052571824e-05*G0_4_2 - 0.00117272498224899*G0_4_4 - 0.000130803940327772*G0_4_5 + 4.17219464838581e-05*G0_5_0 - 4.17219464838586e-05*G0_5_1 + 0.000130803940327771*G0_5_3 - 0.000130803940327772*G0_5_4; + A[154] = A[70]; + A[106] = A[60] + 8.70910394720062e-05*G0_0_0 - 1.15052496004896e-05*G0_0_2 - 1.93104955009749e-05*G0_0_3 + 5.53943411086362e-05*G0_0_4 + 4.54571883143388e-05*G0_0_5 - 8.70910394720059e-05*G0_1_1 + 1.15052496004897e-05*G0_1_2 - 5.5394341108636e-05*G0_1_3 + 1.9310495500975e-05*G0_1_4 - 4.54571883143387e-05*G0_1_5 - 1.15052496004896e-05*G0_2_0 + 1.15052496004897e-05*G0_2_1 - 9.93715279429747e-06*G0_2_3 + 9.93715279429718e-06*G0_2_4 - 1.93104955009749e-05*G0_3_0 - 5.5394341108636e-05*G0_3_1 - 9.93715279429747e-06*G0_3_2 + 0.000437234722949083*G0_3_3 + 3.86209910019499e-05*G0_3_5 + 5.53943411086362e-05*G0_4_0 + 1.9310495500975e-05*G0_4_1 + 9.9371527942972e-06*G0_4_2 - 0.000437234722949082*G0_4_4 - 3.86209910019499e-05*G0_4_5 + 4.54571883143388e-05*G0_5_0 - 4.54571883143387e-05*G0_5_1 + 3.86209910019499e-05*G0_5_3 - 3.86209910019499e-05*G0_5_4; + A[181] = -A[106] - 2.5670978051935e-05*G0_0_0 + 1.75309699119253e-05*G0_0_1 + 6.66000666000785e-06*G0_0_2 - 2.14952595905012e-05*G0_0_3 - 7.84048403096156e-05*G0_0_4 - 5.25400525400616e-05*G0_0_5 + 1.75309699119253e-05*G0_1_0 - 9.32400932401092e-05*G0_1_1 - 2.39090715281232e-05*G0_1_2 + 0.000107758202996317*G0_1_4 + 6.66000666000785e-06*G0_2_0 - 2.39090715281232e-05*G0_2_1 + 0.000115281543852992*G0_2_2 + 5.90943448086405e-05*G0_2_3 + 0.000159523016665901*G0_2_4 + 1.6843826367639e-05*G0_2_5 - 2.14952595905012e-05*G0_3_0 + 5.90943448086405e-05*G0_3_2 + 1.55047774095318e-06*G0_3_3 - 0.000172525886811631*G0_3_4 + 9.30286644572458e-06*G0_3_5 - 7.84048403096156e-05*G0_4_0 + 0.000107758202996317*G0_4_1 + 0.000159523016665901*G0_4_2 - 0.000172525886811631*G0_4_3 - 0.00116525449858803*G0_4_4 - 0.000249204058727911*G0_4_5 - 5.25400525400616e-05*G0_5_0 + 1.6843826367639e-05*G0_5_2 + 9.30286644572459e-06*G0_5_3 - 0.000249204058727911*G0_5_4 + 6.46972075543602e-05*G0_5_5; + A[211] = A[181] + 0.000140952521904927*G0_0_0 - 4.14400414400485e-05*G0_0_1 + 3.83390859581399e-05*G0_0_3 + 0.000237927856975516*G0_0_4 + 0.000111634397348702*G0_0_5 - 4.14400414400485e-05*G0_1_0 + 4.14400414400484e-05*G0_1_2 + 4.14400414400484e-05*G0_2_1 - 0.000140952521904926*G0_2_2 - 0.000111634397348702*G0_2_3 - 0.000237927856975516*G0_2_4 - 3.83390859581403e-05*G0_2_5 + 3.83390859581399e-05*G0_3_0 - 0.000111634397348702*G0_3_2 + 6.31467298134086e-05*G0_3_3 - 7.66781719162792e-05*G0_3_4 + 0.000237927856975516*G0_4_0 - 0.000237927856975516*G0_4_2 - 7.66781719162793e-05*G0_4_3 + 7.66781719162811e-05*G0_4_5 + 0.000111634397348702*G0_5_0 - 3.83390859581403e-05*G0_5_2 + 7.66781719162811e-05*G0_5_4 - 6.31467298134055e-05*G0_5_5; + A[27] = A[181]; + A[14] = A[211] - 0.000121430597621094*G0_0_0 - 6.3428634857214e-07*G0_0_2 + 7.16038811277028e-05*G0_0_3 - 0.000104868676297265*G0_0_4 + 0.000121430597621094*G0_1_1 + 6.34286348572174e-07*G0_1_2 + 0.000104868676297266*G0_1_3 - 7.16038811277027e-05*G0_1_4 - 6.34286348572147e-07*G0_2_0 + 6.34286348572181e-07*G0_2_1 - 3.58019405638514e-05*G0_2_3 + 3.58019405638511e-05*G0_2_4 + 7.16038811277028e-05*G0_3_0 + 0.000104868676297266*G0_3_1 - 3.58019405638514e-05*G0_3_2 - 0.000792716983193308*G0_3_3 - 0.000143207762255406*G0_3_5 - 0.000104868676297265*G0_4_0 - 7.16038811277027e-05*G0_4_1 + 3.58019405638511e-05*G0_4_2 + 0.000792716983193307*G0_4_4 + 0.000143207762255405*G0_4_5 - 0.000143207762255406*G0_5_3 + 0.000143207762255405*G0_5_4; + A[195] = A[14] + 4.14400414400485e-05*G0_0_1 - 4.14400414400484e-05*G0_0_2 + 4.14400414400485e-05*G0_1_0 - 0.000140952521904927*G0_1_1 - 0.000237927856975516*G0_1_3 - 3.833908595814e-05*G0_1_4 - 0.000111634397348702*G0_1_5 - 4.14400414400484e-05*G0_2_0 + 0.000140952521904926*G0_2_2 + 0.000237927856975516*G0_2_3 + 0.000111634397348702*G0_2_4 + 3.83390859581401e-05*G0_2_5 - 0.000237927856975516*G0_3_1 + 0.000237927856975516*G0_3_2 + 7.66781719162798e-05*G0_3_4 - 7.66781719162804e-05*G0_3_5 - 3.833908595814e-05*G0_4_1 + 0.000111634397348702*G0_4_2 + 7.66781719162799e-05*G0_4_3 - 6.31467298134076e-05*G0_4_4 - 0.000111634397348702*G0_5_1 + 3.83390859581402e-05*G0_5_2 - 7.66781719162804e-05*G0_5_3 + 6.31467298134065e-05*G0_5_5; + A[42] = A[181] + 6.34286348572045e-07*G0_0_1 - 6.34286348572195e-07*G0_0_2 + 3.58019405638516e-05*G0_0_4 - 3.58019405638509e-05*G0_0_5 + 6.34286348572045e-07*G0_1_0 + 0.000121430597621095*G0_1_1 - 7.1603881127703e-05*G0_1_4 + 0.000104868676297265*G0_1_5 - 6.34286348572201e-07*G0_2_0 - 0.000121430597621094*G0_2_2 - 0.000104868676297266*G0_2_4 + 7.16038811277024e-05*G0_2_5 + 0.000143207762255406*G0_3_4 - 0.000143207762255405*G0_3_5 + 3.58019405638516e-05*G0_4_0 - 7.1603881127703e-05*G0_4_1 - 0.000104868676297266*G0_4_2 + 0.000143207762255406*G0_4_3 + 0.000792716983193309*G0_4_4 - 3.58019405638509e-05*G0_5_0 + 0.000104868676297265*G0_5_1 + 7.16038811277024e-05*G0_5_2 - 0.000143207762255405*G0_5_3 - 0.000792716983193305*G0_5_5; + A[182] = A[42]; + A[174] = A[126] - 0.000205226871893573*G0_0_1 + 0.000205226871893573*G0_0_2 - 0.000105244549689012*G0_0_4 + 0.000105244549689013*G0_0_5 - 0.000205226871893573*G0_1_0 + 0.000947576820592854*G0_1_1 + 0.000491642396404384*G0_1_3 + 0.000118775991791884*G0_1_4 + 0.000596886946093396*G0_1_5 + 0.000205226871893573*G0_2_0 - 0.000947576820592852*G0_2_2 - 0.000491642396404384*G0_2_3 - 0.000596886946093395*G0_2_4 - 0.000118775991791885*G0_2_5 + 0.000491642396404384*G0_3_1 - 0.000491642396404384*G0_3_2 - 0.000237551983583769*G0_3_4 + 0.00023755198358377*G0_3_5 - 0.000105244549689012*G0_4_0 + 0.000118775991791884*G0_4_1 - 0.000596886946093395*G0_4_2 - 0.000237551983583769*G0_4_3 + 0.000105244549689013*G0_5_0 + 0.000596886946093396*G0_5_1 - 0.000118775991791885*G0_5_2 + 0.000237551983583769*G0_5_3; + A[201] = A[103]; + A[15] = A[1]; + A[50] = A[126] - 0.000947576820592853*G0_0_0 + 0.000205226871893573*G0_0_2 - 0.000118775991791885*G0_0_3 - 0.000596886946093395*G0_0_4 - 0.000491642396404383*G0_0_5 + 0.000947576820592854*G0_1_1 - 0.000205226871893573*G0_1_2 + 0.000596886946093396*G0_1_3 + 0.000118775991791885*G0_1_4 + 0.000491642396404384*G0_1_5 + 0.000205226871893573*G0_2_0 - 0.000205226871893573*G0_2_1 + 0.000105244549689012*G0_2_3 - 0.000105244549689012*G0_2_4 - 0.000118775991791885*G0_3_0 + 0.000596886946093396*G0_3_1 + 0.000105244549689012*G0_3_2 + 0.00023755198358377*G0_3_5 - 0.000596886946093395*G0_4_0 + 0.000118775991791885*G0_4_1 - 0.000105244549689012*G0_4_2 - 0.000237551983583769*G0_4_5 - 0.000491642396404383*G0_5_0 + 0.000491642396404384*G0_5_1 + 0.00023755198358377*G0_5_3 - 0.000237551983583769*G0_5_4; + A[85] = A[108] + 7.00534033867486e-05*G0_0_1 - 7.00534033867484e-05*G0_0_2 + 1.18400118400139e-05*G0_0_4 - 1.18400118400139e-05*G0_0_5 + 7.00534033867486e-05*G0_1_0 - 0.000521947188613945*G0_1_1 - 0.000280213613546996*G0_1_3 + 2.36800236800277e-05*G0_1_4 - 0.000292053625387008*G0_1_5 - 7.00534033867484e-05*G0_2_0 + 0.000521947188613943*G0_2_2 + 0.000280213613546994*G0_2_3 + 0.000292053625387008*G0_2_4 - 2.36800236800276e-05*G0_2_5 - 0.000280213613546996*G0_3_1 + 0.000280213613546994*G0_3_2 - 4.73600473600556e-05*G0_3_4 + 4.7360047360055e-05*G0_3_5 + 1.18400118400139e-05*G0_4_0 + 2.36800236800277e-05*G0_4_1 + 0.000292053625387008*G0_4_2 - 4.73600473600556e-05*G0_4_3 - 0.00115242781909468*G0_4_4 - 1.18400118400139e-05*G0_5_0 - 0.000292053625387008*G0_5_1 - 2.36800236800276e-05*G0_5_2 + 4.7360047360055e-05*G0_5_3 + 0.00115242781909468*G0_5_5; + A[66] = A[94]; + A[160] = A[90] + 0.000334480334480387*G0_0_0 - 0.000420214705929063*G0_0_1 - 8.28096066191405e-06*G0_0_2 - 0.000181264943169736*G0_0_3 + 0.000153920153920179*G0_0_4 + 0.000313760313760366*G0_0_5 - 0.000420214705929062*G0_1_0 + 0.00155827711383293*G0_1_1 - 0.000105632169124251*G0_1_2 + 0.000551876107431757*G0_1_3 - 0.000161531590103046*G0_1_4 + 0.0005226049670495*G0_1_5 - 8.28096066191403e-06*G0_2_0 - 0.000105632169124251*G0_2_1 + 0.000187443362046568*G0_2_2 - 0.00031061237410449*G0_2_3 - 0.000282327901375568*G0_2_4 - 0.000844493542906383*G0_2_5 - 0.000181264943169736*G0_3_0 + 0.000551876107431757*G0_3_1 - 0.00031061237410449*G0_3_2 + 0.00150837992107859*G0_3_3 + 0.000685593066545563*G0_3_4 + 0.00205151697215224*G0_3_5 + 0.000153920153920179*G0_4_0 - 0.000161531590103046*G0_4_1 - 0.000282327901375568*G0_4_2 + 0.000685593066545563*G0_4_3 + 0.001384717575194*G0_4_4 + 0.00201205026601886*G0_4_5 + 0.000313760313760366*G0_5_0 + 0.0005226049670495*G0_5_1 - 0.000844493542906383*G0_5_2 + 0.00205151697215224*G0_5_3 + 0.00201205026601886*G0_5_4 + 0.0135983475666038*G0_5_5; + A[109] = -A[32] - 2.64873280746326e-06*G0_0_0 + 1.45915225280329e-05*G0_0_1 - 0.000182119467833784*G0_0_2 + 4.01127385254442e-06*G0_0_3 - 3.78516251532183e-05*G0_0_4 + 1.45915225280329e-05*G0_1_0 - 2.64873280746434e-06*G0_1_1 - 0.000182119467833783*G0_1_2 - 3.78516251532191e-05*G0_1_3 + 4.01127385254465e-06*G0_1_4 - 0.000182119467833784*G0_2_0 - 0.000182119467833783*G0_2_1 + 0.00243978243978285*G0_2_2 + 0.000770340770340898*G0_2_3 + 0.000770340770340898*G0_2_4 + 6.34286348572171e-05*G0_2_5 + 4.01127385254444e-06*G0_3_0 - 3.78516251532191e-05*G0_3_1 + 0.000770340770340898*G0_3_2 - 0.000684982272283973*G0_3_3 - 1.60450954101782e-05*G0_3_4 - 0.000134879817419523*G0_3_5 - 3.78516251532183e-05*G0_4_0 + 4.01127385254466e-06*G0_4_1 + 0.000770340770340898*G0_4_2 - 1.60450954101782e-05*G0_4_3 - 0.000684982272283976*G0_4_4 - 0.000134879817419523*G0_4_5 + 6.34286348572171e-05*G0_5_2 - 0.000134879817419523*G0_5_3 - 0.000134879817419523*G0_5_4 + 0.000103999469078851*G0_5_5; + A[184] = A[72]; + A[2] = -7.19650719650841e-05*G0_0_0 + 2.05849412198652e-06*G0_0_1 + 1.02601689903295e-05*G0_0_2 - 2.01855757411347e-05*G0_0_4 - 1.19633452966806e-05*G0_0_5 + 2.05849412198652e-06*G0_1_0 + 9.6581842613605e-06*G0_1_1 + 2.05849412198652e-06*G0_1_2 + 3.06571735143216e-06*G0_1_3 + 3.06571735143216e-06*G0_1_5 + 1.02601689903294e-05*G0_2_0 + 2.05849412198652e-06*G0_2_1 - 7.1965071965084e-05*G0_2_2 - 1.19633452966806e-05*G0_2_3 - 2.01855757411347e-05*G0_2_4 + 3.06571735143216e-06*G0_3_1 - 1.19633452966806e-05*G0_3_2 + 2.64285978571737e-06*G0_3_3 + 2.65460582920946e-06*G0_3_5 - 2.01855757411347e-05*G0_4_0 - 2.01855757411347e-05*G0_4_2 - 2.54771683343155e-05*G0_4_4 - 1.19633452966806e-05*G0_5_0 + 3.06571735143216e-06*G0_5_1 + 2.65460582920946e-06*G0_5_3 + 2.6428597857174e-06*G0_5_5; + A[18] = A[46]; + A[133] = A[103] + 0.000387901340282357*G0_0_0 - 0.000128548699977293*G0_0_1 + 0.000342796533272781*G0_0_3 + 0.00104643152262217*G0_0_4 + 0.000198461150842136*G0_0_5 - 0.000128548699977293*G0_1_0 + 0.000128548699977293*G0_1_2 + 2.70628842057459e-05*G0_1_3 - 2.70628842057457e-05*G0_1_5 + 0.000128548699977293*G0_2_1 - 0.000387901340282357*G0_2_2 - 0.000198461150842136*G0_2_3 - 0.00104643152262217*G0_2_4 - 0.000342796533272782*G0_2_5 + 0.000342796533272781*G0_3_0 + 2.70628842057459e-05*G0_3_1 - 0.000198461150842136*G0_3_2 - 0.0019485276628137*G0_3_3 - 0.000685593066545562*G0_3_4 + 0.00104643152262217*G0_4_0 - 0.00104643152262217*G0_4_2 - 0.000685593066545562*G0_4_3 + 0.000685593066545563*G0_4_5 + 0.000198461150842136*G0_5_0 - 2.70628842057457e-05*G0_5_1 - 0.000342796533272782*G0_5_2 + 0.000685593066545563*G0_5_4 + 0.00194852766281371*G0_5_5; + A[45] = A[41] + 6.75397500794433e-05*G0_0_0 - 1.57631903663675e-05*G0_0_1 + 4.69841739683095e-06*G0_0_3 + 1.83238278476404e-05*G0_0_4 - 6.38984765969007e-06*G0_0_5 - 1.57631903663675e-05*G0_1_0 + 1.57631903663677e-05*G0_1_2 - 6.47441917283301e-05*G0_1_3 + 6.47441917283293e-05*G0_1_5 + 1.57631903663677e-05*G0_2_1 - 6.75397500794442e-05*G0_2_2 + 6.38984765969013e-06*G0_2_3 - 1.83238278476405e-05*G0_2_4 - 4.69841739683083e-06*G0_2_5 + 4.69841739683095e-06*G0_3_0 - 6.47441917283301e-05*G0_3_1 + 6.38984765969014e-06*G0_3_2 - 0.000150725230090336*G0_3_3 - 9.39683479366182e-06*G0_3_4 + 1.83238278476404e-05*G0_4_0 - 1.83238278476405e-05*G0_4_2 - 9.39683479366182e-06*G0_4_3 + 9.39683479366172e-06*G0_4_5 - 6.38984765969007e-06*G0_5_0 + 6.47441917283293e-05*G0_5_1 - 4.69841739683083e-06*G0_5_2 + 9.39683479366172e-06*G0_5_4 + 0.000150725230090335*G0_5_5; + A[47] = A[45] - 2.0344147328277e-05*G0_0_0 - 2.11428782857468e-07*G0_0_1 - 2.01327185454203e-05*G0_0_2 - 1.15111226222357e-05*G0_0_3 + 4.22857565714903e-07*G0_0_5 - 2.11428782857468e-07*G0_1_0 - 2.2693356026693e-05*G0_1_1 - 3.63892427384552e-05*G0_1_2 + 2.03911315022463e-05*G0_1_3 + 4.22857565714821e-07*G0_1_4 - 2.01327185454203e-05*G0_2_0 - 3.63892427384552e-05*G0_2_1 + 0.000427180109719864*G0_2_2 + 0.000113654716829339*G0_2_3 + 8.0483890007713e-05*G0_2_4 - 4.22857565714781e-07*G0_2_5 - 1.15111226222357e-05*G0_3_0 + 2.03911315022463e-05*G0_3_1 + 0.000113654716829339*G0_3_2 + 0.000241874527588855*G0_3_3 + 2.21765301130418e-05*G0_3_4 + 2.3867960375901e-05*G0_3_5 + 4.22857565714821e-07*G0_4_1 + 8.0483890007713e-05*G0_4_2 + 2.21765301130418e-05*G0_4_3 - 9.3968347936623e-07*G0_4_4 + 4.22857565714906e-07*G0_5_0 - 4.22857565714784e-07*G0_5_2 + 2.3867960375901e-05*G0_5_3 - 2.38679603759006e-05*G0_5_5; + A[76] = -A[47] - 3.05397130794041e-07*G0_0_1 - 3.05397130794014e-07*G0_0_2 + 2.86603461206684e-05*G0_0_3 + 2.58882798565382e-05*G0_0_4 + 2.58882798565382e-05*G0_0_5 - 3.05397130794044e-07*G0_1_0 + 0.000185000185000216*G0_1_1 + 1.43301730603342e-05*G0_1_3 + 9.02096140191525e-06*G0_1_4 - 1.56457299314467e-05*G0_1_5 - 3.05397130794017e-07*G0_2_0 + 0.000185000185000216*G0_2_2 + 1.43301730603343e-05*G0_2_3 - 1.56457299314468e-05*G0_2_4 + 9.02096140191532e-06*G0_2_5 + 2.86603461206684e-05*G0_3_0 + 1.43301730603342e-05*G0_3_1 + 1.43301730603342e-05*G0_3_2 + 4.20978198756048e-05*G0_3_3 - 7.53626150451674e-05*G0_3_4 - 7.53626150451674e-05*G0_3_5 + 2.58882798565382e-05*G0_4_0 + 9.02096140191525e-06*G0_4_1 - 1.56457299314468e-05*G0_4_2 - 7.53626150451674e-05*G0_4_3 - 0.000104492802905519*G0_4_4 - 3.60838456076612e-05*G0_4_5 + 2.58882798565382e-05*G0_5_0 - 1.56457299314467e-05*G0_5_1 + 9.02096140191532e-06*G0_5_2 - 7.53626150451673e-05*G0_5_3 - 3.60838456076612e-05*G0_5_4 - 0.000104492802905519*G0_5_5; + A[20] = A[76]; + A[5] = A[76] + 2.03441473282775e-05*G0_0_0 + 2.01327185454204e-05*G0_0_1 + 2.11428782857414e-07*G0_0_2 + 1.15111226222357e-05*G0_0_3 - 4.22857565714791e-07*G0_0_4 + 2.01327185454204e-05*G0_1_0 - 0.000427180109719865*G0_1_1 + 3.63892427384553e-05*G0_1_2 - 0.000113654716829339*G0_1_3 + 4.22857565714848e-07*G0_1_4 - 8.04838900077133e-05*G0_1_5 + 2.11428782857414e-07*G0_2_0 + 3.63892427384553e-05*G0_2_1 + 2.2693356026693e-05*G0_2_2 - 2.03911315022461e-05*G0_2_3 - 4.22857565714767e-07*G0_2_5 + 1.15111226222357e-05*G0_3_0 - 0.000113654716829339*G0_3_1 - 2.03911315022462e-05*G0_3_2 - 0.000241874527588854*G0_3_3 - 2.3867960375901e-05*G0_3_4 - 2.21765301130419e-05*G0_3_5 - 4.22857565714794e-07*G0_4_0 + 4.22857565714848e-07*G0_4_1 - 2.38679603759009e-05*G0_4_3 + 2.38679603759008e-05*G0_4_4 - 8.04838900077133e-05*G0_5_1 - 4.22857565714767e-07*G0_5_2 - 2.21765301130419e-05*G0_5_3 + 9.39683479366124e-07*G0_5_5; + A[100] = -A[5] - 0.00155844155844182*G0_0_0 + 0.000209572907985642*G0_0_1 + 0.000266306298052375*G0_0_2 - 4.51987753575133e-05*G0_0_3 - 0.00113170779837465*G0_0_4 - 0.000737698515476417*G0_0_5 + 0.000209572907985642*G0_1_0 - 0.000155423647487165*G0_1_1 + 1.15111226222352e-06*G0_1_2 - 2.20825617651048e-06*G0_1_3 + 0.000219604029127876*G0_1_4 + 9.92775595950369e-05*G0_1_5 + 0.000266306298052375*G0_2_0 + 1.15111226222352e-06*G0_2_1 - 0.000231232612185032*G0_2_2 - 4.75949682298967e-05*G0_2_3 + 0.000286086635293033*G0_2_4 + 0.000199870676061186*G0_2_5 - 4.51987753575132e-05*G0_3_0 - 2.20825617651047e-06*G0_3_1 - 4.75949682298967e-05*G0_3_2 - 0.000606471717582931*G0_3_3 - 0.000348810507540725*G0_3_4 - 0.000309343801407346*G0_3_5 - 0.00113170779837466*G0_4_0 + 0.000219604029127876*G0_4_1 + 0.000286086635293033*G0_4_2 - 0.000348810507540725*G0_4_3 - 0.00174348872761601*G0_4_4 - 0.000838949410378123*G0_4_5 - 0.000737698515476417*G0_5_0 + 9.92775595950369e-05*G0_5_1 + 0.000199870676061186*G0_5_2 - 0.000309343801407346*G0_5_3 - 0.000838949410378123*G0_5_4 - 0.000798918894157124*G0_5_5; + A[153] = A[100] + 0.0014705576610341*G0_0_0 - 0.000280918376156519*G0_0_2 + 0.00026950122188222*G0_0_3 + 0.00112310969453845*G0_0_4 + 0.000855299902919094*G0_0_5 - 0.0014705576610341*G0_1_1 + 0.000280918376156519*G0_1_2 - 0.00112310969453846*G0_1_3 - 0.00026950122188222*G0_1_4 - 0.000855299902919095*G0_1_5 - 0.000280918376156519*G0_2_0 + 0.000280918376156519*G0_2_1 + 0.0002689374117946*G0_2_3 - 0.0002689374117946*G0_2_4 + 0.00026950122188222*G0_3_0 - 0.00112310969453846*G0_3_1 + 0.0002689374117946*G0_3_2 - 0.00128774224012341*G0_3_3 - 0.000539002443764439*G0_3_5 + 0.00112310969453845*G0_4_0 - 0.00026950122188222*G0_4_1 - 0.0002689374117946*G0_4_2 + 0.00128774224012341*G0_4_4 + 0.000539002443764439*G0_4_5 + 0.000855299902919094*G0_5_0 - 0.000855299902919095*G0_5_1 - 0.000539002443764439*G0_5_3 + 0.000539002443764439*G0_5_4; + A[110] = A[153] - 0.000245398340636477*G0_0_1 + 0.000245398340636477*G0_0_2 + 0.000142643952167785*G0_0_4 - 0.000142643952167786*G0_0_5 - 0.000245398340636477*G0_1_0 + 0.00149987578559033*G0_1_1 + 0.00152059580631035*G0_1_3 + 0.000283032663985092*G0_1_4 + 0.000841204650728602*G0_1_5 + 0.000245398340636477*G0_2_0 - 0.00149987578559032*G0_2_2 - 0.00152059580631035*G0_2_3 - 0.0008412046507286*G0_2_4 - 0.000283032663985093*G0_2_5 + 0.00152059580631035*G0_3_1 - 0.00152059580631035*G0_3_2 - 0.000566065327970183*G0_3_4 + 0.000566065327970186*G0_3_5 + 0.000142643952167785*G0_4_0 + 0.000283032663985092*G0_4_1 - 0.0008412046507286*G0_4_2 - 0.000566065327970183*G0_4_3 - 0.000403688022735708*G0_4_4 - 0.000142643952167786*G0_5_0 + 0.000841204650728602*G0_5_1 - 0.000283032663985093*G0_5_2 + 0.000566065327970186*G0_5_3 + 0.000403688022735711*G0_5_5; + A[142] = A[100] + 3.55200355200411e-05*G0_0_1 - 3.55200355200418e-05*G0_0_2 + 0.000410453743787146*G0_0_4 - 0.000410453743787145*G0_0_5 + 3.55200355200411e-05*G0_1_0 + 2.93181245562249e-05*G0_1_1 + 0.000128548699977293*G0_1_3 + 1.35314421028726e-05*G0_1_4 + 0.000254842159604107*G0_1_5 - 3.55200355200418e-05*G0_2_0 - 2.93181245562245e-05*G0_2_2 - 0.000128548699977293*G0_2_3 - 0.000254842159604107*G0_2_4 - 1.35314421028732e-05*G0_2_5 + 0.000128548699977293*G0_3_1 - 0.000128548699977293*G0_3_2 - 2.7062884205745e-05*G0_3_4 + 2.70628842057465e-05*G0_3_5 + 0.000410453743787146*G0_4_0 + 1.35314421028726e-05*G0_4_1 - 0.000254842159604107*G0_4_2 - 2.7062884205745e-05*G0_4_3 + 0.000884054217387703*G0_4_4 - 0.000410453743787144*G0_5_0 + 0.000254842159604107*G0_5_1 - 1.35314421028732e-05*G0_5_2 + 2.70628842057465e-05*G0_5_3 - 0.000884054217387696*G0_5_5; + A[169] = A[153] + 2.93181245562242e-05*G0_0_0 + 3.55200355200411e-05*G0_0_1 + 1.35314421028725e-05*G0_0_3 + 0.000128548699977293*G0_0_4 + 0.000254842159604106*G0_0_5 + 3.55200355200411e-05*G0_1_0 - 3.55200355200421e-05*G0_1_2 + 0.000410453743787149*G0_1_3 - 0.000410453743787144*G0_1_5 - 3.55200355200421e-05*G0_2_1 - 2.93181245562248e-05*G0_2_2 - 0.000254842159604108*G0_2_3 - 0.000128548699977293*G0_2_4 - 1.35314421028733e-05*G0_2_5 + 1.35314421028725e-05*G0_3_0 + 0.000410453743787149*G0_3_1 - 0.000254842159604108*G0_3_2 + 0.000884054217387704*G0_3_3 - 2.70628842057456e-05*G0_3_4 + 0.000128548699977293*G0_4_0 - 0.000128548699977293*G0_4_2 - 2.70628842057457e-05*G0_4_3 + 2.70628842057463e-05*G0_4_5 + 0.000254842159604106*G0_5_0 - 0.000410453743787144*G0_5_1 - 1.35314421028733e-05*G0_5_2 + 2.70628842057463e-05*G0_5_4 - 0.000884054217387695*G0_5_5; + A[71] = A[169]; + A[82] = A[110]; + A[68] = A[100] + 0.00149987578559032*G0_0_0 - 0.000245398340636477*G0_0_1 + 0.000283032663985093*G0_0_3 + 0.00152059580631035*G0_0_4 + 0.000841204650728601*G0_0_5 - 0.000245398340636477*G0_1_0 + 0.000245398340636477*G0_1_2 + 0.000142643952167785*G0_1_3 - 0.000142643952167786*G0_1_5 + 0.000245398340636477*G0_2_1 - 0.00149987578559032*G0_2_2 - 0.000841204650728601*G0_2_3 - 0.00152059580631035*G0_2_4 - 0.000283032663985093*G0_2_5 + 0.000283032663985092*G0_3_0 + 0.000142643952167785*G0_3_1 - 0.000841204650728601*G0_3_2 - 0.000403688022735708*G0_3_3 - 0.000566065327970184*G0_3_4 + 0.00152059580631035*G0_4_0 - 0.00152059580631035*G0_4_2 - 0.000566065327970184*G0_4_3 + 0.000566065327970185*G0_4_5 + 0.000841204650728601*G0_5_0 - 0.000142643952167786*G0_5_1 - 0.000283032663985093*G0_5_2 + 0.000566065327970185*G0_5_4 + 0.00040368802273571*G0_5_5; + A[179] = A[149] + 0.000387901340282357*G0_0_0 - 0.000128548699977293*G0_0_2 + 0.000342796533272781*G0_0_3 + 0.000198461150842136*G0_0_4 + 0.00104643152262217*G0_0_5 - 0.000387901340282357*G0_1_1 + 0.000128548699977293*G0_1_2 - 0.000198461150842136*G0_1_3 - 0.000342796533272781*G0_1_4 - 0.00104643152262217*G0_1_5 - 0.000128548699977293*G0_2_0 + 0.000128548699977293*G0_2_1 + 2.70628842057463e-05*G0_2_3 - 2.70628842057457e-05*G0_2_4 + 0.000342796533272781*G0_3_0 - 0.000198461150842136*G0_3_1 + 2.70628842057463e-05*G0_3_2 - 0.0019485276628137*G0_3_3 - 0.000685593066545562*G0_3_5 + 0.000198461150842136*G0_4_0 - 0.000342796533272781*G0_4_1 - 2.70628842057457e-05*G0_4_2 + 0.0019485276628137*G0_4_4 + 0.000685593066545563*G0_4_5 + 0.00104643152262217*G0_5_0 - 0.00104643152262217*G0_5_1 - 0.000685593066545562*G0_5_3 + 0.000685593066545563*G0_5_4; + A[116] = A[108] - 0.000434556625032888*G0_0_0 + 5.90591066781641e-05*G0_0_1 - 4.17219464838581e-05*G0_0_3 - 0.000238491667063136*G0_0_4 - 0.000216503073645967*G0_0_5 + 5.90591066781641e-05*G0_1_0 - 5.90591066781639e-05*G0_1_2 - 2.19885934171693e-05*G0_1_3 + 2.19885934171692e-05*G0_1_5 - 5.90591066781639e-05*G0_2_1 + 0.000434556625032887*G0_2_2 + 0.000216503073645967*G0_2_3 + 0.000238491667063135*G0_2_4 + 4.17219464838583e-05*G0_2_5 - 4.17219464838581e-05*G0_3_0 - 2.19885934171693e-05*G0_3_1 + 0.000216503073645967*G0_3_2 + 2.02971631543074e-05*G0_3_3 + 8.34438929677164e-05*G0_3_4 - 0.000238491667063136*G0_4_0 + 0.000238491667063135*G0_4_2 + 8.34438929677164e-05*G0_4_3 - 8.34438929677164e-05*G0_4_5 - 0.000216503073645967*G0_5_0 + 2.19885934171692e-05*G0_5_1 + 4.17219464838583e-05*G0_5_2 - 8.34438929677164e-05*G0_5_4 - 2.0297163154309e-05*G0_5_5; + A[219] = A[149]; + A[55] = A[153]; + A[29] = A[211]; + A[43] = A[195] + 0.000121430597621094*G0_0_0 + 6.3428634857214e-07*G0_0_1 - 7.16038811277029e-05*G0_0_3 + 0.000104868676297265*G0_0_5 + 6.34286348572127e-07*G0_1_0 - 6.34286348572262e-07*G0_1_2 + 3.58019405638516e-05*G0_1_3 - 3.58019405638512e-05*G0_1_5 - 6.34286348572269e-07*G0_2_1 - 0.000121430597621094*G0_2_2 - 0.000104868676297265*G0_2_3 + 7.16038811277026e-05*G0_2_5 - 7.16038811277029e-05*G0_3_0 + 3.58019405638516e-05*G0_3_1 - 0.000104868676297265*G0_3_2 + 0.000792716983193309*G0_3_3 + 0.000143207762255406*G0_3_4 + 0.000143207762255406*G0_4_3 - 0.000143207762255405*G0_4_5 + 0.000104868676297265*G0_5_0 - 3.58019405638512e-05*G0_5_1 + 7.16038811277026e-05*G0_5_2 - 0.000143207762255405*G0_5_4 - 0.000792716983193307*G0_5_5; + A[146] = A[174]; + A[75] = A[5]; + A[150] = A[10]; + A[183] = A[57]; + A[220] = A[164]; + A[197] = A[43]; + A[12] = 0.000310800310800363*G0_0_0 - 2.46666913333617e-06*G0_0_1 - 2.46666913333615e-06*G0_0_2 - 9.86667653334488e-05*G0_0_3 - 3.94667061333797e-05*G0_0_4 - 3.94667061333797e-05*G0_0_5 - 2.46666913333617e-06*G0_1_0 + 3.67181319562335e-05*G0_1_1 - 2.6921931683841e-05*G0_1_2 + 4.51048070095776e-06*G0_1_3 + 7.89334122667599e-06*G0_1_4 + 5.72267238934003e-05*G0_1_5 - 2.46666913333615e-06*G0_2_0 - 2.6921931683841e-05*G0_2_1 + 3.67181319562334e-05*G0_2_2 + 4.51048070095766e-06*G0_2_3 + 5.72267238934003e-05*G0_2_4 + 7.893341226676e-06*G0_2_5 - 9.86667653334488e-05*G0_3_0 + 4.51048070095776e-06*G0_3_1 + 4.51048070095766e-06*G0_3_2 + 0.000598766313052129*G0_3_3 + 0.000181546848213545*G0_3_4 + 0.000181546848213545*G0_3_5 - 3.94667061333797e-05*G0_4_0 + 7.89334122667598e-06*G0_4_1 + 5.72267238934003e-05*G0_4_2 + 0.000181546848213545*G0_4_3 - 4.73600473600555e-05*G0_4_4 - 3.15733649067039e-05*G0_4_5 - 3.94667061333797e-05*G0_5_0 + 5.72267238934003e-05*G0_5_1 + 7.89334122667599e-06*G0_5_2 + 0.000181546848213545*G0_5_3 - 3.15733649067038e-05*G0_5_4 - 4.73600473600556e-05*G0_5_5; + A[170] = A[12] - 0.000239572303064407*G0_0_0 - 0.000136042675725238*G0_0_1 - 1.40952521904924e-05*G0_0_3 + 1.87936695873267e-06*G0_0_4 - 0.000162753178626221*G0_0_5 - 0.000136042675725238*G0_1_0 + 0.000744722649484679*G0_1_1 - 8.79073894947058e-05*G0_1_2 + 0.000374369898179485*G0_1_3 + 4.02184529168721e-05*G0_1_4 + 0.000595289484178472*G0_1_5 - 8.79073894947058e-05*G0_2_1 + 5.40552921505395e-05*G0_2_2 - 3.68355923911539e-05*G0_2_3 - 9.11492974985194e-06*G0_2_4 - 0.000111634397348702*G0_2_5 - 1.40952521904924e-05*G0_3_0 + 0.000374369898179484*G0_3_1 - 3.68355923911539e-05*G0_3_2 - 0.000231913882707573*G0_3_3 - 5.22464014527595e-05*G0_3_4 + 0.000251459299078388*G0_3_5 + 1.87936695873267e-06*G0_4_0 + 4.02184529168721e-05*G0_4_1 - 9.11492974985194e-06*G0_4_2 - 5.22464014527595e-05*G0_4_3 + 0.000158618571317011*G0_4_4 + 0.000142831888863659*G0_4_5 - 0.000162753178626221*G0_5_0 + 0.000595289484178472*G0_5_1 - 0.000111634397348702*G0_5_2 + 0.000251459299078388*G0_5_3 + 0.000142831888863659*G0_5_4 + 0.00100358195596308*G0_5_5; + A[86] = A[170]; + A[138] = A[170] + 1.95454163708156e-05*G0_0_0 + 2.36800236800275e-05*G0_0_1 + 9.02096140191506e-06*G0_0_3 + 8.56991333181951e-05*G0_0_4 + 0.000169894773069404*G0_0_5 + 2.36800236800275e-05*G0_1_0 - 2.36800236800279e-05*G0_1_2 + 0.000273635829191432*G0_1_3 - 0.000273635829191429*G0_1_5 - 2.3680023680028e-05*G0_2_1 - 1.95454163708166e-05*G0_2_2 - 0.000169894773069405*G0_2_3 - 8.56991333181955e-05*G0_2_4 - 9.02096140191551e-06*G0_2_5 + 9.02096140191506e-06*G0_3_0 + 0.000273635829191432*G0_3_1 - 0.000169894773069405*G0_3_2 + 0.000589369478258468*G0_3_3 - 1.80419228038305e-05*G0_3_4 + 8.56991333181951e-05*G0_4_0 - 8.56991333181955e-05*G0_4_2 - 1.80419228038305e-05*G0_4_3 + 1.80419228038307e-05*G0_4_5 + 0.000169894773069404*G0_5_0 - 0.000273635829191429*G0_5_1 - 9.02096140191551e-06*G0_5_2 + 1.80419228038307e-05*G0_5_4 - 0.000589369478258466*G0_5_5; + A[129] = A[170] + 0.000710212773704955*G0_0_0 - 0.000124226155972208*G0_0_2 + 0.000160873811667489*G0_0_3 + 0.000416467718055089*G0_0_4 + 0.000854736092831473*G0_0_5 - 0.000710212773704956*G0_1_1 + 0.000124226155972209*G0_1_2 - 0.000416467718055089*G0_1_3 - 0.000160873811667489*G0_1_4 - 0.000854736092831473*G0_1_5 - 0.000124226155972208*G0_2_0 + 0.000124226155972209*G0_2_1 + 8.04369058337444e-05*G0_2_3 - 8.04369058337447e-05*G0_2_4 + 0.000160873811667489*G0_3_0 - 0.000416467718055089*G0_3_1 + 8.04369058337444e-05*G0_3_2 - 0.0002555939063876*G0_3_3 - 0.000321747623334979*G0_3_5 + 0.000416467718055089*G0_4_0 - 0.000160873811667489*G0_4_1 - 8.04369058337447e-05*G0_4_2 + 0.0002555939063876*G0_4_4 + 0.000321747623334979*G0_4_5 + 0.000854736092831473*G0_5_0 - 0.000854736092831473*G0_5_1 - 0.000321747623334979*G0_5_3 + 0.000321747623334979*G0_5_4; + A[97] = -A[129] - 0.00140896140896165*G0_0_0 + 2.23174826349468e-05*G0_0_1 + 0.000288717749035258*G0_0_2 + 7.57384884369136e-05*G0_0_3 - 0.000615680615680721*G0_0_4 - 8.94578672356608e-05*G0_0_5 + 2.23174826349468e-05*G0_1_0 + 4.69841739683108e-07*G0_1_1 + 5.09778287556149e-05*G0_1_2 + 0.000132683307286504*G0_1_3 + 0.000168579216198292*G0_1_4 + 9.77270818540858e-06*G0_1_5 + 0.000288717749035258*G0_2_0 + 5.09778287556149e-05*G0_2_1 - 0.000615680615680718*G0_2_2 - 0.00026085613387205*G0_2_3 - 0.000370611164262019*G0_2_4 + 9.58477148953507e-06*G0_2_5 + 7.57384884369136e-05*G0_3_0 + 0.000132683307286504*G0_3_1 - 0.00026085613387205*G0_3_2 - 0.000673565118009674*G0_3_3 - 0.000488635409270411*G0_3_4 - 0.000170646519852898*G0_3_5 - 0.000615680615680721*G0_4_0 + 0.000168579216198292*G0_4_1 - 0.000370611164262019*G0_4_2 - 0.000488635409270411*G0_4_3 - 0.0010223756255504*G0_4_4 - 0.000356327975375654*G0_4_5 - 8.94578672356609e-05*G0_5_0 + 9.77270818540858e-06*G0_5_1 + 9.58477148953507e-06*G0_5_2 - 0.000170646519852898*G0_5_3 - 0.000356327975375654*G0_5_4 + 0.000135314421028728*G0_5_5; + A[111] = A[97]; + A[113] = A[97] + 0.00148394815061507*G0_0_0 - 0.000119245833531568*G0_0_1 + 8.56991333181952e-05*G0_0_3 + 0.000656274941989338*G0_0_4 + 0.000433006147291934*G0_0_5 - 0.000119245833531568*G0_1_0 + 0.000119245833531567*G0_1_2 + 4.1721946483858e-05*G0_1_3 - 4.17219464838585e-05*G0_1_5 + 0.000119245833531567*G0_2_1 - 0.00148394815061506*G0_2_2 - 0.000433006147291933*G0_2_3 - 0.000656274941989337*G0_2_4 - 8.56991333181955e-05*G0_2_5 + 8.56991333181952e-05*G0_3_0 + 4.1721946483858e-05*G0_3_1 - 0.000433006147291933*G0_3_2 - 3.60838456076611e-05*G0_3_3 - 0.00017139826663639*G0_3_4 + 0.000656274941989339*G0_4_0 - 0.000656274941989337*G0_4_2 - 0.00017139826663639*G0_4_3 + 0.000171398266636391*G0_4_5 + 0.000433006147291934*G0_5_0 - 4.17219464838585e-05*G0_5_1 - 8.56991333181955e-05*G0_5_2 + 0.000171398266636391*G0_5_4 + 3.60838456076628e-05*G0_5_5; + A[65] = A[113] + 0.000635695873791218*G0_0_0 - 0.000242720242720283*G0_0_2 + 0.000168015406110673*G0_0_3 + 0.000550278645516833*G0_0_4 + 0.000479238574476749*G0_0_5 - 0.000635695873791219*G0_1_1 + 0.000242720242720284*G0_1_2 - 0.000550278645516833*G0_1_3 - 0.000168015406110672*G0_1_4 - 0.00047923857447675*G0_1_5 - 0.000242720242720283*G0_2_0 + 0.000242720242720284*G0_2_1 - 0.00025258691925363*G0_2_3 + 0.000252586919253627*G0_2_4 + 0.000168015406110673*G0_3_0 - 0.000550278645516833*G0_3_1 - 0.00025258691925363*G0_3_2 - 0.000568320568320666*G0_3_3 - 0.000336030812221345*G0_3_5 + 0.000550278645516833*G0_4_0 - 0.000168015406110672*G0_4_1 + 0.000252586919253627*G0_4_2 + 0.000568320568320661*G0_4_4 + 0.000336030812221345*G0_4_5 + 0.000479238574476749*G0_5_0 - 0.00047923857447675*G0_5_1 - 0.000336030812221345*G0_5_3 + 0.000336030812221345*G0_5_4; + A[175] = A[113] + 0.000361966076251851*G0_0_1 - 0.000361966076251851*G0_0_2 + 2.93181245562251e-05*G0_0_4 - 2.93181245562259e-05*G0_0_5 + 0.000361966076251851*G0_1_0 - 0.00211964402440629*G0_1_1 - 0.000953966668252542*G0_1_3 - 0.000253714539428867*G0_1_4 - 0.00116483164102231*G0_1_5 - 0.000361966076251851*G0_2_0 + 0.00211964402440628*G0_2_2 + 0.000953966668252541*G0_2_3 + 0.00116483164102231*G0_2_4 + 0.000253714539428868*G0_2_5 - 0.000953966668252543*G0_3_1 + 0.000953966668252541*G0_3_2 + 0.000507429078857734*G0_3_4 - 0.000507429078857736*G0_3_5 + 2.93181245562251e-05*G0_4_0 - 0.000253714539428867*G0_4_1 + 0.00116483164102231*G0_4_2 + 0.000507429078857734*G0_4_3 + 0.000604404413928322*G0_4_4 - 2.93181245562259e-05*G0_5_0 - 0.00116483164102231*G0_5_1 + 0.000253714539428868*G0_5_2 - 0.000507429078857735*G0_5_3 - 0.000604404413928324*G0_5_5; + A[186] = -A[175] + 0.00118794785461472*G0_0_0 - 6.90667357334141e-06*G0_0_1 - 0.000439912820865276*G0_0_2 + 0.000650073031025521*G0_0_3 + 0.00215375453470728*G0_0_4 + 0.00130352892257676*G0_0_5 - 6.90667357334141e-06*G0_1_0 - 0.00214078690269202*G0_1_1 + 0.000338990815181349*G0_1_2 - 0.000701379748998915*G0_1_3 - 0.000400868972297611*G0_1_4 - 0.00145011954535788*G0_1_5 - 0.000439912820865276*G0_2_0 + 0.000338990815181349*G0_2_1 - 7.97791273981882e-05*G0_2_2 - 4.51048070095801e-06*G0_2_3 - 0.000794972223543787*G0_2_4 - 0.00017421731707449*G0_2_5 + 0.000650073031025521*G0_3_0 - 0.000701379748998915*G0_3_1 - 4.51048070095798e-06*G0_3_2 - 0.00244468053991905*G0_3_3 - 0.000498408117455819*G0_3_4 - 0.000951711427902063*G0_3_5 + 0.00215375453470728*G0_4_0 - 0.000400868972297611*G0_4_1 - 0.000794972223543787*G0_4_2 - 0.000498408117455819*G0_4_3 + 0.00275139322758417*G0_4_4 + 0.0011501725787442*G0_4_5 + 0.00130352892257676*G0_5_0 - 0.00145011954535788*G0_5_1 - 0.00017421731707449*G0_5_2 - 0.000951711427902062*G0_5_3 + 0.0011501725787442*G0_5_4 + 0.000378880378880448*G0_5_5; + A[218] = A[186] - 0.00190342285580413*G0_0_0 + 0.000588617731474973*G0_0_1 - 0.000992305754210683*G0_0_3 - 0.00342796533272781*G0_0_4 - 0.00185831804879455*G0_0_5 + 0.000588617731474973*G0_1_0 - 0.000588617731474973*G0_1_2 - 0.000496152877105341*G0_1_3 + 0.000496152877105342*G0_1_5 - 0.000588617731474973*G0_2_1 + 0.00190342285580413*G0_2_2 + 0.00185831804879455*G0_2_3 + 0.00342796533272781*G0_2_4 + 0.000992305754210684*G0_2_5 - 0.000992305754210683*G0_3_0 - 0.000496152877105341*G0_3_1 + 0.00185831804879455*G0_3_2 + 0.00339188148712015*G0_3_3 + 0.00198461150842136*G0_3_4 - 0.00342796533272781*G0_4_0 + 0.00342796533272781*G0_4_2 + 0.00198461150842136*G0_4_3 - 0.00198461150842137*G0_4_5 - 0.00185831804879455*G0_5_0 + 0.000496152877105342*G0_5_1 + 0.000992305754210684*G0_5_2 - 0.00198461150842137*G0_5_4 - 0.00339188148712015*G0_5_5; + A[89] = A[218] + 5.86362491124492e-05*G0_0_0 + 7.10400710400829e-05*G0_0_2 + 2.70628842057459e-05*G0_0_3 + 0.000509684319208214*G0_0_4 + 0.000257097399954586*G0_0_5 - 5.86362491124495e-05*G0_1_1 - 7.1040071040083e-05*G0_1_2 - 0.000509684319208214*G0_1_3 - 2.70628842057458e-05*G0_1_4 - 0.000257097399954586*G0_1_5 + 7.10400710400829e-05*G0_2_0 - 7.1040071040083e-05*G0_2_1 + 0.000820907487574292*G0_2_3 - 0.000820907487574291*G0_2_4 + 2.70628842057458e-05*G0_3_0 - 0.000509684319208214*G0_3_1 + 0.000820907487574292*G0_3_2 + 0.0017681084347754*G0_3_3 - 5.41257684114916e-05*G0_3_5 + 0.000509684319208214*G0_4_0 - 2.7062884205746e-05*G0_4_1 - 0.000820907487574291*G0_4_2 - 0.00176810843477539*G0_4_4 + 5.41257684114918e-05*G0_4_5 + 0.000257097399954586*G0_5_0 - 0.000257097399954586*G0_5_1 - 5.41257684114916e-05*G0_5_3 + 5.41257684114917e-05*G0_5_4; + A[215] = A[89]; + A[198] = A[186] - 0.00184478660669168*G0_0_0 + 0.000659657802515057*G0_0_2 - 0.000965242870004938*G0_0_3 - 0.00242212813641426*G0_0_4 - 0.00209737352594531*G0_0_5 + 0.00184478660669168*G0_1_1 - 0.000659657802515057*G0_1_2 + 0.00242212813641426*G0_1_3 + 0.000965242870004938*G0_1_4 + 0.00209737352594531*G0_1_5 + 0.000659657802515057*G0_2_0 - 0.000659657802515057*G0_2_1 - 0.00074873979635897*G0_2_3 + 0.000748739796358971*G0_2_4 - 0.000965242870004938*G0_3_0 + 0.00242212813641426*G0_3_1 - 0.00074873979635897*G0_3_2 + 0.00515998992189556*G0_3_3 + 0.00193048574000987*G0_3_5 - 0.00242212813641426*G0_4_0 + 0.000965242870004938*G0_4_1 + 0.000748739796358971*G0_4_2 - 0.00515998992189555*G0_4_4 - 0.00193048574000988*G0_4_5 - 0.00209737352594531*G0_5_0 + 0.00209737352594531*G0_5_1 + 0.00193048574000987*G0_5_3 - 0.00193048574000988*G0_5_4; + A[159] = A[97] + 0.000242720242720284*G0_0_1 - 0.000242720242720284*G0_0_2 + 0.000252586919253629*G0_0_4 - 0.000252586919253628*G0_0_5 + 0.000242720242720284*G0_1_0 - 0.00063569587379122*G0_1_1 - 0.000479238574476751*G0_1_3 - 0.000168015406110672*G0_1_4 - 0.000550278645516834*G0_1_5 - 0.000242720242720284*G0_2_0 + 0.000635695873791217*G0_2_2 + 0.00047923857447675*G0_2_3 + 0.000550278645516832*G0_2_4 + 0.000168015406110673*G0_2_5 - 0.000479238574476751*G0_3_1 + 0.00047923857447675*G0_3_2 + 0.000336030812221344*G0_3_4 - 0.000336030812221346*G0_3_5 + 0.000252586919253629*G0_4_0 - 0.000168015406110672*G0_4_1 + 0.000550278645516832*G0_4_2 + 0.000336030812221344*G0_4_3 + 0.000568320568320662*G0_4_4 - 0.000252586919253628*G0_5_0 - 0.000550278645516834*G0_5_1 + 0.000168015406110673*G0_5_2 - 0.000336030812221346*G0_5_3 - 0.000568320568320664*G0_5_5; + A[79] = A[65]; + A[101] = A[129] + 2.36800236800276e-05*G0_0_1 - 2.36800236800278e-05*G0_0_2 + 0.000273635829191431*G0_0_4 - 0.000273635829191429*G0_0_5 + 2.36800236800276e-05*G0_1_0 + 1.95454163708157e-05*G0_1_1 + 8.5699133318195e-05*G0_1_3 + 9.02096140191503e-06*G0_1_4 + 0.000169894773069404*G0_1_5 - 2.36800236800278e-05*G0_2_0 - 1.95454163708162e-05*G0_2_2 - 8.56991333181952e-05*G0_2_3 - 0.000169894773069405*G0_2_4 - 9.02096140191535e-06*G0_2_5 + 8.5699133318195e-05*G0_3_1 - 8.56991333181952e-05*G0_3_2 - 1.80419228038304e-05*G0_3_4 + 1.80419228038306e-05*G0_3_5 + 0.000273635829191431*G0_4_0 + 9.02096140191503e-06*G0_4_1 - 0.000169894773069405*G0_4_2 - 1.80419228038303e-05*G0_4_3 + 0.000589369478258466*G0_4_4 - 0.000273635829191429*G0_5_0 + 0.000169894773069404*G0_5_1 - 9.02096140191535e-06*G0_5_2 + 1.80419228038306e-05*G0_5_3 - 0.000589369478258465*G0_5_5; + A[123] = A[170] + 0.000147906179652236*G0_0_1 - 0.000147906179652236*G0_0_2 - 0.000164632545584954*G0_0_4 + 0.000164632545584954*G0_0_5 + 0.000147906179652236*G0_1_0 - 0.00069066735733414*G0_1_1 - 0.000411205490570639*G0_1_3 - 0.000151852850265574*G0_1_4 - 0.000604404413928324*G0_1_5 - 0.000147906179652236*G0_2_0 + 0.000690667357334139*G0_2_2 + 0.000411205490570638*G0_2_3 + 0.000604404413928324*G0_2_4 + 0.000151852850265574*G0_2_5 - 0.000411205490570639*G0_3_1 + 0.000411205490570638*G0_3_2 + 0.000303705700531148*G0_3_4 - 0.000303705700531148*G0_3_5 - 0.000164632545584954*G0_4_0 - 0.000151852850265574*G0_4_1 + 0.000604404413928324*G0_4_2 + 0.000303705700531148*G0_4_3 + 0.000844963384646065*G0_4_4 + 0.000164632545584954*G0_5_0 - 0.000604404413928324*G0_5_1 + 0.000151852850265574*G0_5_2 - 0.000303705700531148*G0_5_3 - 0.000844963384646066*G0_5_5; + A[143] = A[129]; + A[189] = A[186] - 7.10400710400829e-05*G0_0_1 + 7.10400710400833e-05*G0_0_2 - 0.000820907487574293*G0_0_4 + 0.000820907487574291*G0_0_5 - 7.10400710400829e-05*G0_1_0 - 5.86362491124501e-05*G0_1_1 - 0.000257097399954586*G0_1_3 - 2.70628842057455e-05*G0_1_4 - 0.000509684319208214*G0_1_5 + 7.10400710400833e-05*G0_2_0 + 5.86362491124494e-05*G0_2_2 + 0.000257097399954586*G0_2_3 + 0.000509684319208215*G0_2_4 + 2.70628842057463e-05*G0_2_5 - 0.000257097399954586*G0_3_1 + 0.000257097399954586*G0_3_2 + 5.41257684114911e-05*G0_3_4 - 5.41257684114927e-05*G0_3_5 - 0.000820907487574293*G0_4_0 - 2.70628842057455e-05*G0_4_1 + 0.000509684319208215*G0_4_2 + 5.41257684114911e-05*G0_4_3 - 0.0017681084347754*G0_4_4 + 0.000820907487574292*G0_5_0 - 0.000509684319208214*G0_5_1 + 2.70628842057464e-05*G0_5_2 - 5.41257684114927e-05*G0_5_3 + 0.0017681084347754*G0_5_5; + A[178] = A[218] - 0.000659657802515056*G0_0_1 + 0.000659657802515056*G0_0_2 + 0.000748739796358969*G0_0_4 - 0.00074873979635897*G0_0_5 - 0.000659657802515056*G0_1_0 + 0.00184478660669168*G0_1_1 + 0.00209737352594531*G0_1_3 + 0.000965242870004936*G0_1_4 + 0.00242212813641426*G0_1_5 + 0.000659657802515056*G0_2_0 - 0.00184478660669168*G0_2_2 - 0.00209737352594531*G0_2_3 - 0.00242212813641425*G0_2_4 - 0.000965242870004937*G0_2_5 + 0.00209737352594531*G0_3_1 - 0.00209737352594531*G0_3_2 - 0.00193048574000987*G0_3_4 + 0.00193048574000987*G0_3_5 + 0.000748739796358969*G0_4_0 + 0.000965242870004936*G0_4_1 - 0.00242212813641425*G0_4_2 - 0.00193048574000987*G0_4_3 - 0.00515998992189555*G0_4_4 - 0.00074873979635897*G0_5_0 + 0.00242212813641426*G0_5_1 - 0.000965242870004937*G0_5_2 + 0.00193048574000987*G0_5_3 + 0.00515998992189555*G0_5_5; + A[54] = A[138]; + A[33] = A[47]; + A[127] = A[113]; + A[44] = A[212]; + A[95] = A[123] + 1.95454163708166e-05*G0_0_0 + 2.36800236800276e-05*G0_0_2 + 9.02096140191537e-06*G0_0_3 + 0.000169894773069405*G0_0_4 + 8.56991333181953e-05*G0_0_5 - 1.95454163708166e-05*G0_1_1 - 2.36800236800276e-05*G0_1_2 - 0.000169894773069405*G0_1_3 - 9.02096140191529e-06*G0_1_4 - 8.56991333181954e-05*G0_1_5 + 2.36800236800276e-05*G0_2_0 - 2.36800236800276e-05*G0_2_1 + 0.000273635829191431*G0_2_3 - 0.00027363582919143*G0_2_4 + 9.02096140191539e-06*G0_3_0 - 0.000169894773069405*G0_3_1 + 0.000273635829191431*G0_3_2 + 0.000589369478258465*G0_3_3 - 1.80419228038306e-05*G0_3_5 + 0.000169894773069405*G0_4_0 - 9.02096140191529e-06*G0_4_1 - 0.00027363582919143*G0_4_2 - 0.000589369478258465*G0_4_4 + 1.80419228038307e-05*G0_4_5 + 8.56991333181953e-05*G0_5_0 - 8.56991333181954e-05*G0_5_1 - 1.80419228038306e-05*G0_5_3 + 1.80419228038306e-05*G0_5_4; + A[78] = A[50]; + A[172] = A[116]; + A[155] = A[85]; + A[105] = A[7]; + A[98] = A[126]; + A[180] = A[12]; + A[173] = A[51] + 0.000143019825559532*G0_0_0 - 1.89816062831967e-05*G0_0_1 - 1.95454163708165e-05*G0_0_3 - 0.000101485815771547*G0_0_4 - 3.00698713397157e-06*G0_0_5 - 1.89816062831967e-05*G0_1_0 + 1.89816062831967e-05*G0_1_2 - 9.84788286375754e-05*G0_1_3 + 9.84788286375749e-05*G0_1_5 + 1.89816062831967e-05*G0_2_1 - 0.000143019825559532*G0_2_2 + 3.00698713397195e-06*G0_2_3 + 0.000101485815771547*G0_2_4 + 1.95454163708165e-05*G0_2_5 - 1.95454163708165e-05*G0_3_0 - 9.84788286375754e-05*G0_3_1 + 3.00698713397195e-06*G0_3_2 - 0.000129300446760786*G0_3_3 + 3.9090832741633e-05*G0_3_4 - 0.000101485815771547*G0_4_0 + 0.000101485815771547*G0_4_2 + 3.9090832741633e-05*G0_4_3 - 3.9090832741633e-05*G0_4_5 - 3.00698713397158e-06*G0_5_0 + 9.84788286375749e-05*G0_5_1 + 1.95454163708165e-05*G0_5_2 - 3.9090832741633e-05*G0_5_4 + 0.000129300446760786*G0_5_5; + A[118] = A[202]; + A[6] = A[90]; + A[22] = A[106]; + A[9] = A[135]; + A[49] = A[97] + 0.00211964402440629*G0_0_0 - 0.000361966076251851*G0_0_2 + 0.000253714539428868*G0_0_3 + 0.00116483164102231*G0_0_4 + 0.000953966668252542*G0_0_5 - 0.00211964402440629*G0_1_1 + 0.000361966076251852*G0_1_2 - 0.00116483164102231*G0_1_3 - 0.000253714539428867*G0_1_4 - 0.000953966668252543*G0_1_5 - 0.000361966076251851*G0_2_0 + 0.000361966076251852*G0_2_1 - 2.93181245562254e-05*G0_2_3 + 2.93181245562242e-05*G0_2_4 + 0.000253714539428868*G0_3_0 - 0.00116483164102231*G0_3_1 - 2.93181245562253e-05*G0_3_2 - 0.000604404413928327*G0_3_3 - 0.000507429078857736*G0_3_5 + 0.00116483164102231*G0_4_0 - 0.000253714539428867*G0_4_1 + 2.93181245562243e-05*G0_4_2 + 0.000604404413928324*G0_4_4 + 0.000507429078857735*G0_4_5 + 0.000953966668252542*G0_5_0 - 0.000953966668252543*G0_5_1 - 0.000507429078857736*G0_5_3 + 0.000507429078857735*G0_5_4; + A[147] = A[189]; + A[124] = A[68]; + A[84] = A[51] - 1.89816062831968e-05*G0_0_1 + 1.89816062831968e-05*G0_0_2 - 9.84788286375755e-05*G0_0_4 + 9.8478828637575e-05*G0_0_5 - 1.89816062831968e-05*G0_1_0 + 0.000143019825559533*G0_1_1 - 0.000101485815771547*G0_1_3 - 1.95454163708164e-05*G0_1_4 - 3.0069871339714e-06*G0_1_5 + 1.89816062831968e-05*G0_2_0 - 0.000143019825559532*G0_2_2 + 0.000101485815771547*G0_2_3 + 3.0069871339717e-06*G0_2_4 + 1.95454163708165e-05*G0_2_5 - 0.000101485815771547*G0_3_1 + 0.000101485815771547*G0_3_2 + 3.90908327416328e-05*G0_3_4 - 3.9090832741633e-05*G0_3_5 - 9.84788286375755e-05*G0_4_0 - 1.95454163708164e-05*G0_4_1 + 3.0069871339717e-06*G0_4_2 + 3.90908327416328e-05*G0_4_3 - 0.000129300446760786*G0_4_4 + 9.8478828637575e-05*G0_5_0 - 3.0069871339714e-06*G0_5_1 + 1.95454163708165e-05*G0_5_2 - 3.9090832741633e-05*G0_5_3 + 0.000129300446760785*G0_5_5; + A[67] = A[109]; + A[161] = A[175]; + A[81] = A[95]; + A[167] = A[41]; + A[156] = A[100]; + A[112] = A[160] + 0.000377400377400441*G0_0_1 - 0.000377400377400441*G0_0_2 - 4.73600473600561e-05*G0_0_4 + 4.73600473600551e-05*G0_0_5 + 0.000377400377400441*G0_1_0 - 0.00141720713149309*G0_1_1 - 0.000904915190629629*G0_1_3 - 0.000699406413692245*G0_1_4 - 0.000857555143269574*G0_1_5 - 0.000377400377400441*G0_2_0 + 0.00141720713149308*G0_2_2 + 0.000904915190629627*G0_2_3 + 0.000857555143269571*G0_2_4 + 0.000699406413692245*G0_2_5 - 0.000904915190629629*G0_3_1 + 0.000904915190629627*G0_3_2 + 0.00139881282738449*G0_3_4 - 0.00139881282738449*G0_3_5 - 4.73600473600559e-05*G0_4_0 - 0.000699406413692245*G0_4_1 + 0.000857555143269571*G0_4_2 + 0.00139881282738449*G0_4_3 + 0.0122662522662543*G0_4_4 + 4.73600473600549e-05*G0_5_0 - 0.000857555143269574*G0_5_1 + 0.000699406413692245*G0_5_2 - 0.00139881282738449*G0_5_3 - 0.0122662522662543*G0_5_5; + A[185] = A[149] + 0.000640488259535985*G0_0_0 - 0.000246948818377431*G0_0_1 + 0.000405943263086188*G0_0_3 + 0.000572831049021621*G0_0_4 + 0.000987795273509724*G0_0_5 - 0.000246948818377431*G0_1_0 + 0.000246948818377431*G0_1_2 + 0.000405943263086189*G0_1_3 - 0.000405943263086188*G0_1_5 + 0.000246948818377431*G0_2_1 - 0.000640488259535986*G0_2_2 - 0.000987795273509725*G0_2_3 - 0.000572831049021621*G0_2_4 - 0.000405943263086188*G0_2_5 + 0.000405943263086188*G0_3_0 + 0.000405943263086189*G0_3_1 - 0.000987795273509725*G0_3_2 - 0.00270628842057459*G0_3_3 - 0.000811886526172377*G0_3_4 + 0.000572831049021621*G0_4_0 - 0.000572831049021621*G0_4_2 - 0.000811886526172377*G0_4_3 + 0.000811886526172376*G0_4_5 + 0.000987795273509724*G0_5_0 - 0.000405943263086188*G0_5_1 - 0.000405943263086188*G0_5_2 + 0.000811886526172376*G0_5_4 + 0.00270628842057459*G0_5_5; + A[210] = A[14]; + A[203] = A[133]; + A[3] = A[45]; + A[17] = A[31]; + A[134] = A[218]; + A[69] = A[139]; + A[121] = A[5] - 6.75397500794436e-05*G0_0_0 + 1.57631903663676e-05*G0_0_2 - 4.6984173968309e-06*G0_0_3 + 6.38984765969001e-06*G0_0_4 - 1.83238278476404e-05*G0_0_5 + 6.75397500794438e-05*G0_1_1 - 1.57631903663677e-05*G0_1_2 - 6.38984765968999e-06*G0_1_3 + 4.69841739683086e-06*G0_1_4 + 1.83238278476404e-05*G0_1_5 + 1.57631903663676e-05*G0_2_0 - 1.57631903663677e-05*G0_2_1 + 6.47441917283297e-05*G0_2_3 - 6.47441917283295e-05*G0_2_4 - 4.6984173968309e-06*G0_3_0 - 6.38984765968999e-06*G0_3_1 + 6.47441917283297e-05*G0_3_2 + 0.000150725230090335*G0_3_3 + 9.3968347936618e-06*G0_3_5 + 6.38984765969001e-06*G0_4_0 + 4.69841739683086e-06*G0_4_1 - 6.47441917283295e-05*G0_4_2 - 0.000150725230090335*G0_4_4 - 9.39683479366175e-06*G0_4_5 - 1.83238278476404e-05*G0_5_0 + 1.83238278476405e-05*G0_5_1 + 9.39683479366181e-06*G0_5_3 - 9.39683479366175e-06*G0_5_4; + A[8] = A[121] + 0.000427180109719864*G0_0_0 - 2.01327185454203e-05*G0_0_1 - 3.63892427384552e-05*G0_0_2 - 4.22857565714791e-07*G0_0_3 + 0.000113654716829339*G0_0_4 + 8.04838900077129e-05*G0_0_5 - 2.01327185454203e-05*G0_1_0 - 2.03441473282775e-05*G0_1_1 - 2.11428782857377e-07*G0_1_2 + 4.22857565714797e-07*G0_1_3 - 1.15111226222356e-05*G0_1_4 - 3.63892427384552e-05*G0_2_0 - 2.11428782857373e-07*G0_2_1 - 2.26933560266932e-05*G0_2_2 + 2.03911315022459e-05*G0_2_4 + 4.22857565714765e-07*G0_2_5 - 4.22857565714791e-07*G0_3_0 + 4.22857565714801e-07*G0_3_1 - 2.3867960375901e-05*G0_3_3 + 2.38679603759009e-05*G0_3_4 + 0.000113654716829339*G0_4_0 - 1.15111226222356e-05*G0_4_1 + 2.03911315022459e-05*G0_4_2 + 2.38679603759009e-05*G0_4_3 + 0.000241874527588854*G0_4_4 + 2.21765301130417e-05*G0_4_5 + 8.04838900077129e-05*G0_5_0 + 4.22857565714762e-07*G0_5_2 + 2.21765301130417e-05*G0_5_4 - 9.39683479366119e-07*G0_5_5; + A[36] = -A[8] + 0.000185000185000216*G0_0_0 - 3.05397130793977e-07*G0_0_1 + 9.02096140191527e-06*G0_0_3 + 1.43301730603341e-05*G0_0_4 - 1.5645729931447e-05*G0_0_5 - 3.0539713079398e-07*G0_1_0 - 3.05397130793977e-07*G0_1_2 + 2.58882798565382e-05*G0_1_3 + 2.86603461206684e-05*G0_1_4 + 2.58882798565382e-05*G0_1_5 - 3.05397130793973e-07*G0_2_1 + 0.000185000185000215*G0_2_2 - 1.56457299314469e-05*G0_2_3 + 1.4330173060334e-05*G0_2_4 + 9.02096140191534e-06*G0_2_5 + 9.02096140191527e-06*G0_3_0 + 2.58882798565382e-05*G0_3_1 - 1.56457299314469e-05*G0_3_2 - 0.000104492802905519*G0_3_3 - 7.53626150451674e-05*G0_3_4 - 3.60838456076612e-05*G0_3_5 + 1.43301730603341e-05*G0_4_0 + 2.86603461206684e-05*G0_4_1 + 1.4330173060334e-05*G0_4_2 - 7.53626150451674e-05*G0_4_3 + 4.20978198756048e-05*G0_4_4 - 7.53626150451675e-05*G0_4_5 - 1.5645729931447e-05*G0_5_0 + 2.58882798565382e-05*G0_5_1 + 9.02096140191534e-06*G0_5_2 - 3.60838456076612e-05*G0_5_3 - 7.53626150451675e-05*G0_5_4 - 0.000104492802905519*G0_5_5; + A[21] = A[36] + 2.26933560266933e-05*G0_0_0 + 2.11428782857455e-07*G0_0_1 + 3.63892427384552e-05*G0_0_2 - 4.22857565714831e-07*G0_0_3 - 2.03911315022459e-05*G0_0_4 + 2.11428782857465e-07*G0_1_0 + 2.03441473282771e-05*G0_1_1 + 2.01327185454203e-05*G0_1_2 + 1.15111226222357e-05*G0_1_4 - 4.22857565714865e-07*G0_1_5 + 3.63892427384552e-05*G0_2_0 + 2.01327185454203e-05*G0_2_1 - 0.000427180109719863*G0_2_2 - 8.04838900077129e-05*G0_2_3 - 0.000113654716829339*G0_2_4 + 4.2285756571477e-07*G0_2_5 - 4.2285756571483e-07*G0_3_0 - 8.04838900077129e-05*G0_3_2 + 9.39683479366322e-07*G0_3_3 - 2.21765301130418e-05*G0_3_4 - 2.03911315022459e-05*G0_4_0 + 1.15111226222357e-05*G0_4_1 - 0.000113654716829339*G0_4_2 - 2.21765301130418e-05*G0_4_3 - 0.000241874527588854*G0_4_4 - 2.3867960375901e-05*G0_4_5 - 4.22857565714862e-07*G0_5_1 + 4.2285756571477e-07*G0_5_2 - 2.3867960375901e-05*G0_5_4 + 2.38679603759007e-05*G0_5_5; + A[137] = A[21] + 1.57631903663675e-05*G0_0_1 - 1.57631903663676e-05*G0_0_2 + 6.47441917283297e-05*G0_0_4 - 6.47441917283294e-05*G0_0_5 + 1.57631903663675e-05*G0_1_0 - 6.75397500794435e-05*G0_1_1 - 1.83238278476404e-05*G0_1_3 - 4.69841739683093e-06*G0_1_4 + 6.38984765969e-06*G0_1_5 - 1.57631903663677e-05*G0_2_0 + 6.75397500794438e-05*G0_2_2 + 1.83238278476404e-05*G0_2_3 - 6.38984765969011e-06*G0_2_4 + 4.69841739683084e-06*G0_2_5 - 1.83238278476404e-05*G0_3_1 + 1.83238278476404e-05*G0_3_2 + 9.39683479366178e-06*G0_3_4 - 9.39683479366174e-06*G0_3_5 + 6.47441917283297e-05*G0_4_0 - 4.69841739683092e-06*G0_4_1 - 6.38984765969012e-06*G0_4_2 + 9.39683479366177e-06*G0_4_3 + 0.000150725230090335*G0_4_4 - 6.47441917283294e-05*G0_5_0 + 6.38984765969e-06*G0_5_1 + 4.69841739683084e-06*G0_5_2 - 9.39683479366174e-06*G0_5_3 - 0.000150725230090334*G0_5_5; + A[26] = A[137] + 0.000105737883515679*G0_0_0 - 0.000122722662405223*G0_0_1 - 9.60826357651913e-06*G0_0_2 + 1.04774707949328e-05*G0_0_3 + 5.60991037181607e-05*G0_0_4 + 9.25588227175682e-05*G0_0_5 - 0.000122722662405223*G0_1_0 + 0.00127078095332085*G0_1_1 - 5.12127496254568e-05*G0_1_2 + 0.000221248475216767*G0_1_3 + 1.33904895809679e-05*G0_1_4 + 0.000387290546020771*G0_1_5 - 9.60826357651913e-06*G0_2_0 - 5.12127496254568e-05*G0_2_1 - 2.0555576111135e-05*G0_2_2 - 4.27555983111605e-06*G0_2_4 - 1.10412808825526e-05*G0_2_5 + 1.04774707949328e-05*G0_3_0 + 0.000221248475216767*G0_3_1 - 1.67263659327177e-05*G0_3_3 - 4.77359207518019e-05*G0_3_4 + 1.12762017523957e-06*G0_3_5 + 5.60991037181607e-05*G0_4_0 + 1.33904895809679e-05*G0_4_1 - 4.27555983111605e-06*G0_4_2 - 4.77359207518019e-05*G0_4_3 - 0.000132495370590631*G0_4_4 - 4.69841739683108e-06*G0_4_5 + 9.25588227175682e-05*G0_5_0 + 0.000387290546020771*G0_5_1 - 1.10412808825526e-05*G0_5_2 + 1.12762017523957e-06*G0_5_3 - 4.69841739683108e-06*G0_5_4 + 0.000141892205384293*G0_5_5; + A[25] = -A[26] + 6.55487957075368e-05*G0_0_0 - 4.13167079833817e-05*G0_0_1 - 6.84794335588102e-06*G0_0_2 + 1.19222341444584e-05*G0_0_3 + 4.45292508784647e-05*G0_0_4 + 7.47400747400873e-05*G0_0_5 - 4.13167079833817e-05*G0_1_0 + 0.000381100381100446*G0_1_1 - 6.78334011667462e-06*G0_1_2 + 5.18000518000606e-05*G0_1_3 - 3.70000370000438e-06*G0_1_4 + 8.38667505334314e-05*G0_1_5 - 6.84794335588102e-06*G0_2_0 - 6.7833401166746e-06*G0_2_1 - 5.98460915921338e-06*G0_2_2 - 1.27444571889038e-05*G0_2_3 - 2.0837481154945e-05*G0_2_4 - 6.6600066600078e-06*G0_2_5 + 1.19222341444584e-05*G0_3_0 + 5.18000518000606e-05*G0_3_1 - 1.27444571889038e-05*G0_3_2 - 2.6311137422254e-06*G0_3_3 - 1.64444608889082e-05*G0_3_4 - 1.05244549689012e-05*G0_3_5 + 4.45292508784647e-05*G0_4_0 - 3.70000370000438e-06*G0_4_1 - 2.0837481154945e-05*G0_4_2 - 1.64444608889082e-05*G0_4_3 - 7.51746783493043e-07*G0_4_4 + 2.07200207200242e-05*G0_4_5 + 7.47400747400874e-05*G0_5_0 + 8.38667505334314e-05*G0_5_1 - 6.6600066600078e-06*G0_5_2 - 1.05244549689012e-05*G0_5_3 + 2.07200207200242e-05*G0_5_4 - 5.52533885867319e-05*G0_5_5; + A[61] = A[25] - 0.000117906784573471*G0_0_0 - 3.50267016933743e-05*G0_0_3 - 0.000107793441126793*G0_0_4 - 0.000140106806773497*G0_0_5 - 0.000175133508466871*G0_1_3 + 0.000175133508466872*G0_1_5 + 0.000117906784573471*G0_2_2 + 0.000140106806773497*G0_2_3 + 0.000107793441126793*G0_2_4 + 3.50267016933743e-05*G0_2_5 - 3.50267016933743e-05*G0_3_0 - 0.000175133508466871*G0_3_1 + 0.000140106806773497*G0_3_2 + 7.00534033867486e-05*G0_3_4 - 0.000107793441126793*G0_4_0 + 0.000107793441126793*G0_4_2 + 7.00534033867486e-05*G0_4_3 - 7.00534033867486e-05*G0_4_5 - 0.000140106806773497*G0_5_0 + 0.000175133508466872*G0_5_1 + 3.50267016933743e-05*G0_5_2 - 7.00534033867486e-05*G0_5_4; + A[91] = A[21]; + A[120] = A[8]; + A[92] = A[36]; + A[19] = A[61]; + A[24] = A[137] - 2.26933560266932e-05*G0_0_0 - 3.63892427384552e-05*G0_0_1 - 2.1142878285736e-07*G0_0_2 + 4.2285756571473e-07*G0_0_3 + 2.03911315022458e-05*G0_0_5 - 3.63892427384552e-05*G0_1_0 + 0.000427180109719865*G0_1_1 - 2.01327185454204e-05*G0_1_2 + 8.04838900077134e-05*G0_1_3 - 4.22857565714777e-07*G0_1_4 + 0.00011365471682934*G0_1_5 - 2.1142878285736e-07*G0_2_0 - 2.01327185454204e-05*G0_2_1 - 2.03441473282776e-05*G0_2_2 + 4.22857565714852e-07*G0_2_4 - 1.15111226222357e-05*G0_2_5 + 4.22857565714733e-07*G0_3_0 + 8.04838900077134e-05*G0_3_1 - 9.39683479365893e-07*G0_3_3 + 2.21765301130418e-05*G0_3_5 - 4.22857565714787e-07*G0_4_1 + 4.22857565714848e-07*G0_4_2 - 2.38679603759011e-05*G0_4_4 + 2.38679603759007e-05*G0_4_5 + 2.03911315022458e-05*G0_5_0 + 0.00011365471682934*G0_5_1 - 1.15111226222357e-05*G0_5_2 + 2.21765301130419e-05*G0_5_3 + 2.38679603759007e-05*G0_5_4 + 0.000241874527588854*G0_5_5; + A[136] = A[24]; + A[39] = A[137]; + A[87] = A[185]; + A[64] = A[160] - 0.00141720713149308*G0_0_0 + 0.000377400377400441*G0_0_1 - 0.000699406413692245*G0_0_3 - 0.000904915190629629*G0_0_4 - 0.000857555143269572*G0_0_5 + 0.000377400377400441*G0_1_0 - 0.000377400377400441*G0_1_2 - 4.73600473600557e-05*G0_1_3 + 4.73600473600537e-05*G0_1_5 - 0.000377400377400441*G0_2_1 + 0.00141720713149308*G0_2_2 + 0.000857555143269573*G0_2_3 + 0.000904915190629628*G0_2_4 + 0.000699406413692246*G0_2_5 - 0.000699406413692245*G0_3_0 - 4.73600473600555e-05*G0_3_1 + 0.000857555143269573*G0_3_2 + 0.0122662522662543*G0_3_3 + 0.00139881282738449*G0_3_4 - 0.000904915190629629*G0_4_0 + 0.000904915190629628*G0_4_2 + 0.00139881282738449*G0_4_3 - 0.00139881282738449*G0_4_5 - 0.000857555143269572*G0_5_0 + 4.73600473600537e-05*G0_5_1 + 0.000699406413692245*G0_5_2 - 0.00139881282738449*G0_5_4 - 0.0122662522662543*G0_5_5; + A[93] = A[51]; + A[166] = A[26]; + A[224] = A[192] - 0.0012990184418758*G0_0_0 + 0.00146139574711028*G0_0_1 - 0.00389705532562741*G0_0_3 - 0.00671159528302498*G0_0_4 - 0.00433006147291934*G0_0_5 + 0.00146139574711028*G0_1_0 - 0.00146139574711028*G0_1_2 - 0.00238153381010564*G0_1_3 + 0.00238153381010564*G0_1_5 - 0.00146139574711028*G0_2_1 + 0.0012990184418758*G0_2_2 + 0.00433006147291934*G0_2_3 + 0.00671159528302498*G0_2_4 + 0.00389705532562741*G0_2_5 - 0.00389705532562741*G0_3_0 - 0.00238153381010564*G0_3_1 + 0.00433006147291934*G0_3_2 + 0.0138561967133419*G0_3_3 + 0.00779411065125481*G0_3_4 - 0.00671159528302498*G0_4_0 + 0.00671159528302498*G0_4_2 + 0.00779411065125481*G0_4_3 - 0.00779411065125482*G0_4_5 - 0.00433006147291934*G0_5_0 + 0.00238153381010564*G0_5_1 + 0.00389705532562741*G0_5_2 - 0.00779411065125483*G0_5_4 - 0.0138561967133419*G0_5_5; + A[206] = A[178]; + A[0] = -A[26] + 0.00136053247164381*G0_0_0 - 0.000142758476091834*G0_0_1 - 4.54072676294975e-05*G0_0_2 + 0.00019971797749579*G0_0_4 + 0.000171433504766867*G0_0_5 - 0.000142758476091834*G0_1_0 + 0.00123156678712255*G0_1_1 - 5.26428304206172e-05*G0_1_2 + 0.000208885764441356*G0_1_3 + 1.99389088278009e-05*G0_1_4 + 0.000399805955361579*G0_1_5 - 4.54072676294975e-05*G0_2_0 - 5.26428304206172e-05*G0_2_1 + 7.7700077700091e-06*G0_2_2 + 1.85000185000214e-06*G0_2_4 + 2.05555761111293e-07*G0_2_5 + 0.000208885764441356*G0_3_1 + 4.55511566622758e-05*G0_3_3 - 3.65889254778206e-05*G0_3_4 + 2.87778065555912e-06*G0_3_5 + 0.00019971797749579*G0_4_0 + 1.99389088278009e-05*G0_4_1 + 1.85000185000215e-06*G0_4_2 - 3.65889254778206e-05*G0_4_3 - 8.58400858401002e-05*G0_4_4 - 4.02889291778249e-05*G0_4_5 + 0.000171433504766867*G0_5_0 + 0.000399805955361579*G0_5_1 + 2.05555761111294e-07*G0_5_2 + 2.87778065555912e-06*G0_5_3 - 4.02889291778249e-05*G0_5_4 + 3.78222600444889e-05*G0_5_5; + A[158] = -A[0] + 0.000933634266967761*G0_0_0 + 1.39102520054923e-05*G0_0_1 + 2.91595529690797e-06*G0_0_2 - 4.28495666590978e-05*G0_0_3 - 3.36524146047999e-05*G0_0_4 - 6.74810198619828e-05*G0_0_5 + 1.39102520054923e-05*G0_1_0 - 3.09449515798772e-05*G0_1_1 - 4.11640094179846e-05*G0_1_3 - 1.57220792141454e-05*G0_1_4 - 6.92840375380173e-05*G0_1_5 + 2.91595529690799e-06*G0_2_0 + 5.64456120011773e-05*G0_2_2 + 6.26651420302325e-06*G0_2_4 - 8.11240493780312e-05*G0_2_5 - 4.28495666590979e-05*G0_3_0 - 4.11640094179846e-05*G0_3_1 + 0.000159816667753203*G0_3_3 + 0.000117143291746486*G0_3_4 + 0.000247947232074258*G0_3_5 - 3.36524146047999e-05*G0_4_0 - 1.57220792141454e-05*G0_4_1 + 6.26651420302325e-06*G0_4_2 + 0.000117143291746486*G0_4_3 + 0.000184412882825613*G0_4_4 + 0.000193692257184353*G0_4_5 - 6.74810198619828e-05*G0_5_0 - 6.92840375380172e-05*G0_5_1 - 8.11240493780312e-05*G0_5_2 + 0.000247947232074258*G0_5_3 + 0.000193692257184353*G0_5_4 + 0.0013571378650746*G0_5_5; + A[157] = -A[0] + 0.00243978243978285*G0_0_0 - 0.000182119467833784*G0_0_1 - 0.000182119467833784*G0_0_2 + 6.3428634857217e-05*G0_0_3 + 0.0007703407703409*G0_0_4 + 0.0007703407703409*G0_0_5 - 0.000182119467833784*G0_1_0 - 2.64873280746427e-06*G0_1_1 + 1.45915225280331e-05*G0_1_2 + 4.01127385254433e-06*G0_1_4 - 3.78516251532194e-05*G0_1_5 - 0.000182119467833784*G0_2_0 + 1.45915225280331e-05*G0_2_1 - 2.64873280746355e-06*G0_2_2 - 3.78516251532189e-05*G0_2_4 + 4.01127385254419e-06*G0_2_5 + 6.34286348572169e-05*G0_3_0 + 0.00010399946907885*G0_3_3 - 0.000134879817419523*G0_3_4 - 0.000134879817419523*G0_3_5 + 0.0007703407703409*G0_4_0 + 4.01127385254433e-06*G0_4_1 - 3.78516251532189e-05*G0_4_2 - 0.000134879817419523*G0_4_3 - 0.000684982272283975*G0_4_4 - 1.6045095410177e-05*G0_4_5 + 0.0007703407703409*G0_5_0 - 3.78516251532194e-05*G0_5_1 + 4.0112738525442e-06*G0_5_2 - 0.000134879817419523*G0_5_3 - 1.6045095410177e-05*G0_5_4 - 0.000684982272283972*G0_5_5; + A[122] = -A[0] + 0.00136053247164381*G0_0_0 - 4.54072676294975e-05*G0_0_1 - 0.000142758476091833*G0_0_2 + 0.000171433504766868*G0_0_4 + 0.000199717977495789*G0_0_5 - 4.54072676294975e-05*G0_1_0 + 7.7700077700091e-06*G0_1_1 - 5.26428304206169e-05*G0_1_2 + 2.05555761111386e-07*G0_1_4 + 1.85000185000214e-06*G0_1_5 - 0.000142758476091833*G0_2_0 - 5.26428304206169e-05*G0_2_1 + 0.00123156678712255*G0_2_2 + 0.000208885764441355*G0_2_3 + 0.000399805955361578*G0_2_4 + 1.99389088278012e-05*G0_2_5 + 0.000208885764441355*G0_3_2 + 4.55511566622755e-05*G0_3_3 + 2.87778065555889e-06*G0_3_4 - 3.65889254778205e-05*G0_3_5 + 0.000171433504766868*G0_4_0 + 2.05555761111386e-07*G0_4_1 + 0.000399805955361578*G0_4_2 + 2.8777806555589e-06*G0_4_3 + 3.78222600444891e-05*G0_4_4 - 4.02889291778247e-05*G0_4_5 + 0.000199717977495789*G0_5_0 + 1.85000185000214e-06*G0_5_1 + 1.99389088278012e-05*G0_5_2 - 3.65889254778205e-05*G0_5_3 - 4.02889291778247e-05*G0_5_4 - 8.58400858401e-05*G0_5_5; + A[107] = -A[122] + 6.55487957075369e-05*G0_0_0 - 6.847943355881e-06*G0_0_1 - 4.13167079833817e-05*G0_0_2 + 1.19222341444584e-05*G0_0_3 + 7.47400747400873e-05*G0_0_4 + 4.45292508784647e-05*G0_0_5 - 6.847943355881e-06*G0_1_0 - 5.98460915921342e-06*G0_1_1 - 6.78334011667456e-06*G0_1_2 - 1.27444571889038e-05*G0_1_3 - 6.66000666000776e-06*G0_1_4 - 2.0837481154945e-05*G0_1_5 - 4.13167079833816e-05*G0_2_0 - 6.78334011667458e-06*G0_2_1 + 0.000381100381100445*G0_2_2 + 5.18000518000606e-05*G0_2_3 + 8.38667505334313e-05*G0_2_4 - 3.70000370000429e-06*G0_2_5 + 1.19222341444584e-05*G0_3_0 - 1.27444571889038e-05*G0_3_1 + 5.18000518000605e-05*G0_3_2 - 2.63111374222537e-06*G0_3_3 - 1.05244549689012e-05*G0_3_4 - 1.64444608889082e-05*G0_3_5 + 7.47400747400873e-05*G0_4_0 - 6.66000666000777e-06*G0_4_1 + 8.38667505334313e-05*G0_4_2 - 1.05244549689012e-05*G0_4_3 - 5.52533885867311e-05*G0_4_4 + 2.07200207200242e-05*G0_4_5 + 4.45292508784647e-05*G0_5_0 - 2.0837481154945e-05*G0_5_1 - 3.70000370000429e-06*G0_5_2 - 1.64444608889082e-05*G0_5_3 + 2.07200207200242e-05*G0_5_4 - 7.51746783493205e-07*G0_5_5; + A[99] = A[107] + 0.00196961768390373*G0_0_0 - 0.000286027905075572*G0_0_1 - 0.000348910348910407*G0_0_2 + 8.11534144867616e-05*G0_0_3 + 0.00113392780059466*G0_0_4 + 0.0011924230971852*G0_0_5 - 0.000286027905075572*G0_1_0 + 0.000107235504060919*G0_1_1 + 1.96746228492314e-06*G0_1_2 - 3.55082894765494e-05*G0_1_3 - 0.000252175807731406*G0_1_4 - 0.000283713934507633*G0_1_5 - 0.000348910348910407*G0_2_0 + 1.96746228492314e-06*G0_2_1 + 0.000943947293153799*G0_2_2 + 0.000108791854823619*G0_2_3 + 9.53778731556604e-06*G0_2_4 - 0.000235402457624719*G0_2_5 + 8.11534144867616e-05*G0_3_0 - 3.55082894765494e-05*G0_3_1 + 0.000108791854823619*G0_3_2 + 0.000490514776229144*G0_3_3 + 0.000342044786489289*G0_3_4 + 0.000308498086275916*G0_3_5 + 0.00113392780059466*G0_4_0 - 0.000252175807731406*G0_4_1 + 9.53778731556604e-06*G0_4_2 + 0.000342044786489289*G0_4_3 + 0.00161813495146856*G0_4_4 + 0.00097515653071225*G0_4_5 + 0.0011924230971852*G0_5_0 - 0.000283713934507633*G0_5_1 - 0.000235402457624719*G0_5_2 + 0.000308498086275916*G0_5_3 + 0.000975156530712251*G0_5_4 + 0.00143997096378073*G0_5_5; + A[125] = A[99] - 0.00198028896441628*G0_0_0 + 0.00035087781119533*G0_0_1 - 0.000368355923911541*G0_0_3 - 0.00158393047281963*G0_0_4 - 0.0013095428968447*G0_0_5 + 0.00035087781119533*G0_1_0 - 0.00035087781119533*G0_1_2 - 0.000274387575974923*G0_1_3 + 0.000274387575974924*G0_1_5 - 0.00035087781119533*G0_2_1 + 0.00198028896441628*G0_2_2 + 0.0013095428968447*G0_2_3 + 0.00158393047281963*G0_2_4 + 0.000368355923911542*G0_2_5 - 0.000368355923911541*G0_3_0 - 0.000274387575974923*G0_3_1 + 0.0013095428968447*G0_3_2 + 0.00112762017523941*G0_3_3 + 0.000736711847823081*G0_3_4 - 0.00158393047281963*G0_4_0 + 0.00158393047281963*G0_4_2 + 0.000736711847823081*G0_4_3 - 0.000736711847823083*G0_4_5 - 0.0013095428968447*G0_5_0 + 0.000274387575974924*G0_5_1 + 0.000368355923911542*G0_5_2 - 0.000736711847823083*G0_5_4 - 0.00112762017523941*G0_5_5; + A[83] = A[125]; + A[56] = A[99] - 0.00198028896441628*G0_0_0 + 0.00035087781119533*G0_0_2 - 0.000368355923911541*G0_0_3 - 0.0013095428968447*G0_0_4 - 0.00158393047281963*G0_0_5 + 0.00198028896441628*G0_1_1 - 0.000350877811195331*G0_1_2 + 0.00130954289684471*G0_1_3 + 0.000368355923911541*G0_1_4 + 0.00158393047281963*G0_1_5 + 0.00035087781119533*G0_2_0 - 0.000350877811195331*G0_2_1 - 0.000274387575974924*G0_2_3 + 0.000274387575974924*G0_2_4 - 0.000368355923911541*G0_3_0 + 0.00130954289684471*G0_3_1 - 0.000274387575974924*G0_3_2 + 0.00112762017523941*G0_3_3 + 0.000736711847823082*G0_3_5 - 0.0013095428968447*G0_4_0 + 0.000368355923911541*G0_4_1 + 0.000274387575974924*G0_4_2 - 0.00112762017523941*G0_4_4 - 0.000736711847823083*G0_4_5 - 0.00158393047281963*G0_5_0 + 0.00158393047281963*G0_5_1 + 0.000736711847823082*G0_5_3 - 0.000736711847823083*G0_5_4; + A[176] = A[56] + 0.000412521047441752*G0_0_0 - 0.00053674720341396*G0_0_1 + 2.06730365460552e-06*G0_0_2 - 4.73600473600549e-05*G0_0_3 + 0.000124789966059829*G0_0_4 - 0.000605156160711818*G0_0_5 - 0.00053674720341396*G0_1_0 + 0.00209173542506911*G0_1_1 - 2.36800236800272e-05*G0_1_2 + 4.73600473600546e-05*G0_1_4 + 0.00252586919253628*G0_1_5 + 2.06730365460551e-06*G0_2_0 - 2.36800236800272e-05*G0_2_1 - 2.16127200254222e-05*G0_2_2 + 4.73600473600557e-05*G0_2_3 - 8.56991333181953e-05*G0_2_4 - 0.000226275781831375*G0_2_5 - 4.73600473600549e-05*G0_3_0 + 4.73600473600558e-05*G0_3_2 - 0.000547271658382864*G0_3_3 + 0.00054727165838286*G0_3_5 + 0.000124789966059829*G0_4_0 + 4.73600473600546e-05*G0_4_1 - 8.56991333181953e-05*G0_4_2 + 0.000171398266636391*G0_4_4 + 0.00035783146894264*G0_4_5 - 0.000605156160711818*G0_5_0 + 0.00252586919253628*G0_5_1 - 0.000226275781831375*G0_5_2 + 0.000547271658382861*G0_5_3 + 0.00035783146894264*G0_5_4 + 0.00492544492544575*G0_5_5; + A[144] = A[176] + 0.00365950334204364*G0_0_0 - 0.000376625138529964*G0_0_2 + 0.000463076018631651*G0_0_3 + 0.00118475293078488*G0_0_4 + 0.00471495582606773*G0_0_5 - 0.00365950334204364*G0_1_1 + 0.000376625138529963*G0_1_2 - 0.00118475293078487*G0_1_3 - 0.000463076018631651*G0_1_4 - 0.00471495582606773*G0_1_5 - 0.000376625138529963*G0_2_0 + 0.000376625138529963*G0_2_1 + 0.000141328395296673*G0_2_3 - 0.000141328395296673*G0_2_4 + 0.000463076018631651*G0_3_0 - 0.00118475293078487*G0_3_1 + 0.000141328395296673*G0_3_2 - 0.000408950250220159*G0_3_3 - 0.000926152037263302*G0_3_5 + 0.00118475293078488*G0_4_0 - 0.000463076018631651*G0_4_1 - 0.000141328395296673*G0_4_2 + 0.00040895025022016*G0_4_4 + 0.000926152037263306*G0_4_5 + 0.00471495582606773*G0_5_0 - 0.00471495582606773*G0_5_1 - 0.000926152037263302*G0_5_3 + 0.000926152037263305*G0_5_4; + A[80] = A[144] - 0.00409363710951081*G0_0_0 + 0.000889692318263896*G0_0_1 - 0.000641991753102971*G0_0_3 - 0.00153657042545957*G0_0_4 - 0.00392111122269918*G0_0_5 + 0.000889692318263896*G0_1_0 - 0.000889692318263897*G0_1_2 - 0.00100433370274657*G0_1_3 + 0.00100433370274657*G0_1_5 - 0.000889692318263897*G0_2_1 + 0.00409363710951081*G0_2_2 + 0.00392111122269919*G0_2_3 + 0.00153657042545957*G0_2_4 + 0.000641991753102973*G0_2_5 - 0.000641991753102971*G0_3_0 - 0.00100433370274657*G0_3_1 + 0.00392111122269919*G0_3_2 + 0.00588166683404878*G0_3_3 + 0.00128398350620594*G0_3_4 - 0.00153657042545957*G0_4_0 + 0.00153657042545957*G0_4_2 + 0.00128398350620594*G0_4_3 - 0.00128398350620595*G0_4_5 - 0.00392111122269918*G0_5_0 + 0.00100433370274657*G0_5_1 + 0.000641991753102973*G0_5_2 - 0.00128398350620594*G0_5_4 - 0.00588166683404878*G0_5_5; + A[37] = A[107]; + A[168] = A[56]; + A[38] = A[122]; + A[130] = A[158]; + A[62] = A[107] - 0.000117906784573471*G0_0_0 - 3.50267016933743e-05*G0_0_3 - 0.000140106806773497*G0_0_4 - 0.000107793441126792*G0_0_5 + 0.000117906784573471*G0_1_1 + 0.000140106806773497*G0_1_3 + 3.50267016933742e-05*G0_1_4 + 0.000107793441126793*G0_1_5 - 0.000175133508466871*G0_2_3 + 0.000175133508466871*G0_2_4 - 3.50267016933743e-05*G0_3_0 + 0.000140106806773497*G0_3_1 - 0.000175133508466871*G0_3_2 + 7.00534033867485e-05*G0_3_5 - 0.000140106806773497*G0_4_0 + 3.50267016933742e-05*G0_4_1 + 0.000175133508466871*G0_4_2 - 7.00534033867484e-05*G0_4_5 - 0.000107793441126792*G0_5_0 + 0.000107793441126793*G0_5_1 + 7.00534033867485e-05*G0_5_3 - 7.00534033867484e-05*G0_5_4; + A[117] = A[62] - 0.00111717206955321*G0_0_0 + 0.000335854621568964*G0_0_1 + 0.000124972029733956*G0_0_2 - 0.000401397544254754*G0_0_3 - 0.00117290117290137*G0_0_4 - 0.00119407928931758*G0_0_5 + 0.000335854621568964*G0_1_0 - 0.000127192031953958*G0_1_1 - 0.000156651109032087*G0_1_2 - 0.000416549940359535*G0_1_3 - 0.000402595640690947*G0_1_4 + 0.000250860250860292*G0_1_5 + 0.000124972029733956*G0_2_0 - 0.000156651109032087*G0_2_1 + 0.00114034114034133*G0_2_2 + 0.00064175683223313*G0_2_3 + 0.000270417413274601*G0_2_4 + 0.000400199447818562*G0_2_5 - 0.000401397544254754*G0_3_0 - 0.000416549940359535*G0_3_1 + 0.00064175683223313*G0_3_2 + 0.00170834456548771*G0_3_3 + 0.0016079863698914*G0_3_4 + 2.39619287238436e-06*G0_3_5 - 0.00117290117290137*G0_4_0 - 0.000402595640690947*G0_4_1 + 0.000270417413274601*G0_4_2 + 0.0016079863698914*G0_4_3 + 0.00560539989111512*G0_4_4 + 4.79238574476942e-06*G0_4_5 - 0.00119407928931758*G0_5_0 + 0.000250860250860292*G0_5_1 + 0.000400199447818562*G0_5_2 + 2.3961928723844e-06*G0_5_3 + 4.79238574476976e-06*G0_5_4 - 0.00290813243194244*G0_5_5; + A[199] = A[117] + 0.00110788682217272*G0_0_0 - 0.000281623138766043*G0_0_2 + 3.38286052571817e-05*G0_0_3 + 0.000896458039315333*G0_0_4 + 0.00155273298130467*G0_0_5 - 0.00110788682217272*G0_1_1 + 0.000281623138766043*G0_1_2 - 0.000896458039315332*G0_1_3 - 3.38286052571815e-05*G0_1_4 - 0.00155273298130467*G0_1_5 - 0.000281623138766043*G0_2_0 + 0.000281623138766043*G0_2_1 - 0.000196205910491658*G0_2_3 + 0.000196205910491658*G0_2_4 + 3.38286052571817e-05*G0_3_0 - 0.000896458039315332*G0_3_1 - 0.000196205910491658*G0_3_2 + 0.00389705532562742*G0_3_3 - 6.76572105143639e-05*G0_3_5 + 0.000896458039315333*G0_4_0 - 3.38286052571816e-05*G0_4_1 + 0.000196205910491658*G0_4_2 - 0.00389705532562741*G0_4_4 + 6.76572105143634e-05*G0_4_5 + 0.00155273298130467*G0_5_0 - 0.00155273298130467*G0_5_1 - 6.76572105143643e-05*G0_5_3 + 6.7657210514363e-05*G0_5_4; + A[214] = A[199] - 0.000429623286766216*G0_0_1 + 0.000429623286766216*G0_0_2 + 0.000608914894629282*G0_0_4 - 0.000608914894629282*G0_0_5 - 0.000429623286766216*G0_1_0 + 0.00142080142080166*G0_1_1 + 0.0012990184418758*G0_1_3 + 0.00078482364196663*G0_1_4 + 0.00154258439972752*G0_1_5 + 0.000429623286766216*G0_2_0 - 0.00142080142080166*G0_2_2 - 0.0012990184418758*G0_2_3 - 0.00154258439972751*G0_2_4 - 0.000784823641966631*G0_2_5 + 0.0012990184418758*G0_3_1 - 0.0012990184418758*G0_3_2 - 0.00156964728393326*G0_3_4 + 0.00156964728393326*G0_3_5 + 0.000608914894629282*G0_4_0 + 0.00078482364196663*G0_4_1 - 0.00154258439972751*G0_4_2 - 0.00156964728393326*G0_4_3 - 0.00443831300974232*G0_4_4 - 0.000608914894629282*G0_5_0 + 0.00154258439972752*G0_5_1 - 0.000784823641966631*G0_5_2 + 0.00156964728393326*G0_5_3 + 0.00443831300974233*G0_5_5; + A[163] = A[199] + 0.000312914598628937*G0_0_0 - 0.000148000148000173*G0_0_1 + 0.000750995036709449*G0_0_3 + 0.000598766313052127*G0_0_4 - 0.000206354492068813*G0_0_5 - 0.000148000148000173*G0_1_0 + 0.000148000148000173*G0_1_2 - 4.7360047360057e-05*G0_1_3 + 4.73600473600551e-05*G0_1_5 + 0.000148000148000173*G0_2_1 - 0.000312914598628936*G0_2_2 + 0.000206354492068813*G0_2_3 - 0.000598766313052127*G0_2_4 - 0.000750995036709449*G0_2_5 + 0.000750995036709449*G0_3_0 - 4.73600473600568e-05*G0_3_1 + 0.000206354492068813*G0_3_2 - 0.00833536833536975*G0_3_3 - 0.0015019900734189*G0_3_4 + 0.000598766313052127*G0_4_0 - 0.000598766313052127*G0_4_2 - 0.0015019900734189*G0_4_3 + 0.0015019900734189*G0_4_5 - 0.000206354492068813*G0_5_0 + 4.73600473600549e-05*G0_5_1 - 0.000750995036709449*G0_5_2 + 0.0015019900734189*G0_5_4 + 0.00833536833536974*G0_5_5; + A[191] = -A[117] - 0.000544640544640635*G0_0_0 + 0.00026950122188222*G0_0_1 + 8.45715131429466e-07*G0_0_2 - 0.0002289068955736*G0_0_3 - 0.000534491963063481*G0_0_4 - 0.000681082585844604*G0_0_5 + 0.00026950122188222*G0_1_0 - 0.000383954669669021*G0_1_1 + 5.63810087619758e-06*G0_1_2 - 0.000666423523566494*G0_1_3 - 0.000718294051627507*G0_1_4 + 5.63810087619458e-06*G0_1_5 + 8.45715131429466e-07*G0_2_0 + 5.63810087619756e-06*G0_2_1 + 0.000312350788541317*G0_2_2 + 0.000414964224488103*G0_2_3 - 0.000187184949089744*G0_2_4 + 0.000402560402560469*G0_2_5 - 0.0002289068955736*G0_3_0 - 0.000666423523566494*G0_3_1 + 0.000414964224488103*G0_3_2 + 0.00119076690505282*G0_3_3 + 0.00189440189440222*G0_3_4 - 0.000347307013973738*G0_3_5 - 0.000534491963063481*G0_4_0 - 0.000718294051627507*G0_4_1 - 0.000187184949089744*G0_4_2 + 0.00189440189440222*G0_4_3 + 0.00804669757050845*G0_4_4 + 0.000631467298134074*G0_4_5 - 0.000681082585844604*G0_5_0 + 5.63810087619474e-06*G0_5_1 + 0.000402560402560469*G0_5_2 - 0.000347307013973738*G0_5_3 + 0.000631467298134075*G0_5_4 - 0.00350013302394313*G0_5_5; + A[205] = A[163]; + A[132] = A[191] - 0.000120655358750617*G0_0_1 + 0.000120655358750617*G0_0_2 - 9.92305754210685e-05*G0_0_4 + 9.92305754210671e-05*G0_0_5 - 0.000120655358750617*G0_1_0 + 0.000383390859581401*G0_1_1 + 0.000482621435002469*G0_1_3 + 0.000369859417478528*G0_1_4 + 1.3531442102875e-05*G0_1_5 + 0.000120655358750617*G0_2_0 - 0.0003833908595814*G0_2_2 - 0.000482621435002468*G0_2_3 - 1.35314421028723e-05*G0_2_4 - 0.000369859417478527*G0_2_5 + 0.000482621435002469*G0_3_1 - 0.000482621435002468*G0_3_2 - 0.000739718834957056*G0_3_4 + 0.000739718834957053*G0_3_5 - 9.92305754210685e-05*G0_4_0 + 0.000369859417478528*G0_4_1 - 1.35314421028722e-05*G0_4_2 - 0.000739718834957056*G0_4_3 - 0.00321146225908185*G0_4_4 + 9.92305754210671e-05*G0_5_0 + 1.3531442102875e-05*G0_5_1 - 0.000369859417478527*G0_5_2 + 0.000739718834957053*G0_5_3 + 0.00321146225908184*G0_5_5; + A[188] = A[132]; + A[104] = A[132] - 0.000947200947201105*G0_0_0 + 0.000286415524510811*G0_0_1 - 0.000523215761311087*G0_0_3 - 0.000866012294583869*G0_0_4 - 0.00102838959981834*G0_0_5 + 0.000286415524510811*G0_1_0 - 0.000286415524510811*G0_1_2 - 0.000405943263086188*G0_1_3 + 0.000405943263086188*G0_1_5 - 0.000286415524510811*G0_2_1 + 0.000947200947201106*G0_2_2 + 0.00102838959981834*G0_2_3 + 0.000866012294583869*G0_2_4 + 0.000523215761311087*G0_2_5 - 0.000523215761311087*G0_3_0 - 0.000405943263086188*G0_3_1 + 0.00102838959981834*G0_3_2 + 0.00295887533982822*G0_3_3 + 0.00104643152262217*G0_3_4 - 0.000866012294583869*G0_4_0 + 0.000866012294583869*G0_4_2 + 0.00104643152262217*G0_4_3 - 0.00104643152262217*G0_4_5 - 0.00102838959981834*G0_5_0 + 0.000405943263086188*G0_5_1 + 0.000523215761311087*G0_5_2 - 0.00104643152262217*G0_5_4 - 0.00295887533982822*G0_5_5; + A[193] = -A[117] - 0.00168128168128196*G0_0_0 + 0.000608914894629283*G0_0_1 + 0.00032560032560038*G0_0_2 - 1.69143026285902e-05*G0_0_3 - 0.00199588771017376*G0_0_4 - 0.00193499622071083*G0_0_5 + 0.000608914894629283*G0_1_0 - 0.000573394859109242*G0_1_1 + 4.39771868343375e-05*G0_1_2 - 0.00109942967085843*G0_1_3 + 1.69143026285912e-05*G0_1_4 - 0.000382263239406162*G0_1_5 + 0.00032560032560038*G0_2_0 + 4.39771868343375e-05*G0_2_1 + 0.000280777423634613*G0_2_2 + 0.000906606620892488*G0_2_3 + 0.000710400710400829*G0_2_4 + 0.000118400118400138*G0_2_5 - 1.69143026285902e-05*G0_3_0 - 0.00109942967085843*G0_3_1 + 0.000906606620892488*G0_3_2 - 0.00389705532562742*G0_3_3 - 0.000202971631543096*G0_3_5 - 0.00199588771017376*G0_4_0 + 1.69143026285914e-05*G0_4_1 + 0.00071040071040083*G0_4_2 - 0.000270628842057458*G0_4_5 - 0.00193499622071083*G0_5_0 - 0.000382263239406162*G0_5_1 + 0.000118400118400139*G0_5_2 - 0.000202971631543095*G0_5_3 - 0.000270628842057458*G0_5_4 + 0.00205677919963669*G0_5_5; + A[187] = A[117]; + A[216] = A[104]; + A[148] = A[191] - 0.000947200947201106*G0_0_0 + 0.000286415524510811*G0_0_2 - 0.000523215761311088*G0_0_3 - 0.00102838959981834*G0_0_4 - 0.00086601229458387*G0_0_5 + 0.000947200947201109*G0_1_1 - 0.000286415524510811*G0_1_2 + 0.00102838959981835*G0_1_3 + 0.000523215761311088*G0_1_4 + 0.000866012294583871*G0_1_5 + 0.000286415524510811*G0_2_0 - 0.000286415524510811*G0_2_1 - 0.000405943263086188*G0_2_3 + 0.000405943263086189*G0_2_4 - 0.000523215761311088*G0_3_0 + 0.00102838959981835*G0_3_1 - 0.000405943263086188*G0_3_2 + 0.00295887533982822*G0_3_3 + 0.00104643152262217*G0_3_5 - 0.00102838959981834*G0_4_0 + 0.000523215761311088*G0_4_1 + 0.000405943263086189*G0_4_2 - 0.00295887533982822*G0_4_4 - 0.00104643152262218*G0_4_5 - 0.00086601229458387*G0_5_0 + 0.000866012294583871*G0_5_1 + 0.00104643152262217*G0_5_3 - 0.00104643152262218*G0_5_4; + A[222] = A[193] - 0.00013531442102873*G0_0_1 + 0.00013531442102873*G0_0_2 + 0.000108251536822982*G0_0_4 - 0.000108251536822983*G0_0_5 - 0.00013531442102873*G0_1_0 + 0.000541257684114919*G0_1_1 + 0.00140726997869879*G0_1_3 - 0.000649509220937901*G0_1_4 + 0.0012990184418758*G0_1_5 + 0.00013531442102873*G0_2_0 - 0.000541257684114918*G0_2_2 - 0.00140726997869879*G0_2_3 - 0.0012990184418758*G0_2_4 + 0.000649509220937901*G0_2_5 + 0.00140726997869879*G0_3_1 - 0.00140726997869879*G0_3_2 + 0.0012990184418758*G0_3_4 - 0.0012990184418758*G0_3_5 + 0.000108251536822982*G0_4_0 - 0.000649509220937902*G0_4_1 - 0.0012990184418758*G0_4_2 + 0.0012990184418758*G0_4_3 + 0.0103921475350064*G0_4_4 - 0.000108251536822983*G0_5_0 + 0.0012990184418758*G0_5_1 + 0.000649509220937901*G0_5_2 - 0.0012990184418758*G0_5_3 - 0.0103921475350064*G0_5_5; + A[213] = A[191] - 0.000563810087619706*G0_0_0 + 0.000165760165760193*G0_0_1 - 0.00015335634383256*G0_0_3 - 0.000951711427902064*G0_0_4 - 0.000446537589394808*G0_0_5 + 0.000165760165760193*G0_1_0 - 0.000165760165760194*G0_1_2 + 6.31467298134074e-05*G0_1_3 - 6.31467298134054e-05*G0_1_5 - 0.000165760165760194*G0_2_1 + 0.000563810087619705*G0_2_2 + 0.000446537589394807*G0_2_3 + 0.000951711427902064*G0_2_4 + 0.00015335634383256*G0_2_5 - 0.00015335634383256*G0_3_0 + 6.31467298134075e-05*G0_3_1 + 0.000446537589394807*G0_3_2 - 0.000252586919253629*G0_3_3 + 0.000306712687665118*G0_3_4 - 0.000951711427902064*G0_4_0 + 0.000951711427902064*G0_4_2 + 0.000306712687665118*G0_4_3 - 0.000306712687665122*G0_4_5 - 0.000446537589394808*G0_5_0 - 6.31467298134054e-05*G0_5_1 + 0.00015335634383256*G0_5_2 - 0.000306712687665122*G0_5_4 + 0.000252586919253628*G0_5_5; + A[204] = A[148]; + A[88] = A[132] - 0.000563810087619705*G0_0_0 + 0.000165760165760193*G0_0_2 - 0.00015335634383256*G0_0_3 - 0.000446537589394807*G0_0_4 - 0.000951711427902063*G0_0_5 + 0.000563810087619707*G0_1_1 - 0.000165760165760194*G0_1_2 + 0.000446537589394807*G0_1_3 + 0.000153356343832559*G0_1_4 + 0.000951711427902063*G0_1_5 + 0.000165760165760193*G0_2_0 - 0.000165760165760194*G0_2_1 + 6.31467298134079e-05*G0_2_3 - 6.31467298134065e-05*G0_2_4 - 0.00015335634383256*G0_3_0 + 0.000446537589394807*G0_3_1 + 6.31467298134078e-05*G0_3_2 - 0.000252586919253627*G0_3_3 + 0.000306712687665121*G0_3_5 - 0.000446537589394807*G0_4_0 + 0.000153356343832559*G0_4_1 - 6.31467298134065e-05*G0_4_2 + 0.000252586919253631*G0_4_4 - 0.000306712687665118*G0_4_5 - 0.000951711427902063*G0_5_0 + 0.000951711427902063*G0_5_1 + 0.000306712687665122*G0_5_3 - 0.000306712687665118*G0_5_4; + A[207] = A[193]; + A[73] = A[199]; + A[119] = A[117] + 0.00142080142080166*G0_0_0 - 0.000429623286766215*G0_0_1 + 0.000784823641966629*G0_0_3 + 0.0012990184418758*G0_0_4 + 0.00154258439972751*G0_0_5 - 0.000429623286766215*G0_1_0 + 0.000429623286766215*G0_1_2 + 0.000608914894629281*G0_1_3 - 0.000608914894629282*G0_1_5 + 0.000429623286766215*G0_2_1 - 0.00142080142080166*G0_2_2 - 0.00154258439972751*G0_2_3 - 0.0012990184418758*G0_2_4 - 0.00078482364196663*G0_2_5 + 0.000784823641966629*G0_3_0 + 0.000608914894629281*G0_3_1 - 0.00154258439972751*G0_3_2 - 0.00443831300974232*G0_3_3 - 0.00156964728393326*G0_3_4 + 0.0012990184418758*G0_4_0 - 0.0012990184418758*G0_4_2 - 0.00156964728393326*G0_4_3 + 0.00156964728393326*G0_4_5 + 0.00154258439972751*G0_5_0 - 0.000608914894629282*G0_5_1 - 0.00078482364196663*G0_5_2 + 0.00156964728393326*G0_5_4 + 0.00443831300974232*G0_5_5; + A[194] = A[222]; + A[141] = A[99]; + A[217] = A[119]; + A[200] = A[88]; + A[34] = A[62]; + A[96] = A[144] + 0.000513067179733932*G0_0_1 - 0.000513067179733934*G0_0_2 + 0.00252586919253629*G0_0_4 - 0.00252586919253628*G0_0_5 + 0.000513067179733932*G0_1_0 - 0.000434133767467174*G0_1_1 - 0.000210489099378024*G0_1_3 - 0.00017891573447132*G0_1_4 + 0.000652516208071872*G0_1_5 - 0.000513067179733934*G0_2_0 + 0.000434133767467174*G0_2_2 + 0.000210489099378023*G0_2_3 - 0.000652516208071875*G0_2_4 + 0.00017891573447132*G0_2_5 - 0.000210489099378024*G0_3_1 + 0.000210489099378023*G0_3_2 + 0.000357831468942641*G0_3_4 - 0.000357831468942641*G0_3_5 + 0.00252586919253629*G0_4_0 - 0.00017891573447132*G0_4_1 - 0.000652516208071875*G0_4_2 + 0.000357831468942641*G0_4_3 + 0.00547271658382863*G0_4_4 - 0.00252586919253628*G0_5_0 + 0.000652516208071872*G0_5_1 + 0.00017891573447132*G0_5_2 - 0.000357831468942641*G0_5_3 - 0.00547271658382862*G0_5_5; + A[223] = A[193] + 0.000541257684114917*G0_0_0 - 0.000135314421028729*G0_0_1 - 0.000649509220937903*G0_0_3 + 0.00140726997869879*G0_0_4 + 0.0012990184418758*G0_0_5 - 0.000135314421028729*G0_1_0 + 0.000135314421028729*G0_1_2 + 0.000108251536822983*G0_1_3 - 0.000108251536822984*G0_1_5 + 0.000135314421028729*G0_2_1 - 0.000541257684114917*G0_2_2 - 0.0012990184418758*G0_2_3 - 0.00140726997869879*G0_2_4 + 0.000649509220937902*G0_2_5 - 0.000649509220937903*G0_3_0 + 0.000108251536822983*G0_3_1 - 0.0012990184418758*G0_3_2 + 0.0103921475350064*G0_3_3 + 0.00129901844187581*G0_3_4 + 0.00140726997869879*G0_4_0 - 0.00140726997869879*G0_4_2 + 0.00129901844187581*G0_4_3 - 0.0012990184418758*G0_4_5 + 0.0012990184418758*G0_5_0 - 0.000108251536822984*G0_5_1 + 0.000649509220937902*G0_5_2 - 0.0012990184418758*G0_5_4 - 0.0103921475350064*G0_5_5; + A[59] = A[213]; + A[48] = A[176] - 0.000434133767467174*G0_0_0 + 0.000513067179733932*G0_0_1 - 0.000178915734471321*G0_0_3 - 0.000210489099378024*G0_0_4 + 0.000652516208071873*G0_0_5 + 0.000513067179733932*G0_1_0 - 0.000513067179733935*G0_1_2 + 0.00252586919253629*G0_1_3 - 0.00252586919253628*G0_1_5 - 0.000513067179733935*G0_2_1 + 0.000434133767467174*G0_2_2 - 0.000652516208071876*G0_2_3 + 0.000210489099378023*G0_2_4 + 0.000178915734471319*G0_2_5 - 0.000178915734471321*G0_3_0 + 0.00252586919253629*G0_3_1 - 0.000652516208071876*G0_3_2 + 0.00547271658382863*G0_3_3 + 0.000357831468942641*G0_3_4 - 0.000210489099378024*G0_4_0 + 0.000210489099378023*G0_4_2 + 0.000357831468942641*G0_4_3 - 0.000357831468942639*G0_4_5 + 0.000652516208071873*G0_5_0 - 0.00252586919253628*G0_5_1 + 0.000178915734471319*G0_5_2 - 0.000357831468942639*G0_5_4 - 0.00547271658382861*G0_5_5; + A[162] = A[117] - 0.000148000148000173*G0_0_1 + 0.000148000148000173*G0_0_2 - 4.73600473600564e-05*G0_0_4 + 4.73600473600536e-05*G0_0_5 - 0.000148000148000173*G0_1_0 + 0.000312914598628938*G0_1_1 + 0.000598766313052129*G0_1_3 + 0.00075099503670945*G0_1_4 - 0.00020635449206881*G0_1_5 + 0.000148000148000173*G0_2_0 - 0.000312914598628937*G0_2_2 - 0.000598766313052128*G0_2_3 + 0.000206354492068814*G0_2_4 - 0.000750995036709448*G0_2_5 + 0.000598766313052129*G0_3_1 - 0.000598766313052128*G0_3_2 - 0.0015019900734189*G0_3_4 + 0.0015019900734189*G0_3_5 - 4.73600473600564e-05*G0_4_0 + 0.00075099503670945*G0_4_1 + 0.000206354492068814*G0_4_2 - 0.0015019900734189*G0_4_3 - 0.00833536833536974*G0_4_4 + 4.73600473600531e-05*G0_5_0 - 0.00020635449206881*G0_5_1 - 0.000750995036709448*G0_5_2 + 0.0015019900734189*G0_5_3 + 0.00833536833536973*G0_5_5; + A[115] = A[157]; + A[190] = A[162]; + A[58] = A[198]; + A[28] = 3.67181319562334e-05*G0_0_0 - 2.46666913333632e-06*G0_0_1 - 2.69219316838409e-05*G0_0_2 + 7.89334122667569e-06*G0_0_3 + 4.51048070095757e-06*G0_0_4 + 5.72267238934001e-05*G0_0_5 - 2.46666913333633e-06*G0_1_0 + 0.000310800310800365*G0_1_1 - 2.46666913333634e-06*G0_1_2 - 3.94667061333789e-05*G0_1_3 - 9.86667653334487e-05*G0_1_4 - 3.9466706133379e-05*G0_1_5 - 2.69219316838409e-05*G0_2_0 - 2.46666913333635e-06*G0_2_1 + 3.67181319562334e-05*G0_2_2 + 5.72267238933999e-05*G0_2_3 + 4.5104807009575e-06*G0_2_4 + 7.89334122667574e-06*G0_2_5 + 7.89334122667569e-06*G0_3_0 - 3.94667061333789e-05*G0_3_1 + 5.72267238933999e-05*G0_3_2 - 4.73600473600538e-05*G0_3_3 + 0.000181546848213546*G0_3_4 - 3.15733649067028e-05*G0_3_5 + 4.51048070095757e-06*G0_4_0 - 9.86667653334487e-05*G0_4_1 + 4.51048070095749e-06*G0_4_2 + 0.000181546848213546*G0_4_3 + 0.000598766313052128*G0_4_4 + 0.000181546848213546*G0_4_5 + 5.72267238934001e-05*G0_5_0 - 3.9466706133379e-05*G0_5_1 + 7.89334122667575e-06*G0_5_2 - 3.15733649067029e-05*G0_5_3 + 0.000181546848213546*G0_5_4 - 4.7360047360055e-05*G0_5_5; + A[131] = A[173]; + A[74] = A[214]; + A[40] = A[60] + 8.70910394720062e-05*G0_0_0 - 1.15052496004896e-05*G0_0_1 - 1.93104955009749e-05*G0_0_3 + 4.54571883143388e-05*G0_0_4 + 5.53943411086361e-05*G0_0_5 - 1.15052496004896e-05*G0_1_0 + 1.15052496004896e-05*G0_1_2 - 9.93715279429739e-06*G0_1_3 + 9.93715279429724e-06*G0_1_5 + 1.15052496004896e-05*G0_2_1 - 8.70910394720064e-05*G0_2_2 - 5.53943411086361e-05*G0_2_3 - 4.54571883143388e-05*G0_2_4 + 1.93104955009749e-05*G0_2_5 - 1.93104955009749e-05*G0_3_0 - 9.93715279429736e-06*G0_3_1 - 5.53943411086361e-05*G0_3_2 + 0.000437234722949083*G0_3_3 + 3.86209910019499e-05*G0_3_4 + 4.54571883143388e-05*G0_4_0 - 4.54571883143388e-05*G0_4_2 + 3.86209910019499e-05*G0_4_3 - 3.86209910019498e-05*G0_4_5 + 5.53943411086361e-05*G0_5_0 + 9.93715279429724e-06*G0_5_1 + 1.93104955009749e-05*G0_5_2 - 3.86209910019498e-05*G0_5_4 - 0.000437234722949082*G0_5_5; + A[145] = A[159]; + A[151] = A[25]; + A[102] = A[186]; + A[177] = A[191]; + A[114] = A[142]; + A[221] = A[179]; + A[196] = A[28]; + A[209] = A[223]; + A[13] = A[195]; + A[53] = A[123]; + A[30] = A[2]; + A[23] = A[121]; + A[128] = A[176] + 0.000889692318263896*G0_0_1 - 0.000889692318263896*G0_0_2 - 0.00100433370274657*G0_0_4 + 0.00100433370274657*G0_0_5 + 0.000889692318263896*G0_1_0 - 0.00409363710951082*G0_1_1 - 0.00153657042545957*G0_1_3 - 0.000641991753102971*G0_1_4 - 0.00392111122269918*G0_1_5 - 0.000889692318263896*G0_2_0 + 0.00409363710951081*G0_2_2 + 0.00153657042545957*G0_2_3 + 0.00392111122269918*G0_2_4 + 0.000641991753102972*G0_2_5 - 0.00153657042545957*G0_3_1 + 0.00153657042545957*G0_3_2 + 0.00128398350620594*G0_3_4 - 0.00128398350620594*G0_3_5 - 0.00100433370274657*G0_4_0 - 0.00064199175310297*G0_4_1 + 0.00392111122269918*G0_4_2 + 0.00128398350620594*G0_4_3 + 0.00588166683404877*G0_4_4 + 0.00100433370274657*G0_5_0 - 0.00392111122269918*G0_5_1 + 0.000641991753102972*G0_5_2 - 0.00128398350620594*G0_5_3 - 0.00588166683404877*G0_5_5; + A[63] = A[49]; + A[140] = A[84]; + A[77] = A[35]; + A[171] = A[101]; + A[152] = A[40]; + } + + /// 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 mass_matrix_f2_p2_q4_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p2_q4_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p2_q4_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1))), 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 mass_matrix_f2_p2_q4_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p2_q4_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p2_q4_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p2_q4_tensor_finite_element_0(); + 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 mass_matrix_f2_p2_q4_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p2_q4_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p2_q4_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p2_q4_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f2_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/mass_matrix_2d/mass_matrix_f2_p3_q1_excafe.h b/mass_matrix_2d/mass_matrix_f2_p3_q1_excafe.h new file mode 100644 index 0000000..74a20a5 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p3_q1_excafe.h @@ -0,0 +1,207 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 47.32 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][9]*w[1][3] + w[0][3]*w[1][9]; + const double var_1 = -1.0000000000000000000000000*w[0][7]*w[1][3] + -1.0000000000000000000000000*w[0][3]*w[1][7]; + const double var_2 = 0.5000000000000000000000000*var_1; + const double var_3 = var_2 + var_0; + const double var_4 = w[0][9]*w[1][4] + w[0][4]*w[1][9]; + const double var_5 = -1.0000000000000000000000000*w[0][5]*w[1][4] + -1.0000000000000000000000000*w[0][4]*w[1][5]; + const double var_6 = 0.5000000000000000000000000*var_5; + const double var_7 = var_4 + var_6; + const double var_8 = var_3 + var_7; + const double var_9 = w[0][0]*w[1][1] + w[0][1]*w[1][0]; + const double var_10 = w[0][4]*w[1][6] + w[0][6]*w[1][4]; + const double var_11 = 1.5000000000000000000000000*var_10 + w[0][2]*w[1][9] + w[0][9]*w[1][2]; + const double var_12 = w[0][4]*w[1][4]; + const double var_13 = w[0][6]*w[1][6]; + const double var_14 = var_12 + var_13; + const double var_15 = w[0][3]*w[1][2] + w[0][2]*w[1][3]; + const double var_16 = w[0][2]*w[1][5] + w[0][5]*w[1][2]; + const double var_17 = var_16 + var_15; + const double var_18 = w[0][0]*w[1][3] + w[0][3]*w[1][0]; + const double var_19 = w[0][1]*w[1][5] + w[0][5]*w[1][1]; + const double var_20 = var_19 + var_18; + const double var_21 = w[0][4]*w[1][0] + w[0][0]*w[1][4]; + const double var_22 = w[0][6]*w[1][1] + w[0][1]*w[1][6]; + const double var_23 = var_22 + var_21; + const double var_24 = w[0][6]*w[1][3] + w[0][3]*w[1][6]; + const double var_25 = -0.5000000000000000000000000*var_24; + const double var_26 = -1.0000000000000000000000000*var_4 + var_25; + const double var_27 = w[0][6]*w[1][9] + w[0][9]*w[1][6]; + const double var_28 = -1.0000000000000000000000000*var_27 + var_6; + const double var_29 = w[0][6]*w[1][5] + w[0][5]*w[1][6]; + const double var_30 = -1.0000000000000000000000000*var_29; + const double var_31 = var_30 + var_26 + var_28; + const double var_32 = w[0][4]*w[1][8] + w[0][8]*w[1][4]; + const double var_33 = -0.5000000000000000000000000*var_32; + const double var_34 = w[0][7]*w[1][8] + w[0][8]*w[1][7]; + const double var_35 = w[0][8]*w[1][9] + w[0][9]*w[1][8]; + const double var_36 = var_33 + -0.5000000000000000000000000*var_34 + var_35; + const double var_37 = w[0][7]*w[1][9] + w[0][9]*w[1][7]; + const double var_38 = -1.0000000000000000000000000*w[0][7]*w[1][6] + -1.0000000000000000000000000*w[0][6]*w[1][7]; + const double var_39 = 0.5000000000000000000000000*var_38; + const double var_40 = var_39 + var_37; + const double var_41 = var_40 + var_36; + const double var_42 = w[0][5]*w[1][9] + w[0][9]*w[1][5]; + const double var_43 = -1.0000000000000000000000000*w[0][8]*w[1][5] + -1.0000000000000000000000000*w[0][5]*w[1][8]; + const double var_44 = 0.5000000000000000000000000*var_43; + const double var_45 = var_44 + var_42; + const double var_46 = var_45 + var_3; + const double var_47 = 13.5000000000000000000000000*var_41 + 6.7500000000000000000000000*var_14 + var_20 + 0.3611111111111111049432054*var_9 + 9.0000000000000000000000000*var_46 + 0.2500000000000000000000000*var_23 + 3.0000000000000000000000000*var_11 + var_17 + 4.5000000000000000000000000*var_31; + const double var_48 = -1.0000000000000000000000000*x[0][1]; + const double var_49 = var_48 + x[1][1]; + const double var_50 = -1.0000000000000000000000000*x[0][0]; + const double var_51 = var_50 + x[2][0]; + const double var_52 = x[2][1] + var_48; + const double var_53 = x[1][0] + var_50; + const double var_54 = var_52*var_53 + -1.0000000000000000000000000*var_49*var_51; + const double var_55 = w[0][2]*w[1][0] + w[0][0]*w[1][2]; + const double var_56 = w[0][1]*w[1][4] + w[0][4]*w[1][1]; + const double var_57 = w[0][1]*w[1][7] + w[0][7]*w[1][1]; + const double var_58 = var_57 + var_56; + const double var_59 = w[0][2]*w[1][6] + w[0][6]*w[1][2]; + const double var_60 = w[0][8]*w[1][2] + w[0][2]*w[1][8]; + const double var_61 = w[0][2]*w[1][2]; + const double var_62 = 0.3214285714285713968507707*var_10 + 0.0015873015873015873002105*var_9 + 0.0476190476190476164042309*var_61; + const double var_63 = var_39 + -1.0000000000000000000000000*var_42; + const double var_64 = var_44 + -1.0000000000000000000000000*var_37; + const double var_65 = var_64 + var_63; + const double var_66 = w[0][3]*w[1][8] + w[0][8]*w[1][3]; + const double var_67 = w[0][1]*w[1][1]; + const double var_68 = 0.0476190476190476164042309*var_67 + 0.0015873015873015873002105*var_55 + 0.3214285714285713968507707*var_66; + const double var_69 = std::abs(var_54); + const double var_70 = w[0][3]*w[1][4] + w[0][4]*w[1][3]; + const double var_71 = -1.0000000000000000000000000*var_70; + const double var_72 = w[0][5]*w[1][7] + w[0][7]*w[1][5]; + const double var_73 = w[0][2]*w[1][1] + w[0][1]*w[1][2]; + const double var_74 = w[0][3]*w[1][5] + w[0][5]*w[1][3]; + const double var_75 = w[0][7]*w[1][4] + w[0][4]*w[1][7]; + const double var_76 = w[0][6]*w[1][8] + w[0][8]*w[1][6]; + const double var_77 = -1.0000000000000000000000000*var_76 + -1.0000000000000000000000000*var_74 + -1.0000000000000000000000000*var_75; + const double var_78 = 0.0642857142857142793701541*var_77 + 2.3142857142857140573255492*w[0][9]*w[1][9]; + const double var_79 = w[0][0]*w[1][0]; + const double var_80 = 0.1285714285714285587403083*var_71 + 0.0476190476190476164042309*var_79 + 0.3214285714285713968507707*var_72 + 0.0015873015873015873002105*var_73 + var_78; + const double var_81 = w[0][7]*w[1][7]; + const double var_82 = var_12 + var_81; + const double var_83 = w[0][5]*w[1][5]; + const double var_84 = var_13 + var_83; + const double var_85 = var_19 + var_22; + const double var_86 = w[0][1]*w[1][3] + w[0][3]*w[1][1]; + const double var_87 = -1.0000000000000000000000000*var_86; + const double var_88 = w[0][1]*w[1][8] + w[0][8]*w[1][1]; + const double var_89 = -1.0000000000000000000000000*var_88; + const double var_90 = var_87 + var_89; + const double var_91 = w[0][9]*w[1][1] + w[0][1]*w[1][9] + 1.5000000000000000000000000*var_66; + const double var_92 = w[0][3]*w[1][3]; + const double var_93 = w[0][8]*w[1][8]; + const double var_94 = var_93 + var_92; + const double var_95 = w[0][2]*w[1][7] + w[0][7]*w[1][2]; + const double var_96 = var_95 + var_21; + const double var_97 = var_18 + var_60; + const double var_98 = -1.0000000000000000000000000*var_34; + const double var_99 = var_40 + 0.5000000000000000000000000*var_98; + const double var_100 = var_99 + var_7; + const double var_101 = var_33 + -1.0000000000000000000000000*var_0; + const double var_102 = var_2 + -1.0000000000000000000000000*var_35; + const double var_103 = var_102 + var_101; + const double var_104 = var_27 + var_25 + -0.5000000000000000000000000*var_29; + const double var_105 = var_104 + var_45; + const double var_106 = 6.7500000000000000000000000*var_94 + 0.2500000000000000000000000*var_97 + 3.0000000000000000000000000*var_91 + 0.3611111111111111049432054*var_55 + 13.5000000000000000000000000*var_105 + 4.5000000000000000000000000*var_103 + 9.0000000000000000000000000*var_100 + var_96 + var_58; + const double var_107 = 0.9642857142857141905523122*var_84 + 0.0158730158730158721347436*var_67 + var_80 + 0.0285714285714285705364279*var_106 + var_62 + 0.0500000000000000027755576*var_85 + 0.3214285714285713968507707*var_82 + 0.0357142857142857123031732*var_90; + A[2] = 0.0062500000000000003469447*var_107*var_69; + const double var_108 = var_56 + var_15; + const double var_109 = 1.5000000000000000000000000*var_72 + w[0][9]*w[1][0] + w[0][0]*w[1][9]; + const double var_110 = 0.7714285714285713524418497*w[0][9]*w[1][9]; + const double var_111 = 0.1607142857142856984253854*var_71 + 0.0119047619047619041010577*var_73 + 0.0321428571428571396850771*var_109 + 0.0079365079365079360673718*w[0][0]*w[1][0] + -0.0482142857142857095276156*var_76 + var_110; + const double var_112 = w[0][0]*w[1][7] + w[0][7]*w[1][0]; + const double var_113 = w[0][8]*w[1][0] + w[0][0]*w[1][8]; + const double var_114 = var_57 + var_113; + const double var_115 = var_93 + var_13; + const double var_116 = var_12 + var_92; + const double var_117 = -1.0000000000000000000000000*var_112; + const double var_118 = w[0][5]*w[1][0] + w[0][0]*w[1][5]; + const double var_119 = -1.0000000000000000000000000*var_118; + const double var_120 = var_117 + var_119; + const double var_121 = var_18 + var_21; + const double var_122 = w[0][6]*w[1][0] + w[0][0]*w[1][6]; + const double var_123 = var_122 + var_113; + const double var_124 = var_19 + var_95; + const double var_125 = var_22 + var_60; + const double var_126 = var_104 + var_36; + const double var_127 = var_81 + var_83; + const double var_128 = var_127 + var_71; + const double var_129 = 13.5000000000000000000000000*var_8 + 6.7500000000000000000000000*var_128 + 9.0000000000000000000000000*var_126 + var_125 + 0.2500000000000000000000000*var_124 + 0.3611111111111111049432054*var_73 + 4.5000000000000000000000000*var_65 + 3.0000000000000000000000000*var_109 + var_123; + const double var_130 = 0.0158730158730158721347436*var_79 + var_68 + 0.9642857142857141905523122*var_116 + var_62 + 0.0285714285714285705364279*var_129 + 0.3214285714285713968507707*var_115 + var_78 + 0.0357142857142857123031732*var_120 + 0.0500000000000000027755576*var_121; + A[5] = 0.0062500000000000003469447*var_130*var_69; + A[7] = A[5]; + const double var_131 = var_57 + var_16; + const double var_132 = w[0][2]*w[1][4] + w[0][4]*w[1][2]; + const double var_133 = var_92 + var_83; + const double var_134 = var_93 + var_81; + const double var_135 = var_64 + var_102 + var_134 + var_74; + const double var_136 = var_63 + var_101; + const double var_137 = 0.6000000000000000888178420*var_133 + 0.0500000000000000027755576*var_98 + 0.1000000000000000055511151*var_135 + var_7 + var_10 + var_104 + 0.2000000000000000111022302*var_136; + const double var_138 = var_87 + var_119; + const double var_139 = -0.0500000000000000027755576*var_20 + var_132 + var_59 + 3.0000000000000000000000000*var_137 + -0.5000000000000000000000000*var_17 + 0.2500000000000000000000000*var_138; + const double var_140 = -1.0000000000000000000000000*var_59; + const double var_141 = var_140 + var_119; + const double var_142 = -1.0000000000000000000000000*var_132; + const double var_143 = var_16 + var_122; + const double var_144 = 0.0079365079365079360673718*w[0][1]*w[1][1] + 0.0321428571428571396850771*var_91 + 0.0119047619047619041010577*var_55 + -0.0482142857142857095276156*var_75; + const double var_145 = var_117 + var_89; + const double var_146 = var_122 + var_56; + const double var_147 = 0.1071428571428571369095195*var_139 + var_144 + 0.6428571428571427937015414*var_14 + var_111 + 0.0375000000000000055511151*var_146 + 0.0017857142857142856585267*var_114 + 0.0021825396825396825919996*var_9 + 0.1547619047619047671915382*w[0][2]*w[1][2] + 0.0089285714285714280757933*var_145 + 0.0428571428571428575393654*var_23; + const double var_148 = 0.0321428571428571396850771*var_11 + 0.0079365079365079360673718*w[0][2]*w[1][2] + 0.0119047619047619041010577*var_9 + -0.0482142857142857095276156*var_74; + const double var_149 = var_113 + var_15; + const double var_150 = 0.5000000000000000000000000*var_30; + const double var_151 = var_84 + var_75 + var_28 + var_63 + var_150; + const double var_152 = var_64 + var_26; + const double var_153 = var_66 + 0.2000000000000000111022302*var_152 + var_36 + 0.1000000000000000055511151*var_151 + var_3 + 0.6000000000000000888178420*var_82; + const double var_154 = var_117 + var_142; + const double var_155 = var_86 + 0.2500000000000000000000000*var_154 + 3.0000000000000000000000000*var_153 + -0.0500000000000000027755576*var_96 + var_88 + -0.5000000000000000000000000*var_58; + const double var_156 = 0.6428571428571427937015414*var_94 + var_148 + 0.0428571428571428575393654*var_97 + var_111 + 0.0021825396825396825919996*var_55 + 0.0089285714285714280757933*var_141 + 0.1071428571428571369095195*var_155 + 0.1547619047619047671915382*w[0][1]*w[1][1] + 0.0375000000000000055511151*var_149 + 0.0017857142857142856585267*var_143; + A[4] = 0.0250000000000000013877788*var_156*var_69; + const double var_157 = var_102 + var_28; + const double var_158 = var_88 + var_59; + const double var_159 = var_116 + var_76 + var_101 + var_26; + const double var_160 = var_95 + var_60; + const double var_161 = var_99 + var_45 + -0.0500000000000000027755576*var_70 + var_150 + var_72 + 0.2000000000000000111022302*var_157 + 0.1000000000000000055511151*var_159 + 0.6000000000000000888178420*var_115; + const double var_162 = var_87 + var_142; + const double var_163 = var_112 + var_118 + -0.0500000000000000027755576*var_125 + 3.0000000000000000000000000*var_161 + -0.5000000000000000000000000*var_123; + const double var_164 = 0.1071428571428571369095195*var_163 + var_144 + var_110 + 0.6428571428571427937015414*var_127 + var_148 + -0.0267857142857142842273799*var_158 + 0.0021825396825396825919996*var_73 + 0.0017857142857142856585267*var_108 + 0.0375000000000000055511151*var_131 + 0.0089285714285714280757933*var_162 + 0.1547619047619047671915382*w[0][0]*w[1][0] + 0.0428571428571428575393654*var_124; + const double var_165 = var_140 + var_142; + const double var_166 = 0.9642857142857141905523122*var_134 + 0.0158730158730158721347436*var_61 + 0.3214285714285713968507707*var_133 + var_80 + var_68 + 0.0285714285714285705364279*var_47 + 0.0357142857142857123031732*var_165 + 0.0500000000000000027755576*var_160; + A[0] = 0.0250000000000000013877788*var_164*var_69; + A[8] = 0.0250000000000000013877788*var_147*var_69; + A[1] = 0.0062500000000000003469447*var_166*var_69; + A[6] = A[2]; + A[3] = A[1]; + } + + 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/mass_matrix_2d/mass_matrix_f2_p3_q1_quadrature.h b/mass_matrix_2d/mass_matrix_f2_p3_q1_quadrature.h new file mode 100644 index 0000000..e49796d --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p3_q1_quadrature.h @@ -0,0 +1,4605 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P3_Q1_QUADRATURE_H +#define __MASS_MATRIX_F2_P3_Q1_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p3_q1_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p3_q1_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p3_q1_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p3_q1_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p3_q1_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p3_q1_quadrature_finite_element_1() + { + // 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 mass_matrix_f2_p3_q1_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p3_q1_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p3_q1_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_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.0*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 mass_matrix_f2_p3_q1_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p3_q1_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p3_q1_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_p3_q1_quadrature_dofmap_1() + { + // 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 mass_matrix_f2_p3_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 mass_matrix_f2_p3_q1_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p3_q1_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // 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[25][3] = \ + {{0.915147549378728, 0.0450425935698037, 0.0398098570514687}, + {0.764365329781281, 0.0376212523451112, 0.198013417873608}, + {0.535660544808143, 0.026364644944471, 0.437974810247386}, + {0.290249932250793, 0.0142857943955714, 0.695464273353636}, + {0.09391279733378, 0.00462228846504648, 0.901464914201173}, + {0.738611533396152, 0.221578609552379, 0.0398098570514687}, + {0.616915871859002, 0.185070710267389, 0.198013417873608}, + {0.43232925297036, 0.129695936782254, 0.437974810247386}, + {0.234259434638082, 0.0702762920082818, 0.695464273353636}, + {0.0757966027350624, 0.0227384830637641, 0.901464914201173}, + {0.480095071474266, 0.480095071474266, 0.0398098570514687}, + {0.400993291063196, 0.400993291063196, 0.198013417873608}, + {0.281012594876307, 0.281012594876307, 0.437974810247386}, + {0.152267863323182, 0.152267863323182, 0.695464273353636}, + {0.0492675428994132, 0.0492675428994133, 0.901464914201173}, + {0.221578609552379, 0.738611533396152, 0.0398098570514687}, + {0.185070710267389, 0.616915871859002, 0.198013417873608}, + {0.129695936782254, 0.43232925297036, 0.437974810247386}, + {0.0702762920082818, 0.234259434638082, 0.695464273353636}, + {0.022738483063764, 0.0757966027350624, 0.901464914201173}, + {0.0450425935698037, 0.915147549378728, 0.0398098570514687}, + {0.0376212523451112, 0.764365329781281, 0.198013417873608}, + {0.0263646449444709, 0.535660544808143, 0.437974810247386}, + {0.0142857943955715, 0.290249932250793, 0.695464273353636}, + {0.00462228846504642, 0.0939127973337801, 0.901464914201173}}; + + static const double FE1[25][10] = \ + {{0.595361771100889, 0.0363240630142744, 0.0329620582231266, -0.00697876330105453, -0.00710543413900173, 0.286154010031837, -0.144363814874519, 0.323767019699913, -0.160427557536749, 0.0443066477812842}, + {0.144847707077251, 0.031491752557511, 0.056509372357196, -0.0297392974343587, -0.0136089104009562, 0.880722068301204, -0.276497422020097, 0.167331423967527, -0.114798724929776, 0.153742030524499}, + {-0.0638922318573471, 0.0233191863197456, -0.0471646056404562, -0.0478518692290425, 0.0163120554591614, 0.640806423249974, 0.331418250941681, 0.038574441798557, -0.0585247318831845, 0.167003080840912}, + {0.0211818331847306, 0.0133805365030047, 0.0326369349932555, -0.0427925717552784, 0.0485711762178746, -0.117406110387015, 0.98683910857276, -0.0024116832712123, -0.0178593517002863, 0.0778601276421673}, + {0.0579517721596659, 0.00452658789692546, 0.541134376806172, -0.0184907249626245, 0.0319586608616019, -0.273633189306433, 0.649316299328904, -0.0014030624094848, -0.00192632644777788, 0.010565606073051}, + {0.0969129145557495, 0.0495966310503562, 0.0329620582231266, -0.0133081629182569, -0.0349538534974921, 0.160876909651335, -0.116515395516028, 0.895428534283356, -0.246912783611135, 0.175913147778989}, + {-0.0391667888544834, 0.0594654509565622, 0.056509372357196, -0.0733496016702976, -0.0669464878724995, 0.467663868980969, -0.223159844548554, 0.437096058075966, -0.228522561505531, 0.610410534080673}, + {-0.0451321541833679, 0.0638185648099453, -0.0471646056404562, -0.15615892407532, 0.0802441041051714, 0.253054939278284, 0.267486202295671, 0.074936267198872, -0.154146013447678, 0.663061619658879}, + {0.045160818752146, 0.0496137334753148, 0.0326369349932555, -0.17356708239734, 0.238936811531546, -0.217903867034122, 0.796473473259088, -0.0220190689531468, -0.0584641485580772, 0.309132394931336}, + {0.0519031146003489, 0.0204647143413336, 0.541134376806172, -0.0859485068100627, 0.157214651192224, -0.23755901477889, 0.524060308998282, -0.00599217068695466, -0.00722668705539908, 0.0419492133929461}, + {-0.0591559090807405, -0.0591559090807405, 0.0329620582231266, 0.03786731225338, -0.0757346245067602, 0.03786731225338, -0.0757346245067601, 0.456668557219904, 0.456668557219904, 0.247747270005307}, + {-0.032436155693348, -0.032436155693348, 0.056509372357196, 0.0725265831052634, -0.145053166210527, 0.0725265831052632, -0.145053166210527, 0.146872235029605, 0.146872235029605, 0.859671635180817}, + {0.025515852626442, 0.0255158526264419, -0.0471646056404562, -0.0869325766002105, 0.173865153200421, -0.0869325766002107, 0.173865153200421, -0.0557775204375565, -0.0557775204375563, 0.933822788062264}, + {0.0638199343796498, 0.0638199343796498, 0.0326369349932555, -0.258852571197659, 0.517705142395317, -0.258852571197659, 0.517705142395317, -0.0566742670215316, -0.0566742670215314, 0.435366587895191}, + {0.0388828743119486, 0.0388828743119486, 0.541134376806172, -0.170318740047627, 0.340637480095253, -0.170318740047627, 0.340637480095253, -0.0093083887122843, -0.00930838871228411, 0.0590791718992466}, + {0.0495966310503563, 0.0969129145557494, 0.0329620582231266, 0.160876909651335, -0.116515395516028, -0.013308162918257, -0.034953853497492, -0.246912783611135, 0.895428534283356, 0.175913147778989}, + {0.0594654509565623, -0.0391667888544834, 0.056509372357196, 0.467663868980969, -0.223159844548554, -0.0733496016702976, -0.0669464878724995, -0.228522561505532, 0.437096058075966, 0.610410534080673}, + {0.0638185648099453, -0.0451321541833679, -0.0471646056404562, 0.253054939278284, 0.267486202295671, -0.15615892407532, 0.0802441041051715, -0.154146013447678, 0.0749362671988722, 0.663061619658879}, + {0.0496137334753148, 0.045160818752146, 0.0326369349932555, -0.217903867034122, 0.796473473259088, -0.17356708239734, 0.238936811531547, -0.0584641485580774, -0.0220190689531466, 0.309132394931336}, + {0.0204647143413336, 0.0519031146003489, 0.541134376806172, -0.23755901477889, 0.524060308998282, -0.0859485068100628, 0.157214651192223, -0.00722668705539924, -0.00599217068695446, 0.041949213392946}, + {0.0363240630142745, 0.595361771100889, 0.0329620582231266, 0.286154010031837, -0.144363814874519, -0.00697876330105458, -0.00710543413900171, -0.160427557536749, 0.323767019699913, 0.0443066477812842}, + {0.031491752557511, 0.144847707077251, 0.056509372357196, 0.880722068301204, -0.276497422020097, -0.0297392974343586, -0.0136089104009562, -0.114798724929776, 0.167331423967527, 0.153742030524498}, + {0.0233191863197457, -0.0638922318573471, -0.0471646056404562, 0.640806423249974, 0.331418250941681, -0.0478518692290426, 0.0163120554591614, -0.0585247318831847, 0.0385744417985573, 0.167003080840912}, + {0.0133805365030048, 0.0211818331847307, 0.0326369349932554, -0.117406110387015, 0.986839108572759, -0.0427925717552788, 0.0485711762178751, -0.0178593517002866, -0.00241168327121213, 0.0778601276421677}, + {0.00452658789692547, 0.057951772159666, 0.541134376806172, -0.273633189306433, 0.649316299328904, -0.0184907249626247, 0.0319586608616018, -0.00192632644777806, -0.0014030624094846, 0.0105656060730509}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 9; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 1750 + for (unsigned int ip = 0; ip < 25; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + + // Total number of operations to compute function values = 40 + for (unsigned int r = 0; r < 10; r++) + { + F0 += FE1[ip][r]*w[0][r]; + F1 += FE1[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 3 + double I[1]; + // Number of operations: 3 + I[0] = F0*F1*W25[ip]*det; + + + // Number of operations for primary indices: 27 + for (unsigned int j = 0; j < 3; j++) + { + for (unsigned int k = 0; k < 3; k++) + { + // Number of operations to compute entry: 3 + A[j*3 + k] += FE0[ip][j]*FE0[ip][k]*I[0]; + }// 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 mass_matrix_f2_p3_q1_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p3_q1_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p3_q1_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1))), 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 mass_matrix_f2_p3_q1_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p3_q1_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p3_q1_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p3_q1_quadrature_finite_element_0(); + 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 mass_matrix_f2_p3_q1_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p3_q1_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p3_q1_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p3_q1_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f2_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/mass_matrix_2d/mass_matrix_f2_p3_q1_tensor.h b/mass_matrix_2d/mass_matrix_f2_p3_q1_tensor.h new file mode 100644 index 0000000..64952be --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p3_q1_tensor.h @@ -0,0 +1,4617 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P3_Q1_TENSOR_H +#define __MASS_MATRIX_F2_P3_Q1_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p3_q1_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p3_q1_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p3_q1_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p3_q1_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p3_q1_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p3_q1_tensor_finite_element_1() + { + // 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 mass_matrix_f2_p3_q1_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p3_q1_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p3_q1_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_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.0*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 mass_matrix_f2_p3_q1_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p3_q1_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p3_q1_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_p3_q1_tensor_dofmap_1() + { + // 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 mass_matrix_f2_p3_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 mass_matrix_f2_p3_q1_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p3_q1_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 150 + // Number of operations (multiply-add pairs) for tensor contraction: 504 + // Total number of operations (multiply-add pairs): 663 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0 = det*w[0][0]*w[1][0]*(1.0); + const double G0_0_1 = det*w[0][0]*w[1][1]*(1.0); + const double G0_0_2 = det*w[0][0]*w[1][2]*(1.0); + const double G0_0_3 = det*w[0][0]*w[1][3]*(1.0); + const double G0_0_4 = det*w[0][0]*w[1][4]*(1.0); + const double G0_0_5 = det*w[0][0]*w[1][5]*(1.0); + const double G0_0_6 = det*w[0][0]*w[1][6]*(1.0); + const double G0_0_7 = det*w[0][0]*w[1][7]*(1.0); + const double G0_0_8 = det*w[0][0]*w[1][8]*(1.0); + const double G0_0_9 = det*w[0][0]*w[1][9]*(1.0); + const double G0_1_0 = det*w[0][1]*w[1][0]*(1.0); + const double G0_1_1 = det*w[0][1]*w[1][1]*(1.0); + const double G0_1_2 = det*w[0][1]*w[1][2]*(1.0); + const double G0_1_3 = det*w[0][1]*w[1][3]*(1.0); + const double G0_1_4 = det*w[0][1]*w[1][4]*(1.0); + const double G0_1_5 = det*w[0][1]*w[1][5]*(1.0); + const double G0_1_6 = det*w[0][1]*w[1][6]*(1.0); + const double G0_1_7 = det*w[0][1]*w[1][7]*(1.0); + const double G0_1_8 = det*w[0][1]*w[1][8]*(1.0); + const double G0_1_9 = det*w[0][1]*w[1][9]*(1.0); + const double G0_2_0 = det*w[0][2]*w[1][0]*(1.0); + const double G0_2_1 = det*w[0][2]*w[1][1]*(1.0); + const double G0_2_2 = det*w[0][2]*w[1][2]*(1.0); + const double G0_2_3 = det*w[0][2]*w[1][3]*(1.0); + const double G0_2_4 = det*w[0][2]*w[1][4]*(1.0); + const double G0_2_5 = det*w[0][2]*w[1][5]*(1.0); + const double G0_2_6 = det*w[0][2]*w[1][6]*(1.0); + const double G0_2_7 = det*w[0][2]*w[1][7]*(1.0); + const double G0_2_8 = det*w[0][2]*w[1][8]*(1.0); + const double G0_2_9 = det*w[0][2]*w[1][9]*(1.0); + const double G0_3_0 = det*w[0][3]*w[1][0]*(1.0); + const double G0_3_1 = det*w[0][3]*w[1][1]*(1.0); + const double G0_3_2 = det*w[0][3]*w[1][2]*(1.0); + const double G0_3_3 = det*w[0][3]*w[1][3]*(1.0); + const double G0_3_4 = det*w[0][3]*w[1][4]*(1.0); + const double G0_3_5 = det*w[0][3]*w[1][5]*(1.0); + const double G0_3_6 = det*w[0][3]*w[1][6]*(1.0); + const double G0_3_7 = det*w[0][3]*w[1][7]*(1.0); + const double G0_3_8 = det*w[0][3]*w[1][8]*(1.0); + const double G0_3_9 = det*w[0][3]*w[1][9]*(1.0); + const double G0_4_0 = det*w[0][4]*w[1][0]*(1.0); + const double G0_4_1 = det*w[0][4]*w[1][1]*(1.0); + const double G0_4_2 = det*w[0][4]*w[1][2]*(1.0); + const double G0_4_3 = det*w[0][4]*w[1][3]*(1.0); + const double G0_4_4 = det*w[0][4]*w[1][4]*(1.0); + const double G0_4_5 = det*w[0][4]*w[1][5]*(1.0); + const double G0_4_6 = det*w[0][4]*w[1][6]*(1.0); + const double G0_4_7 = det*w[0][4]*w[1][7]*(1.0); + const double G0_4_8 = det*w[0][4]*w[1][8]*(1.0); + const double G0_4_9 = det*w[0][4]*w[1][9]*(1.0); + const double G0_5_0 = det*w[0][5]*w[1][0]*(1.0); + const double G0_5_1 = det*w[0][5]*w[1][1]*(1.0); + const double G0_5_2 = det*w[0][5]*w[1][2]*(1.0); + const double G0_5_3 = det*w[0][5]*w[1][3]*(1.0); + const double G0_5_4 = det*w[0][5]*w[1][4]*(1.0); + const double G0_5_5 = det*w[0][5]*w[1][5]*(1.0); + const double G0_5_6 = det*w[0][5]*w[1][6]*(1.0); + const double G0_5_7 = det*w[0][5]*w[1][7]*(1.0); + const double G0_5_8 = det*w[0][5]*w[1][8]*(1.0); + const double G0_5_9 = det*w[0][5]*w[1][9]*(1.0); + const double G0_6_0 = det*w[0][6]*w[1][0]*(1.0); + const double G0_6_1 = det*w[0][6]*w[1][1]*(1.0); + const double G0_6_2 = det*w[0][6]*w[1][2]*(1.0); + const double G0_6_3 = det*w[0][6]*w[1][3]*(1.0); + const double G0_6_4 = det*w[0][6]*w[1][4]*(1.0); + const double G0_6_5 = det*w[0][6]*w[1][5]*(1.0); + const double G0_6_6 = det*w[0][6]*w[1][6]*(1.0); + const double G0_6_7 = det*w[0][6]*w[1][7]*(1.0); + const double G0_6_8 = det*w[0][6]*w[1][8]*(1.0); + const double G0_6_9 = det*w[0][6]*w[1][9]*(1.0); + const double G0_7_0 = det*w[0][7]*w[1][0]*(1.0); + const double G0_7_1 = det*w[0][7]*w[1][1]*(1.0); + const double G0_7_2 = det*w[0][7]*w[1][2]*(1.0); + const double G0_7_3 = det*w[0][7]*w[1][3]*(1.0); + const double G0_7_4 = det*w[0][7]*w[1][4]*(1.0); + const double G0_7_5 = det*w[0][7]*w[1][5]*(1.0); + const double G0_7_6 = det*w[0][7]*w[1][6]*(1.0); + const double G0_7_7 = det*w[0][7]*w[1][7]*(1.0); + const double G0_7_8 = det*w[0][7]*w[1][8]*(1.0); + const double G0_7_9 = det*w[0][7]*w[1][9]*(1.0); + const double G0_8_0 = det*w[0][8]*w[1][0]*(1.0); + const double G0_8_1 = det*w[0][8]*w[1][1]*(1.0); + const double G0_8_2 = det*w[0][8]*w[1][2]*(1.0); + const double G0_8_3 = det*w[0][8]*w[1][3]*(1.0); + const double G0_8_4 = det*w[0][8]*w[1][4]*(1.0); + const double G0_8_5 = det*w[0][8]*w[1][5]*(1.0); + const double G0_8_6 = det*w[0][8]*w[1][6]*(1.0); + const double G0_8_7 = det*w[0][8]*w[1][7]*(1.0); + const double G0_8_8 = det*w[0][8]*w[1][8]*(1.0); + const double G0_8_9 = det*w[0][8]*w[1][9]*(1.0); + const double G0_9_0 = det*w[0][9]*w[1][0]*(1.0); + const double G0_9_1 = det*w[0][9]*w[1][1]*(1.0); + const double G0_9_2 = det*w[0][9]*w[1][2]*(1.0); + const double G0_9_3 = det*w[0][9]*w[1][3]*(1.0); + const double G0_9_4 = det*w[0][9]*w[1][4]*(1.0); + const double G0_9_5 = det*w[0][9]*w[1][5]*(1.0); + const double G0_9_6 = det*w[0][9]*w[1][6]*(1.0); + const double G0_9_7 = det*w[0][9]*w[1][7]*(1.0); + const double G0_9_8 = det*w[0][9]*w[1][8]*(1.0); + const double G0_9_9 = det*w[0][9]*w[1][9]*(1.0); + + // Compute element tensor + A[1] = 0.000297619047619046*G0_0_0 + 6.44841269841266e-05*G0_0_1 + 9.92063492063482e-06*G0_0_2 + 0.000178571428571428*G0_0_3 + 4.46428571428571e-05*G0_0_4 + 6.44841269841266e-05*G0_1_0 + 0.000297619047619046*G0_1_1 + 9.92063492063475e-06*G0_1_2 + 0.000178571428571428*G0_1_5 + 4.46428571428572e-05*G0_1_6 + 9.92063492063482e-06*G0_2_0 + 9.92063492063475e-06*G0_2_1 + 9.92063492063487e-05*G0_2_2 + 0.000178571428571428*G0_2_3 - 0.000223214285714285*G0_2_4 + 0.000178571428571428*G0_2_5 - 0.000223214285714285*G0_2_6 + 0.000312499999999998*G0_2_7 + 0.000312499999999998*G0_2_8 + 0.000535714285714283*G0_2_9 + 0.000178571428571428*G0_3_0 + 0.000178571428571428*G0_3_2 + 0.00200892857142856*G0_3_3 - 0.000803571428571425*G0_3_4 - 0.000401785714285713*G0_3_5 - 0.000401785714285713*G0_3_6 - 0.000803571428571426*G0_3_7 + 0.00200892857142856*G0_3_8 + 0.00160714285714285*G0_3_9 + 4.46428571428571e-05*G0_4_0 - 0.000223214285714285*G0_4_2 - 0.000803571428571425*G0_4_3 + 0.00120535714285714*G0_4_4 - 0.000401785714285713*G0_4_5 + 0.000803571428571426*G0_4_6 - 0.000401785714285712*G0_4_7 - 0.00120535714285714*G0_4_8 - 0.000803571428571426*G0_4_9 + 0.000178571428571428*G0_5_1 + 0.000178571428571428*G0_5_2 - 0.000401785714285713*G0_5_3 - 0.000401785714285713*G0_5_4 + 0.00200892857142856*G0_5_5 - 0.000803571428571425*G0_5_6 + 0.00200892857142856*G0_5_7 - 0.000803571428571426*G0_5_8 + 0.00160714285714285*G0_5_9 + 4.46428571428572e-05*G0_6_1 - 0.000223214285714285*G0_6_2 - 0.000401785714285713*G0_6_3 + 0.000803571428571426*G0_6_4 - 0.000803571428571425*G0_6_5 + 0.00120535714285714*G0_6_6 - 0.00120535714285714*G0_6_7 - 0.000401785714285712*G0_6_8 - 0.000803571428571425*G0_6_9 + 0.000312499999999998*G0_7_2 - 0.000803571428571426*G0_7_3 - 0.000401785714285712*G0_7_4 + 0.00200892857142856*G0_7_5 - 0.00120535714285714*G0_7_6 + 0.00602678571428568*G0_7_7 - 0.00120535714285714*G0_7_8 + 0.00241071428571427*G0_7_9 + 0.000312499999999998*G0_8_2 + 0.00200892857142856*G0_8_3 - 0.00120535714285714*G0_8_4 - 0.000803571428571426*G0_8_5 - 0.000401785714285712*G0_8_6 - 0.00120535714285714*G0_8_7 + 0.00602678571428569*G0_8_8 + 0.00241071428571428*G0_8_9 + 0.000535714285714283*G0_9_2 + 0.00160714285714285*G0_9_3 - 0.000803571428571425*G0_9_4 + 0.00160714285714285*G0_9_5 - 0.000803571428571426*G0_9_6 + 0.00241071428571427*G0_9_7 + 0.00241071428571428*G0_9_8 + 0.0144642857142857*G0_9_9; + A[5] = 9.92063492063489e-05*G0_0_0 + 9.92063492063482e-06*G0_0_1 + 9.92063492063481e-06*G0_0_2 + 0.000312499999999999*G0_0_3 + 0.000312499999999999*G0_0_4 - 0.000223214285714285*G0_0_5 + 0.000178571428571428*G0_0_6 - 0.000223214285714285*G0_0_7 + 0.000178571428571428*G0_0_8 + 0.000535714285714284*G0_0_9 + 9.92063492063482e-06*G0_1_0 + 0.000297619047619046*G0_1_1 + 6.44841269841266e-05*G0_1_2 + 4.46428571428568e-05*G0_1_5 + 0.000178571428571428*G0_1_6 + 9.92063492063481e-06*G0_2_0 + 6.44841269841266e-05*G0_2_1 + 0.000297619047619046*G0_2_2 + 4.46428571428569e-05*G0_2_7 + 0.000178571428571428*G0_2_8 + 0.000312499999999999*G0_3_0 + 0.00602678571428569*G0_3_3 - 0.00120535714285714*G0_3_4 - 0.000401785714285712*G0_3_5 - 0.000803571428571426*G0_3_6 - 0.00120535714285714*G0_3_7 + 0.00200892857142856*G0_3_8 + 0.00241071428571428*G0_3_9 + 0.000312499999999999*G0_4_0 - 0.00120535714285714*G0_4_3 + 0.00602678571428569*G0_4_4 - 0.00120535714285714*G0_4_5 + 0.00200892857142857*G0_4_6 - 0.000401785714285714*G0_4_7 - 0.000803571428571425*G0_4_8 + 0.00241071428571428*G0_4_9 - 0.000223214285714285*G0_5_0 + 4.46428571428569e-05*G0_5_1 - 0.000401785714285713*G0_5_3 - 0.00120535714285714*G0_5_4 + 0.00120535714285714*G0_5_5 - 0.000803571428571427*G0_5_6 + 0.000803571428571426*G0_5_7 - 0.000401785714285713*G0_5_8 - 0.000803571428571429*G0_5_9 + 0.000178571428571428*G0_6_0 + 0.000178571428571428*G0_6_1 - 0.000803571428571426*G0_6_3 + 0.00200892857142857*G0_6_4 - 0.000803571428571427*G0_6_5 + 0.00200892857142857*G0_6_6 - 0.000401785714285714*G0_6_7 - 0.000401785714285713*G0_6_8 + 0.00160714285714285*G0_6_9 - 0.000223214285714285*G0_7_0 + 4.46428571428569e-05*G0_7_2 - 0.00120535714285714*G0_7_3 - 0.000401785714285714*G0_7_4 + 0.000803571428571426*G0_7_5 - 0.000401785714285714*G0_7_6 + 0.00120535714285714*G0_7_7 - 0.000803571428571426*G0_7_8 - 0.000803571428571428*G0_7_9 + 0.000178571428571428*G0_8_0 + 0.000178571428571428*G0_8_2 + 0.00200892857142856*G0_8_3 - 0.000803571428571425*G0_8_4 - 0.000401785714285713*G0_8_5 - 0.000401785714285713*G0_8_6 - 0.000803571428571426*G0_8_7 + 0.00200892857142856*G0_8_8 + 0.00160714285714285*G0_8_9 + 0.000535714285714284*G0_9_0 + 0.00241071428571428*G0_9_3 + 0.00241071428571428*G0_9_4 - 0.000803571428571429*G0_9_5 + 0.00160714285714285*G0_9_6 - 0.000803571428571428*G0_9_7 + 0.00160714285714285*G0_9_8 + 0.0144642857142857*G0_9_9; + A[0] = A[1] + 0.00357142857142855*G0_0_0 + 0.000233134920634919*G0_0_1 + 0.000287698412698411*G0_0_2 - 0.000178571428571428*G0_0_3 - 4.46428571428574e-05*G0_0_4 + 0.00267857142857141*G0_0_5 - 0.00133928571428571*G0_0_6 + 0.00267857142857141*G0_0_7 - 0.00133928571428571*G0_0_8 + 0.000233134920634919*G0_1_0 - 9.92063492063484e-05*G0_1_1 + 4.46428571428569e-05*G0_1_2 - 0.000223214285714284*G0_1_3 + 4.46428571428566e-05*G0_1_4 + 0.000892857142857139*G0_1_5 - 0.000178571428571428*G0_1_6 + 0.000937499999999995*G0_1_7 - 0.000669642857142853*G0_1_8 + 0.000803571428571426*G0_1_9 + 0.000287698412698411*G0_2_0 + 4.46428571428569e-05*G0_2_1 + 9.92063492063487e-05*G0_2_2 - 0.000133928571428571*G0_2_3 + 0.000758928571428568*G0_2_5 - 0.00044642857142857*G0_2_6 + 0.000758928571428568*G0_2_7 - 0.000446428571428569*G0_2_8 + 0.000267857142857142*G0_2_9 - 0.000178571428571428*G0_3_0 - 0.000223214285714284*G0_3_1 - 0.000133928571428571*G0_3_2 - 0.00120535714285714*G0_3_3 + 0.000401785714285712*G0_3_4 - 0.000803571428571427*G0_3_5 - 0.000803571428571424*G0_3_8 - 0.00241071428571428*G0_3_9 - 4.46428571428573e-05*G0_4_0 + 4.46428571428566e-05*G0_4_1 + 0.000401785714285712*G0_4_3 - 0.000401785714285713*G0_4_4 - 0.000401785714285713*G0_4_5 + 0.000401785714285712*G0_4_6 - 0.000803571428571426*G0_4_7 + 0.000803571428571425*G0_4_8 + 0.00267857142857141*G0_5_0 + 0.000892857142857139*G0_5_1 + 0.000758928571428568*G0_5_2 - 0.000803571428571427*G0_5_3 - 0.000401785714285713*G0_5_4 + 0.0140624999999999*G0_5_5 - 0.0032142857142857*G0_5_6 + 0.00602678571428569*G0_5_7 - 0.0032142857142857*G0_5_8 + 0.00642857142857141*G0_5_9 - 0.00133928571428571*G0_6_0 - 0.000178571428571428*G0_6_1 - 0.00044642857142857*G0_6_2 + 0.000401785714285712*G0_6_4 - 0.0032142857142857*G0_6_5 + 0.00361607142857142*G0_6_6 - 0.00281249999999999*G0_6_7 + 0.00120535714285714*G0_6_8 - 0.000803571428571428*G0_6_9 + 0.00267857142857141*G0_7_0 + 0.000937499999999995*G0_7_1 + 0.000758928571428568*G0_7_2 - 0.000803571428571426*G0_7_4 + 0.00602678571428569*G0_7_5 - 0.00281249999999999*G0_7_6 + 0.0100446428571428*G0_7_7 - 0.00281249999999998*G0_7_8 + 0.00562499999999998*G0_7_9 - 0.00133928571428571*G0_8_0 - 0.000669642857142853*G0_8_1 - 0.000446428571428569*G0_8_2 - 0.000803571428571424*G0_8_3 + 0.000803571428571425*G0_8_4 - 0.0032142857142857*G0_8_5 + 0.00120535714285714*G0_8_6 - 0.00281249999999998*G0_8_7 - 0.00120535714285714*G0_8_8 - 0.00401785714285713*G0_8_9 + 0.000803571428571426*G0_9_1 + 0.000267857142857142*G0_9_2 - 0.00241071428571428*G0_9_3 + 0.00642857142857141*G0_9_5 - 0.000803571428571427*G0_9_6 + 0.00562499999999998*G0_9_7 - 0.00401785714285713*G0_9_8 + 0.00482142857142856*G0_9_9; + A[7] = A[5]; + A[6] = 0.000297619047619046*G0_0_0 + 9.92063492063481e-06*G0_0_1 + 6.44841269841266e-05*G0_0_2 + 4.46428571428569e-05*G0_0_3 + 0.000178571428571428*G0_0_4 + 9.92063492063481e-06*G0_1_0 + 9.92063492063488e-05*G0_1_1 + 9.9206349206348e-06*G0_1_2 - 0.000223214285714285*G0_1_3 + 0.000178571428571428*G0_1_4 + 0.000312499999999999*G0_1_5 + 0.000312499999999999*G0_1_6 + 0.000178571428571428*G0_1_7 - 0.000223214285714285*G0_1_8 + 0.000535714285714283*G0_1_9 + 6.44841269841266e-05*G0_2_0 + 9.92063492063479e-06*G0_2_1 + 0.000297619047619046*G0_2_2 + 0.000178571428571428*G0_2_7 + 4.46428571428569e-05*G0_2_8 + 4.46428571428569e-05*G0_3_0 - 0.000223214285714285*G0_3_1 + 0.00120535714285714*G0_3_3 - 0.000803571428571426*G0_3_4 - 0.000401785714285713*G0_3_5 - 0.00120535714285714*G0_3_6 - 0.000401785714285713*G0_3_7 + 0.000803571428571425*G0_3_8 - 0.000803571428571427*G0_3_9 + 0.000178571428571428*G0_4_0 + 0.000178571428571428*G0_4_1 - 0.000803571428571426*G0_4_3 + 0.00200892857142856*G0_4_4 - 0.000803571428571426*G0_4_5 + 0.00200892857142856*G0_4_6 - 0.000401785714285713*G0_4_7 - 0.000401785714285712*G0_4_8 + 0.00160714285714285*G0_4_9 + 0.000312499999999999*G0_5_1 - 0.000401785714285713*G0_5_3 - 0.000803571428571426*G0_5_4 + 0.00602678571428569*G0_5_5 - 0.00120535714285714*G0_5_6 + 0.00200892857142856*G0_5_7 - 0.00120535714285714*G0_5_8 + 0.00241071428571427*G0_5_9 + 0.000312499999999999*G0_6_1 - 0.00120535714285714*G0_6_3 + 0.00200892857142856*G0_6_4 - 0.00120535714285714*G0_6_5 + 0.00602678571428569*G0_6_6 - 0.000803571428571427*G0_6_7 - 0.000401785714285712*G0_6_8 + 0.00241071428571428*G0_6_9 + 0.000178571428571428*G0_7_1 + 0.000178571428571428*G0_7_2 - 0.000401785714285713*G0_7_3 - 0.000401785714285713*G0_7_4 + 0.00200892857142856*G0_7_5 - 0.000803571428571427*G0_7_6 + 0.00200892857142856*G0_7_7 - 0.000803571428571425*G0_7_8 + 0.00160714285714285*G0_7_9 - 0.000223214285714285*G0_8_1 + 4.46428571428569e-05*G0_8_2 + 0.000803571428571425*G0_8_3 - 0.000401785714285712*G0_8_4 - 0.00120535714285714*G0_8_5 - 0.000401785714285712*G0_8_6 - 0.000803571428571425*G0_8_7 + 0.00120535714285714*G0_8_8 - 0.000803571428571425*G0_8_9 + 0.000535714285714283*G0_9_1 - 0.000803571428571427*G0_9_3 + 0.00160714285714285*G0_9_4 + 0.00241071428571427*G0_9_5 + 0.00241071428571428*G0_9_6 + 0.00160714285714285*G0_9_7 - 0.000803571428571425*G0_9_8 + 0.0144642857142857*G0_9_9; + A[2] = A[6]; + A[8] = A[0] - 0.0036706349206349*G0_0_0 - 0.000243055555555554*G0_0_1 - 0.000133928571428571*G0_0_3 + 0.00107142857142857*G0_0_4 - 0.00334821428571427*G0_0_5 + 0.0022767857142857*G0_0_6 - 0.0029017857142857*G0_0_7 + 0.00138392857142856*G0_0_8 + 0.000803571428571426*G0_0_9 - 0.000243055555555554*G0_1_0 + 0.000243055555555554*G0_1_2 - 0.000446428571428569*G0_1_3 + 0.000892857142857139*G0_1_4 - 0.00120535714285714*G0_1_5 + 0.00120535714285714*G0_1_6 - 0.000892857142857138*G0_1_7 + 0.00044642857142857*G0_1_8 + 0.000243055555555554*G0_2_1 + 0.0036706349206349*G0_2_2 - 0.00138392857142856*G0_2_3 + 0.00290178571428569*G0_2_4 - 0.0022767857142857*G0_2_5 + 0.00334821428571427*G0_2_6 - 0.00107142857142857*G0_2_7 + 0.000133928571428572*G0_2_8 - 0.000803571428571426*G0_2_9 - 0.000133928571428571*G0_3_0 - 0.000446428571428569*G0_3_1 - 0.00138392857142856*G0_3_2 + 0.00401785714285712*G0_3_3 - 0.00361607142857142*G0_3_4 + 0.00200892857142857*G0_3_5 - 0.00361607142857141*G0_3_6 + 0.000401785714285714*G0_3_7 - 0.000803571428571425*G0_3_9 + 0.00107142857142857*G0_4_0 + 0.000892857142857139*G0_4_1 + 0.00290178571428569*G0_4_2 - 0.00361607142857142*G0_4_3 + 0.0152678571428571*G0_4_4 - 0.0032142857142857*G0_4_5 + 0.00683035714285712*G0_4_6 - 0.000401785714285712*G0_4_8 + 0.00883928571428568*G0_4_9 - 0.00334821428571427*G0_5_0 - 0.00120535714285714*G0_5_1 - 0.0022767857142857*G0_5_2 + 0.00200892857142857*G0_5_3 - 0.0032142857142857*G0_5_4 - 0.0112499999999999*G0_5_5 - 0.00683035714285711*G0_5_7 + 0.00361607142857141*G0_5_8 - 0.00964285714285711*G0_5_9 + 0.0022767857142857*G0_6_0 + 0.00120535714285714*G0_6_1 + 0.00334821428571427*G0_6_2 - 0.00361607142857141*G0_6_3 + 0.00683035714285712*G0_6_4 + 0.01125*G0_6_6 + 0.0032142857142857*G0_6_7 - 0.00200892857142856*G0_6_8 + 0.00964285714285711*G0_6_9 - 0.0029017857142857*G0_7_0 - 0.000892857142857138*G0_7_1 - 0.00107142857142857*G0_7_2 + 0.000401785714285714*G0_7_3 - 0.00683035714285711*G0_7_5 + 0.0032142857142857*G0_7_6 - 0.0152678571428571*G0_7_7 + 0.00361607142857141*G0_7_8 - 0.00883928571428568*G0_7_9 + 0.00138392857142856*G0_8_0 + 0.00044642857142857*G0_8_1 + 0.000133928571428572*G0_8_2 - 0.000401785714285712*G0_8_4 + 0.00361607142857141*G0_8_5 - 0.00200892857142856*G0_8_6 + 0.00361607142857141*G0_8_7 - 0.00401785714285712*G0_8_8 + 0.000803571428571429*G0_8_9 + 0.000803571428571426*G0_9_0 - 0.000803571428571426*G0_9_2 - 0.000803571428571425*G0_9_3 + 0.00883928571428568*G0_9_4 - 0.00964285714285711*G0_9_5 + 0.00964285714285711*G0_9_6 - 0.00883928571428568*G0_9_7 + 0.000803571428571429*G0_9_8; + A[3] = A[1]; + A[4] = A[0] - 0.0036706349206349*G0_0_0 - 0.000243055555555554*G0_0_2 + 0.00107142857142857*G0_0_3 - 0.00013392857142857*G0_0_4 - 0.0029017857142857*G0_0_5 + 0.00138392857142856*G0_0_6 - 0.00334821428571427*G0_0_7 + 0.0022767857142857*G0_0_8 + 0.000803571428571426*G0_0_9 + 0.0036706349206349*G0_1_1 + 0.000243055555555554*G0_1_2 + 0.0029017857142857*G0_1_3 - 0.00138392857142856*G0_1_4 - 0.00107142857142857*G0_1_5 + 0.000133928571428571*G0_1_6 - 0.0022767857142857*G0_1_7 + 0.00334821428571427*G0_1_8 - 0.000803571428571426*G0_1_9 - 0.000243055555555554*G0_2_0 + 0.000243055555555554*G0_2_1 + 0.000892857142857139*G0_2_3 - 0.000446428571428569*G0_2_4 - 0.000892857142857139*G0_2_5 + 0.000446428571428569*G0_2_6 - 0.00120535714285714*G0_2_7 + 0.00120535714285714*G0_2_8 + 0.00107142857142857*G0_3_0 + 0.0029017857142857*G0_3_1 + 0.000892857142857139*G0_3_2 + 0.0152678571428571*G0_3_3 - 0.00361607142857141*G0_3_4 - 0.000401785714285713*G0_3_6 - 0.0032142857142857*G0_3_7 + 0.00683035714285711*G0_3_8 + 0.00883928571428568*G0_3_9 - 0.00013392857142857*G0_4_0 - 0.00138392857142856*G0_4_1 - 0.000446428571428569*G0_4_2 - 0.00361607142857141*G0_4_3 + 0.00401785714285713*G0_4_4 + 0.000401785714285712*G0_4_5 + 0.00200892857142856*G0_4_7 - 0.00361607142857141*G0_4_8 - 0.000803571428571424*G0_4_9 - 0.0029017857142857*G0_5_0 - 0.00107142857142857*G0_5_1 - 0.000892857142857139*G0_5_2 + 0.000401785714285712*G0_5_4 - 0.0152678571428571*G0_5_5 + 0.00361607142857141*G0_5_6 - 0.00683035714285711*G0_5_7 + 0.0032142857142857*G0_5_8 - 0.00883928571428569*G0_5_9 + 0.00138392857142856*G0_6_0 + 0.000133928571428571*G0_6_1 + 0.00044642857142857*G0_6_2 - 0.000401785714285713*G0_6_3 + 0.00361607142857141*G0_6_5 - 0.00401785714285713*G0_6_6 + 0.00361607142857141*G0_6_7 - 0.00200892857142856*G0_6_8 + 0.000803571428571428*G0_6_9 - 0.00334821428571427*G0_7_0 - 0.0022767857142857*G0_7_1 - 0.00120535714285714*G0_7_2 - 0.0032142857142857*G0_7_3 + 0.00200892857142856*G0_7_4 - 0.00683035714285711*G0_7_5 + 0.00361607142857141*G0_7_6 - 0.0112499999999999*G0_7_7 - 0.00964285714285711*G0_7_9 + 0.0022767857142857*G0_8_0 + 0.00334821428571427*G0_8_1 + 0.00120535714285714*G0_8_2 + 0.00683035714285711*G0_8_3 - 0.00361607142857141*G0_8_4 + 0.0032142857142857*G0_8_5 - 0.00200892857142856*G0_8_6 + 0.0112499999999999*G0_8_8 + 0.00964285714285711*G0_8_9 + 0.000803571428571426*G0_9_0 - 0.000803571428571426*G0_9_1 + 0.00883928571428568*G0_9_3 - 0.000803571428571425*G0_9_4 - 0.00883928571428569*G0_9_5 + 0.000803571428571428*G0_9_6 - 0.00964285714285711*G0_9_7 + 0.00964285714285711*G0_9_8; + } + + /// 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 mass_matrix_f2_p3_q1_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p3_q1_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p3_q1_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1))), 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 mass_matrix_f2_p3_q1_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p3_q1_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p3_q1_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p3_q1_tensor_finite_element_0(); + 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 mass_matrix_f2_p3_q1_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p3_q1_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p3_q1_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p3_q1_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f2_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/mass_matrix_2d/mass_matrix_f2_p3_q2_excafe.h b/mass_matrix_2d/mass_matrix_f2_p3_q2_excafe.h new file mode 100644 index 0000000..db4f8f5 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p3_q2_excafe.h @@ -0,0 +1,350 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 15 minutes and 2.68 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][7]*w[1][4] + w[0][4]*w[1][7]; + const double var_1 = -1.0000000000000000000000000*x[0][1]; + const double var_2 = var_1 + x[1][1]; + const double var_3 = -1.0000000000000000000000000*x[0][0]; + const double var_4 = var_3 + x[2][0]; + const double var_5 = x[2][1] + var_1; + const double var_6 = x[1][0] + var_3; + const double var_7 = var_5*var_6 + -1.0000000000000000000000000*var_2*var_4; + const double var_8 = std::abs(var_7); + const double var_9 = w[0][1]*w[1][7] + w[0][7]*w[1][1]; + const double var_10 = w[0][6]*w[1][0] + w[0][0]*w[1][6]; + const double var_11 = w[0][1]*w[1][8] + w[0][8]*w[1][1]; + const double var_12 = w[0][7]*w[1][9] + w[0][9]*w[1][7]; + const double var_13 = w[0][4]*w[1][9] + w[0][9]*w[1][4]; + const double var_14 = w[0][7]*w[1][3] + w[0][3]*w[1][7]; + const double var_15 = w[0][4]*w[1][8] + w[0][8]*w[1][4]; + const double var_16 = w[0][1]*w[1][5] + w[0][5]*w[1][1]; + const double var_17 = w[0][6]*w[1][1] + w[0][1]*w[1][6]; + const double var_18 = w[0][4]*w[1][4]; + const double var_19 = w[0][6]*w[1][6]; + const double var_20 = w[0][6]*w[1][5] + w[0][5]*w[1][6]; + const double var_21 = w[0][2]*w[1][0] + w[0][0]*w[1][2]; + const double var_22 = w[0][3]*w[1][8] + w[0][8]*w[1][3]; + const double var_23 = -0.0035064935064935067073055*w[0][9]*w[1][9]; + const double var_24 = w[0][1]*w[1][9] + w[0][9]*w[1][1]; + const double var_25 = var_24 + -1.5000000000000000000000000*var_0; + const double var_26 = -0.0001948051948051948050258*var_22 + -0.0008766233766233766768264*var_20 + 0.0000649350649350649350086*var_21 + 0.0000324675324675324675043*var_25 + -0.0000036075036075036075005*w[0][1]*w[1][1] + var_23; + const double var_27 = w[0][3]*w[1][5] + w[0][5]*w[1][3]; + const double var_28 = w[0][7]*w[1][8] + w[0][8]*w[1][7]; + const double var_29 = w[0][0]*w[1][1] + w[0][1]*w[1][0]; + const double var_30 = w[0][4]*w[1][6] + w[0][6]*w[1][4]; + const double var_31 = 0.3333333333333333148296163*w[0][2]*w[1][2]; + const double var_32 = 0.0014610389610389610919039*var_30 + 0.0016233766233766234836355*var_31 + 0.0005844155844155844150775*var_27 + 0.0000234487734487734487531*var_29 + 0.0003409090909090909359003*var_28; + const double var_33 = w[0][3]*w[1][4] + w[0][4]*w[1][3]; + const double var_34 = w[0][2]*w[1][1] + w[0][1]*w[1][2]; + const double var_35 = w[0][5]*w[1][7] + w[0][7]*w[1][5]; + const double var_36 = w[0][6]*w[1][8] + w[0][8]*w[1][6]; + const double var_37 = w[0][9]*w[1][0] + w[0][0]*w[1][9]; + const double var_38 = var_37 + -1.5000000000000000000000000*var_36; + const double var_39 = 0.3333333333333333148296163*w[0][0]*w[1][0]; + const double var_40 = -0.0007305194805194805459519*var_35 + 0.0001948051948051948050258*var_38 + -0.0005844155844155844150775*var_33 + -0.0001623376623376623375215*var_39 + 0.0000432900432900432900057*var_34; + const double var_41 = w[0][0]*w[1][3] + w[0][3]*w[1][0]; + const double var_42 = -1.0000000000000000000000000*var_41; + const double var_43 = w[0][8]*w[1][2] + w[0][2]*w[1][8]; + const double var_44 = -1.0000000000000000000000000*var_43; + const double var_45 = w[0][2]*w[1][7] + w[0][7]*w[1][2]; + const double var_46 = -1.0000000000000000000000000*var_45; + const double var_47 = w[0][1]*w[1][3] + w[0][3]*w[1][1]; + const double var_48 = -1.0000000000000000000000000*var_47; + const double var_49 = w[0][5]*w[1][0] + w[0][0]*w[1][5]; + const double var_50 = -1.0000000000000000000000000*var_49; + const double var_51 = w[0][8]*w[1][0] + w[0][0]*w[1][8]; + const double var_52 = -1.0000000000000000000000000*var_51; + const double var_53 = w[0][7]*w[1][7]; + const double var_54 = -1.0000000000000000000000000*var_53; + const double var_55 = w[0][8]*w[1][8]; + const double var_56 = -1.0000000000000000000000000*var_55; + const double var_57 = w[0][6]*w[1][9] + w[0][9]*w[1][6]; + const double var_58 = w[0][5]*w[1][5]; + const double var_59 = -1.0000000000000000000000000*var_58; + const double var_60 = w[0][5]*w[1][9] + w[0][9]*w[1][5]; + const double var_61 = -1.0000000000000000000000000*var_60; + const double var_62 = var_57 + var_59 + var_61; + const double var_63 = w[0][2]*w[1][6] + w[0][6]*w[1][2]; + const double var_64 = w[0][2]*w[1][5] + w[0][5]*w[1][2]; + const double var_65 = -1.0000000000000000000000000*var_64; + const double var_66 = var_63 + 0.5000000000000000000000000*var_65; + const double var_67 = w[0][2]*w[1][4] + w[0][4]*w[1][2]; + const double var_68 = w[0][3]*w[1][2] + w[0][2]*w[1][3]; + const double var_69 = -1.0000000000000000000000000*var_68; + const double var_70 = var_67 + 0.5000000000000000000000000*var_69; + const double var_71 = w[0][5]*w[1][4] + w[0][4]*w[1][5]; + const double var_72 = w[0][6]*w[1][3] + w[0][3]*w[1][6]; + const double var_73 = w[0][7]*w[1][6] + w[0][6]*w[1][7]; + const double var_74 = w[0][8]*w[1][5] + w[0][5]*w[1][8]; + const double var_75 = w[0][9]*w[1][3] + w[0][3]*w[1][9]; + const double var_76 = -1.0000000000000000000000000*var_75; + const double var_77 = 0.2500000000000000000000000*var_73 + -1.5000000000000000000000000*var_72 + var_76 + -1.0000000000000000000000000*var_71 + var_74; + const double var_78 = w[0][1]*w[1][4] + w[0][4]*w[1][1]; + const double var_79 = w[0][4]*w[1][0] + w[0][0]*w[1][4]; + const double var_80 = var_78 + var_79; + const double var_81 = 0.0004329004329004329000574*var_70 + 0.0000378787878787878787550*var_48 + 0.0005844155844155844150775*var_77 + 0.0002435064935064935062823*var_14 + -0.0008766233766233766768264*var_12 + 0.0000541125541125541125072*var_11 + 0.0000216450216450216450029*var_44 + 0.0003896103896103896100517*var_56 + var_26 + 0.0003246753246753246750431*var_10 + 0.0001623376623376623375215*var_50 + 0.0014610389610389610919039*var_18 + 0.0000865800865800865800115*var_46 + -0.0000487012987012987012565*var_15 + 0.0043831168831168828420308*var_19 + var_32 + 0.0001190476190476190475158*var_42 + 0.0017532467532467533536528*var_62 + -0.0000919913419913419912622*var_9 + 0.0011688311688311688301550*var_13 + 0.0001569264069264069262708*var_80 + 0.0008658008658008658001148*var_66 + -0.0002326839826839826837809*var_16 + 0.0000324675324675324675043*var_52 + 0.0006818181818181818718005*var_54 + 0.0002543290043290043558888*var_17 + var_40; + A[16] = var_8*var_81; + A[26] = A[16]; + const double var_82 = 0.0277777777777777762358014*var_34 + 0.7500000000000000000000000*var_36 + var_37 + 2.2500000000000000000000000*var_33; + const double var_83 = var_45 + var_16; + const double var_84 = var_12 + var_60; + const double var_85 = var_39 + 0.5666666666666666518636930*var_83 + 5.4000000000000003552713679*var_84; + const double var_86 = var_73 + var_74; + const double var_87 = 0.0375000000000000055511151*var_86 + 0.0071428571428571426341070*var_82 + -0.0178571428571428561515866*var_85 + -0.0750000000000000111022302*var_35; + const double var_88 = w[0][9]*w[1][2] + w[0][2]*w[1][9]; + const double var_89 = var_88 + 2.2500000000000000000000000*var_28 + 0.7500000000000000000000000*var_27 + 0.0277777777777777762358014*var_29; + const double var_90 = var_79 + var_17; + const double var_91 = var_57 + var_13; + const double var_92 = var_31 + 0.5666666666666666518636930*var_90 + 5.4000000000000003552713679*var_91; + const double var_93 = var_71 + var_72; + const double var_94 = 0.0375000000000000055511151*var_93 + -0.0750000000000000111022302*var_30 + 0.0071428571428571426341070*var_89 + -0.0178571428571428561515866*var_92; + const double var_95 = var_43 + var_41; + const double var_96 = w[0][8]*w[1][9] + w[0][9]*w[1][8]; + const double var_97 = var_96 + var_75; + const double var_98 = var_64 + var_10; + const double var_99 = var_11 + var_47; + const double var_100 = var_53 + var_18; + const double var_101 = var_78 + var_9; + const double var_102 = var_51 + var_68; + const double var_103 = var_58 + var_19; + const double var_104 = var_63 + var_49; + const double var_105 = -1.0000000000000000000000000*var_24; + const double var_106 = var_14 + var_15; + const double var_107 = -0.5000000000000000000000000*var_106 + var_22; + const double var_108 = w[0][3]*w[1][3]; + const double var_109 = var_55 + var_108; + const double var_110 = 0.4500000000000000111022302*var_109 + 0.3000000000000000444089210*var_107; + const double var_111 = 0.0267857142857142842273799*var_0 + -0.5785714285714285143313873*w[0][9]*w[1][9] + 0.0059523809523809520505289*var_104 + -0.0001984126984126984125263*var_21 + 0.0035714285714285713170535*var_102 + 0.0041666666666666666088426*var_95 + 0.0964285714285714190552312*var_97 + -0.0047619047619047623343125*var_98 + -0.0803571428571428492126927*var_100 + var_94 + 0.0482142857142857095276156*var_20 + 0.0285714285714285705364279*var_105 + 0.0119047619047619041010577*var_99 + -0.0095238095238095246686250*var_101 + 0.0357142857142857123031732*var_110 + var_87 + -0.1446428571428571285828468*var_103; + const double var_112 = -1.0000000000000000000000000*var_78; + const double var_113 = 0.5000000000000000000000000*var_112 + var_47; + const double var_114 = -0.5000000000000000000000000*var_86 + var_35; + const double var_115 = 0.0701298701298701254724932*w[0][9]*w[1][9]; + const double var_116 = -1.0000000000000000000000000*var_20; + const double var_117 = 0.0018759018759018759002488*w[0][1]*w[1][1]; + const double var_118 = 0.0092532467532467528592566*var_22 + 0.0064935064935064939345422*var_21 + 0.0035714285714285713170535*var_25 + var_115 + 0.0535714285714285684547598*var_116 + var_117; + const double var_119 = var_88 + -1.5000000000000000000000000*var_27; + const double var_120 = -1.0000000000000000000000000*var_28; + const double var_121 = 0.0018759018759018759002488*w[0][2]*w[1][2]; + const double var_122 = 0.0535714285714285684547598*var_120 + 0.0092532467532467528592566*var_30 + var_121 + 0.0064935064935064939345422*var_29 + 0.0035714285714285713170535*var_119; + const double var_123 = var_51 + var_10; + const double var_124 = var_55 + var_19; + const double var_125 = var_18 + var_108; + const double var_126 = var_78 + var_68; + const double var_127 = var_9 + var_64; + const double var_128 = w[0][0]*w[1][7] + w[0][7]*w[1][0]; + const double var_129 = var_128 + var_49; + const double var_130 = var_53 + var_58; + const double var_131 = -1.0000000000000000000000000*var_79; + const double var_132 = var_131 + var_42; + const double var_133 = var_96 + var_57; + const double var_134 = var_13 + var_75; + const double var_135 = var_15 + var_72; + const double var_136 = var_14 + var_71; + const double var_137 = var_43 + var_17; + const double var_138 = var_67 + var_47; + const double var_139 = var_63 + var_11; + const double var_140 = 0.0681818181818181906495013*var_114 + 0.0029220779220779221838078*var_134 + -0.0009199134199134199668321*var_138 + 0.0292207792207792235728014*var_84 + 0.0129870129870129878690843*var_37 + 0.1363636363636363812990027*var_130 + 0.0370129870129870114370263*var_124 + 0.2954545454545454696848594*var_39 + 0.0126623376623376630856210*var_36 + 0.0080086580086580084342218*var_83 + -0.0043831168831168828420308*var_33 + -0.0042748917748917751591176*var_139 + 0.0008838383838383838918273*var_34 + 0.0000541125541125541125072*var_126 + -0.0275974025974025996554850*var_123 + 0.0087662337662337656840617*var_125 + var_118 + 0.0010822510822510822501435*var_132 + -0.0025432900432900431252070*var_137 + -0.0024350649350649354422937*var_135 + var_122 + 0.0106601731601731596760230*var_127 + -0.0058441558441558443676156*var_133 + 0.0616883116883116949802357*var_129 + -0.0068181818181818178506437*var_136; + A[0] = 0.0250000000000000013877788*var_140*var_8; + const double var_141 = 0.3333333333333333148296163*w[0][1]*w[1][1]; + const double var_142 = -0.0007305194805194805459519*var_22 + -0.0005844155844155844150775*var_20 + 0.0000432900432900432900057*var_21 + 0.0001948051948051948050258*var_25 + -0.0001623376623376623375215*var_141 + var_23; + const double var_143 = -0.0001948051948051948050258*var_35 + -0.0008766233766233766768264*var_33 + 0.0000324675324675324675043*var_38 + -0.0000108225108225108225014*var_39 + 0.0000649350649350649350086*var_34; + const double var_144 = -1.0000000000000000000000000*var_16; + const double var_145 = -1.0000000000000000000000000*var_9; + const double var_146 = -1.0000000000000000000000000*var_108; + const double var_147 = var_76 + var_13 + var_146; + const double var_148 = -1.0000000000000000000000000*var_72; + const double var_149 = var_148 + var_14 + 0.2500000000000000000000000*var_15 + var_61; + const double var_150 = var_96 + var_71; + const double var_151 = var_17 + var_10; + const double var_152 = -0.0000487012987012987012565*var_73 + var_142 + 0.0001569264069264069262708*var_151 + 0.0000541125541125541125072*var_128 + 0.0001623376623376623375215*var_48 + 0.0008658008658008658001148*var_70 + 0.0011688311688311688301550*var_57 + -0.0000919913419913419912622*var_51 + -0.0008766233766233766768264*var_150 + 0.0000865800865800865800115*var_44 + var_143 + 0.0006818181818181818718005*var_56 + 0.0043831168831168828420308*var_18 + 0.0000378787878787878787550*var_50 + -0.0002326839826839826837809*var_41 + 0.0002435064935064935062823*var_74 + 0.0000216450216450216450029*var_46 + 0.0003246753246753246750431*var_78 + 0.0002543290043290043558888*var_79 + 0.0014610389610389610919039*var_19 + var_32 + 0.0001190476190476190475158*var_144 + 0.0005844155844155844150775*var_149 + 0.0000324675324675324675043*var_145 + 0.0004329004329004329000574*var_66 + 0.0017532467532467533536528*var_147 + 0.0003896103896103896100517*var_54; + A[15] = var_152*var_8; + const double var_153 = var_58 + var_108; + const double var_154 = var_107 + -0.5000000000000000000000000*var_0 + var_116; + const double var_155 = 2.3142857142857140573255492*w[0][9]*w[1][9]; + const double var_156 = var_95 + w[0][1]*w[1][1]; + const double var_157 = 0.0119047619047619041010577*var_156 + var_155 + 0.0428571428571428575393654*var_24 + 0.1285714285714285587403083*var_154; + const double var_158 = -1.0000000000000000000000000*var_138; + const double var_159 = -0.5000000000000000000000000*var_93 + var_30; + const double var_160 = var_159 + var_120; + const double var_161 = 0.0428571428571428575393654*var_119 + 0.0357142857142857123031732*var_31 + 0.0119047619047619041010577*var_90 + 0.1285714285714285587403083*var_160; + const double var_162 = 1.5000000000000000000000000*var_130 + var_114; + const double var_163 = -1.0000000000000000000000000*var_129; + const double var_164 = var_126 + var_163; + const double var_165 = -1.0000000000000000000000000*var_63; + const double var_166 = -1.0000000000000000000000000*var_11; + const double var_167 = var_165 + var_166; + const double var_168 = 0.2500000000000000000000000*var_167 + 0.2000000000000000111022302*var_127; + const double var_169 = 0.2571428571428571174806166*var_124 + 0.3000000000000000444089210*var_162 + 0.1428571428571428492126927*var_168 + 0.0714285714285714246063463*var_85 + -0.0285714285714285705364279*var_82 + 0.0119047619047619041010577*var_164 + 0.0023809523809523811671562*var_123 + var_161 + 0.0238095238095238082021154*var_158 + var_157 + 0.1285714285714285587403083*var_125; + A[29] = 0.0090909090909090904675249*var_169*var_8; + A[34] = A[29]; + const double var_170 = -1.0000000000000000000000000*var_104; + const double var_171 = -1.0000000000000000000000000*var_33; + const double var_172 = var_171 + var_114; + const double var_173 = 0.0357142857142857123031732*var_39 + 0.0119047619047619041010577*var_83 + 0.0428571428571428575393654*var_38 + 0.1285714285714285587403083*var_172; + const double var_174 = 0.3857142857142856762209249*var_97 + 0.0404761904761904781069326*var_95 + var_155 + 0.0714285714285714246063463*var_141; + const double var_175 = 0.0277777777777777762358014*var_21 + var_24 + 0.7500000000000000000000000*var_0 + 2.2500000000000000000000000*var_20; + const double var_176 = -1.0000000000000000000000000*var_99; + const double var_177 = var_176 + var_98; + const double var_178 = -1.0000000000000000000000000*var_128; + const double var_179 = -1.0000000000000000000000000*var_67; + const double var_180 = var_178 + var_179; + const double var_181 = 0.2000000000000000111022302*var_102 + 0.2500000000000000000000000*var_180; + const double var_182 = 0.0238095238095238082021154*var_170 + 0.1428571428571428492126927*var_181 + 0.0023809523809523811671562*var_101 + -0.0285714285714285705364279*var_175 + 0.2571428571428571174806166*var_100 + 0.0119047619047619041010577*var_177 + var_174 + var_161 + var_173 + var_110 + 0.1285714285714285587403083*var_103; + A[23] = 0.0090909090909090904675249*var_182*var_8; + A[33] = A[23]; + const double var_183 = var_18 + var_19; + const double var_184 = var_15 + var_73; + const double var_185 = var_49 + var_47; + const double var_186 = -1.0000000000000000000000000*var_88; + const double var_187 = -0.0028246753246753248355050*var_30 + -0.0032467532467532469672711*var_31 + -0.0004870129870129870125646*var_27 + -0.0001298701298701298700172*var_29 + 0.0007792207792207792201034*var_28 + 0.0002597402597402597400345*var_186; + const double var_188 = -1.0000000000000000000000000*var_37; + const double var_189 = -0.0028246753246753248355050*var_35 + -0.0004870129870129870125646*var_36 + 0.0007792207792207792201034*var_33 + -0.0032467532467532469672711*var_39 + 0.0002597402597402597400345*var_188 + -0.0001298701298701298700172*var_34; + const double var_190 = -1.0000000000000000000000000*var_17; + const double var_191 = var_144 + var_190; + const double var_192 = -1.0000000000000000000000000*var_12; + const double var_193 = -1.0000000000000000000000000*var_13; + const double var_194 = var_193 + var_192; + const double var_195 = var_72 + var_74; + const double var_196 = var_73 + var_71; + const double var_197 = var_57 + var_60; + const double var_198 = var_45 + var_79; + const double var_199 = 0.0006818181818181818718005*var_0 + 0.0000432900432900432900057*var_141 + var_189 + -0.0002633477633477633475349*var_21 + 0.0005627705627705627700746*var_102 + -0.0003246753246753246750431*var_198 + 0.0003571428571428571425474*var_95 + -0.0017532467532467533536528*var_197 + 0.0002272727272727272725301*var_191 + 0.0029220779220779221838078*var_97 + 0.0001298701298701298700172*var_98 + var_187 + -0.0030194805194805195321106*var_100 + 0.0008658008658008658001148*var_180 + 0.0043831168831168828420308*var_20 + 0.0006493506493506493500861*var_105 + 0.0001839826839826839825244*var_99 + 0.0023376623376623376603101*var_194 + 0.0009740259740259740251292*var_107 + 0.0500000000000000027755576*var_115 + 0.0015584415584415584402067*var_196 + -0.0003030303030303030300402*var_101 + 0.0012662337662337661784578*var_195 + 0.0012987012987012987001723*var_170 + -0.0078896103896103891156555*var_103 + 0.0010714285714285714818522*var_109; + const double var_200 = -1.0000000000000000000000000*var_96; + const double var_201 = var_56 + var_200 + var_12; + const double var_202 = 0.0014610389610389610919039*var_22 + 0.0003409090909090909359003*var_20 + 0.0000234487734487734487531*var_21 + 0.0016233766233766234836355*var_141 + 0.0005844155844155844150775*var_0 + var_23; + const double var_203 = -0.0001948051948051948050258*var_30 + -0.0000108225108225108225014*var_31 + 0.0000649350649350649350086*var_29 + -0.0008766233766233766768264*var_28 + 0.0000324675324675324675043*var_119; + const double var_204 = -1.0000000000000000000000000*var_19; + const double var_205 = -1.0000000000000000000000000*var_10; + const double var_206 = var_96 + var_54 + var_192; + const double var_207 = -1.0000000000000000000000000*var_14 + var_193 + var_73; + const double var_208 = 0.5000000000000000000000000*var_145 + var_11; + const double var_209 = var_15 + var_60; + const double var_210 = var_68 + var_41; + const double var_211 = 0.0008658008658008658001148*var_208 + 0.0017532467532467533536528*var_206 + var_203 + 0.0002543290043290043558888*var_43 + 0.0043831168831168828420308*var_55 + 0.0014610389610389610919039*var_108 + 0.0004329004329004329000574*var_113 + -0.0002326839826839826837809*var_45 + 0.0003896103896103896100517*var_204 + 0.0005844155844155844150775*var_207 + 0.0003246753246753246750431*var_51 + 0.0011688311688311688301550*var_75 + 0.0006818181818181818718005*var_59 + 0.0001190476190476190475158*var_131 + var_202 + 0.0002435064935064935062823*var_71 + 0.0000541125541125541125072*var_63 + 0.0001461038961038961037694*var_74 + 0.0000378787878787878787550*var_179 + 0.0000487012987012987012565*var_148 + 0.0000216450216450216450029*var_190 + 0.0001569264069264069262708*var_210 + 0.0000865800865800865800115*var_144 + 0.0001623376623376623375215*var_178 + -0.0000919913419913419912622*var_64 + -0.0008766233766233766768264*var_209 + var_40 + 0.0000324675324675324675043*var_205; + A[11] = var_211*var_8; + A[31] = A[11]; + const double var_212 = 0.0018759018759018759002488*w[0][0]*w[1][0]; + const double var_213 = -0.0007305194805194805459519*var_30 + -0.0001623376623376623375215*var_31 + 0.0000432900432900432900057*var_29 + -0.0005844155844155844150775*var_28 + 0.0001948051948051948050258*var_119; + const double var_214 = -1.0000000000000000000000000*var_18; + const double var_215 = var_193 + var_214 + var_75; + const double var_216 = -1.0000000000000000000000000*var_15 + var_71 + var_192; + const double var_217 = -1.0000000000000000000000000*var_74; + const double var_218 = var_43 + var_51; + const double var_219 = var_14 + var_57; + const double var_220 = 0.0004329004329004329000574*var_208 + 0.0017532467532467533536528*var_215 + 0.0002435064935064935062823*var_73 + 0.0001461038961038961037694*var_72 + 0.0014610389610389610919039*var_55 + 0.0000541125541125541125072*var_49 + 0.0043831168831168828420308*var_108 + 0.0008658008658008658001148*var_113 + 0.0005844155844155844150775*var_216 + 0.0006818181818181818718005*var_204 + 0.0000324675324675324675043*var_65 + 0.0003246753246753246750431*var_68 + 0.0011688311688311688301550*var_96 + 0.0003896103896103896100517*var_59 + var_143 + -0.0000919913419913419912622*var_10 + var_202 + 0.0002543290043290043558888*var_41 + 0.0001623376623376623375215*var_179 + 0.0001190476190476190475158*var_46 + -0.0002326839826839826837809*var_79 + var_213 + 0.0000865800865800865800115*var_190 + 0.0000216450216450216450029*var_144 + 0.0000378787878787878787550*var_178 + 0.0001569264069264069262708*var_218 + -0.0008766233766233766768264*var_219 + 0.0000487012987012987012565*var_217; + A[9] = var_220*var_8; + const double var_221 = 0.0071428571428571426341070*var_175 + -0.2500000000000000000000000*var_174 + 0.0375000000000000055511151*var_106 + -0.0750000000000000111022302*var_22; + const double var_222 = 0.0092532467532467528592566*var_35 + var_212 + 0.0035714285714285713170535*var_38 + 0.0064935064935064939345422*var_34 + 0.0535714285714285684547598*var_171; + const double var_223 = var_63 + var_67; + const double var_224 = var_68 + var_64; + const double var_225 = var_78 + var_10; + const double var_226 = var_9 + var_51; + const double var_227 = var_55 + var_53; + const double var_228 = var_44 + var_46; + const double var_229 = var_14 + var_74; + const double var_230 = var_96 + var_12; + const double var_231 = var_75 + var_60; + const double var_232 = var_16 + var_41; + const double var_233 = var_128 + var_11; + const double var_234 = -0.0024350649350649354422937*var_229 + 0.0008838383838383838918273*var_29 + 0.0106601731601731596760230*var_225 + 0.0681818181818181906495013*var_159 + 0.0370129870129870114370263*var_153 + 0.2954545454545454696848594*var_31 + -0.0068181818181818178506437*var_184 + -0.0025432900432900431252070*var_232 + 0.0087662337662337656840617*var_227 + 0.0616883116883116949802357*var_223 + 0.0010822510822510822501435*var_228 + 0.0080086580086580084342218*var_90 + 0.0029220779220779221838078*var_230 + 0.0292207792207792235728014*var_91 + var_222 + 0.0000541125541125541125072*var_226 + 0.0129870129870129878690843*var_88 + -0.0058441558441558443676156*var_231 + var_118 + 0.1363636363636363812990027*var_183 + 0.0126623376623376630856210*var_27 + -0.0275974025974025996554850*var_224 + -0.0009199134199134199668321*var_233 + -0.0042748917748917751591176*var_185 + -0.0043831168831168828420308*var_28; + A[14] = 0.0250000000000000013877788*var_234*var_8; + A[2] = 0.1250000000000000000000000*var_199*var_8; + A[12] = A[2]; + const double var_235 = 0.4500000000000000111022302*var_183 + 0.3000000000000000444089210*var_159; + const double var_236 = var_67 + var_128; + const double var_237 = 0.0126623376623376630856210*var_0 + -0.0009199134199134199668321*var_104 + 0.2954545454545454696848594*var_141 + 0.0008838383838383838918273*var_21 + 0.0106601731601731596760230*var_102 + 0.0080086580086580084342218*var_95 + -0.0025432900432900431252070*var_198 + 0.0029220779220779221838078*var_197 + 0.0010822510822510822501435*var_191 + 0.0292207792207792235728014*var_97 + 0.0000541125541125541125072*var_98 + 0.0370129870129870114370263*var_100 + -0.0043831168831168828420308*var_20 + -0.0042748917748917751591176*var_236 + 0.0616883116883116949802357*var_99 + 0.0058441558441558443676156*var_194 + 0.0129870129870129878690843*var_24 + 0.0681818181818181906495013*var_107 + var_115 + var_222 + -0.0024350649350649354422937*var_196 + -0.0275974025974025996554850*var_101 + -0.0068181818181818178506437*var_195 + var_122 + 0.0087662337662337656840617*var_103 + 0.1363636363636363812990027*var_109; + const double var_238 = 0.0035714285714285713170535*var_127 + var_94 + -0.0803571428571428492126927*var_124 + 0.0107142857142857143848413*var_162 + 0.0059523809523809520505289*var_138 + 0.0267857142857142842273799*var_36 + 0.0119047619047619041010577*var_129 + 0.0482142857142857095276156*var_33 + 0.0041666666666666666088426*var_83 + -0.0095238095238095246686250*var_123 + 0.0285714285714285705364279*var_188 + -0.0001984126984126984125263*var_34 + 0.0964285714285714190552312*var_84 + var_221 + -0.0047619047619047623343125*var_126 + -0.1446428571428571285828468*var_125; + A[3] = 0.0090909090909090904675249*var_238*var_8; + A[18] = A[3]; + const double var_239 = -0.0028246753246753248355050*var_22 + 0.0007792207792207792201034*var_20 + -0.0001298701298701298700172*var_21 + 0.0002597402597402597400345*var_105 + -0.0032467532467532469672711*var_141 + 0.0035064935064935067073055*w[0][9]*w[1][9] + -0.0004870129870129870125646*var_0; + const double var_240 = var_48 + var_50; + const double var_241 = -1.0000000000000000000000000*var_233; + const double var_242 = -0.0002633477633477633475349*var_29 + 0.0005627705627705627700746*var_225 + 0.0015584415584415584402067*var_229 + var_189 + 0.0008658008658008658001148*var_240 + 0.0009740259740259740251292*var_159 + -0.0030194805194805195321106*var_153 + 0.0000432900432900432900057*var_31 + -0.0078896103896103891156555*var_227 + -0.0003246753246753246750431*var_232 + 0.0012662337662337661784578*var_184 + 0.0001839826839826839825244*var_223 + 0.0012987012987012987001723*var_241 + 0.0002272727272727272725301*var_228 + 0.0003571428571428571425474*var_90 + -0.0017532467532467533536528*var_230 + 0.0029220779220779221838078*var_91 + var_239 + 0.0001298701298701298700172*var_226 + -0.0023376623376623376603101*var_231 + 0.0006493506493506493500861*var_186 + 0.0010714285714285714818522*var_183 + 0.0006818181818181818718005*var_27 + -0.0003030303030303030300402*var_224 + 0.0043831168831168828420308*var_28; + A[1] = 0.1250000000000000000000000*var_242*var_8; + const double var_243 = -1.0000000000000000000000000*var_223; + const double var_244 = var_226 + var_243; + const double var_245 = 0.2000000000000000111022302*var_225 + 0.2500000000000000000000000*var_240; + const double var_246 = 0.1428571428571428492126927*var_245 + 0.2571428571428571174806166*var_153 + 0.0714285714285714246063463*var_92 + 0.0023809523809523811671562*var_224 + 0.1285714285714285587403083*var_227 + -0.0285714285714285705364279*var_89 + var_235 + var_173 + 0.0238095238095238082021154*var_241 + var_157 + 0.0119047619047619041010577*var_244; + A[22] = 0.0090909090909090904675249*var_246*var_8; + A[27] = A[22]; + const double var_247 = 0.0204545454545454544192928*var_22 + -0.0019480519480519480502584*var_24 + -0.0001082251082251082250144*var_21 + 0.0064935064935064939345422*var_141 + 0.0068181818181818178506437*var_116 + -0.0058441558441558443676156*var_0; + const double var_248 = 0.0068181818181818178506437*var_120 + 0.0204545454545454544192928*var_30 + 0.0064935064935064939345422*var_31 + -0.0058441558441558443676156*var_27 + -0.0001082251082251082250144*var_29 + -0.0019480519480519480502584*var_88; + const double var_249 = 0.1402597402597402509449864*w[0][9]*w[1][9]; + const double var_250 = var_130 + var_37; + const double var_251 = var_79 + var_41; + const double var_252 = var_133 + -1.0000000000000000000000000*var_84; + const double var_253 = -0.5000000000000000000000000*var_36 + var_172 + -1.0000000000000000000000000*var_135; + const double var_254 = 27.0000000000000000000000000*var_252 + 0.5000000000000000000000000*var_83 + -1.0000000000000000000000000*var_126 + 9.0000000000000000000000000*var_253 + var_34 + 6.5000000000000000000000000*var_251 + 2.8333333333333330372738601*var_123; + const double var_255 = -0.0146103896103896117864007*var_136 + 0.0350649350649350627362466*var_134 + 0.5000000000000000000000000*var_212 + 0.0136363636363636357012874*var_124 + 0.0021645021645021645002871*var_168 + var_248 + 0.0077922077922077922010335*var_250 + 0.0012987012987012987001723*var_137 + var_247 + 0.0016233766233766234836355*var_158 + var_249 + 0.0023809523809523811671562*var_163 + 0.0006493506493506493500861*var_254 + 0.0818181818181818176771714*var_125; + A[21] = 0.2000000000000000111022302*var_255*var_8; + A[10] = 0.0090909090909090904675249*var_111*var_8; + A[25] = A[10]; + const double var_256 = -1.0000000000000000000000000*var_57; + const double var_257 = -1.5000000000000000000000000*var_73 + var_256 + var_217 + 0.2500000000000000000000000*var_14 + var_15; + const double var_258 = 0.0014610389610389610919039*var_35 + 0.0005844155844155844150775*var_36 + 0.0003409090909090909359003*var_33 + 0.0016233766233766234836355*var_39 + 0.0000234487734487734487531*var_34; + const double var_259 = 0.5000000000000000000000000*var_205 + var_49; + const double var_260 = 0.5000000000000000000000000*var_52 + var_128; + const double var_261 = var_16 + var_64; + const double var_262 = 0.0001623376623376623375215*var_166 + var_203 + 0.0004329004329004329000574*var_259 + 0.0003896103896103896100517*var_214 + var_142 + 0.0002435064935064935062823*var_72 + -0.0002326839826839826837809*var_43 + 0.0000541125541125541125072*var_67 + 0.0011688311688311688301550*var_60 + 0.0008658008658008658001148*var_260 + 0.0001569264069264069262708*var_261 + 0.0002543290043290043558888*var_45 + 0.0017532467532467533536528*var_201 + 0.0043831168831168828420308*var_53 + -0.0000919913419913419912622*var_68 + -0.0008766233766233766768264*var_75 + 0.0014610389610389610919039*var_58 + 0.0000216450216450216450029*var_131 + 0.0006818181818181818718005*var_146 + -0.0000487012987012987012565*var_71 + 0.0000378787878787878787550*var_165 + 0.0005844155844155844150775*var_257 + 0.0000865800865800865800115*var_42 + 0.0001190476190476190475158*var_190 + 0.0003246753246753246750431*var_9 + var_258 + 0.0000324675324675324675043*var_112; + const double var_263 = var_45 + var_9; + const double var_264 = var_256 + var_204 + var_60; + const double var_265 = var_13 + var_74; + A[7] = 0.0250000000000000013877788*var_237*var_8; + const double var_266 = 0.0035714285714285713170535*var_225 + var_87 + -0.0047619047619047623343125*var_226 + 0.0041666666666666666088426*var_90 + 0.0059523809523809520505289*var_233 + -0.0803571428571428492126927*var_153 + -0.0095238095238095246686250*var_224 + 0.0267857142857142842273799*var_27 + -0.1446428571428571285828468*var_227 + -0.0001984126984126984125263*var_29 + 0.0357142857142857123031732*var_235 + 0.0964285714285714190552312*var_91 + 0.0285714285714285705364279*var_186 + var_221 + 0.0482142857142857095276156*var_28 + 0.0119047619047619041010577*var_223; + A[17] = 0.0090909090909090904675249*var_266*var_8; + A[32] = A[17]; + A[5] = var_262*var_8; + A[30] = A[5]; + const double var_267 = -1.0000000000000000000000000*var_97 + var_13 + var_12; + const double var_268 = var_16 + var_17; + const double var_269 = var_154 + -1.0000000000000000000000000*var_196; + const double var_270 = 6.5000000000000000000000000*var_268 + 27.0000000000000000000000000*var_267 + var_21 + 0.5000000000000000000000000*var_95 + 2.8333333333333330372738601*var_101 + 9.0000000000000000000000000*var_269 + -1.0000000000000000000000000*var_98; + const double var_271 = var_183 + var_88; + const double var_272 = 0.0006493506493506493500861*var_188 + 0.0009740259740259740251292*var_114 + -0.0017532467532467533536528*var_134 + 0.0008658008658008658001148*var_167 + 0.0029220779220779221838078*var_84 + var_187 + 0.0000432900432900432900057*var_39 + -0.0030194805194805195321106*var_124 + 0.0010714285714285714818522*var_130 + 0.0006818181818181818718005*var_36 + 0.0003571428571428571425474*var_83 + 0.0043831168831168828420308*var_33 + -0.0002633477633477633475349*var_34 + var_239 + 0.0001298701298701298700172*var_126 + -0.0003030303030303030300402*var_123 + -0.0078896103896103891156555*var_125 + 0.0012987012987012987001723*var_158 + 0.0002272727272727272725301*var_132 + -0.0003246753246753246750431*var_137 + 0.0015584415584415584402067*var_135 + 0.0005627705627705627700746*var_127 + -0.0023376623376623376603101*var_133 + 0.0001839826839826839825244*var_129 + 0.0012662337662337661784578*var_136; + A[8] = 0.1250000000000000000000000*var_272*var_8; + const double var_273 = 0.0204545454545454544192928*var_35 + var_249 + -0.0019480519480519480502584*var_37 + -0.0058441558441558443676156*var_36 + 0.0064935064935064939345422*var_39 + -0.0001082251082251082250144*var_34 + 0.0068181818181818178506437*var_171; + const double var_274 = var_109 + var_24; + const double var_275 = 0.0021645021645021645002871*var_181 + 0.0016233766233766234836355*var_170 + 0.0012987012987012987001723*var_198 + 0.0350649350649350627362466*var_197 + var_248 + 0.0136363636363636357012874*var_100 + 0.5000000000000000000000000*var_117 + 0.0006493506493506493500861*var_270 + 0.0077922077922077922010335*var_274 + -0.0146103896103896117864007*var_195 + var_273 + 0.0818181818181818176771714*var_103 + 0.0023809523809523811671562*var_176; + const double var_276 = var_43 + var_45; + const double var_277 = var_231 + -1.0000000000000000000000000*var_91; + const double var_278 = var_160 + -1.0000000000000000000000000*var_229 + -0.5000000000000000000000000*var_27; + const double var_279 = -1.0000000000000000000000000*var_226 + 6.5000000000000000000000000*var_276 + 0.5000000000000000000000000*var_90 + var_29 + 27.0000000000000000000000000*var_277 + 9.0000000000000000000000000*var_278 + 2.8333333333333330372738601*var_224; + const double var_280 = 0.0021645021645021645002871*var_245 + 0.0136363636363636357012874*var_153 + 0.0012987012987012987001723*var_232 + 0.0077922077922077922010335*var_271 + 0.5000000000000000000000000*var_121 + 0.0818181818181818176771714*var_227 + -0.0146103896103896117864007*var_184 + var_247 + 0.0023809523809523811671562*var_243 + 0.0350649350649350627362466*var_230 + 0.0016233766233766234836355*var_241 + var_273 + 0.0006493506493506493500861*var_279; + A[35] = 0.2000000000000000111022302*var_280*var_8; + A[6] = A[1]; + const double var_281 = -1.0000000000000000000000000*var_73 + var_72 + 3.0000000000000000000000000*var_264 + var_200 + -1.5000000000000000000000000*var_265 + 0.2500000000000000000000000*var_71; + const double var_282 = 0.0008658008658008658001148*var_259 + 0.0000378787878787878787550*var_166 + 0.0006818181818181818718005*var_214 + 0.0004329004329004329000574*var_260 + 0.0000541125541125541125072*var_47 + -0.0000487012987012987012565*var_14 + 0.0011688311688311688301550*var_12 + 0.0014610389610389610919039*var_53 + 0.0005844155844155844150775*var_281 + 0.0001190476190476190475158*var_44 + var_26 + 0.0043831168831168828420308*var_58 + 0.0000865800865800865800115*var_131 + 0.0003896103896103896100517*var_146 + 0.0001623376623376623375215*var_165 + -0.0000919913419913419912622*var_78 + var_213 + 0.0002435064935064935062823*var_15 + 0.0000216450216450216450029*var_42 + var_258 + 0.0002543290043290043558888*var_16 + 0.0003246753246753246750431*var_64 + 0.0001569264069264069262708*var_263 + 0.0000324675324675324675043*var_69 + -0.0002326839826839826837809*var_17; + A[4] = var_282*var_8; + A[24] = A[4]; + A[20] = A[15]; + A[19] = A[9]; + A[13] = A[8]; + A[28] = 0.2000000000000000111022302*var_275*var_8; + } + + 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/mass_matrix_2d/mass_matrix_f2_p3_q2_quadrature.h b/mass_matrix_2d/mass_matrix_f2_p3_q2_quadrature.h new file mode 100644 index 0000000..8aa380f --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p3_q2_quadrature.h @@ -0,0 +1,5391 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P3_Q2_QUADRATURE_H +#define __MASS_MATRIX_F2_P3_Q2_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p3_q2_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p3_q2_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p3_q2_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p3_q2_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p3_q2_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p3_q2_quadrature_finite_element_1() + { + // 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p3_q2_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p3_q2_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p3_q2_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_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.0*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 mass_matrix_f2_p3_q2_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p3_q2_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p3_q2_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_p3_q2_quadrature_dofmap_1() + { + // 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 mass_matrix_f2_p3_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 mass_matrix_f2_p3_q2_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p3_q2_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Array of quadrature weights. + static const double W36[36] = {0.00619426535265906, 0.0116108747669979, 0.0120606064042655, 0.0084515357969434, 0.0037652982126918, 0.000748542561236343, 0.0130433943300833, 0.0244492622580587, 0.0253962715890485, 0.0177965759970269, 0.00792866733379675, 0.00157622175402364, 0.0169175056800133, 0.0317111115907051, 0.0329393989007878, 0.023082463651359, 0.0102836172287667, 0.00204438659154493, 0.0169175056800133, 0.0317111115907051, 0.0329393989007878, 0.023082463651359, 0.0102836172287667, 0.00204438659154493, 0.0130433943300833, 0.0244492622580587, 0.0253962715890485, 0.0177965759970269, 0.00792866733379675, 0.00157622175402364, 0.00619426535265908, 0.0116108747669979, 0.0120606064042655, 0.00845153579694342, 0.00376529821269181, 0.000748542561236345}; + // Quadrature points on the UFC reference element: (0.0327753666144599, 0.0293164271597849), (0.0287653330125591, 0.148078599668484), (0.0223868729780306, 0.336984690281154), (0.0149015633666711, 0.55867151877155), (0.00779187470128645, 0.769233862030055), (0.00246669715267023, 0.926945671319741), (0.164429241594827, 0.0293164271597849), (0.144311486950417, 0.148078599668484), (0.112311681780954, 0.336984690281154), (0.0747589734626491, 0.55867151877155), (0.0390907007328242, 0.769233862030055), (0.01237506041744, 0.926945671319741), (0.369529924372377, 0.0293164271597849), (0.324318304588776, 0.148078599668484), (0.252403568076518, 0.336984690281154), (0.168009519121192, 0.55867151877155), (0.0878504549759972, 0.769233862030055), (0.0278110821153606, 0.926945671319741), (0.601153648467838, 0.0293164271597849), (0.52760309574274, 0.148078599668484), (0.410611741642328, 0.336984690281154), (0.273318962107258, 0.55867151877155), (0.142915682993948, 0.769233862030055), (0.0452432465648983, 0.926945671319741), (0.806254331245388, 0.0293164271597849), (0.707609913381099, 0.148078599668484), (0.550703627937892, 0.336984690281154), (0.366569507765801, 0.55867151877155), (0.191675437237121, 0.769233862030055), (0.0606792682628189, 0.926945671319741), (0.937908206225755, 0.0293164271597849), (0.823156067318956, 0.148078599668484), (0.640628436740815, 0.336984690281154), (0.426426917861779, 0.55867151877155), (0.222974263268659, 0.769233862030055), (0.0705876315275886, 0.926945671319741) + + // Value of basis functions at quadrature points. + static const double FE0[36][6] = \ + {{0.821435400385472, -0.0306269173010354, -0.027597521356955, 0.00384342659195225, 0.109984470441528, 0.122961141239038}, + {0.532015755009065, -0.0271104442459123, -0.104224056308926, 0.0170381209259896, 0.487567191028831, 0.0947134335909535}, + {0.180181151181146, -0.0213845288145617, -0.109867327313383, 0.0301761338274608, 0.863527901361615, 0.0573666697577237}, + {-0.0627470853075864, -0.0144574501851293, 0.0655562130014708, 0.0333003161525148, 0.952930295387644, 0.0254177109510863}, + {-0.123539219108257, -0.00767044807856534, 0.414207606957291, 0.0239750954756995, 0.686077414669827, 0.00694955008400423}, + {-0.0606224040782395, -0.0024545279629842, 0.79151088383707, 0.00914597699249764, 0.261723597972845, 0.00069647323881139}, + {0.493837762058507, -0.110355290611927, -0.027597521356955, 0.0192819115366138, 0.0945459854968659, 0.530287152876896}, + {0.293813665649314, -0.102659876418736, -0.104224056308926, 0.0854777716147778, 0.419127540340042, 0.408464955123528}, + {0.0558453437100203, -0.0870838540520213, -0.109867327313383, 0.151389269199641, 0.742314765989434, 0.247401802466309}, + {-0.0978230997184779, -0.0635811652362709, 0.0655562130014709, 0.167062836984721, 0.819167774555438, 0.109617440413119}, + {-0.118196490757038, -0.0360345349652578, 0.414207606957291, 0.120279562776686, 0.58977294736884, 0.0299709086194782}, + {-0.0533153210689967, -0.0120687761767694, 0.79151088383707, 0.0458840347450652, 0.224985540220277, 0.00300363844335377}, + {0.121617769664549, -0.0964251943590678, -0.027597521356955, 0.0433331884448944, 0.0704947085885853, 0.888577049017995}, + {0.0291269575319054, -0.1139535792061, -0.104224056308926, 0.192098401561452, 0.312506910393369, 0.6844453660283}, + {-0.0734077368932363, -0.124988445721003, -0.109867327313383, 0.340224552856495, 0.553479482332581, 0.414559474738547}, + {-0.123912452012481, -0.111555122090524, 0.0655562130014709, 0.375448532862056, 0.610782078678102, 0.183680749561375}, + {-0.102065898102695, -0.0724150500970178, 0.414207606957291, 0.270310179049135, 0.439742331096391, 0.050220831096895}, + {-0.041149343845434, -0.0262641695385059, 0.79151088383707, 0.103117448726206, 0.167752126239137, 0.00503305458152761}, + {-0.0964251943590678, 0.121617769664549, -0.027597521356955, 0.0704947085885853, 0.0433331884448943, 0.888577049017995}, + {-0.1139535792061, 0.0291269575319054, -0.104224056308926, 0.312506910393369, 0.192098401561452, 0.6844453660283}, + {-0.124988445721003, -0.0734077368932363, -0.109867327313383, 0.553479482332581, 0.340224552856495, 0.414559474738547}, + {-0.111555122090524, -0.123912452012481, 0.0655562130014709, 0.610782078678102, 0.375448532862056, 0.183680749561375}, + {-0.0724150500970178, -0.102065898102695, 0.414207606957291, 0.439742331096391, 0.270310179049135, 0.050220831096895}, + {-0.026264169538506, -0.0411493438454339, 0.79151088383707, 0.167752126239137, 0.103117448726206, 0.00503305458152761}, + {-0.110355290611927, 0.493837762058507, -0.027597521356955, 0.094545985496866, 0.0192819115366137, 0.530287152876895}, + {-0.102659876418736, 0.293813665649314, -0.104224056308926, 0.419127540340043, 0.0854777716147777, 0.408464955123527}, + {-0.0870838540520213, 0.0558453437100204, -0.109867327313383, 0.742314765989434, 0.151389269199641, 0.247401802466309}, + {-0.0635811652362708, -0.0978230997184778, 0.0655562130014709, 0.819167774555438, 0.16706283698472, 0.109617440413119}, + {-0.0360345349652578, -0.118196490757038, 0.414207606957291, 0.58977294736884, 0.120279562776686, 0.0299709086194782}, + {-0.0120687761767695, -0.0533153210689966, 0.79151088383707, 0.224985540220277, 0.0458840347450654, 0.00300363844335377}, + {-0.0306269173010354, 0.821435400385472, -0.027597521356955, 0.109984470441527, 0.00384342659195216, 0.122961141239039}, + {-0.0271104442459124, 0.532015755009064, -0.104224056308926, 0.487567191028831, 0.0170381209259896, 0.0947134335909537}, + {-0.0213845288145617, 0.180181151181146, -0.109867327313383, 0.863527901361614, 0.0301761338274608, 0.0573666697577238}, + {-0.0144574501851293, -0.0627470853075864, 0.0655562130014709, 0.952930295387644, 0.0333003161525146, 0.0254177109510863}, + {-0.00767044807856535, -0.123539219108256, 0.414207606957291, 0.686077414669827, 0.0239750954756995, 0.00694955008400424}, + {-0.00245452796298434, -0.0606224040782394, 0.79151088383707, 0.261723597972845, 0.00914597699249803, 0.000696473238811418}}; + + static const double FE1[36][10] = \ + {{0.692116405326339, 0.02809979214053, 0.0255622715011347, -0.00389870712577275, -0.00394357498286782, 0.224416734425978, -0.112850342203846, 0.250894855131633, -0.124729708262302, 0.0243322740491734}, + {0.283934759651154, 0.0251489409971642, 0.0640171956914923, -0.0175137741663261, -0.0106528248707412, 0.806022543976085, -0.304843939147456, 0.156575676330067, -0.0973575486190499, 0.0946689701576109}, + {-0.0230667189458806, 0.0201820871510281, -0.00182545940770507, -0.0316681717528919, 0.000371870446193849, 0.89558289813655, 0.0106415390326746, 0.0594961764142811, -0.0602031247994332, 0.130488903725183}, + {-0.042916247694867, 0.0139171991648146, -0.0611798040376018, -0.0357880903185195, 0.0253254357551023, 0.299401977386427, 0.724719094689676, 0.00798601215243768, -0.0273165975674619, 0.0958510204699925}, + {0.0491311892659461, 0.00752079361748066, 0.154762873078755, -0.026341495488006, 0.0352713041777646, -0.255537670979266, 1.00933258876242, -0.0025884423606554, -0.00763548751524317, 0.0360843474408066}, + {0.0497485688239403, 0.00243938401571425, 0.644479118812606, -0.0102130829170651, 0.0183234311516915, -0.232087782696187, 0.524347954533704, -0.000617609305981537, -0.000777734182289297, 0.00435775176386716}, + {0.239508104110957, 0.0627683640711487, 0.0255622715011347, -0.0109916789233747, -0.0197843414303476, 0.150905638607928, -0.0970095757563665, 0.846395762124882, -0.302290885970787, 0.104936341664825}, + {0.0487956775975465, 0.0641196764159749, 0.0640171956914923, -0.0545304359767136, -0.0534436711248166, 0.529434975607773, -0.26205309289338, 0.515966174346368, -0.260579700000555, 0.40827320033631}, + {-0.0624669400507792, 0.0619241738506681, -0.00182545940770509, -0.112928533782117, 0.00186561987722207, 0.544580480381976, 0.00914778960164644, 0.181500084071326, -0.18454889805122, 0.562751683508982}, + {-0.0164528736892738, 0.0514890982575726, -0.0611798040376018, -0.145793810693828, 0.127054023323504, 0.0918877602754595, 0.622990507121273, 0.0122960172501371, -0.0956618757635125, 0.413370957956269}, + {0.0580370533440932, 0.0324831299939718, 0.154762873078755, -0.119445891298145, 0.176950996894466, -0.281967732783221, 0.867652896045716, -0.0143289535245541, -0.0297631768059827, 0.1556188050549}, + {0.045115774663025, 0.0116944490193934, 0.644479118812606, -0.0497031543433876, 0.0919259858517786, -0.207033374665612, 0.450745399833617, -0.00276397053159101, -0.00325364379944372, 0.0187934151596152}, + {-0.0474645235382767, -0.0178848851455664, 0.0255622715011347, 0.00529373373938191, -0.044462323864076, 0.0637197133595963, -0.0723315933226381, 0.803179075351347, 0.108551677668697, 0.1758368542504}, + {-0.0641414000235847, 0.00450421741088884, 0.0640171956914923, -0.00584473256502761, -0.120106591488146, 0.204898420912783, -0.195390172530051, 0.448763755411812, -0.0208247444397816, 0.684124051619613}, + {-0.0365624407658455, 0.0380796136728451, -0.00182545940770511, -0.0929282395408237, 0.00419269933650997, 0.144355545313924, 0.00682071014235854, 0.108123175205576, -0.11323192829258, 0.94297632433574}, + {0.029034487004146, 0.062328097021337, -0.0611798040376018, -0.209488219289238, 0.285534757531946, -0.123712995627073, 0.464509772912832, -0.037204260833003, -0.102487957137557, 0.692666122454212}, + {0.0641393355313791, 0.0561718105163469, 0.154762873078755, -0.223953257707656, 0.397670681113729, -0.282604617367218, 0.646933211826454, -0.0322748977125214, -0.0416081953276764, 0.260763056048409}, + {0.0364487137089397, 0.024427326771013, 0.644479118812606, -0.106328278377059, 0.206589790661253, -0.163106070537901, 0.336081595024143, -0.00489365931747124, -0.00518977181109788, 0.0314912350655752}, + {-0.0178848851455664, -0.0474645235382767, 0.0255622715011347, 0.0637197133595962, -0.072331593322638, 0.00529373373938194, -0.044462323864076, 0.108551677668697, 0.803179075351347, 0.1758368542504}, + {0.00450421741088887, -0.0641414000235847, 0.0640171956914923, 0.204898420912783, -0.195390172530051, -0.00584473256502761, -0.120106591488146, -0.0208247444397817, 0.448763755411812, 0.684124051619613}, + {0.0380796136728452, -0.0365624407658455, -0.00182545940770511, 0.144355545313924, 0.00682071014235857, -0.0929282395408238, 0.00419269933651001, -0.11323192829258, 0.108123175205576, 0.94297632433574}, + {0.062328097021337, 0.029034487004146, -0.0611798040376018, -0.123712995627073, 0.464509772912832, -0.209488219289239, 0.285534757531946, -0.102487957137557, -0.0372042608330028, 0.692666122454212}, + {0.0561718105163469, 0.0641393355313791, 0.154762873078755, -0.282604617367218, 0.646933211826454, -0.223953257707657, 0.397670681113729, -0.0416081953276766, -0.0322748977125212, 0.260763056048409}, + {0.0244273267710131, 0.0364487137089397, 0.644479118812606, -0.163106070537901, 0.336081595024142, -0.106328278377059, 0.206589790661253, -0.00518977181109807, -0.00489365931747109, 0.0314912350655752}, + {0.0627683640711488, 0.239508104110958, 0.0255622715011347, 0.150905638607928, -0.0970095757563665, -0.0109916789233747, -0.0197843414303476, -0.302290885970787, 0.846395762124882, 0.104936341664825}, + {0.064119676415975, 0.0487956775975466, 0.0640171956914923, 0.529434975607773, -0.26205309289338, -0.0545304359767137, -0.0534436711248165, -0.260579700000555, 0.515966174346368, 0.40827320033631}, + {0.0619241738506681, -0.0624669400507792, -0.00182545940770511, 0.544580480381976, 0.00914778960164649, -0.112928533782117, 0.00186561987722211, -0.18454889805122, 0.181500084071326, 0.562751683508982}, + {0.0514890982575726, -0.0164528736892739, -0.0611798040376018, 0.0918877602754599, 0.622990507121273, -0.145793810693828, 0.127054023323504, -0.0956618757635126, 0.0122960172501373, 0.413370957956269}, + {0.0324831299939719, 0.0580370533440933, 0.154762873078755, -0.28196773278322, 0.867652896045716, -0.119445891298145, 0.176950996894467, -0.0297631768059829, -0.0143289535245539, 0.1556188050549}, + {0.0116944490193935, 0.0451157746630249, 0.644479118812606, -0.207033374665612, 0.450745399833616, -0.0497031543433881, 0.091925985851779, -0.00325364379944393, -0.0027639705315908, 0.0187934151596153}, + {0.02809979214053, 0.692116405326339, 0.0255622715011347, 0.224416734425978, -0.112850342203846, -0.00389870712577277, -0.00394357498286788, -0.124729708262302, 0.250894855131634, 0.0243322740491735}, + {0.0251489409971643, 0.283934759651153, 0.0640171956914923, 0.806022543976084, -0.304843939147455, -0.0175137741663261, -0.0106528248707413, -0.0973575486190503, 0.156575676330067, 0.0946689701576112}, + {0.0201820871510282, -0.0230667189458806, -0.0018254594077051, 0.89558289813655, 0.0106415390326748, -0.0316681717528918, 0.000371870446193856, -0.0602031247994334, 0.0594961764142812, 0.130488903725183}, + {0.0139171991648146, -0.042916247694867, -0.0611798040376018, 0.299401977386428, 0.724719094689675, -0.0357880903185195, 0.0253254357551024, -0.027316597567462, 0.00798601215243784, 0.0958510204699924}, + {0.00752079361748067, 0.0491311892659461, 0.154762873078755, -0.255537670979266, 1.00933258876242, -0.026341495488006, 0.0352713041777647, -0.00763548751524335, -0.00258844236065517, 0.0360843474408064}, + {0.00243938401571438, 0.0497485688239402, 0.644479118812606, -0.232087782696186, 0.524347954533703, -0.0102130829170658, 0.0183234311516924, -0.000777734182289533, -0.00061760930598137, 0.00435775176386732}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 36; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 5436 + for (unsigned int ip = 0; ip < 36; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + + // Total number of operations to compute function values = 40 + for (unsigned int r = 0; r < 10; r++) + { + F0 += FE1[ip][r]*w[0][r]; + F1 += FE1[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 3 + double I[1]; + // Number of operations: 3 + I[0] = F0*F1*W36[ip]*det; + + + // Number of operations for primary indices: 108 + for (unsigned int j = 0; j < 6; j++) + { + for (unsigned int k = 0; k < 6; k++) + { + // Number of operations to compute entry: 3 + A[j*6 + k] += FE0[ip][j]*FE0[ip][k]*I[0]; + }// 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 mass_matrix_f2_p3_q2_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p3_q2_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p3_q2_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1))), 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 mass_matrix_f2_p3_q2_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p3_q2_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p3_q2_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p3_q2_quadrature_finite_element_0(); + 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 mass_matrix_f2_p3_q2_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p3_q2_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p3_q2_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p3_q2_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f2_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/mass_matrix_2d/mass_matrix_f2_p3_q2_tensor.h b/mass_matrix_2d/mass_matrix_f2_p3_q2_tensor.h new file mode 100644 index 0000000..bf99c31 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p3_q2_tensor.h @@ -0,0 +1,5408 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P3_Q2_TENSOR_H +#define __MASS_MATRIX_F2_P3_Q2_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p3_q2_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p3_q2_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p3_q2_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p3_q2_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p3_q2_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p3_q2_tensor_finite_element_1() + { + // 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p3_q2_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p3_q2_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p3_q2_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_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.0*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 mass_matrix_f2_p3_q2_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p3_q2_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p3_q2_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_p3_q2_tensor_dofmap_1() + { + // 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 mass_matrix_f2_p3_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 mass_matrix_f2_p3_q2_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p3_q2_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 150 + // Number of operations (multiply-add pairs) for tensor contraction: 1810 + // Total number of operations (multiply-add pairs): 1969 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0 = det*w[0][0]*w[1][0]*(1.0); + const double G0_0_1 = det*w[0][0]*w[1][1]*(1.0); + const double G0_0_2 = det*w[0][0]*w[1][2]*(1.0); + const double G0_0_3 = det*w[0][0]*w[1][3]*(1.0); + const double G0_0_4 = det*w[0][0]*w[1][4]*(1.0); + const double G0_0_5 = det*w[0][0]*w[1][5]*(1.0); + const double G0_0_6 = det*w[0][0]*w[1][6]*(1.0); + const double G0_0_7 = det*w[0][0]*w[1][7]*(1.0); + const double G0_0_8 = det*w[0][0]*w[1][8]*(1.0); + const double G0_0_9 = det*w[0][0]*w[1][9]*(1.0); + const double G0_1_0 = det*w[0][1]*w[1][0]*(1.0); + const double G0_1_1 = det*w[0][1]*w[1][1]*(1.0); + const double G0_1_2 = det*w[0][1]*w[1][2]*(1.0); + const double G0_1_3 = det*w[0][1]*w[1][3]*(1.0); + const double G0_1_4 = det*w[0][1]*w[1][4]*(1.0); + const double G0_1_5 = det*w[0][1]*w[1][5]*(1.0); + const double G0_1_6 = det*w[0][1]*w[1][6]*(1.0); + const double G0_1_7 = det*w[0][1]*w[1][7]*(1.0); + const double G0_1_8 = det*w[0][1]*w[1][8]*(1.0); + const double G0_1_9 = det*w[0][1]*w[1][9]*(1.0); + const double G0_2_0 = det*w[0][2]*w[1][0]*(1.0); + const double G0_2_1 = det*w[0][2]*w[1][1]*(1.0); + const double G0_2_2 = det*w[0][2]*w[1][2]*(1.0); + const double G0_2_3 = det*w[0][2]*w[1][3]*(1.0); + const double G0_2_4 = det*w[0][2]*w[1][4]*(1.0); + const double G0_2_5 = det*w[0][2]*w[1][5]*(1.0); + const double G0_2_6 = det*w[0][2]*w[1][6]*(1.0); + const double G0_2_7 = det*w[0][2]*w[1][7]*(1.0); + const double G0_2_8 = det*w[0][2]*w[1][8]*(1.0); + const double G0_2_9 = det*w[0][2]*w[1][9]*(1.0); + const double G0_3_0 = det*w[0][3]*w[1][0]*(1.0); + const double G0_3_1 = det*w[0][3]*w[1][1]*(1.0); + const double G0_3_2 = det*w[0][3]*w[1][2]*(1.0); + const double G0_3_3 = det*w[0][3]*w[1][3]*(1.0); + const double G0_3_4 = det*w[0][3]*w[1][4]*(1.0); + const double G0_3_5 = det*w[0][3]*w[1][5]*(1.0); + const double G0_3_6 = det*w[0][3]*w[1][6]*(1.0); + const double G0_3_7 = det*w[0][3]*w[1][7]*(1.0); + const double G0_3_8 = det*w[0][3]*w[1][8]*(1.0); + const double G0_3_9 = det*w[0][3]*w[1][9]*(1.0); + const double G0_4_0 = det*w[0][4]*w[1][0]*(1.0); + const double G0_4_1 = det*w[0][4]*w[1][1]*(1.0); + const double G0_4_2 = det*w[0][4]*w[1][2]*(1.0); + const double G0_4_3 = det*w[0][4]*w[1][3]*(1.0); + const double G0_4_4 = det*w[0][4]*w[1][4]*(1.0); + const double G0_4_5 = det*w[0][4]*w[1][5]*(1.0); + const double G0_4_6 = det*w[0][4]*w[1][6]*(1.0); + const double G0_4_7 = det*w[0][4]*w[1][7]*(1.0); + const double G0_4_8 = det*w[0][4]*w[1][8]*(1.0); + const double G0_4_9 = det*w[0][4]*w[1][9]*(1.0); + const double G0_5_0 = det*w[0][5]*w[1][0]*(1.0); + const double G0_5_1 = det*w[0][5]*w[1][1]*(1.0); + const double G0_5_2 = det*w[0][5]*w[1][2]*(1.0); + const double G0_5_3 = det*w[0][5]*w[1][3]*(1.0); + const double G0_5_4 = det*w[0][5]*w[1][4]*(1.0); + const double G0_5_5 = det*w[0][5]*w[1][5]*(1.0); + const double G0_5_6 = det*w[0][5]*w[1][6]*(1.0); + const double G0_5_7 = det*w[0][5]*w[1][7]*(1.0); + const double G0_5_8 = det*w[0][5]*w[1][8]*(1.0); + const double G0_5_9 = det*w[0][5]*w[1][9]*(1.0); + const double G0_6_0 = det*w[0][6]*w[1][0]*(1.0); + const double G0_6_1 = det*w[0][6]*w[1][1]*(1.0); + const double G0_6_2 = det*w[0][6]*w[1][2]*(1.0); + const double G0_6_3 = det*w[0][6]*w[1][3]*(1.0); + const double G0_6_4 = det*w[0][6]*w[1][4]*(1.0); + const double G0_6_5 = det*w[0][6]*w[1][5]*(1.0); + const double G0_6_6 = det*w[0][6]*w[1][6]*(1.0); + const double G0_6_7 = det*w[0][6]*w[1][7]*(1.0); + const double G0_6_8 = det*w[0][6]*w[1][8]*(1.0); + const double G0_6_9 = det*w[0][6]*w[1][9]*(1.0); + const double G0_7_0 = det*w[0][7]*w[1][0]*(1.0); + const double G0_7_1 = det*w[0][7]*w[1][1]*(1.0); + const double G0_7_2 = det*w[0][7]*w[1][2]*(1.0); + const double G0_7_3 = det*w[0][7]*w[1][3]*(1.0); + const double G0_7_4 = det*w[0][7]*w[1][4]*(1.0); + const double G0_7_5 = det*w[0][7]*w[1][5]*(1.0); + const double G0_7_6 = det*w[0][7]*w[1][6]*(1.0); + const double G0_7_7 = det*w[0][7]*w[1][7]*(1.0); + const double G0_7_8 = det*w[0][7]*w[1][8]*(1.0); + const double G0_7_9 = det*w[0][7]*w[1][9]*(1.0); + const double G0_8_0 = det*w[0][8]*w[1][0]*(1.0); + const double G0_8_1 = det*w[0][8]*w[1][1]*(1.0); + const double G0_8_2 = det*w[0][8]*w[1][2]*(1.0); + const double G0_8_3 = det*w[0][8]*w[1][3]*(1.0); + const double G0_8_4 = det*w[0][8]*w[1][4]*(1.0); + const double G0_8_5 = det*w[0][8]*w[1][5]*(1.0); + const double G0_8_6 = det*w[0][8]*w[1][6]*(1.0); + const double G0_8_7 = det*w[0][8]*w[1][7]*(1.0); + const double G0_8_8 = det*w[0][8]*w[1][8]*(1.0); + const double G0_8_9 = det*w[0][8]*w[1][9]*(1.0); + const double G0_9_0 = det*w[0][9]*w[1][0]*(1.0); + const double G0_9_1 = det*w[0][9]*w[1][1]*(1.0); + const double G0_9_2 = det*w[0][9]*w[1][2]*(1.0); + const double G0_9_3 = det*w[0][9]*w[1][3]*(1.0); + const double G0_9_4 = det*w[0][9]*w[1][4]*(1.0); + const double G0_9_5 = det*w[0][9]*w[1][5]*(1.0); + const double G0_9_6 = det*w[0][9]*w[1][6]*(1.0); + const double G0_9_7 = det*w[0][9]*w[1][7]*(1.0); + const double G0_9_8 = det*w[0][9]*w[1][8]*(1.0); + const double G0_9_9 = det*w[0][9]*w[1][9]*(1.0); + + // Compute element tensor + A[9] = -3.60750360750367e-06*G0_0_0 + 4.3290043290045e-05*G0_0_1 + 2.34487734487743e-05*G0_0_2 + 0.000254329004329014*G0_0_3 - 0.000232683982683991*G0_0_4 + 5.41125541125559e-05*G0_0_5 - 9.19913419913452e-05*G0_0_6 - 3.78787878787894e-05*G0_0_7 + 0.000156926406926413*G0_0_8 + 3.24675324675339e-05*G0_0_9 + 4.3290043290045e-05*G0_1_0 + 0.00054112554112556*G0_1_1 + 6.49350649350672e-05*G0_1_2 + 0.000865800865800896*G0_1_3 - 0.000432900432900448*G0_1_4 - 2.16450216450225e-05*G0_1_5 - 8.65800865800897e-05*G0_1_6 - 0.000216450216450225*G0_1_7 + 0.000432900432900449*G0_1_8 + 2.34487734487743e-05*G0_2_0 + 6.49350649350672e-05*G0_2_1 - 5.41125541125559e-05*G0_2_2 + 0.000324675324675336*G0_2_3 - 0.000162337662337668*G0_2_4 - 3.24675324675336e-05*G0_2_5 - 0.000119047619047623*G0_2_7 + 0.000156926406926413*G0_2_8 + 0.000194805194805201*G0_2_9 + 0.000254329004329014*G0_3_0 + 0.000865800865800896*G0_3_1 + 0.000324675324675336*G0_3_2 + 0.00438311688311704*G0_3_3 - 0.000876623376623407*G0_3_4 - 0.000292207792207803*G0_3_5 + 0.000146103896103901*G0_3_6 - 0.000876623376623409*G0_3_7 + 0.00146103896103901*G0_3_8 + 0.00175324675324682*G0_3_9 - 0.000232683982683991*G0_4_0 - 0.000432900432900448*G0_4_1 - 0.000162337662337668*G0_4_2 - 0.000876623376623408*G0_4_3 - 0.00175324675324681*G0_4_4 + 0.000584415584415605*G0_4_5 - 0.000730519480519506*G0_4_6 + 0.000584415584415606*G0_4_7 - 0.000584415584415606*G0_4_8 - 0.00175324675324681*G0_4_9 + 5.41125541125559e-05*G0_5_0 - 2.16450216450225e-05*G0_5_1 - 3.24675324675336e-05*G0_5_2 - 0.000292207792207803*G0_5_3 + 0.000584415584415605*G0_5_4 - 0.000389610389610403*G0_5_5 + 0.000340909090909103*G0_5_6 - 0.000194805194805201*G0_5_7 - 4.87012987013007e-05*G0_5_8 - 9.19913419913452e-05*G0_6_0 - 8.65800865800897e-05*G0_6_1 + 0.000146103896103901*G0_6_3 - 0.000730519480519506*G0_6_4 + 0.000340909090909103*G0_6_5 - 0.000681818181818206*G0_6_6 + 0.000243506493506502*G0_6_7 - 4.87012987013008e-05*G0_6_8 - 0.000876623376623407*G0_6_9 - 3.78787878787894e-05*G0_7_0 - 0.000216450216450225*G0_7_1 - 0.000119047619047623*G0_7_2 - 0.000876623376623409*G0_7_3 + 0.000584415584415606*G0_7_4 - 0.000194805194805201*G0_7_5 + 0.000243506493506502*G0_7_6 - 0.000584415584415606*G0_7_8 - 0.000584415584415606*G0_7_9 + 0.000156926406926413*G0_8_0 + 0.000432900432900449*G0_8_1 + 0.000156926406926413*G0_8_2 + 0.00146103896103901*G0_8_3 - 0.000584415584415606*G0_8_4 - 4.87012987013007e-05*G0_8_5 - 4.87012987013008e-05*G0_8_6 - 0.000584415584415606*G0_8_7 + 0.00146103896103901*G0_8_8 + 0.00116883116883121*G0_8_9 + 3.24675324675339e-05*G0_9_0 + 0.000194805194805201*G0_9_2 + 0.00175324675324682*G0_9_3 - 0.00175324675324681*G0_9_4 - 0.000876623376623407*G0_9_6 - 0.000584415584415605*G0_9_7 + 0.00116883116883121*G0_9_8 - 0.00350649350649362*G0_9_9; + A[18] = A[9] - 4.14862914862931e-05*G0_0_1 - 2.16450216450224e-05*G0_0_2 - 0.000346320346320359*G0_0_3 + 0.000140692640692646*G0_0_4 + 5.41125541125562e-05*G0_0_5 + 5.4112554112556e-06*G0_0_6 + 0.000146103896103901*G0_0_7 - 0.000243506493506502*G0_0_8 - 0.000292207792207803*G0_0_9 - 4.14862914862931e-05*G0_1_0 - 0.000595238095238116*G0_1_1 - 6.67388167388191e-05*G0_1_2 - 0.00081168831168834*G0_1_3 + 0.000389610389610403*G0_1_4 + 5.95238095238117e-05*G0_1_5 - 5.41125541125545e-06*G0_1_6 + 0.000248917748917758*G0_1_7 - 0.000432900432900449*G0_1_8 + 6.49350649350666e-05*G0_1_9 - 2.16450216450224e-05*G0_2_0 - 6.67388167388191e-05*G0_2_1 - 0.000367965367965381*G0_2_3 + 0.000216450216450224*G0_2_4 + 6.49350649350673e-05*G0_2_5 + 0.000156926406926413*G0_2_7 - 0.000248917748917758*G0_2_8 - 0.000129870129870134*G0_2_9 - 0.000346320346320359*G0_3_0 - 0.00081168831168834*G0_3_1 - 0.000367965367965381*G0_3_2 - 0.00569805194805215*G0_3_3 + 0.00131493506493511*G0_3_4 + 0.000340909090909103*G0_3_5 + 0.000194805194805202*G0_3_6 + 0.00121753246753251*G0_3_7 - 0.00214285714285722*G0_3_8 - 0.00262987012987022*G0_3_9 + 0.000140692640692646*G0_4_0 + 0.000389610389610403*G0_4_1 + 0.000216450216450224*G0_4_2 + 0.00131493506493511*G0_4_3 + 0.000438311688311704*G0_4_4 - 0.000243506493506503*G0_4_5 + 4.87012987013004e-05*G0_4_6 - 0.000535714285714305*G0_4_7 + 0.000925324675324709*G0_4_8 + 0.000876623376623407*G0_4_9 + 5.41125541125562e-05*G0_5_0 + 5.95238095238117e-05*G0_5_1 + 6.49350649350673e-05*G0_5_2 + 0.000340909090909103*G0_5_3 - 0.000243506493506502*G0_5_4 + 0.000535714285714304*G0_5_5 - 0.000194805194805202*G0_5_6 + 0.000292207792207802*G0_5_7 + 0.000876623376623407*G0_5_9 + 5.41125541125559e-06*G0_6_0 - 5.41125541125547e-06*G0_6_1 + 0.000194805194805202*G0_6_3 + 4.87012987013004e-05*G0_6_4 - 0.000194805194805202*G0_6_5 - 4.87012987013005e-05*G0_6_6 - 0.000292207792207803*G0_6_7 + 0.000292207792207803*G0_6_8 + 0.000146103896103901*G0_7_0 + 0.000248917748917759*G0_7_1 + 0.000156926406926413*G0_7_2 + 0.00121753246753251*G0_7_3 - 0.000535714285714305*G0_7_4 + 0.000292207792207802*G0_7_5 - 0.000292207792207803*G0_7_6 + 0.000146103896103901*G0_7_7 + 0.000730519480519507*G0_7_8 + 0.00146103896103901*G0_7_9 - 0.000243506493506502*G0_8_0 - 0.000432900432900449*G0_8_1 - 0.000248917748917758*G0_8_2 - 0.00214285714285722*G0_8_3 + 0.000925324675324709*G0_8_4 + 0.000292207792207803*G0_8_6 + 0.000730519480519507*G0_8_7 - 0.00219155844155852*G0_8_8 - 0.00204545454545462*G0_8_9 - 0.000292207792207803*G0_9_0 + 6.49350649350666e-05*G0_9_1 - 0.000129870129870134*G0_9_2 - 0.00262987012987022*G0_9_3 + 0.000876623376623407*G0_9_4 + 0.000876623376623408*G0_9_5 + 0.00146103896103901*G0_9_7 - 0.00204545454545462*G0_9_8 - 0.00175324675324681*G0_9_9; + A[20] = A[9] - 1.98412698412707e-05*G0_0_1 + 1.98412698412705e-05*G0_0_2 - 0.000487012987013005*G0_0_3 + 0.000487012987013004*G0_0_4 - 9.19913419913451e-05*G0_0_5 + 0.000248917748917758*G0_0_6 + 9.19913419913454e-05*G0_0_7 - 0.000248917748917758*G0_0_8 - 1.98412698412707e-05*G0_1_0 - 0.000595238095238116*G0_1_1 - 0.00102813852813856*G0_1_3 + 0.000757575757575784*G0_1_4 - 9.74025974026007e-05*G0_1_5 + 0.000243506493506502*G0_1_6 + 0.000183982683982691*G0_1_7 - 0.000432900432900449*G0_1_8 + 0.000194805194805201*G0_1_9 + 1.98412698412705e-05*G0_2_0 + 0.000595238095238115*G0_2_2 - 0.000757575757575784*G0_2_3 + 0.00102813852813856*G0_2_4 - 0.000183982683982691*G0_2_5 + 0.000432900432900448*G0_2_6 + 9.74025974026007e-05*G0_2_7 - 0.000243506493506502*G0_2_8 - 0.000194805194805201*G0_2_9 - 0.000487012987013005*G0_3_0 - 0.00102813852813856*G0_3_1 - 0.000757575757575784*G0_3_2 - 0.00613636363636385*G0_3_3 + 0.000876623376623408*G0_3_5 - 0.000730519480519506*G0_3_6 + 0.00146103896103901*G0_3_7 - 0.00219155844155852*G0_3_8 - 0.00350649350649363*G0_3_9 + 0.000487012987013004*G0_4_0 + 0.000757575757575784*G0_4_1 + 0.00102813852813856*G0_4_2 + 0.00613636363636385*G0_4_4 - 0.00146103896103901*G0_4_5 + 0.00219155844155852*G0_4_6 - 0.000876623376623408*G0_4_7 + 0.000730519480519508*G0_4_8 + 0.00350649350649363*G0_4_9 - 9.19913419913451e-05*G0_5_0 - 9.74025974026007e-05*G0_5_1 - 0.000183982683982691*G0_5_2 + 0.000876623376623408*G0_5_3 - 0.00146103896103901*G0_5_4 + 0.000389610389610403*G0_5_5 - 0.000925324675324708*G0_5_6 + 0.000292207792207803*G0_5_8 - 0.000584415584415604*G0_5_9 + 0.000248917748917758*G0_6_0 + 0.000243506493506502*G0_6_1 + 0.000432900432900448*G0_6_2 - 0.000730519480519506*G0_6_3 + 0.00219155844155852*G0_6_4 - 0.000925324675324708*G0_6_5 + 0.00214285714285722*G0_6_6 - 0.000292207792207803*G0_6_7 + 0.00204545454545462*G0_6_9 + 9.19913419913454e-05*G0_7_0 + 0.000183982683982691*G0_7_1 + 9.74025974026007e-05*G0_7_2 + 0.00146103896103901*G0_7_3 - 0.000876623376623408*G0_7_4 - 0.000292207792207803*G0_7_6 - 0.000389610389610404*G0_7_7 + 0.000925324675324709*G0_7_8 + 0.000584415584415605*G0_7_9 - 0.000248917748917758*G0_8_0 - 0.000432900432900449*G0_8_1 - 0.000243506493506502*G0_8_2 - 0.00219155844155852*G0_8_3 + 0.000730519480519508*G0_8_4 + 0.000292207792207803*G0_8_5 + 0.000925324675324709*G0_8_7 - 0.00214285714285722*G0_8_8 - 0.00204545454545462*G0_8_9 + 0.000194805194805201*G0_9_1 - 0.000194805194805201*G0_9_2 - 0.00350649350649363*G0_9_3 + 0.00350649350649363*G0_9_4 - 0.000584415584415604*G0_9_5 + 0.00204545454545462*G0_9_6 + 0.000584415584415605*G0_9_7 - 0.00204545454545462*G0_9_8; + A[31] = A[9] - 5.05050505050523e-05*G0_0_0 + 2.16450216450225e-05*G0_0_1 - 9.74025974026011e-05*G0_0_3 + 0.000113636363636368*G0_0_4 - 5.4112554112556e-05*G0_0_5 + 5.95238095238116e-05*G0_0_6 - 0.000124458874458879*G0_0_7 + 0.000167748917748923*G0_0_8 + 0.000162337662337668*G0_0_9 + 2.16450216450225e-05*G0_1_0 - 2.16450216450223e-05*G0_1_2 - 0.000432900432900446*G0_1_3 + 0.000216450216450223*G0_1_4 - 6.49350649350672e-05*G0_1_5 + 6.49350649350672e-05*G0_1_6 - 0.000216450216450225*G0_1_7 + 0.000432900432900449*G0_1_8 - 2.16450216450223e-05*G0_2_1 + 5.05050505050522e-05*G0_2_2 - 0.000167748917748924*G0_2_3 + 0.000124458874458879*G0_2_4 - 5.95238095238116e-05*G0_2_5 + 5.4112554112556e-05*G0_2_6 - 0.000113636363636368*G0_2_7 + 9.74025974026006e-05*G0_2_8 - 0.000162337662337668*G0_2_9 - 9.74025974026011e-05*G0_3_0 - 0.000432900432900446*G0_3_1 - 0.000167748917748924*G0_3_2 - 0.00292207792207802*G0_3_3 + 0.000292207792207801*G0_3_4 + 0.000243506493506502*G0_3_5 - 0.000194805194805202*G0_3_6 + 0.000292207792207804*G0_3_7 - 0.000584415584415606*G0_3_9 + 0.000113636363636368*G0_4_0 + 0.000216450216450223*G0_4_1 + 0.000124458874458879*G0_4_2 + 0.000292207792207802*G0_4_3 + 0.00175324675324681*G0_4_4 - 0.000340909090909103*G0_4_5 + 0.000535714285714304*G0_4_6 - 0.000292207792207802*G0_4_8 + 0.00116883116883121*G0_4_9 - 5.4112554112556e-05*G0_5_0 - 6.49350649350672e-05*G0_5_1 - 5.95238095238116e-05*G0_5_2 + 0.000243506493506502*G0_5_3 - 0.000340909090909103*G0_5_4 - 0.000292207792207802*G0_5_5 - 0.000535714285714304*G0_5_7 + 0.000194805194805201*G0_5_8 - 0.000876623376623406*G0_5_9 + 5.95238095238116e-05*G0_6_0 + 6.49350649350672e-05*G0_6_1 + 5.4112554112556e-05*G0_6_2 - 0.000194805194805202*G0_6_3 + 0.000535714285714304*G0_6_4 + 0.000292207792207802*G0_6_6 + 0.000340909090909103*G0_6_7 - 0.000243506493506502*G0_6_8 + 0.000876623376623407*G0_6_9 - 0.000124458874458879*G0_7_0 - 0.000216450216450225*G0_7_1 - 0.000113636363636368*G0_7_2 + 0.000292207792207804*G0_7_3 - 0.000535714285714304*G0_7_5 + 0.000340909090909103*G0_7_6 - 0.00175324675324681*G0_7_7 - 0.000292207792207803*G0_7_8 - 0.00116883116883121*G0_7_9 + 0.000167748917748923*G0_8_0 + 0.000432900432900449*G0_8_1 + 9.74025974026006e-05*G0_8_2 - 0.000292207792207802*G0_8_4 + 0.000194805194805201*G0_8_5 - 0.000243506493506502*G0_8_6 - 0.000292207792207803*G0_8_7 + 0.00292207792207802*G0_8_8 + 0.000584415584415605*G0_8_9 + 0.000162337662337668*G0_9_0 - 0.000162337662337668*G0_9_2 - 0.000584415584415606*G0_9_3 + 0.00116883116883121*G0_9_4 - 0.000876623376623406*G0_9_5 + 0.000876623376623407*G0_9_6 - 0.00116883116883121*G0_9_7 + 0.000584415584415605*G0_9_8; + A[3] = A[18]; + A[17] = A[18] - 5.41125541125561e-05*G0_0_0 + 0.000129870129870134*G0_0_4 - 0.000108225108225112*G0_0_5 + 0.000119047619047623*G0_0_6 - 5.41125541125561e-05*G0_0_7 + 4.32900432900449e-05*G0_0_8 + 0.000324675324675336*G0_0_9 - 5.41125541125559e-05*G0_1_3 + 7.57575757575784e-05*G0_1_4 - 0.000129870129870134*G0_1_5 + 0.000129870129870134*G0_1_6 - 7.57575757575784e-05*G0_1_7 + 5.4112554112556e-05*G0_1_8 + 5.41125541125561e-05*G0_2_2 - 4.32900432900448e-05*G0_2_3 + 5.41125541125562e-05*G0_2_4 - 0.000119047619047623*G0_2_5 + 0.000108225108225112*G0_2_6 - 0.000129870129870134*G0_2_7 - 0.000324675324675336*G0_2_9 - 5.4112554112556e-05*G0_3_1 - 4.32900432900448e-05*G0_3_2 + 0.000584415584415605*G0_3_3 - 0.000292207792207803*G0_3_4 + 0.000194805194805202*G0_3_5 - 0.000389610389610403*G0_3_6 + 0.000129870129870134*G0_4_0 + 7.57575757575784e-05*G0_4_1 + 5.41125541125562e-05*G0_4_2 - 0.000292207792207803*G0_4_3 + 0.00146103896103901*G0_4_4 - 0.000389610389610403*G0_4_5 + 0.000779220779220806*G0_4_6 + 0.00175324675324681*G0_4_9 - 0.000108225108225112*G0_5_0 - 0.000129870129870134*G0_5_1 - 0.000119047619047623*G0_5_2 + 0.000194805194805202*G0_5_3 - 0.000389610389610403*G0_5_4 - 0.000876623376623406*G0_5_5 - 0.000779220779220806*G0_5_7 + 0.000389610389610403*G0_5_8 - 0.00175324675324681*G0_5_9 + 0.000119047619047623*G0_6_0 + 0.000129870129870134*G0_6_1 + 0.000108225108225112*G0_6_2 - 0.000389610389610403*G0_6_3 + 0.000779220779220806*G0_6_4 + 0.000876623376623407*G0_6_6 + 0.000389610389610403*G0_6_7 - 0.000194805194805201*G0_6_8 + 0.00175324675324681*G0_6_9 - 5.4112554112556e-05*G0_7_0 - 7.57575757575784e-05*G0_7_1 - 0.000129870129870134*G0_7_2 - 0.000779220779220805*G0_7_5 + 0.000389610389610403*G0_7_6 - 0.00146103896103901*G0_7_7 + 0.000292207792207802*G0_7_8 - 0.00175324675324681*G0_7_9 + 4.32900432900449e-05*G0_8_0 + 5.4112554112556e-05*G0_8_1 + 0.000389610389610403*G0_8_5 - 0.000194805194805201*G0_8_6 + 0.000292207792207802*G0_8_7 - 0.000584415584415605*G0_8_8 + 0.000324675324675336*G0_9_0 - 0.000324675324675336*G0_9_2 + 0.00175324675324681*G0_9_4 - 0.00175324675324681*G0_9_5 + 0.00175324675324681*G0_9_6 - 0.00175324675324681*G0_9_7; + A[13] = -A[17] - 5.23088023088042e-05*G0_0_0 - 1.80375180375187e-05*G0_0_1 - 1.44300144300149e-05*G0_0_2 - 0.000120400432900437*G0_0_3 + 9.4696969696974e-06*G0_0_4 + 2.29978354978363e-05*G0_0_5 - 5.41125541125557e-06*G0_0_6 + 7.71103896103924e-05*G0_0_7 - 8.11688311688341e-05*G0_0_8 - 1.62337662337669e-05*G0_0_9 - 1.80375180375187e-05*G0_1_0 - 0.000189393939393946*G0_1_1 - 3.11147186147197e-05*G0_1_2 - 0.000162337662337668*G0_1_3 + 4.87012987013006e-05*G0_1_4 - 4.73484848484865e-05*G0_1_5 - 2.70562770562773e-06*G0_1_6 + 2.70562770562784e-05*G0_1_7 - 5.41125541125566e-05*G0_1_8 + 3.24675324675333e-05*G0_1_9 - 1.44300144300149e-05*G0_2_0 - 3.11147186147197e-05*G0_2_1 - 0.00013528138528139*G0_2_2 - 7.03463203463229e-05*G0_2_3 - 5.41125541125557e-05*G0_2_4 - 1.62337662337668e-05*G0_2_5 - 4.73484848484864e-05*G0_2_7 - 0.000132575757575762*G0_2_8 - 0.000292207792207802*G0_2_9 - 0.000120400432900437*G0_3_0 - 0.000162337662337668*G0_3_1 - 7.03463203463229e-05*G0_3_2 - 0.00171672077922084*G0_3_3 + 0.000693993506493531*G0_3_4 + 0.000182629870129877*G0_3_5 + 0.000146103896103901*G0_3_6 + 0.00049918831168833*G0_3_7 - 0.00103490259740263*G0_3_8 - 0.00109577922077926*G0_3_9 + 9.46969696969742e-06*G0_4_0 + 4.87012987013006e-05*G0_4_1 - 5.41125541125557e-05*G0_4_2 + 0.000693993506493531*G0_4_3 - 0.000840097402597432*G0_4_4 + 0.000109577922077926*G0_4_5 - 0.000255681818181827*G0_4_6 - 1.21753246753253e-05*G0_4_7 + 0.000535714285714304*G0_4_8 + 0.000657467532467555*G0_4_9 + 2.29978354978363e-05*G0_5_0 - 4.73484848484865e-05*G0_5_1 - 1.62337662337668e-05*G0_5_2 + 0.000182629870129877*G0_5_3 + 0.000109577922077926*G0_5_4 - 0.000596590909090929*G0_5_5 + 0.000243506493506502*G0_5_6 - 0.000560064935064954*G0_5_7 + 0.000280032467532477*G0_5_8 - 0.000511363636363654*G0_5_9 - 5.41125541125557e-06*G0_6_0 - 2.70562770562773e-06*G0_6_1 + 0.000146103896103901*G0_6_3 - 0.000255681818181827*G0_6_4 + 0.000243506493506502*G0_6_5 - 0.000231331168831177*G0_6_6 + 0.000280032467532477*G0_6_7 + 0.000133928571428576*G0_6_8 + 0.000584415584415605*G0_6_9 + 7.71103896103924e-05*G0_7_0 + 2.70562770562784e-05*G0_7_1 - 4.73484848484864e-05*G0_7_2 + 0.00049918831168833*G0_7_3 - 1.21753246753252e-05*G0_7_4 - 0.000560064935064954*G0_7_5 + 0.000280032467532477*G0_7_6 - 0.00118100649350654*G0_7_7 + 0.000535714285714305*G0_7_8 - 0.000511363636363654*G0_7_9 - 8.11688311688341e-05*G0_8_0 - 5.41125541125566e-05*G0_8_1 - 0.000132575757575762*G0_8_2 - 0.00103490259740263*G0_8_3 + 0.000535714285714304*G0_8_4 + 0.000280032467532477*G0_8_5 + 0.000133928571428576*G0_8_6 + 0.000535714285714305*G0_8_7 - 0.00169237012987019*G0_8_8 - 0.00116883116883121*G0_8_9 - 1.62337662337669e-05*G0_9_0 + 3.24675324675333e-05*G0_9_1 - 0.000292207792207802*G0_9_2 - 0.00109577922077926*G0_9_3 + 0.000657467532467555*G0_9_4 - 0.000511363636363654*G0_9_5 + 0.000584415584415605*G0_9_6 - 0.000511363636363654*G0_9_7 - 0.00116883116883121*G0_9_8 - 0.00482142857142874*G0_9_9; + A[24] = A[9] + 0.000544733044733063*G0_0_0 + 4.14862914862928e-05*G0_0_2 - 0.000275974025974036*G0_0_3 + 0.000146103896103901*G0_0_4 + 0.000811688311688339*G0_0_5 - 0.000340909090909103*G0_0_6 + 0.000470779220779237*G0_0_7 - 0.000373376623376636*G0_0_8 - 3.2467532467534e-05*G0_0_9 - 0.000544733044733064*G0_1_1 - 4.1486291486293e-05*G0_1_2 - 0.00081168831168834*G0_1_3 + 0.000340909090909103*G0_1_4 + 0.000275974025974035*G0_1_5 - 0.000146103896103901*G0_1_6 + 0.000373376623376637*G0_1_7 - 0.000470779220779238*G0_1_8 + 3.24675324675331e-05*G0_1_9 + 4.14862914862928e-05*G0_2_0 - 4.1486291486293e-05*G0_2_1 - 0.00035714285714287*G0_2_3 + 0.000162337662337668*G0_2_4 + 0.000357142857142869*G0_2_5 - 0.000162337662337668*G0_2_6 + 0.000275974025974036*G0_2_7 - 0.000275974025974036*G0_2_8 - 0.000275974025974036*G0_3_0 - 0.00081168831168834*G0_3_1 - 0.00035714285714287*G0_3_2 - 0.00477272727272744*G0_3_3 + 0.00121753246753251*G0_3_4 + 0.000438311688311704*G0_3_6 + 0.000827922077922109*G0_3_7 - 0.00165584415584422*G0_3_8 - 0.00175324675324682*G0_3_9 + 0.000146103896103901*G0_4_0 + 0.000340909090909103*G0_4_1 + 0.000162337662337668*G0_4_2 + 0.00121753246753251*G0_4_3 + 0.00107142857142861*G0_4_4 - 0.000438311688311704*G0_4_5 - 0.000633116883116906*G0_4_7 + 0.000827922077922108*G0_4_8 + 0.000876623376623407*G0_4_9 + 0.000811688311688339*G0_5_0 + 0.000275974025974035*G0_5_1 + 0.000357142857142869*G0_5_2 - 0.000438311688311704*G0_5_4 + 0.00477272727272743*G0_5_5 - 0.00121753246753251*G0_5_6 + 0.00165584415584421*G0_5_7 - 0.000827922077922105*G0_5_8 + 0.00175324675324681*G0_5_9 - 0.000340909090909103*G0_6_0 - 0.000146103896103901*G0_6_1 - 0.000162337662337668*G0_6_2 + 0.000438311688311704*G0_6_3 - 0.00121753246753251*G0_6_5 - 0.00107142857142861*G0_6_6 - 0.000827922077922107*G0_6_7 + 0.000633116883116905*G0_6_8 - 0.000876623376623407*G0_6_9 + 0.000470779220779237*G0_7_0 + 0.000373376623376637*G0_7_1 + 0.000275974025974036*G0_7_2 + 0.000827922077922109*G0_7_3 - 0.000633116883116906*G0_7_4 + 0.00165584415584421*G0_7_5 - 0.000827922077922107*G0_7_6 + 0.00146103896103901*G0_7_7 + 0.00175324675324681*G0_7_9 - 0.000373376623376636*G0_8_0 - 0.000470779220779238*G0_8_1 - 0.000275974025974036*G0_8_2 - 0.00165584415584422*G0_8_3 + 0.000827922077922108*G0_8_4 - 0.000827922077922105*G0_8_5 + 0.000633116883116905*G0_8_6 - 0.00146103896103901*G0_8_8 - 0.00175324675324681*G0_8_9 - 3.2467532467534e-05*G0_9_0 + 3.24675324675331e-05*G0_9_1 - 0.00175324675324682*G0_9_3 + 0.000876623376623406*G0_9_4 + 0.00175324675324681*G0_9_5 - 0.000876623376623407*G0_9_6 + 0.00175324675324681*G0_9_7 - 0.00175324675324681*G0_9_8; + A[8] = A[13]; + A[11] = A[31]; + A[30] = A[17] + 0.000595238095238116*G0_0_0 + 6.6738816738819e-05*G0_0_1 + 4.14862914862929e-05*G0_0_2 + 5.41125541125555e-06*G0_0_3 - 5.95238095238116e-05*G0_0_4 + 0.000432900432900448*G0_0_5 - 0.000248917748917758*G0_0_6 + 0.00081168831168834*G0_0_7 - 0.000389610389610403*G0_0_8 - 6.49350649350672e-05*G0_0_9 + 6.67388167388191e-05*G0_1_0 + 2.16450216450224e-05*G0_1_2 - 6.49350649350672e-05*G0_1_4 + 0.000248917748917757*G0_1_5 - 0.000156926406926412*G0_1_6 + 0.00036796536796538*G0_1_7 - 0.000216450216450224*G0_1_8 + 0.000129870129870134*G0_1_9 + 4.14862914862929e-05*G0_2_0 + 2.16450216450224e-05*G0_2_1 - 5.41125541125549e-06*G0_2_3 - 5.41125541125562e-05*G0_2_4 + 0.000243506493506502*G0_2_5 - 0.000146103896103901*G0_2_6 + 0.000346320346320358*G0_2_7 - 0.000140692640692645*G0_2_8 + 0.000292207792207802*G0_2_9 + 5.41125541125552e-06*G0_3_0 - 5.41125541125553e-06*G0_3_2 + 4.87012987013006e-05*G0_3_3 + 0.000194805194805201*G0_3_4 - 0.000292207792207803*G0_3_5 + 0.000292207792207803*G0_3_6 - 0.000194805194805202*G0_3_7 - 4.87012987012998e-05*G0_3_8 - 5.95238095238116e-05*G0_4_0 - 6.49350649350672e-05*G0_4_1 - 5.41125541125562e-05*G0_4_2 + 0.000194805194805201*G0_4_3 - 0.000535714285714304*G0_4_4 - 0.000292207792207802*G0_4_6 - 0.000340909090909103*G0_4_7 + 0.000243506493506502*G0_4_8 - 0.000876623376623407*G0_4_9 + 0.000432900432900448*G0_5_0 + 0.000248917748917757*G0_5_1 + 0.000243506493506502*G0_5_2 - 0.000292207792207803*G0_5_3 + 0.00219155844155852*G0_5_5 - 0.000730519480519506*G0_5_6 + 0.00214285714285722*G0_5_7 - 0.000925324675324706*G0_5_8 + 0.00204545454545462*G0_5_9 - 0.000248917748917758*G0_6_0 - 0.000156926406926412*G0_6_1 - 0.000146103896103901*G0_6_2 + 0.000292207792207803*G0_6_3 - 0.000292207792207802*G0_6_4 - 0.000730519480519506*G0_6_5 - 0.000146103896103901*G0_6_6 - 0.00121753246753251*G0_6_7 + 0.000535714285714304*G0_6_8 - 0.00146103896103901*G0_6_9 + 0.00081168831168834*G0_7_0 + 0.00036796536796538*G0_7_1 + 0.000346320346320358*G0_7_2 - 0.000194805194805202*G0_7_3 - 0.000340909090909103*G0_7_4 + 0.00214285714285722*G0_7_5 - 0.00121753246753251*G0_7_6 + 0.00569805194805215*G0_7_7 - 0.00131493506493511*G0_7_8 + 0.00262987012987022*G0_7_9 - 0.000389610389610403*G0_8_0 - 0.000216450216450224*G0_8_1 - 0.000140692640692645*G0_8_2 - 4.87012987012998e-05*G0_8_3 + 0.000243506493506502*G0_8_4 - 0.000925324675324706*G0_8_5 + 0.000535714285714304*G0_8_6 - 0.00131493506493511*G0_8_7 - 0.000438311688311704*G0_8_8 - 0.000876623376623407*G0_8_9 - 6.49350649350672e-05*G0_9_0 + 0.000129870129870134*G0_9_1 + 0.000292207792207802*G0_9_2 - 0.000876623376623407*G0_9_4 + 0.00204545454545462*G0_9_5 - 0.00146103896103901*G0_9_6 + 0.00262987012987022*G0_9_7 - 0.000876623376623407*G0_9_8 + 0.00175324675324682*G0_9_9; + A[4] = A[24]; + A[25] = A[18] - 5.4112554112556e-05*G0_0_0 + 0.000129870129870135*G0_0_3 - 5.41125541125562e-05*G0_0_5 + 4.32900432900448e-05*G0_0_6 - 0.000108225108225112*G0_0_7 + 0.000119047619047623*G0_0_8 + 0.000324675324675336*G0_0_9 + 5.41125541125559e-05*G0_1_1 + 5.41125541125564e-05*G0_1_3 - 4.32900432900449e-05*G0_1_4 - 0.000129870129870134*G0_1_5 - 0.000119047619047623*G0_1_7 + 0.000108225108225112*G0_1_8 - 0.000324675324675336*G0_1_9 + 7.57575757575784e-05*G0_2_3 - 5.4112554112556e-05*G0_2_4 - 7.57575757575785e-05*G0_2_5 + 5.41125541125561e-05*G0_2_6 - 0.000129870129870134*G0_2_7 + 0.000129870129870134*G0_2_8 + 0.000129870129870135*G0_3_0 + 5.41125541125564e-05*G0_3_1 + 7.57575757575784e-05*G0_3_2 + 0.00146103896103901*G0_3_3 - 0.000292207792207803*G0_3_4 - 0.000389610389610403*G0_3_7 + 0.000779220779220806*G0_3_8 + 0.00175324675324681*G0_3_9 - 4.32900432900449e-05*G0_4_1 - 5.4112554112556e-05*G0_4_2 - 0.000292207792207803*G0_4_3 + 0.000584415584415604*G0_4_4 + 0.000194805194805202*G0_4_7 - 0.000389610389610403*G0_4_8 - 5.41125541125562e-05*G0_5_0 - 0.000129870129870134*G0_5_1 - 7.57575757575785e-05*G0_5_2 - 0.00146103896103901*G0_5_5 + 0.000292207792207803*G0_5_6 - 0.000779220779220806*G0_5_7 + 0.000389610389610403*G0_5_8 - 0.00175324675324681*G0_5_9 + 4.32900432900448e-05*G0_6_0 + 5.4112554112556e-05*G0_6_2 + 0.000292207792207803*G0_6_5 - 0.000584415584415604*G0_6_6 + 0.000389610389610404*G0_6_7 - 0.000194805194805202*G0_6_8 - 0.000108225108225112*G0_7_0 - 0.000119047619047623*G0_7_1 - 0.000129870129870134*G0_7_2 - 0.000389610389610403*G0_7_3 + 0.000194805194805202*G0_7_4 - 0.000779220779220806*G0_7_5 + 0.000389610389610404*G0_7_6 - 0.000876623376623407*G0_7_7 - 0.00175324675324681*G0_7_9 + 0.000119047619047623*G0_8_0 + 0.000108225108225112*G0_8_1 + 0.000129870129870134*G0_8_2 + 0.000779220779220806*G0_8_3 - 0.000389610389610403*G0_8_4 + 0.000389610389610403*G0_8_5 - 0.000194805194805202*G0_8_6 + 0.000876623376623407*G0_8_8 + 0.00175324675324681*G0_8_9 + 0.000324675324675336*G0_9_0 - 0.000324675324675336*G0_9_1 + 0.00175324675324681*G0_9_3 - 0.00175324675324681*G0_9_5 - 0.00175324675324681*G0_9_7 + 0.00175324675324681*G0_9_8; + A[34] = 0.000216450216450224*G0_0_0 + 0.000108225108225112*G0_0_3 + 0.000108225108225112*G0_0_4 - 0.000108225108225112*G0_0_5 + 2.16450216450225e-05*G0_0_6 - 0.000108225108225112*G0_0_7 + 2.16450216450225e-05*G0_0_8 - 0.000259740259740269*G0_0_9 + 0.000108225108225112*G0_1_1 - 7.21500721500743e-06*G0_1_2 - 0.000216450216450224*G0_1_3 + 0.000108225108225112*G0_1_4 + 0.00036796536796538*G0_1_5 + 0.000108225108225112*G0_1_6 + 0.000259740259740269*G0_1_7 - 0.000324675324675336*G0_1_8 + 0.000389610389610403*G0_1_9 - 7.21500721500743e-06*G0_2_1 + 0.000108225108225112*G0_2_2 + 0.000108225108225112*G0_2_3 - 0.000216450216450224*G0_2_4 + 0.000259740259740269*G0_2_5 - 0.000324675324675336*G0_2_6 + 0.000367965367965381*G0_2_7 + 0.000108225108225112*G0_2_8 + 0.000389610389610403*G0_2_9 + 0.000108225108225112*G0_3_0 - 0.000216450216450224*G0_3_1 + 0.000108225108225112*G0_3_2 + 0.00116883116883121*G0_3_3 - 0.000584415584415604*G0_3_4 - 0.000584415584415605*G0_3_5 - 0.000584415584415605*G0_3_6 - 0.000584415584415605*G0_3_7 + 0.00116883116883121*G0_3_8 + 0.000108225108225112*G0_4_0 + 0.000108225108225112*G0_4_1 - 0.000216450216450224*G0_4_2 - 0.000584415584415604*G0_4_3 + 0.00116883116883121*G0_4_4 - 0.000584415584415605*G0_4_5 + 0.00116883116883121*G0_4_6 - 0.000584415584415605*G0_4_7 - 0.000584415584415604*G0_4_8 - 0.000108225108225112*G0_5_0 + 0.00036796536796538*G0_5_1 + 0.000259740259740269*G0_5_2 - 0.000584415584415605*G0_5_3 - 0.000584415584415605*G0_5_4 + 0.00409090909090923*G0_5_5 - 0.00116883116883121*G0_5_6 + 0.00272727272727282*G0_5_7 - 0.00136363636363641*G0_5_8 + 0.00350649350649362*G0_5_9 + 2.16450216450225e-05*G0_6_0 + 0.000108225108225112*G0_6_1 - 0.000324675324675336*G0_6_2 - 0.000584415584415604*G0_6_3 + 0.00116883116883121*G0_6_4 - 0.00116883116883121*G0_6_5 + 0.00233766233766242*G0_6_6 - 0.00136363636363641*G0_6_7 - 0.000194805194805201*G0_6_8 - 0.000108225108225112*G0_7_0 + 0.000259740259740269*G0_7_1 + 0.000367965367965381*G0_7_2 - 0.000584415584415605*G0_7_3 - 0.000584415584415605*G0_7_4 + 0.00272727272727282*G0_7_5 - 0.00136363636363641*G0_7_6 + 0.00409090909090923*G0_7_7 - 0.00116883116883121*G0_7_8 + 0.00350649350649363*G0_7_9 + 2.16450216450225e-05*G0_8_0 - 0.000324675324675336*G0_8_1 + 0.000108225108225112*G0_8_2 + 0.00116883116883121*G0_8_3 - 0.000584415584415604*G0_8_4 - 0.00136363636363641*G0_8_5 - 0.000194805194805201*G0_8_6 - 0.00116883116883121*G0_8_7 + 0.00233766233766242*G0_8_8 - 0.000259740259740269*G0_9_0 + 0.000389610389610403*G0_9_1 + 0.000389610389610403*G0_9_2 + 0.00350649350649362*G0_9_5 + 0.00350649350649363*G0_9_7 + 0.0210389610389618*G0_9_9; + A[28] = A[34] + 0.000216450216450223*G0_0_0 - 2.16450216450224e-05*G0_0_1 + 0.000129870129870134*G0_0_2 - 4.3290043290045e-05*G0_0_3 + 0.000151515151515157*G0_0_4 - 0.000216450216450224*G0_0_5 - 0.000151515151515156*G0_0_6 + 6.49350649350671e-05*G0_0_8 - 0.000129870129870134*G0_0_9 - 2.16450216450224e-05*G0_1_0 + 7.93650793650821e-05*G0_1_1 - 1.44300144300149e-05*G0_1_2 - 0.000259740259740269*G0_1_3 + 0.000259740259740269*G0_1_4 + 0.000476190476190492*G0_1_5 + 0.000735930735930761*G0_1_6 + 0.000108225108225112*G0_1_7 - 0.000151515151515156*G0_1_8 + 0.00116883116883121*G0_1_9 + 0.000129870129870134*G0_2_0 - 1.44300144300149e-05*G0_2_1 + 0.000324675324675336*G0_2_2 - 2.16450216450225e-05*G0_2_3 + 0.000108225108225112*G0_2_4 - 0.000389610389610402*G0_2_5 - 0.000108225108225112*G0_2_7 - 4.32900432900449e-05*G0_2_8 - 0.000779220779220805*G0_2_9 - 4.3290043290045e-05*G0_3_0 - 0.000259740259740269*G0_3_1 - 2.16450216450225e-05*G0_3_2 + 0.000389610389610403*G0_3_3 - 0.000779220779220807*G0_3_4 - 0.000584415584415603*G0_3_5 - 0.00233766233766242*G0_3_6 - 0.00350649350649363*G0_3_9 + 0.000151515151515157*G0_4_0 + 0.000259740259740269*G0_4_1 + 0.000108225108225112*G0_4_2 - 0.000779220779220807*G0_4_3 + 0.00155844155844161*G0_4_4 - 0.000584415584415605*G0_4_5 + 0.00292207792207802*G0_4_6 + 0.00350649350649363*G0_4_9 - 0.000216450216450225*G0_5_0 + 0.000476190476190492*G0_5_1 - 0.000389610389610402*G0_5_2 - 0.000584415584415603*G0_5_3 - 0.000584415584415605*G0_5_4 + 0.0122727272727277*G0_5_5 + 0.00136363636363641*G0_5_7 - 0.00155844155844161*G0_5_8 + 0.00350649350649362*G0_5_9 - 0.000151515151515156*G0_6_0 + 0.000735930735930761*G0_6_1 - 0.00233766233766242*G0_6_3 + 0.00292207792207802*G0_6_4 + 0.0140259740259745*G0_6_6 + 0.000194805194805199*G0_6_7 - 0.000974025974026006*G0_6_8 + 0.00701298701298725*G0_6_9 + 0.000108225108225112*G0_7_1 - 0.000108225108225112*G0_7_2 + 0.00136363636363641*G0_7_5 + 0.000194805194805199*G0_7_6 - 0.00136363636363641*G0_7_7 - 0.000194805194805201*G0_7_8 + 6.49350649350671e-05*G0_8_0 - 0.000151515151515156*G0_8_1 - 4.32900432900449e-05*G0_8_2 - 0.00155844155844161*G0_8_5 - 0.000974025974026006*G0_8_6 - 0.000194805194805201*G0_8_7 - 0.000779220779220807*G0_8_8 - 0.00350649350649362*G0_8_9 - 0.000129870129870134*G0_9_0 + 0.00116883116883121*G0_9_1 - 0.000779220779220805*G0_9_2 - 0.00350649350649363*G0_9_3 + 0.00350649350649363*G0_9_4 + 0.00350649350649362*G0_9_5 + 0.00701298701298725*G0_9_6 - 0.00350649350649363*G0_9_8 + 0.00701298701298725*G0_9_9; + A[29] = A[34]; + A[10] = A[25]; + A[5] = A[30]; + A[26] = A[25] + 2.16450216450224e-05*G0_0_1 + 6.67388167388191e-05*G0_0_2 - 0.000156926406926412*G0_0_3 + 0.000248917748917757*G0_0_4 - 0.000216450216450224*G0_0_5 + 0.000367965367965381*G0_0_6 - 6.49350649350672e-05*G0_0_8 + 0.000129870129870134*G0_0_9 + 2.16450216450224e-05*G0_1_0 + 4.14862914862929e-05*G0_1_2 - 0.000146103896103901*G0_1_3 + 0.000243506493506502*G0_1_4 - 0.000140692640692646*G0_1_5 + 0.000346320346320358*G0_1_6 - 5.41125541125568e-06*G0_1_7 - 5.41125541125559e-05*G0_1_8 + 0.000292207792207802*G0_1_9 + 6.67388167388191e-05*G0_2_0 + 4.14862914862929e-05*G0_2_1 + 0.000595238095238116*G0_2_2 - 0.000248917748917758*G0_2_3 + 0.000432900432900448*G0_2_4 - 0.000389610389610403*G0_2_5 + 0.00081168831168834*G0_2_6 + 5.41125541125537e-06*G0_2_7 - 5.95238095238115e-05*G0_2_8 - 6.49350649350667e-05*G0_2_9 - 0.000156926406926412*G0_3_0 - 0.000146103896103901*G0_3_1 - 0.000248917748917758*G0_3_2 - 0.000146103896103901*G0_3_3 - 0.000730519480519506*G0_3_4 + 0.000535714285714305*G0_3_5 - 0.00121753246753251*G0_3_6 + 0.000292207792207803*G0_3_7 - 0.000292207792207802*G0_3_8 - 0.00146103896103901*G0_3_9 + 0.000248917748917757*G0_4_0 + 0.000243506493506502*G0_4_1 + 0.000432900432900448*G0_4_2 - 0.000730519480519506*G0_4_3 + 0.00219155844155852*G0_4_4 - 0.000925324675324708*G0_4_5 + 0.00214285714285722*G0_4_6 - 0.000292207792207803*G0_4_7 + 0.00204545454545462*G0_4_9 - 0.000216450216450224*G0_5_0 - 0.000140692640692646*G0_5_1 - 0.000389610389610403*G0_5_2 + 0.000535714285714305*G0_5_3 - 0.000925324675324708*G0_5_4 - 0.000438311688311702*G0_5_5 - 0.00131493506493511*G0_5_6 - 4.87012987012995e-05*G0_5_7 + 0.000243506493506502*G0_5_8 - 0.000876623376623407*G0_5_9 + 0.000367965367965381*G0_6_0 + 0.000346320346320358*G0_6_1 + 0.00081168831168834*G0_6_2 - 0.00121753246753251*G0_6_3 + 0.00214285714285722*G0_6_4 - 0.00131493506493511*G0_6_5 + 0.00569805194805215*G0_6_6 - 0.000194805194805203*G0_6_7 - 0.000340909090909102*G0_6_8 + 0.00262987012987022*G0_6_9 - 5.4112554112557e-06*G0_7_1 + 5.41125541125538e-06*G0_7_2 + 0.000292207792207803*G0_7_3 - 0.000292207792207803*G0_7_4 - 4.87012987012995e-05*G0_7_5 - 0.000194805194805203*G0_7_6 + 4.87012987013007e-05*G0_7_7 + 0.000194805194805202*G0_7_8 - 6.49350649350672e-05*G0_8_0 - 5.41125541125559e-05*G0_8_1 - 5.95238095238115e-05*G0_8_2 - 0.000292207792207802*G0_8_3 + 0.000243506493506502*G0_8_5 - 0.000340909090909102*G0_8_6 + 0.000194805194805202*G0_8_7 - 0.000535714285714304*G0_8_8 - 0.000876623376623406*G0_8_9 + 0.000129870129870134*G0_9_0 + 0.000292207792207802*G0_9_1 - 6.49350649350667e-05*G0_9_2 - 0.00146103896103901*G0_9_3 + 0.00204545454545462*G0_9_4 - 0.000876623376623407*G0_9_5 + 0.00262987012987022*G0_9_6 - 0.000876623376623406*G0_9_8 + 0.00175324675324681*G0_9_9; + A[6] = A[13] - 0.000137085137085142*G0_0_0 - 1.66847041847048e-05*G0_0_1 - 1.2175324675325e-05*G0_0_3 + 7.30519480519506e-05*G0_0_4 - 0.000131222943722948*G0_0_5 + 0.000108225108225112*G0_0_6 - 0.000185335497835504*G0_0_7 + 5.4112554112556e-05*G0_0_8 + 4.87012987013004e-05*G0_0_9 - 1.66847041847048e-05*G0_1_0 + 1.66847041847047e-05*G0_1_2 + 5.41125541125558e-05*G0_1_3 + 5.41125541125561e-05*G0_1_4 - 8.52272727272756e-05*G0_1_5 + 8.52272727272757e-05*G0_1_6 - 5.41125541125559e-05*G0_1_7 - 5.41125541125562e-05*G0_1_8 + 1.66847041847047e-05*G0_2_1 + 0.000137085137085142*G0_2_2 - 5.41125541125559e-05*G0_2_3 + 0.000185335497835504*G0_2_4 - 0.000108225108225112*G0_2_5 + 0.000131222943722948*G0_2_6 - 7.30519480519506e-05*G0_2_7 + 1.21753246753251e-05*G0_2_8 - 4.87012987013003e-05*G0_2_9 - 1.2175324675325e-05*G0_3_0 + 5.41125541125558e-05*G0_3_1 - 5.4112554112556e-05*G0_3_2 + 0.000608766233766255*G0_3_3 - 0.000450487012987029*G0_3_4 + 0.000146103896103901*G0_3_5 - 0.000255681818181827*G0_3_6 + 3.65259740259753e-05*G0_3_7 - 7.30519480519503e-05*G0_3_9 + 7.30519480519506e-05*G0_4_0 + 5.41125541125561e-05*G0_4_1 + 0.000185335497835504*G0_4_2 - 0.000450487012987029*G0_4_3 + 0.00112012987012991*G0_4_4 - 0.000219155844155852*G0_4_5 + 0.000474837662337679*G0_4_6 - 3.65259740259752e-05*G0_4_8 + 0.000584415584415604*G0_4_9 - 0.000131222943722948*G0_5_0 - 8.52272727272756e-05*G0_5_1 - 0.000108225108225112*G0_5_2 + 0.000146103896103901*G0_5_3 - 0.000219155844155852*G0_5_4 - 0.000511363636363654*G0_5_5 - 0.000474837662337678*G0_5_7 + 0.000255681818181827*G0_5_8 - 0.000657467532467555*G0_5_9 + 0.000108225108225112*G0_6_0 + 8.52272727272757e-05*G0_6_1 + 0.000131222943722948*G0_6_2 - 0.000255681818181827*G0_6_3 + 0.000474837662337679*G0_6_4 + 0.000511363636363654*G0_6_6 + 0.000219155844155852*G0_6_7 - 0.000146103896103901*G0_6_8 + 0.000657467532467555*G0_6_9 - 0.000185335497835504*G0_7_0 - 5.41125541125559e-05*G0_7_1 - 7.30519480519506e-05*G0_7_2 + 3.65259740259753e-05*G0_7_3 - 0.000474837662337678*G0_7_5 + 0.000219155844155852*G0_7_6 - 0.00112012987012991*G0_7_7 + 0.000450487012987029*G0_7_8 - 0.000584415584415605*G0_7_9 + 5.4112554112556e-05*G0_8_0 - 5.41125541125562e-05*G0_8_1 + 1.21753246753251e-05*G0_8_2 - 3.65259740259752e-05*G0_8_4 + 0.000255681818181827*G0_8_5 - 0.000146103896103901*G0_8_6 + 0.000450487012987029*G0_8_7 - 0.000608766233766255*G0_8_8 + 7.30519480519507e-05*G0_8_9 + 4.87012987013004e-05*G0_9_0 - 4.87012987013003e-05*G0_9_2 - 7.30519480519503e-05*G0_9_3 + 0.000584415584415604*G0_9_4 - 0.000657467532467555*G0_9_5 + 0.000657467532467555*G0_9_6 - 0.000584415584415605*G0_9_7 + 7.30519480519507e-05*G0_9_8; + A[1] = A[6]; + A[14] = A[6] + 0.000182178932178938*G0_0_0 + 5.5014430014432e-05*G0_0_1 + 0.000178571428571435*G0_0_2 - 2.29978354978362e-05*G0_0_3 + 0.000155573593073598*G0_0_4 + 1.35281385281376e-06*G0_0_5 + 0.000196158008658015*G0_0_6 + 0.000139339826839832*G0_0_7 - 1.48809523809528e-05*G0_0_8 + 0.000121753246753251*G0_0_9 + 5.5014430014432e-05*G0_1_0 + 0.000182178932178939*G0_1_1 + 0.000178571428571435*G0_1_2 + 1.35281385281423e-06*G0_1_3 + 0.000196158008658015*G0_1_4 - 2.29978354978365e-05*G0_1_5 + 0.000155573593073598*G0_1_6 - 1.48809523809533e-05*G0_1_7 + 0.000139339826839832*G0_1_8 + 0.000121753246753251*G0_1_9 + 0.000178571428571435*G0_2_0 + 0.000178571428571435*G0_2_1 + 0.00246031746031754*G0_2_2 - 0.000652056277056299*G0_2_3 + 0.00151920995671001*G0_2_4 - 0.0006520562770563*G0_2_5 + 0.00151920995671001*G0_2_6 + 1.35281385281317e-06*G0_2_7 + 1.35281385281418e-06*G0_2_8 + 0.00040584415584417*G0_2_9 - 2.29978354978362e-05*G0_3_0 + 1.35281385281421e-06*G0_3_1 - 0.000652056277056299*G0_3_2 + 0.00130275974025979*G0_3_3 - 0.00143668831168836*G0_3_4 + 0.000231331168831177*G0_3_5 - 0.000791396103896132*G0_3_6 - 0.000255681818181827*G0_3_7 + 0.000584415584415605*G0_3_8 + 0.000146103896103901*G0_3_9 + 0.000155573593073598*G0_4_0 + 0.000196158008658015*G0_4_1 + 0.00151920995671001*G0_4_2 - 0.00143668831168836*G0_4_3 + 0.00327516233766245*G0_4_4 - 0.000791396103896132*G0_4_5 + 0.00158279220779226*G0_4_6 - 7.30519480519511e-05*G0_4_7 - 0.000328733766233778*G0_4_8 + 0.000365259740259753*G0_4_9 + 1.35281385281371e-06*G0_5_0 - 2.29978354978365e-05*G0_5_1 - 0.0006520562770563*G0_5_2 + 0.000231331168831177*G0_5_3 - 0.000791396103896132*G0_5_4 + 0.00130275974025979*G0_5_5 - 0.00143668831168836*G0_5_6 + 0.000584415584415605*G0_5_7 - 0.000255681818181827*G0_5_8 + 0.000146103896103901*G0_5_9 + 0.000196158008658016*G0_6_0 + 0.000155573593073598*G0_6_1 + 0.00151920995671001*G0_6_2 - 0.000791396103896132*G0_6_3 + 0.00158279220779226*G0_6_4 - 0.00143668831168836*G0_6_5 + 0.00327516233766245*G0_6_6 - 0.000328733766233778*G0_6_7 - 7.30519480519503e-05*G0_6_8 + 0.000365259740259753*G0_6_9 + 0.000139339826839832*G0_7_0 - 1.48809523809533e-05*G0_7_1 + 1.35281385281317e-06*G0_7_2 - 0.000255681818181827*G0_7_3 - 7.30519480519511e-05*G0_7_4 + 0.000584415584415605*G0_7_5 - 0.000328733766233778*G0_7_6 + 0.00120535714285719*G0_7_7 - 0.000657467532467556*G0_7_8 + 0.000292207792207802*G0_7_9 - 1.48809523809528e-05*G0_8_0 + 0.000139339826839832*G0_8_1 + 1.35281385281418e-06*G0_8_2 + 0.000584415584415605*G0_8_3 - 0.000328733766233778*G0_8_4 - 0.000255681818181827*G0_8_5 - 7.30519480519503e-05*G0_8_6 - 0.000657467532467556*G0_8_7 + 0.00120535714285719*G0_8_8 + 0.000292207792207802*G0_8_9 + 0.000121753246753251*G0_9_0 + 0.000121753246753251*G0_9_1 + 0.00040584415584417*G0_9_2 + 0.000146103896103901*G0_9_3 + 0.000365259740259753*G0_9_4 + 0.000146103896103901*G0_9_5 + 0.000365259740259753*G0_9_6 + 0.000292207792207802*G0_9_7 + 0.000292207792207802*G0_9_8 + 0.00131493506493511*G0_9_9; + A[7] = A[14] + 0.000140241702741708*G0_0_1 - 0.000140241702741708*G0_0_2 + 0.000263798701298711*G0_0_3 - 0.000263798701298711*G0_0_4 + 8.38744588744618e-05*G0_0_5 - 0.000265151515151524*G0_0_6 - 8.38744588744622e-05*G0_0_7 + 0.000265151515151525*G0_0_8 + 0.000140241702741708*G0_1_0 + 0.00241522366522375*G0_1_1 + 0.00164908008658014*G0_1_3 - 0.000956439393939427*G0_1_4 + 3.65259740259748e-05*G0_1_5 - 0.000227272727272736*G0_1_6 - 0.000691287878787905*G0_1_7 + 0.00156520562770569*G0_1_8 + 0.000235389610389619*G0_1_9 - 0.000140241702741708*G0_2_0 - 0.00241522366522374*G0_2_2 + 0.000956439393939427*G0_2_3 - 0.00164908008658014*G0_2_4 + 0.000691287878787903*G0_2_5 - 0.00156520562770568*G0_2_6 - 3.65259740259749e-05*G0_2_7 + 0.000227272727272735*G0_2_8 - 0.000235389610389619*G0_2_9 + 0.000263798701298711*G0_3_0 + 0.00164908008658014*G0_3_1 + 0.000956439393939427*G0_3_2 + 0.00248376623376632*G0_3_3 - 0.000450487012987029*G0_3_5 + 0.000681818181818205*G0_3_6 - 0.000791396103896134*G0_3_7 + 0.00147321428571434*G0_3_8 + 0.000876623376623409*G0_3_9 - 0.000263798701298711*G0_4_0 - 0.000956439393939427*G0_4_1 - 0.00164908008658014*G0_4_2 - 0.00248376623376632*G0_4_4 + 0.000791396103896132*G0_4_5 - 0.00147321428571434*G0_4_6 + 0.00045048701298703*G0_4_7 - 0.000681818181818207*G0_4_8 - 0.000876623376623408*G0_4_9 + 8.38744588744618e-05*G0_5_0 + 3.65259740259748e-05*G0_5_1 + 0.000691287878787903*G0_5_2 - 0.000450487012987029*G0_5_3 + 0.000791396103896132*G0_5_4 - 0.000706168831168856*G0_5_5 + 0.00122970779220784*G0_5_6 - 0.000109577922077926*G0_5_8 + 0.000219155844155852*G0_5_9 - 0.000265151515151525*G0_6_0 - 0.000227272727272736*G0_6_1 - 0.00156520562770568*G0_6_2 + 0.000681818181818205*G0_6_3 - 0.00147321428571434*G0_6_4 + 0.00122970779220784*G0_6_5 - 0.00318993506493518*G0_6_6 + 0.000109577922077927*G0_6_7 - 0.000657467532467556*G0_6_9 - 8.38744588744622e-05*G0_7_0 - 0.000691287878787906*G0_7_1 - 3.65259740259749e-05*G0_7_2 - 0.000791396103896134*G0_7_3 + 0.00045048701298703*G0_7_4 + 0.000109577922077927*G0_7_6 + 0.000706168831168858*G0_7_7 - 0.00122970779220784*G0_7_8 - 0.000219155844155852*G0_7_9 + 0.000265151515151525*G0_8_0 + 0.00156520562770569*G0_8_1 + 0.000227272727272735*G0_8_2 + 0.00147321428571434*G0_8_3 - 0.000681818181818207*G0_8_4 - 0.000109577922077926*G0_8_5 - 0.00122970779220784*G0_8_7 + 0.00318993506493518*G0_8_8 + 0.000657467532467556*G0_8_9 + 0.000235389610389619*G0_9_1 - 0.000235389610389619*G0_9_2 + 0.000876623376623409*G0_9_3 - 0.000876623376623408*G0_9_4 + 0.000219155844155852*G0_9_5 - 0.000657467532467556*G0_9_6 - 0.000219155844155852*G0_9_7 + 0.000657467532467556*G0_9_8; + A[0] = A[14] + 0.00241522366522375*G0_0_0 + 0.000140241702741708*G0_0_1 + 3.65259740259749e-05*G0_0_3 - 0.000227272727272735*G0_0_4 + 0.00164908008658014*G0_0_5 - 0.000956439393939427*G0_0_6 + 0.00156520562770568*G0_0_7 - 0.000691287878787902*G0_0_8 + 0.000235389610389618*G0_0_9 + 0.000140241702741708*G0_1_0 - 0.000140241702741708*G0_1_2 + 8.38744588744618e-05*G0_1_3 - 0.000265151515151524*G0_1_4 + 0.00026379870129871*G0_1_5 - 0.00026379870129871*G0_1_6 + 0.000265151515151524*G0_1_7 - 8.38744588744618e-05*G0_1_8 - 0.000140241702741708*G0_2_1 - 0.00241522366522374*G0_2_2 + 0.000691287878787902*G0_2_3 - 0.00156520562770568*G0_2_4 + 0.000956439393939427*G0_2_5 - 0.00164908008658014*G0_2_6 + 0.000227272727272736*G0_2_7 - 3.65259740259755e-05*G0_2_8 - 0.000235389610389619*G0_2_9 + 3.65259740259749e-05*G0_3_0 + 8.38744588744618e-05*G0_3_1 + 0.000691287878787902*G0_3_2 - 0.000706168831168856*G0_3_3 + 0.00122970779220783*G0_3_4 - 0.000450487012987029*G0_3_5 + 0.000791396103896132*G0_3_6 - 0.000109577922077926*G0_3_7 + 0.000219155844155852*G0_3_9 - 0.000227272727272735*G0_4_0 - 0.000265151515151524*G0_4_1 - 0.00156520562770568*G0_4_2 + 0.00122970779220783*G0_4_3 - 0.00318993506493517*G0_4_4 + 0.000681818181818206*G0_4_5 - 0.00147321428571434*G0_4_6 + 0.000109577922077926*G0_4_8 - 0.000657467532467556*G0_4_9 + 0.00164908008658014*G0_5_0 + 0.00026379870129871*G0_5_1 + 0.000956439393939427*G0_5_2 - 0.000450487012987029*G0_5_3 + 0.000681818181818206*G0_5_4 + 0.00248376623376631*G0_5_5 + 0.00147321428571433*G0_5_7 - 0.00079139610389613*G0_5_8 + 0.000876623376623407*G0_5_9 - 0.000956439393939427*G0_6_0 - 0.00026379870129871*G0_6_1 - 0.00164908008658014*G0_6_2 + 0.000791396103896132*G0_6_3 - 0.00147321428571434*G0_6_4 - 0.00248376623376632*G0_6_6 - 0.000681818181818205*G0_6_7 + 0.000450487012987028*G0_6_8 - 0.000876623376623407*G0_6_9 + 0.00156520562770568*G0_7_0 + 0.000265151515151524*G0_7_1 + 0.000227272727272736*G0_7_2 - 0.000109577922077926*G0_7_3 + 0.00147321428571433*G0_7_5 - 0.000681818181818205*G0_7_6 + 0.00318993506493518*G0_7_7 - 0.00122970779220783*G0_7_8 + 0.000657467532467556*G0_7_9 - 0.000691287878787902*G0_8_0 - 8.38744588744617e-05*G0_8_1 - 3.65259740259755e-05*G0_8_2 + 0.000109577922077926*G0_8_4 - 0.00079139610389613*G0_8_5 + 0.000450487012987028*G0_8_6 - 0.00122970779220783*G0_8_7 + 0.000706168831168856*G0_8_8 - 0.000219155844155852*G0_8_9 + 0.000235389610389618*G0_9_0 - 0.000235389610389619*G0_9_2 + 0.000219155844155852*G0_9_3 - 0.000657467532467556*G0_9_4 + 0.000876623376623407*G0_9_5 - 0.000876623376623407*G0_9_6 + 0.000657467532467556*G0_9_7 - 0.000219155844155852*G0_9_8; + A[35] = A[34] + 0.000216450216450224*G0_0_0 + 0.000129870129870134*G0_0_1 - 2.16450216450223e-05*G0_0_2 + 0.000151515151515157*G0_0_3 - 4.32900432900449e-05*G0_0_4 + 6.49350649350671e-05*G0_0_6 - 0.000216450216450223*G0_0_7 - 0.000151515151515156*G0_0_8 - 0.000129870129870134*G0_0_9 + 0.000129870129870134*G0_1_0 + 0.000324675324675337*G0_1_1 - 1.44300144300149e-05*G0_1_2 + 0.000108225108225113*G0_1_3 - 2.16450216450228e-05*G0_1_4 - 0.000108225108225112*G0_1_5 - 4.32900432900448e-05*G0_1_6 - 0.000389610389610404*G0_1_7 - 0.000779220779220806*G0_1_9 - 2.16450216450224e-05*G0_2_0 - 1.44300144300149e-05*G0_2_1 + 7.93650793650821e-05*G0_2_2 + 0.000259740259740268*G0_2_3 - 0.000259740259740269*G0_2_4 + 0.000108225108225112*G0_2_5 - 0.000151515151515157*G0_2_6 + 0.000476190476190493*G0_2_7 + 0.000735930735930761*G0_2_8 + 0.00116883116883121*G0_2_9 + 0.000151515151515157*G0_3_0 + 0.000108225108225113*G0_3_1 + 0.000259740259740268*G0_3_2 + 0.00155844155844161*G0_3_3 - 0.000779220779220805*G0_3_4 - 0.000584415584415608*G0_3_7 + 0.00292207792207802*G0_3_8 + 0.00350649350649363*G0_3_9 - 4.32900432900449e-05*G0_4_0 - 2.16450216450228e-05*G0_4_1 - 0.000259740259740269*G0_4_2 - 0.000779220779220805*G0_4_3 + 0.000389610389610403*G0_4_4 - 0.000584415584415603*G0_4_7 - 0.00233766233766242*G0_4_8 - 0.00350649350649363*G0_4_9 - 0.000108225108225112*G0_5_1 + 0.000108225108225112*G0_5_2 - 0.00136363636363641*G0_5_5 - 0.000194805194805201*G0_5_6 + 0.00136363636363641*G0_5_7 + 0.000194805194805199*G0_5_8 + 6.49350649350671e-05*G0_6_0 - 4.32900432900448e-05*G0_6_1 - 0.000151515151515157*G0_6_2 - 0.000194805194805201*G0_6_5 - 0.000779220779220806*G0_6_6 - 0.00155844155844161*G0_6_7 - 0.000974025974026009*G0_6_8 - 0.00350649350649363*G0_6_9 - 0.000216450216450223*G0_7_0 - 0.000389610389610404*G0_7_1 + 0.000476190476190493*G0_7_2 - 0.000584415584415607*G0_7_3 - 0.000584415584415603*G0_7_4 + 0.00136363636363641*G0_7_5 - 0.00155844155844161*G0_7_6 + 0.0122727272727277*G0_7_7 + 0.00350649350649363*G0_7_9 - 0.000151515151515157*G0_8_0 + 0.000735930735930761*G0_8_2 + 0.00292207792207802*G0_8_3 - 0.00233766233766242*G0_8_4 + 0.000194805194805199*G0_8_5 - 0.000974025974026009*G0_8_6 + 0.0140259740259745*G0_8_8 + 0.00701298701298725*G0_8_9 - 0.000129870129870134*G0_9_0 - 0.000779220779220806*G0_9_1 + 0.00116883116883121*G0_9_2 + 0.00350649350649363*G0_9_3 - 0.00350649350649363*G0_9_4 - 0.00350649350649363*G0_9_6 + 0.00350649350649363*G0_9_7 + 0.00701298701298725*G0_9_8 + 0.00701298701298725*G0_9_9; + A[23] = A[34] - 0.000108225108225112*G0_0_0 + 0.000259740259740269*G0_0_3 - 0.000108225108225112*G0_0_5 + 8.65800865800894e-05*G0_0_6 - 0.000216450216450224*G0_0_7 + 0.000238095238095246*G0_0_8 + 0.000649350649350672*G0_0_9 + 0.000108225108225113*G0_1_1 + 0.000108225108225113*G0_1_3 - 8.65800865800899e-05*G0_1_4 - 0.000259740259740269*G0_1_5 - 0.000238095238095247*G0_1_7 + 0.000216450216450225*G0_1_8 - 0.000649350649350671*G0_1_9 + 0.000151515151515157*G0_2_3 - 0.000108225108225112*G0_2_4 - 0.000151515151515157*G0_2_5 + 0.000108225108225112*G0_2_6 - 0.000259740259740269*G0_2_7 + 0.000259740259740269*G0_2_8 + 0.000259740259740269*G0_3_0 + 0.000108225108225113*G0_3_1 + 0.000151515151515157*G0_3_2 + 0.00292207792207803*G0_3_3 - 0.000584415584415606*G0_3_4 - 0.000779220779220807*G0_3_7 + 0.00155844155844161*G0_3_8 + 0.00350649350649363*G0_3_9 - 8.65800865800899e-05*G0_4_1 - 0.000108225108225112*G0_4_2 - 0.000584415584415606*G0_4_3 + 0.00116883116883121*G0_4_4 + 0.000389610389610404*G0_4_7 - 0.000779220779220806*G0_4_8 - 0.000108225108225112*G0_5_0 - 0.000259740259740269*G0_5_1 - 0.000151515151515157*G0_5_2 - 0.00292207792207802*G0_5_5 + 0.000584415584415606*G0_5_6 - 0.00155844155844161*G0_5_7 + 0.000779220779220804*G0_5_8 - 0.00350649350649363*G0_5_9 + 8.65800865800894e-05*G0_6_0 + 0.000108225108225112*G0_6_2 + 0.000584415584415606*G0_6_5 - 0.00116883116883121*G0_6_6 + 0.000779220779220807*G0_6_7 - 0.000389610389610404*G0_6_8 - 0.000216450216450224*G0_7_0 - 0.000238095238095247*G0_7_1 - 0.000259740259740269*G0_7_2 - 0.000779220779220807*G0_7_3 + 0.000389610389610404*G0_7_4 - 0.00155844155844161*G0_7_5 + 0.000779220779220807*G0_7_6 - 0.00175324675324681*G0_7_7 - 0.00350649350649363*G0_7_9 + 0.000238095238095246*G0_8_0 + 0.000216450216450225*G0_8_1 + 0.000259740259740269*G0_8_2 + 0.00155844155844161*G0_8_3 - 0.000779220779220806*G0_8_4 + 0.000779220779220804*G0_8_5 - 0.000389610389610404*G0_8_6 + 0.00175324675324681*G0_8_8 + 0.00350649350649363*G0_8_9 + 0.000649350649350672*G0_9_0 - 0.000649350649350671*G0_9_1 + 0.00350649350649363*G0_9_3 - 0.00350649350649363*G0_9_5 - 0.00350649350649363*G0_9_7 + 0.00350649350649363*G0_9_8; + A[21] = A[23] + 7.93650793650822e-05*G0_0_0 - 2.16450216450224e-05*G0_0_1 - 1.44300144300149e-05*G0_0_2 + 0.000476190476190493*G0_0_3 + 0.000735930735930761*G0_0_4 - 0.000259740259740269*G0_0_5 + 0.000259740259740269*G0_0_6 - 0.000151515151515157*G0_0_7 + 0.000108225108225112*G0_0_8 + 0.00116883116883121*G0_0_9 - 2.16450216450224e-05*G0_1_0 + 0.000216450216450223*G0_1_1 + 0.000129870129870134*G0_1_2 - 0.000216450216450225*G0_1_3 - 0.000151515151515156*G0_1_4 - 4.32900432900449e-05*G0_1_5 + 0.000151515151515157*G0_1_6 + 6.4935064935067e-05*G0_1_7 - 0.000129870129870134*G0_1_9 - 1.44300144300149e-05*G0_2_0 + 0.000129870129870134*G0_2_1 + 0.000324675324675336*G0_2_2 - 0.000389610389610403*G0_2_3 - 2.16450216450225e-05*G0_2_5 + 0.000108225108225112*G0_2_6 - 4.32900432900451e-05*G0_2_7 - 0.000108225108225112*G0_2_8 - 0.000779220779220805*G0_2_9 + 0.000476190476190493*G0_3_0 - 0.000216450216450225*G0_3_1 - 0.000389610389610403*G0_3_2 + 0.0122727272727277*G0_3_3 - 0.000584415584415605*G0_3_5 - 0.000584415584415605*G0_3_6 - 0.00155844155844161*G0_3_7 + 0.00136363636363641*G0_3_8 + 0.00350649350649363*G0_3_9 + 0.000735930735930762*G0_4_0 - 0.000151515151515156*G0_4_1 + 0.0140259740259745*G0_4_4 - 0.00233766233766242*G0_4_5 + 0.00292207792207802*G0_4_6 - 0.000974025974026008*G0_4_7 + 0.000194805194805202*G0_4_8 + 0.00701298701298725*G0_4_9 - 0.000259740259740269*G0_5_0 - 4.32900432900449e-05*G0_5_1 - 2.16450216450225e-05*G0_5_2 - 0.000584415584415604*G0_5_3 - 0.00233766233766242*G0_5_4 + 0.000389610389610404*G0_5_5 - 0.000779220779220807*G0_5_6 - 0.00350649350649363*G0_5_9 + 0.000259740259740269*G0_6_0 + 0.000151515151515157*G0_6_1 + 0.000108225108225112*G0_6_2 - 0.000584415584415605*G0_6_3 + 0.00292207792207802*G0_6_4 - 0.000779220779220807*G0_6_5 + 0.00155844155844161*G0_6_6 + 0.00350649350649363*G0_6_9 - 0.000151515151515157*G0_7_0 + 6.4935064935067e-05*G0_7_1 - 4.32900432900451e-05*G0_7_2 - 0.00155844155844161*G0_7_3 - 0.000974025974026009*G0_7_4 - 0.000779220779220807*G0_7_7 - 0.000194805194805202*G0_7_8 - 0.00350649350649363*G0_7_9 + 0.000108225108225112*G0_8_0 - 0.000108225108225112*G0_8_2 + 0.00136363636363641*G0_8_3 + 0.000194805194805202*G0_8_4 - 0.000194805194805202*G0_8_7 - 0.00136363636363641*G0_8_8 + 0.00116883116883121*G0_9_0 - 0.000129870129870134*G0_9_1 - 0.000779220779220805*G0_9_2 + 0.00350649350649363*G0_9_3 + 0.00701298701298725*G0_9_4 - 0.00350649350649363*G0_9_5 + 0.00350649350649363*G0_9_6 - 0.00350649350649363*G0_9_7 + 0.00701298701298725*G0_9_9; + A[33] = A[23]; + A[19] = A[9]; + A[16] = A[26]; + A[27] = A[34] - 0.000108225108225112*G0_0_0 + 0.000259740259740269*G0_0_4 - 0.000216450216450224*G0_0_5 + 0.000238095238095246*G0_0_6 - 0.000108225108225112*G0_0_7 + 8.65800865800895e-05*G0_0_8 + 0.000649350649350672*G0_0_9 - 0.000108225108225112*G0_1_3 + 0.000151515151515157*G0_1_4 - 0.000259740259740269*G0_1_5 + 0.000259740259740269*G0_1_6 - 0.000151515151515157*G0_1_7 + 0.000108225108225112*G0_1_8 + 0.000108225108225112*G0_2_2 - 8.65800865800896e-05*G0_2_3 + 0.000108225108225112*G0_2_4 - 0.000238095238095246*G0_2_5 + 0.000216450216450224*G0_2_6 - 0.000259740259740269*G0_2_7 - 0.000649350649350671*G0_2_9 - 0.000108225108225112*G0_3_1 - 8.65800865800896e-05*G0_3_2 + 0.00116883116883121*G0_3_3 - 0.000584415584415605*G0_3_4 + 0.000389610389610404*G0_3_5 - 0.000779220779220806*G0_3_6 + 0.000259740259740269*G0_4_0 + 0.000151515151515157*G0_4_1 + 0.000108225108225112*G0_4_2 - 0.000584415584415605*G0_4_3 + 0.00292207792207802*G0_4_4 - 0.000779220779220806*G0_4_5 + 0.00155844155844161*G0_4_6 + 0.00350649350649363*G0_4_9 - 0.000216450216450224*G0_5_0 - 0.000259740259740269*G0_5_1 - 0.000238095238095246*G0_5_2 + 0.000389610389610404*G0_5_3 - 0.000779220779220806*G0_5_4 - 0.00175324675324681*G0_5_5 - 0.00155844155844161*G0_5_7 + 0.000779220779220805*G0_5_8 - 0.00350649350649363*G0_5_9 + 0.000238095238095246*G0_6_0 + 0.000259740259740269*G0_6_1 + 0.000216450216450224*G0_6_2 - 0.000779220779220807*G0_6_3 + 0.00155844155844161*G0_6_4 + 0.00175324675324682*G0_6_6 + 0.000779220779220807*G0_6_7 - 0.000389610389610403*G0_6_8 + 0.00350649350649363*G0_6_9 - 0.000108225108225112*G0_7_0 - 0.000151515151515157*G0_7_1 - 0.000259740259740269*G0_7_2 - 0.00155844155844161*G0_7_5 + 0.000779220779220807*G0_7_6 - 0.00292207792207802*G0_7_7 + 0.000584415584415604*G0_7_8 - 0.00350649350649363*G0_7_9 + 8.65800865800895e-05*G0_8_0 + 0.000108225108225112*G0_8_1 + 0.000779220779220805*G0_8_5 - 0.000389610389610403*G0_8_6 + 0.000584415584415604*G0_8_7 - 0.00116883116883121*G0_8_8 + 0.000649350649350672*G0_9_0 - 0.000649350649350671*G0_9_2 + 0.00350649350649363*G0_9_4 - 0.00350649350649363*G0_9_5 + 0.00350649350649363*G0_9_6 - 0.00350649350649363*G0_9_7; + A[22] = A[27]; + A[15] = A[20]; + A[32] = A[17]; + A[2] = A[13] - 0.000137085137085142*G0_0_0 - 1.66847041847048e-05*G0_0_2 + 7.30519480519507e-05*G0_0_3 - 1.21753246753252e-05*G0_0_4 - 0.000185335497835504*G0_0_5 + 5.41125541125559e-05*G0_0_6 - 0.000131222943722948*G0_0_7 + 0.000108225108225112*G0_0_8 + 4.87012987013005e-05*G0_0_9 + 0.000137085137085142*G0_1_1 + 1.66847041847048e-05*G0_1_2 + 0.000185335497835504*G0_1_3 - 5.41125541125561e-05*G0_1_4 - 7.30519480519506e-05*G0_1_5 + 1.21753246753251e-05*G0_1_6 - 0.000108225108225112*G0_1_7 + 0.000131222943722949*G0_1_8 - 4.87012987013002e-05*G0_1_9 - 1.66847041847048e-05*G0_2_0 + 1.66847041847048e-05*G0_2_1 + 5.41125541125561e-05*G0_2_3 + 5.41125541125558e-05*G0_2_4 - 5.41125541125559e-05*G0_2_5 - 5.41125541125561e-05*G0_2_6 - 8.52272727272757e-05*G0_2_7 + 8.52272727272757e-05*G0_2_8 + 7.30519480519507e-05*G0_3_0 + 0.000185335497835504*G0_3_1 + 5.41125541125561e-05*G0_3_2 + 0.00112012987012991*G0_3_3 - 0.000450487012987029*G0_3_4 - 3.65259740259753e-05*G0_3_6 - 0.000219155844155852*G0_3_7 + 0.000474837662337679*G0_3_8 + 0.000584415584415605*G0_3_9 - 1.21753246753252e-05*G0_4_0 - 5.41125541125561e-05*G0_4_1 + 5.41125541125558e-05*G0_4_2 - 0.000450487012987029*G0_4_3 + 0.000608766233766255*G0_4_4 + 3.65259740259754e-05*G0_4_5 + 0.000146103896103901*G0_4_7 - 0.000255681818181827*G0_4_8 - 7.30519480519506e-05*G0_4_9 - 0.000185335497835504*G0_5_0 - 7.30519480519506e-05*G0_5_1 - 5.41125541125559e-05*G0_5_2 + 3.65259740259754e-05*G0_5_4 - 0.00112012987012991*G0_5_5 + 0.000450487012987029*G0_5_6 - 0.000474837662337678*G0_5_7 + 0.000219155844155851*G0_5_8 - 0.000584415584415604*G0_5_9 + 5.41125541125559e-05*G0_6_0 + 1.21753246753251e-05*G0_6_1 - 5.41125541125561e-05*G0_6_2 - 3.65259740259754e-05*G0_6_3 + 0.000450487012987029*G0_6_5 - 0.000608766233766255*G0_6_6 + 0.000255681818181827*G0_6_7 - 0.000146103896103901*G0_6_8 + 7.30519480519506e-05*G0_6_9 - 0.000131222943722948*G0_7_0 - 0.000108225108225112*G0_7_1 - 8.52272727272757e-05*G0_7_2 - 0.000219155844155852*G0_7_3 + 0.000146103896103901*G0_7_4 - 0.000474837662337679*G0_7_5 + 0.000255681818181827*G0_7_6 - 0.000511363636363654*G0_7_7 - 0.000657467532467555*G0_7_9 + 0.000108225108225112*G0_8_0 + 0.000131222943722949*G0_8_1 + 8.52272727272757e-05*G0_8_2 + 0.000474837662337679*G0_8_3 - 0.000255681818181827*G0_8_4 + 0.000219155844155851*G0_8_5 - 0.000146103896103901*G0_8_6 + 0.000511363636363655*G0_8_8 + 0.000657467532467555*G0_8_9 + 4.87012987013004e-05*G0_9_0 - 4.87012987013002e-05*G0_9_1 + 0.000584415584415605*G0_9_3 - 7.30519480519506e-05*G0_9_4 - 0.000584415584415604*G0_9_5 + 7.30519480519506e-05*G0_9_6 - 0.000657467532467555*G0_9_7 + 0.000657467532467555*G0_9_8; + A[12] = A[2]; + } + + /// 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 mass_matrix_f2_p3_q2_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p3_q2_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p3_q2_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1))), 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 mass_matrix_f2_p3_q2_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p3_q2_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p3_q2_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p3_q2_tensor_finite_element_0(); + 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 mass_matrix_f2_p3_q2_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p3_q2_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p3_q2_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p3_q2_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f2_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/mass_matrix_2d/mass_matrix_f2_p3_q3_excafe.h b/mass_matrix_2d/mass_matrix_f2_p3_q3_excafe.h new file mode 100644 index 0000000..a586220 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p3_q3_excafe.h @@ -0,0 +1,626 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 243 minutes and 4.58 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][7]*w[1][3] + w[0][3]*w[1][7]; + const double var_1 = -1.0000000000000000000000000*var_0; + const double var_2 = w[0][6]*w[1][6]; + const double var_3 = -1.0000000000000000000000000*var_2; + const double var_4 = var_3 + var_1; + const double var_5 = -1.0000000000000000000000000*x[0][1]; + const double var_6 = var_5 + x[1][1]; + const double var_7 = -1.0000000000000000000000000*x[0][0]; + const double var_8 = var_7 + x[2][0]; + const double var_9 = x[2][1] + var_5; + const double var_10 = x[1][0] + var_7; + const double var_11 = -1.0000000000000000000000000*var_6*var_8 + var_10*var_9; + const double var_12 = std::abs(var_11); + const double var_13 = w[0][6]*w[1][0] + w[0][0]*w[1][6]; + const double var_14 = w[0][4]*w[1][8] + w[0][8]*w[1][4]; + const double var_15 = w[0][0]*w[1][7] + w[0][7]*w[1][0]; + const double var_16 = w[0][2]*w[1][4] + w[0][4]*w[1][2]; + const double var_17 = w[0][4]*w[1][9] + w[0][9]*w[1][4]; + const double var_18 = w[0][8]*w[1][5] + w[0][5]*w[1][8]; + const double var_19 = w[0][8]*w[1][2] + w[0][2]*w[1][8]; + const double var_20 = w[0][2]*w[1][7] + w[0][7]*w[1][2]; + const double var_21 = w[0][0]*w[1][3] + w[0][3]*w[1][0]; + const double var_22 = w[0][1]*w[1][5] + w[0][5]*w[1][1]; + const double var_23 = w[0][3]*w[1][2] + w[0][2]*w[1][3]; + const double var_24 = w[0][8]*w[1][0] + w[0][0]*w[1][8]; + const double var_25 = w[0][6]*w[1][3] + w[0][3]*w[1][6]; + const double var_26 = w[0][8]*w[1][9] + w[0][9]*w[1][8]; + const double var_27 = w[0][7]*w[1][9] + w[0][9]*w[1][7]; + const double var_28 = -1.0000000000000000000000000*var_27; + const double var_29 = w[0][6]*w[1][9] + w[0][9]*w[1][6]; + const double var_30 = -1.0000000000000000000000000*var_29; + const double var_31 = w[0][5]*w[1][9] + w[0][9]*w[1][5]; + const double var_32 = -1.0000000000000000000000000*var_31; + const double var_33 = w[0][5]*w[1][7] + w[0][7]*w[1][5]; + const double var_34 = w[0][3]*w[1][4] + w[0][4]*w[1][3]; + const double var_35 = w[0][6]*w[1][8] + w[0][8]*w[1][6]; + const double var_36 = w[0][9]*w[1][0] + w[0][0]*w[1][9]; + const double var_37 = 11.5714285714285711748061658*w[0][9]*w[1][9]; + const double var_38 = 0.0003371628371628371625447*var_37; + const double var_39 = w[0][2]*w[1][1] + w[0][1]*w[1][2]; + const double var_40 = 0.0000357678036249464801222*var_39; + const double var_41 = var_40 + -0.0009705473098330240269010*var_34 + -0.0002135364635364635362783*var_36 + -0.0025661838161838163713258*w[0][0]*w[1][0] + var_38 + -0.0018038211788211787247466*var_33 + -0.0007273084058798344854815*var_35; + const double var_42 = w[0][4]*w[1][6] + w[0][6]*w[1][4]; + const double var_43 = w[0][3]*w[1][5] + w[0][5]*w[1][3]; + const double var_44 = w[0][9]*w[1][2] + w[0][2]*w[1][9]; + const double var_45 = w[0][7]*w[1][8] + w[0][8]*w[1][7]; + const double var_46 = w[0][0]*w[1][1] + w[0][1]*w[1][0]; + const double var_47 = 0.0001172042243470814917730*var_44 + -0.0000102575995433138278092*w[0][2]*w[1][2] + -0.0004575781361495647012357*var_43 + -0.0008597652347652347780416*var_45 + -0.0001613565006422149181089*var_42 + -0.0002004245754245754379541*var_46; + const double var_48 = w[0][7]*w[1][4] + w[0][4]*w[1][7]; + const double var_49 = w[0][3]*w[1][8] + w[0][8]*w[1][3]; + const double var_50 = w[0][6]*w[1][5] + w[0][5]*w[1][6]; + const double var_51 = w[0][2]*w[1][0] + w[0][0]*w[1][2]; + const double var_52 = w[0][1]*w[1][9] + w[0][9]*w[1][1]; + const double var_53 = 0.0001252319109461966565016*var_52; + const double var_54 = -0.0001423576423576423575189*var_51 + 0.0008742150706436419959483*var_48 + 0.0027165691451405734463398*var_49 + 0.0005638111888111887971473*w[0][1]*w[1][1] + var_53 + 0.0013823676323676324477485*var_50; + const double var_55 = w[0][1]*w[1][7] + w[0][7]*w[1][1]; + const double var_56 = -1.0000000000000000000000000*var_55; + const double var_57 = w[0][6]*w[1][1] + w[0][1]*w[1][6]; + const double var_58 = w[0][2]*w[1][6] + w[0][6]*w[1][2]; + const double var_59 = var_58 + var_57; + const double var_60 = w[0][4]*w[1][0] + w[0][0]*w[1][4]; + const double var_61 = -1.0000000000000000000000000*var_60; + const double var_62 = w[0][5]*w[1][4] + w[0][4]*w[1][5]; + const double var_63 = w[0][4]*w[1][4]; + const double var_64 = var_62 + var_63; + const double var_65 = w[0][1]*w[1][4] + w[0][4]*w[1][1]; + const double var_66 = -0.0002817717996289424839049*var_65; + const double var_67 = w[0][2]*w[1][5] + w[0][5]*w[1][2]; + const double var_68 = -0.0002817717996289424839049*var_67; + const double var_69 = w[0][5]*w[1][0] + w[0][0]*w[1][5]; + const double var_70 = -1.0000000000000000000000000*var_69; + const double var_71 = 0.0017139110889110888147346*var_70; + const double var_72 = w[0][7]*w[1][6] + w[0][6]*w[1][7]; + const double var_73 = w[0][1]*w[1][8] + w[0][8]*w[1][1]; + const double var_74 = var_72 + var_73; + const double var_75 = w[0][1]*w[1][3] + w[0][3]*w[1][1]; + const double var_76 = w[0][9]*w[1][3] + w[0][3]*w[1][9]; + const double var_77 = 0.1205357142857142738190390*var_76 + 0.0215909090909090911614143*var_75; + const double var_78 = var_47 + 0.0021241258741258742595570*var_28 + 0.0003227130012844298362178*var_64 + -0.0009970386756101041070971*var_17 + var_68 + 0.0007706579135150563560422*var_56 + 0.0002022977022977022975268*var_32 + 0.0043638504352790062623679*w[0][8]*w[1][8] + var_71 + -0.0051080169830169828634747*w[0][7]*w[1][7] + var_66 + 0.0013823676323676324477485*var_74 + -0.0001453011274439845886518*var_22 + 0.0004407199942914228566609*var_19 + 0.0004214535464535464396284*var_18 + 0.0002873911802483231168331*var_23 + 0.0197802197802197793352619*var_77 + 0.0001123876123876123875149*var_61 + 0.0004551698301698301829879*var_21 + -0.0013799593263878978752907*var_0 + -0.0019049700299700299006150*w[0][5]*w[1][5] + 0.0022975239046667617417996*var_26 + -0.0007273084058798344854815*var_2 + -0.0001613565006422149181089*var_25 + 0.0000288996717568146119963*var_30 + 0.0018206793206793207319516*var_24 + 0.0000489688882546025373702*var_59 + var_41 + 0.0006968031968031968568025*var_13 + -0.0028939810189810189107462*var_15 + var_54 + -0.0001436955901241615584166*var_16 + -0.0004656058227486798524117*var_20 + -0.0013366098187526757878896*var_14 + 0.0029814828029113742483003*w[0][3]*w[1][3]; + A[8] = 0.1250000000000000000000000*var_12*var_78; + const double var_79 = w[0][8]*w[1][8]; + const double var_80 = -1.0000000000000000000000000*var_26; + const double var_81 = -0.0002004245754245754379541*var_51 + -0.0004575781361495647012357*var_48 + 0.0001172042243470814917730*var_52 + -0.0001613565006422149181089*var_49 + -0.0000102575995433138278092*w[0][1]*w[1][1] + -0.0008597652347652347780416*var_50; + const double var_82 = 0.0001252319109461966565016*var_44; + const double var_83 = 0.0005638111888111887971473*w[0][2]*w[1][2] + var_82 + 0.0008742150706436419959483*var_43 + 0.0013823676323676324477485*var_45 + 0.0027165691451405734463398*var_42 + -0.0001423576423576423575189*var_46; + const double var_84 = -1.0000000000000000000000000*var_67; + const double var_85 = var_19 + var_73; + const double var_86 = -1.0000000000000000000000000*var_21; + const double var_87 = w[0][3]*w[1][3]; + const double var_88 = var_0 + var_87; + const double var_89 = -0.0002817717996289424839049*var_55; + const double var_90 = -0.0002817717996289424839049*var_23; + const double var_91 = -1.0000000000000000000000000*var_15; + const double var_92 = 0.0017139110889110888147346*var_91; + const double var_93 = var_58 + var_18; + const double var_94 = 0.1205357142857142738190390*var_17 + 0.0215909090909090911614143*var_16; + const double var_95 = 0.0000288996717568146119963*var_80 + 0.0002022977022977022975268*var_28 + 0.0029814828029113742483003*w[0][4]*w[1][4] + -0.0009970386756101041070971*var_76 + 0.0000489688882546025373702*var_85 + var_89 + 0.0021241258741258742595570*var_32 + 0.0022975239046667617417996*var_29 + 0.0003227130012844298362178*var_88 + -0.0013799593263878978752907*var_62 + -0.0019049700299700299006150*w[0][7]*w[1][7] + -0.0004656058227486798524117*var_22 + 0.0004551698301698301829879*var_60 + 0.0004214535464535464396284*var_72 + -0.0001436955901241615584166*var_75 + var_81 + 0.0001123876123876123875149*var_86 + 0.0013823676323676324477485*var_93 + 0.0043638504352790062623679*w[0][6]*w[1][6] + 0.0004407199942914228566609*var_57 + -0.0051080169830169828634747*w[0][5]*w[1][5] + var_90 + -0.0013366098187526757878896*var_25 + -0.0028939810189810189107462*var_69 + 0.0006968031968031968568025*var_24 + var_92 + 0.0197802197802197793352619*var_94 + 0.0002873911802483231168331*var_65 + var_41 + 0.0018206793206793207319516*var_13 + var_83 + 0.0007706579135150563560422*var_84 + -0.0007273084058798344854815*var_79 + -0.0001453011274439845886518*var_20 + -0.0001613565006422149181089*var_14; + A[6] = 0.1250000000000000000000000*var_12*var_95; + A[60] = A[6]; + const double var_96 = -1.0000000000000000000000000*var_19; + const double var_97 = var_57 + var_22; + const double var_98 = var_39 + var_51; + const double var_99 = -1.0000000000000000000000000*var_20; + const double var_100 = w[0][0]*w[1][0]; + const double var_101 = -1.0000000000000000000000000*var_37; + const double var_102 = 0.0006293706293706293700835*var_101; + const double var_103 = 0.0001252319109461966565016*var_36; + const double var_104 = var_103 + 0.0003914835164835164696244*var_39 + -0.0002004245754245754379541*var_100 + -0.0018038211788211787247466*var_34 + -0.0013799593263878978752907*var_33 + var_102 + -0.0001011488511488511487634*var_35; + const double var_105 = -0.0001477094334237191340046*var_44 + -0.0000097224204367061504994*w[0][2]*w[1][2] + 0.0001348651348651348650179*var_43 + -0.0051080169830169828634747*var_45 + -0.0004575781361495647012357*var_42 + 0.0005638111888111887971473*var_46; + const double var_106 = 0.0000357678036249464801222*var_51; + const double var_107 = 0.0013823676323676324477485*var_48 + 0.0010676823176823176542866*var_52 + var_106 + 0.0037087912087912086253616*var_49 + 0.0055257242757242759634284*w[0][1]*w[1][1] + 0.0006478343085485942448934*var_50; + const double var_108 = -1.0000000000000000000000000*var_22; + const double var_109 = -1.0000000000000000000000000*var_17; + const double var_110 = var_76 + 0.5000000000000000000000000*var_109; + const double var_111 = var_23 + var_21; + const double var_112 = -1.0000000000000000000000000*var_65; + const double var_113 = 0.5000000000000000000000000*var_112 + var_75; + const double var_114 = -0.0001453011274439845886518*var_16; + const double var_115 = 0.0006068931068931069467906*var_26; + const double var_116 = -0.0001453011274439845886518*var_69; + const double var_117 = 0.0519230769230769259592329*var_29 + 0.0146634615384615401428858*var_13; + const double var_118 = var_105 + 0.0004656058227486798524117*var_99 + 0.0033395176252319106954825*var_117 + 0.0004045954045954045950537*var_110 + 0.0034278221778221776294693*var_113 + 0.0003427822177822177954730*var_108 + 0.0013871842443271013758238*var_32 + 0.0003227130012844298362178*var_62 + -0.0008597652347652347780416*w[0][7]*w[1][7] + 0.0001164014556871699631029*var_58 + -0.0002817717996289424839049*var_60 + 0.0004607892107892108159162*var_19 + 0.0008742150706436419959483*var_72 + 0.0037087912087912086253616*var_87 + 0.0005057442557442557709221*var_18 + 0.0004214535464535464396284*var_63 + 0.0007706579135150563560422*var_91 + -0.0021241258741258742595570*var_27 + var_115 + -0.0010716961609818752027695*w[0][6]*w[1][6] + var_104 + 0.0004270729270729270725566*var_111 + var_116 + -0.0001436955901241615584166*var_67 + -0.0002191558441558441692066*var_57 + -0.0018038211788211787247466*var_0 + -0.0020109354930783500045588*w[0][5]*w[1][5] + 0.0001348651348651348650179*var_25 + 0.0013823676323676324477485*var_24 + -0.0028939810189810189107462*var_55 + var_114 + var_107 + 0.0111263736263736267434465*var_79 + 0.0068556443556443552589386*var_73 + -0.0019049700299700299006150*var_14; + A[18] = 0.1250000000000000000000000*var_118*var_12; + const double var_119 = -1.0000000000000000000000000*var_50; + const double var_120 = 0.0001198801198801198800159*var_37; + const double var_121 = 0.0000383991008991008990676*var_51 + -0.0000830865563008420179598*var_48 + 0.0007080419580419580142389*var_119 + var_120 + 0.0001240277579563293702727*var_52 + 0.0000848927857856429201981*var_49 + 0.0000176163122591694005592*w[0][1]*w[1][1]; + const double var_122 = w[0][2]*w[1][2]; + const double var_123 = 0.0000168581418581418581272*var_44 + 0.0001318547523904666765506*var_43 + -0.0000584014200085628671071*var_45 + 0.0001904345654345654479528*var_122 + 0.0009609140859140859539100*var_42 + 0.0000122422220636506343426*var_46; + const double var_124 = -1.0000000000000000000000000*var_34; + const double var_125 = 0.0003203046953046953179700*var_124 + 0.0000127997002997002996892*var_39 + 0.0000505744255744255743817*var_100 + 0.0000638201084629656009272*var_36 + 0.0001968790138432995637068*var_33 + -0.0002095226202369059335853*var_35; + const double var_126 = -1.0000000000000000000000000*var_14; + const double var_127 = -1.0000000000000000000000000*var_72; + const double var_128 = -1.0000000000000000000000000*var_25; + const double var_129 = -1.0000000000000000000000000*var_62; + const double var_130 = -1.0000000000000000000000000*var_76; + const double var_131 = var_130 + 0.2500000000000000000000000*var_27; + const double var_132 = 0.0006068931068931069467906*var_17; + const double var_133 = 0.0002035018552875695566507*var_87; + const double var_134 = w[0][7]*w[1][7]; + const double var_135 = 0.0002035018552875695566507*var_134; + const double var_136 = 0.0000939239332096474855999*var_126 + 0.0000866990152704438359890*var_32 + 0.0012137862137862138935812*var_29 + 0.0000915156272299129402471*w[0][8]*w[1][8] + 0.0003090659340659340521135*var_58 + 0.0000754602540316825972375*var_60 + -0.0000166574496931639793478*var_22 + -0.0000529158341658341691764*var_23 + -0.0000523806550592264833963*var_18 + 0.0006406093906093906359400*var_63 + -0.0000558593192521763935330*var_75 + 0.0000028096903096903096879*var_96 + var_132 + 0.0003287337662337662131523*var_129 + -0.0001418893606393606290732*var_67 + 0.0001766091051805337595534*var_57 + -0.0000371280505209076622805*var_21 + 0.0003901455687169972687267*var_131 + var_121 + 0.0000090311474240045670959*var_0 + 0.0007008170401027544052855*w[0][5]*w[1][5] + -0.0001842354074496931667232*var_26 + 0.0038436563436563438156401*var_2 + 0.0006321803196803196323375*var_128 + var_125 + -0.0000238823676323676323469*var_69 + var_135 + -0.0000202030112744398468189*var_24 + 0.0000828189667475381750697*var_65 + 0.0001444983587840730735342*var_127 + 0.0000089642500356786063734*var_55 + 0.0001212180676466390673611*var_13 + 0.0000117070429570429570328*var_15 + var_123 + var_133 + 0.0001030219780219780218887*var_16 + -0.0000297693378050520878364*var_73 + 0.0000140484515484515484394*var_20; + const double var_137 = -1.0000000000000000000000000*var_87; + const double var_138 = var_127 + var_137; + const double var_139 = 0.2500000000000000000000000*var_76 + var_30; + const double var_140 = var_79 + var_87; + const double var_141 = var_20 + var_22; + const double var_142 = var_2 + var_25; + const double var_143 = var_72 + var_142; + const double var_144 = var_21 + var_19; + const double var_145 = var_58 + var_69; + const double var_146 = var_62 + var_72; + const double var_147 = 6.7500000000000000000000000*var_146 + var_145 + var_144; + const double var_148 = var_58 + var_16; + const double var_149 = var_69 + var_75; + const double var_150 = var_73 + var_15; + const double var_151 = var_148 + var_149 + var_150; + const double var_152 = 0.0002747252747252747250364*var_101; + const double var_153 = -0.0007184779506208076836626*var_60 + 0.0016135650064221492352989*var_62; + const double var_154 = var_19 + var_20; + const double var_155 = var_35 + var_48; + const double var_156 = var_49 + var_33; + const double var_157 = var_23 + var_67; + const double var_158 = var_14 + var_72; + const double var_159 = var_26 + var_27; + const double var_160 = var_76 + var_31; + const double var_161 = var_134 + var_79; + const double var_162 = w[0][5]*w[1][5]; + const double var_163 = var_162 + var_87; + const double var_164 = var_119 + var_124; + const double var_165 = -1.0000000000000000000000000*var_43; + const double var_166 = var_25 + var_62; + const double var_167 = -0.5000000000000000000000000*var_166 + var_42; + const double var_168 = var_2 + var_63; + const double var_169 = var_167 + 1.5000000000000000000000000*var_168; + const double var_170 = w[0][1]*w[1][1]; + const double var_171 = var_100 + var_170; + const double var_172 = var_98 + var_171; + const double var_173 = var_109 + var_30; + const double var_174 = var_65 + var_13; + const double var_175 = var_174 + var_149; + const double var_176 = var_52 + var_36; + const double var_177 = -1.0000000000000000000000000*var_176; + const double var_178 = 0.0004495504495504495500596*var_37; + const double var_179 = var_21 + var_22; + const double var_180 = var_24 + var_55; + const double var_181 = var_180 + var_179; + const double var_182 = var_0 + var_18; + const double var_183 = var_60 + var_57; + const double var_184 = var_183 + 6.7500000000000000000000000*var_182 + var_150; + const double var_185 = 0.0002435064935064935062823*var_172 + 0.0010596546310832025573206*var_177 + var_178 + 0.0002087198515769944184677*var_175 + 0.0038292065077779359472121*var_163 + 0.0017794705294705294960911*var_148 + 0.0121378621378621376347695*var_173 + 0.0000481661195946910222526*var_165 + 0.0065024261452832883903530*var_160 + -0.0002461823890395318809726*var_184 + 0.0074416654773797625416210*var_161 + 0.0013111888111888112418840*var_122 + 0.0039737048665620094273221*var_156 + 0.0000945483088340231099750*var_46 + 0.0042707292707292706171462*var_44 + 0.0035402097902097902880347*var_164 + 0.0002889967175681461470683*var_155 + 0.0078029113743399453745342*var_159 + 0.0001953403739118024637009*var_181 + -0.0027454688168973883158341*var_45 + -0.0023119737405451691765468*var_158 + -0.0003558941058941059209023*var_157 + 0.0006743256743256743250894*var_169 + 0.0004120879120879120875547*var_154; + A[29] = 0.0750000000000000111022302*var_12*var_185; + A[92] = A[29]; + A[80] = A[8]; + const double var_186 = var_103 + -0.0001423576423576423575189*var_39 + 0.0013823676323676324477485*var_34 + 0.0005638111888111887971473*w[0][0]*w[1][0] + 0.0027165691451405734463398*var_33 + 0.0008742150706436419959483*var_35; + const double var_187 = 0.0020229770229770230836885*var_37; + const double var_188 = -0.0000512879977165691441281*var_39 + var_187 + 0.0043710753532182101965819*var_34 + -0.0007385471671185956429179*var_36 + 0.0149074140145568703741397*var_33 + 0.0019574175824175824023321*w[0][0]*w[1][0] + 0.0032391715427429711160467*var_35; + const double var_189 = -0.0007117882117882118418045*var_170 + -0.0000486121021835307491089*var_51 + -0.0053584808049093757970072*var_48 + 0.0005860211217354073911026*var_52 + -0.0048527365491651203513457*var_49 + -0.0068997966319394882922511*var_50; + const double var_190 = 0.0012362637362637362084539*var_44 + -0.0008067825032110746176495*var_43 + -0.0029983409447695160386649*var_45 + -0.0003277972027972028104710*var_122 + 0.0006743256743256743250894*var_42 + 0.0001788390181247324006112*var_46; + const double var_191 = -1.0000000000000000000000000*var_16; + const double var_192 = -1.0000000000000000000000000*var_63; + const double var_193 = -1.0000000000000000000000000*var_23; + const double var_194 = 0.0016135650064221492352989*var_0 + -0.0007184779506208076836626*var_21; + const double var_195 = -0.0007184779506208076836626*var_57 + 0.0016135650064221492352989*var_25; + const double var_196 = -1.0000000000000000000000000*var_73; + const double var_197 = -1.0000000000000000000000000*var_24; + const double var_198 = var_196 + var_197; + const double var_199 = -1.0000000000000000000000000*var_58; + const double var_200 = 0.0017139110889110888147346*var_199; + const double var_201 = 0.1205357142857142738190390*var_31 + 0.0215909090909090911614143*var_69; + const double var_202 = 0.0272321428571428575393654*var_65 + 0.0964285714285714190552312*var_17; + const double var_203 = 0.0023280291137433993704786*var_198 + var_195 + var_200 + var_190 + -0.0049851933780505203186451*var_76 + 0.0989010989010989105540972*var_201 + 0.0005057442557442557709221*var_192 + -0.0022878906807478234519682*var_62 + var_189 + 0.0317896389324960754185767*var_134 + 0.0014369559012416153673253*var_22 + 0.0005820072784358498426197*var_60 + 0.0005619380619380619917846*var_193 + -0.0012603467960610817161921*var_19 + -0.0100546774653917508901557*var_72 + -0.0048527365491651203513457*var_18 + -0.0014088589981447123111041*var_75 + 0.0223249964321392893595863*var_27 + var_194 + 0.0022758491508491508065193*var_67 + var_188 + 0.0135828457257028672316990*w[0][5]*w[1][5] + -0.0082364064506921640801407*var_26 + 0.0025287212787212785293500*var_2 + 0.0069359212216355070959595*var_30 + 0.0089910089910089918685543*var_202 + 0.0022035999714571140664643*var_55 + -0.0007265056372199228890488*var_13 + 0.0023039460539460540795809*var_15 + 0.0010957792207792207105077*var_191 + -0.0029983409447695160386649*var_79 + 0.0031709362066504923581556*var_20 + 0.0032391715427429711160467*var_14 + -0.0066830490937633789394479*w[0][3]*w[1][3]; + const double var_204 = -1.0000000000000000000000000*var_45; + const double var_205 = -1.0000000000000000000000000*var_42; + const double var_206 = var_204 + var_205; + const double var_207 = 0.0005418688454402740325294*var_44 + 0.0010837376908805480650588*var_206 + -0.0000296578421578421578164*w[0][2]*w[1][2] + -0.0009211770372484657251957*var_43 + var_38 + -0.0000205151990866276556183*var_46; + const double var_208 = -1.0000000000000000000000000*var_36; + const double var_209 = var_35 + var_34; + const double var_210 = 0.0010114885114885115418443*var_208 + 0.0000162783644926502064378*var_39 + 0.0001482892107892107823059*var_100 + 0.0005960557299843014791504*var_209 + 0.0030344655344655344086924*var_33; + const double var_211 = var_49 + var_48; + const double var_212 = 0.0000343406593406593406296*var_170 + -0.0001625606536320822043378*var_211 + 0.0000173933209647495371311*var_51 + 0.0006502426145283288173513*var_52 + 0.0004334950763522191934975*var_119; + const double var_213 = var_21 + var_75; + const double var_214 = 0.5000000000000000000000000*var_80 + var_27; + const double var_215 = var_20 + var_55; + const double var_216 = -1.0000000000000000000000000*var_13; + const double var_217 = var_216 + var_199; + const double var_218 = var_65 + var_19; + const double var_219 = 0.5000000000000000000000000*var_197 + var_15; + const double var_220 = var_62 + var_79; + const double var_221 = -1.0000000000000000000000000*var_18; + const double var_222 = var_192 + var_221; + const double var_223 = var_196 + var_61; + const double var_224 = 0.0000561938061938061937575*var_219 + var_207 + 0.0002950174825174825240029*var_217 + 0.0016256065363208220975882*var_130 + 0.0030344655344655344086924*var_134 + 0.0060689310689310688173848*var_162 + 0.0006201387897816468784684*var_22 + 0.0000040138432995575849054*var_193 + 0.0052019409162266305388100*var_214 + -0.0009211770372484657251957*var_87 + 0.0003311420722135007856102*var_215 + 0.0000240830597973455111263*var_213 + 0.0001926644783787640890105*var_223 + 0.0003191005423148280317411*var_67 + 0.0026009704581133152694050*var_109 + -0.0002287890680747823506178*var_57 + var_210 + -0.0001384775938347366965996*var_218 + 0.0005960557299843014791504*var_25 + 0.0028177179962894246222083*var_30 + 0.0000842907092907092906362*var_69 + 0.0069359212216355070959595*var_31 + 0.0019507278435849863436335*var_222 + 0.0010837376908805480650588*var_127 + 0.0001625606536320822043378*var_1 + 0.0004876819608962465859084*var_220 + 0.0000280969030969030968787*var_191 + 0.0004334950763522191934975*var_3 + var_212 + 0.0003251213072641644086756*var_14; + A[59] = 0.9000000000000000222044605*var_12*var_224; + const double var_225 = var_67 + var_13; + const double var_226 = -1.0000000000000000000000000*var_79; + const double var_227 = 0.0215909090909090911614143*var_58 + 0.1205357142857142738190390*var_29; + const double var_228 = 0.0012587412587412587401670*var_101; + const double var_229 = -1.0000000000000000000000000*var_39; + const double var_230 = 0.0010789210789210789201431*var_208 + var_228 + 0.0036919330669330668349970*var_34 + -0.0002666083916083915946078*w[0][0]*w[1][0] + -0.0023264235764235766112940*var_33 + 0.0002191558441558441692066*var_229 + 0.0002528721278721278854611*var_35; + const double var_231 = -1.0000000000000000000000000*var_170; + const double var_232 = -0.0001130119880119880118900*var_51 + 0.0023769980019980019823878*var_48 + -0.0007754745254745255009579*var_52 + 0.0002528721278721278854611*var_49 + 0.0000874125874125874125116*var_231 + 0.0055126123876123875669486*var_50; + const double var_233 = 1.2785714285714284699224663*var_46 + 18.7071428571428555187594611*var_43 + 1.8000000000000000444089210*var_44; + const double var_234 = 0.0002528721278721278854611*var_45 + -0.0013330419580419581356695*var_122 + -0.0000874125874125874125116*var_233 + -0.0089685314685314689031603*var_42; + const double var_235 = -1.0000000000000000000000000*var_134; + const double var_236 = -1.0000000000000000000000000*var_162; + const double var_237 = 0.5000000000000000000000000*var_28 + var_26; + const double var_238 = 0.2500000000000000000000000*var_31 + var_109; + const double var_239 = var_14 + var_79; + const double var_240 = var_239 + var_18; + const double var_241 = var_24 + var_22; + const double var_242 = var_241 + -0.5000000000000000000000000*var_55 + var_85; + const double var_243 = var_230 + 0.0033379120879120879362978*var_76 + 0.0177010489510489518738545*var_192 + 0.0056980519480519476946401*var_62 + -0.0014029720279720280656788*var_58 + -0.0015640609390609389647148*var_60 + 0.0020735514485514484547823*var_72 + 0.0010751748251748250925774*var_23 + 0.0006799450549450549580177*var_75 + 0.0018206793206793207319516*var_237 + 0.0003277972027972028104710*var_67 + -0.0007548701298701298830277*var_57 + 0.0005038711288711288571393*var_21 + var_232 + var_234 + 0.0032704795204795203411585*var_25 + 0.0060689310689310688173848*var_30 + 0.0026298701298701297052185*var_235 + 0.0003933566433566433834072*var_69 + 0.0040459540459540461673771*var_236 + -0.0010395854145854145980654*var_65 + 0.0005057442557442557709221*var_1 + -0.0010733016983016983956351*var_13 + 0.0001048951048951048950139*var_15 + 0.0002509990009990010258883*var_242 + -0.0014816433566433567098342*var_16 + 0.0092045454545454548356265*var_3 + 0.0109240759240759235243479*var_238 + -0.0003558941058941059209023*var_20 + -0.0014666583416583416164120*w[0][3]*w[1][3] + 0.0002528721278721278854611*var_240; + A[45] = 0.1607142857142856984253854*var_12*var_243; + const double var_244 = var_72 + var_134; + const double var_245 = var_0 + var_244; + const double var_246 = var_60 + var_21; + const double var_247 = var_24 + var_13; + const double var_248 = var_69 + var_15; + const double var_249 = var_247 + var_248 + var_246; + const double var_250 = var_2 + var_162; + const double var_251 = 0.5000000000000000000000000*var_216 + var_69; + const double var_252 = var_31 + 0.5000000000000000000000000*var_30; + const double var_253 = 0.1205357142857142738190390*var_26 + 0.0215909090909090911614143*var_73; + const double var_254 = -0.0000512879977165691441281*var_51 + 0.0032391715427429711160467*var_48 + var_187 + -0.0007385471671185956429179*var_52 + 0.0149074140145568703741397*var_49 + 0.0019574175824175824023321*w[0][1]*w[1][1] + 0.0043710753532182101965819*var_50; + const double var_255 = -0.0000486121021835307491089*var_39 + -0.0007117882117882118418045*var_100 + -0.0068997966319394882922511*var_34 + 0.0005860211217354073911026*var_36 + -0.0048527365491651203513457*var_33 + -0.0053584808049093757970072*var_35; + const double var_256 = -0.0007184779506208076836626*var_22 + 0.0016135650064221492352989*var_18; + const double var_257 = var_56 + var_91; + const double var_258 = 0.0017139110889110888147346*var_191; + const double var_259 = var_190 + 0.0166975881261595543447740*var_117 + var_254 + 0.0010957792207792207105077*var_199 + var_258 + -0.0029983409447695160386649*var_134 + var_153 + 0.0031709362066504923581556*var_19 + 0.0032391715427429711160467*var_72 + 0.0022758491508491508065193*var_23 + 0.0025287212787212785293500*var_63 + -0.0082364064506921640801407*var_27 + 0.0989010989010989105540972*var_77 + 0.0069359212216355070959595*var_109 + 0.0005820072784358498426197*var_57 + 0.0014369559012416153673253*var_21 + -0.0048527365491651203513457*var_0 + -0.0066830490937633789394479*w[0][5]*w[1][5] + 0.0223249964321392893595863*var_26 + -0.0022878906807478234519682*var_25 + -0.0014088589981447123111041*var_69 + 0.0022035999714571140664643*var_24 + 0.0023280291137433993704786*var_257 + -0.0049851933780505203186451*var_31 + var_256 + -0.0007265056372199228890488*var_65 + var_255 + 0.0005619380619380619917846*var_84 + 0.0317896389324960754185767*var_79 + 0.0023039460539460540795809*var_73 + 0.0005057442557442557709221*var_3 + -0.0012603467960610817161921*var_20 + -0.0100546774653917508901557*var_14 + 0.0135828457257028672316990*w[0][3]*w[1][3]; + A[28] = 0.0250000000000000013877788*var_12*var_259; + A[82] = A[28]; + const double var_260 = -1.0000000000000000000000000*var_57; + const double var_261 = -0.0007273084058798344854815*var_48 + -0.0002135364635364635362783*var_52 + var_106 + -0.0018038211788211787247466*var_49 + -0.0025661838161838163713258*w[0][1]*w[1][1] + var_38 + -0.0009705473098330240269010*var_50; + const double var_262 = -0.0002004245754245754379541*var_39 + -0.0008597652347652347780416*var_34 + 0.0001172042243470814917730*var_36 + -0.0000102575995433138278092*w[0][0]*w[1][0] + -0.0001613565006422149181089*var_33 + -0.0004575781361495647012357*var_35; + const double var_263 = var_20 + var_15; + const double var_264 = var_162 + var_18; + const double var_265 = -0.0002817717996289424839049*var_24; + const double var_266 = 0.0017139110889110888147346*var_196; + const double var_267 = var_0 + var_16; + const double var_268 = 0.0002022977022977022975268*var_80 + 0.0000288996717568146119963*var_28 + 0.0043638504352790062623679*w[0][4]*w[1][4] + var_261 + var_68 + 0.0022975239046667617417996*var_17 + 0.0197802197802197793352619*var_227 + 0.0001123876123876123875149*var_108 + -0.0019049700299700299006150*w[0][8]*w[1][8] + 0.0021241258741258742595570*var_130 + -0.0013366098187526757878896*var_62 + var_262 + 0.0003227130012844298362178*var_264 + -0.0007273084058798344854815*var_134 + 0.0004407199942914228566609*var_60 + 0.0007706579135150563560422*var_193 + -0.0001453011274439845886518*var_19 + -0.0001613565006422149181089*var_72 + var_265 + -0.0028939810189810189107462*var_75 + var_266 + 0.0029814828029113742483003*w[0][6]*w[1][6] + 0.0004551698301698301829879*var_57 + -0.0004656058227486798524117*var_21 + 0.0013823676323676324477485*var_267 + -0.0013799593263878978752907*var_25 + -0.0001436955901241615584166*var_69 + 0.0000489688882546025373702*var_263 + -0.0009970386756101041070971*var_31 + 0.0018206793206793207319516*var_65 + 0.0006968031968031968568025*var_55 + 0.0002873911802483231168331*var_13 + var_83 + 0.0004214535464535464396284*var_14 + -0.0051080169830169828634747*w[0][3]*w[1][3]; + const double var_269 = -1.0000000000000000000000000*var_44; + const double var_270 = -1.0000000000000000000000000*var_46; + const double var_271 = 0.0010789210789210789201431*var_269 + -0.0002666083916083915946078*w[0][2]*w[1][2] + var_228 + 0.0002191558441558441692066*var_270 + 0.0002528721278721278854611*var_43 + 0.0036919330669330668349970*var_45 + -0.0023264235764235766112940*var_42; + const double var_272 = 93.5357142857142775937973056*var_35 + 6.3928571428571423496123316*var_39 + 9.0000000000000000000000000*var_36; + const double var_273 = -0.0000174825174825174825023*var_272 + -0.0089685314685314689031603*var_33 + -0.0013330419580419581356695*var_100 + 0.0002528721278721278854611*var_34; + const double var_274 = var_28 + 0.2500000000000000000000000*var_29; + const double var_275 = var_25 + var_88; + const double var_276 = var_57 + var_23; + const double var_277 = -0.5000000000000000000000000*var_65 + var_276 + var_213; + const double var_278 = 0.0005057442557442557709221*var_126 + var_271 + 0.0018206793206793207319516*var_110 + 0.0060689310689310688173848*var_32 + 0.0109240759240759235243479*var_274 + 0.0026298701298701297052185*var_192 + -0.0014666583416583416164120*w[0][8]*w[1][8] + 0.0020735514485514484547823*var_62 + 0.0003933566433566433834072*var_58 + -0.0007548701298701298830277*var_22 + -0.0003558941058941059209023*var_60 + 0.0005038711288711288571393*var_19 + 0.0056980519480519476946401*var_72 + var_273 + 0.0032704795204795203411585*var_18 + -0.0010733016983016983956351*var_67 + var_232 + 0.0033379120879120879362978*var_26 + 0.0002528721278721278854611*var_275 + 0.0177010489510489518738545*var_235 + -0.0014029720279720280656788*var_69 + 0.0092045454545454548356265*var_236 + 0.0010751748251748250925774*var_24 + -0.0010395854145854145980654*var_55 + 0.0003277972027972028104710*var_13 + -0.0014816433566433567098342*var_15 + 0.0001048951048951048950139*var_16 + 0.0006799450549450549580177*var_73 + 0.0002509990009990010258883*var_277 + 0.0040459540459540461673771*var_3 + -0.0015640609390609389647148*var_20; + const double var_279 = 0.0005860211217354073911026*var_44 + -0.0053584808049093757970072*var_43 + -0.0068997966319394882922511*var_45 + -0.0007117882117882118418045*var_122 + -0.0048527365491651203513457*var_42 + -0.0000486121021835307491089*var_46; + const double var_280 = 0.0001788390181247324006112*var_39 + -0.0003277972027972028104710*var_100 + -0.0029983409447695160386649*var_34 + 0.0012362637362637362084539*var_36 + 0.0006743256743256743250894*var_33 + -0.0008067825032110746176495*var_35; + const double var_281 = 0.0016135650064221492352989*var_72 + -0.0007184779506208076836626*var_20; + const double var_282 = var_191 + var_112; + const double var_283 = 0.0519230769230769259592329*var_31 + 0.0146634615384615401428858*var_67; + const double var_284 = var_195 + 0.0223249964321392893595863*var_76 + 0.0069359212216355070959595*var_28 + 0.0023280291137433993704786*var_282 + var_254 + -0.0082364064506921640801407*var_17 + 0.0010957792207792207105077*var_70 + -0.0049851933780505203186451*var_29 + 0.0135828457257028672316990*w[0][8]*w[1][8] + 0.0032391715427429711160467*var_62 + -0.0014088589981447123111041*var_58 + 0.0025287212787212785293500*var_134 + 0.0005820072784358498426197*var_22 + -0.0012603467960610817161921*var_60 + 0.0014369559012416153673253*var_19 + 0.0317896389324960754185767*var_87 + -0.0022878906807478234519682*var_18 + 0.0022035999714571140664643*var_23 + 0.0005619380619380619917846*var_216 + -0.0029983409447695160386649*var_63 + 0.0023039460539460540795809*var_75 + var_281 + -0.0066830490937633789394479*w[0][6]*w[1][6] + 0.0166975881261595543447740*var_283 + 0.0031709362066504923581556*var_21 + 0.0989010989010989105540972*var_253 + -0.0100546774653917508901557*var_0 + 0.0005057442557442557709221*var_236 + 0.0022758491508491508065193*var_24 + var_92 + var_279 + -0.0007265056372199228890488*var_55 + var_280 + -0.0048527365491651203513457*var_14; + A[3] = 0.0250000000000000013877788*var_12*var_284; + A[30] = A[3]; + const double var_285 = var_39 + var_100; + const double var_286 = -1.0000000000000000000000000*var_52; + const double var_287 = var_48 + var_50; + const double var_288 = 0.0001482892107892107823059*var_170 + 0.0005960557299843014791504*var_287 + 0.0000162783644926502064378*var_51 + 0.0030344655344655344086924*var_49 + 0.0010114885114885115418443*var_286; + const double var_289 = var_35 + var_33; + const double var_290 = 0.0004334950763522191934975*var_124 + 0.0000173933209647495371311*var_39 + 0.0000343406593406593406296*var_100 + -0.0001625606536320822043378*var_289 + 0.0006502426145283288173513*var_36; + const double var_291 = var_69 + var_22; + const double var_292 = var_20 + var_13; + const double var_293 = var_24 + var_19; + const double var_294 = 0.5000000000000000000000000*var_56 + var_73; + const double var_295 = var_260 + var_91; + const double var_296 = var_25 + var_134; + const double var_297 = 0.0010837376908805480650588*var_126 + var_207 + 0.0003311420722135007856102*var_293 + 0.0069359212216355070959595*var_76 + 0.0002950174825174825240029*var_282 + 0.0001926644783787640890105*var_295 + -0.0001384775938347366965996*var_292 + 0.0016256065363208220975882*var_32 + 0.0004334950763522191934975*var_192 + 0.0000280969030969030968787*var_199 + 0.0005960557299843014791504*var_62 + 0.0019507278435849863436335*var_4 + 0.0000240830597973455111263*var_291 + 0.0004876819608962465859084*var_296 + -0.0009211770372484657251957*var_162 + -0.0002287890680747823506178*var_60 + 0.0003251213072641644086756*var_72 + 0.0060689310689310688173848*var_87 + 0.0003191005423148280317411*var_23 + 0.0000842907092907092906362*var_75 + 0.0052019409162266305388100*var_237 + 0.0028177179962894246222083*var_109 + 0.0000561938061938061937575*var_294 + 0.0006201387897816468784684*var_21 + var_290 + 0.0026009704581133152694050*var_30 + var_288 + 0.0000040138432995575849054*var_84 + 0.0030344655344655344086924*var_79 + 0.0001625606536320822043378*var_221; + A[39] = 0.9000000000000000222044605*var_12*var_297; + A[93] = A[39]; + const double var_298 = 0.0000122422220636506343426*var_39 + 0.0001904345654345654479528*var_100 + -0.0000584014200085628671071*var_34 + 0.0000168581418581418581272*var_36 + 0.0009609140859140859539100*var_33 + 0.0001318547523904666765506*var_35; + const double var_299 = 0.0003203046953046953179700*var_204 + 0.0000638201084629656009272*var_44 + -0.0002095226202369059335853*var_43 + 0.0000505744255744255743817*var_122 + 0.0001968790138432995637068*var_42 + 0.0000127997002997002996892*var_46; + const double var_300 = 0.2500000000000000000000000*var_17 + var_80; + const double var_301 = 0.0006068931068931069467906*var_27; + const double var_302 = 0.0002035018552875695566507*var_79; + const double var_303 = 0.0002035018552875695566507*var_63; + const double var_304 = -0.0001842354074496931667232*var_76 + var_303 + 0.0006406093906093906359400*var_134 + -0.0000238823676323676323469*var_58 + 0.0038436563436563438156401*var_162 + 0.0000140484515484515484394*var_60 + 0.0001766091051805337595534*var_22 + -0.0000371280505209076622805*var_19 + var_299 + -0.0000202030112744398468189*var_23 + 0.0003901455687169972687267*var_300 + -0.0000297693378050520878364*var_75 + var_302 + 0.0001444983587840730735342*var_129 + 0.0000028096903096903096879*var_86 + 0.0007008170401027544052855*w[0][6]*w[1][6] + var_298 + 0.0001212180676466390673611*var_67 + -0.0000166574496931639793478*var_57 + var_121 + -0.0000523806550592264833963*var_25 + 0.0000866990152704438359890*var_30 + 0.0003090659340659340521135*var_69 + -0.0000529158341658341691764*var_24 + 0.0012137862137862138935812*var_31 + 0.0000089642500356786063734*var_65 + 0.0003287337662337662131523*var_127 + var_301 + 0.0000828189667475381750697*var_55 + 0.0000939239332096474855999*var_1 + -0.0001418893606393606290732*var_13 + 0.0001030219780219780218887*var_15 + 0.0000117070429570429570328*var_16 + -0.0000558593192521763935330*var_73 + 0.0000754602540316825972375*var_20 + 0.0000090311474240045670959*var_14 + 0.0006321803196803196323375*var_221 + 0.0000915156272299129402471*w[0][3]*w[1][3]; + A[55] = 4.5000000000000000000000000*var_12*var_304; + const double var_305 = var_40 + 0.0006478343085485942448934*var_34 + 0.0055257242757242759634284*w[0][0]*w[1][0] + 0.0037087912087912086253616*var_33 + 0.0010676823176823176542866*var_36 + var_102 + 0.0013823676323676324477485*var_35; + const double var_306 = 0.0001348651348651348650179*var_48 + 0.0005638111888111887971473*var_51 + -0.0001477094334237191340046*var_52 + -0.0004575781361495647012357*var_49 + -0.0000097224204367061504994*w[0][1]*w[1][1] + -0.0051080169830169828634747*var_50; + const double var_307 = var_82 + -0.0001011488511488511487634*var_43 + -0.0018038211788211787247466*var_45 + -0.0002004245754245754379541*var_122 + -0.0013799593263878978752907*var_42 + 0.0003914835164835164696244*var_46; + const double var_308 = 0.0006068931068931069467906*var_31; + const double var_309 = -0.0001453011274439845886518*var_73; + const double var_310 = 0.1906250000000000166533454*var_23 + 0.6750000000000000444089210*var_76; + const double var_311 = 0.0034278221778221776294693*var_219 + -0.0020109354930783500045588*w[0][4]*w[1][4] + var_306 + -0.0021241258741258742595570*var_29 + 0.0007706579135150563560422*var_199 + var_309 + 0.0005057442557442557709221*var_62 + 0.0004656058227486798524117*var_260 + 0.0037087912087912086253616*var_134 + 0.0111263736263736267434465*var_162 + 0.0004607892107892108159162*var_22 + 0.0004045954045954045950537*var_214 + -0.0002817717996289424839049*var_19 + -0.0018038211788211787247466*var_72 + -0.0019049700299700299006150*var_18 + 0.0004270729270729270725566*var_215 + 0.0001164014556871699631029*var_75 + -0.0008597652347652347780416*w[0][6]*w[1][6] + var_307 + 0.0003427822177822177954730*var_61 + 0.0013823676323676324477485*var_67 + 0.0013871842443271013758238*var_109 + -0.0002191558441558441692066*var_21 + 0.0002568859711716854339440*var_310 + 0.0001348651348651348650179*var_0 + var_308 + 0.0008742150706436419959483*var_25 + 0.0068556443556443552589386*var_69 + -0.0001436955901241615584166*var_65 + -0.0028939810189810189107462*var_13 + var_114 + var_305 + 0.0004214535464535464396284*var_79 + 0.0003227130012844298362178*var_14 + -0.0010716961609818752027695*w[0][3]*w[1][3]; + const double var_312 = var_0 + var_2; + const double var_313 = -1.0000000000000000000000000*var_49; + const double var_314 = -0.0001453011274439845886518*var_58; + const double var_315 = -1.0000000000000000000000000*var_33; + const double var_316 = var_23 + var_24; + const double var_317 = var_70 + var_96; + const double var_318 = var_39 + var_170; + const double var_319 = var_17 + var_29; + const double var_320 = var_50 + var_34; + const double var_321 = 0.0102497502497502501750404*w[0][9]*w[1][9]; + const double var_322 = -1.0000000000000000000000000*var_155; + const double var_323 = -0.0000410303981732553112367*var_180 + -0.0000388896817468246019977*var_150 + -0.0008016983016983017518164*var_149 + 0.0072827172827172829278064*var_163 + 0.0005221762364619507781893*var_171 + 0.0022552447552447551885890*var_174 + 0.0015659340659340658784976*var_183 + -0.0005694305694305694300755*var_179 + -0.0013711288711288711818920*var_158 + 0.0274225774225774210357542*var_168 + -0.0115759240759240756429849*var_320 + 0.0005844155844155844150775*var_176 + var_321 + 0.0221028971028971038537136*var_148 + 0.0009890109890109890101312*var_159 + 0.0137112887112887105178771*var_167 + 0.0027872127872127874272101*var_43 + 0.0025367489653203936263159*var_161 + -0.0102647352647352654853030*var_157 + 0.0042707292707292706171462*var_319 + 0.0002154195011337868440136*var_46 + 0.0008766233766233766768264*var_322 + -0.0004495504495504495500596*var_182 + -0.0010082774368488653729536*var_45 + -0.0008541458541458541451133*var_160 + 0.0031468531468531470672578*var_44 + 0.0018206793206793207319516*var_156 + 0.0023684648684648684086040*var_98 + -0.0002622377622377622375348*var_154 + 0.0494838494838494846739252*w[0][2]*w[1][2]; + A[22] = 0.0312500000000000000000000*var_12*var_323; + const double var_324 = 0.0005638111888111887971473*var_39 + -0.0051080169830169828634747*var_34 + -0.0000097224204367061504994*w[0][0]*w[1][0] + -0.0004575781361495647012357*var_33 + -0.0001477094334237191340046*var_36 + var_102 + 0.0001348651348651348650179*var_35; + const double var_325 = -0.0001453011274439845886518*var_15; + const double var_326 = 0.0006068931068931069467906*var_76; + const double var_327 = -0.0008597652347652347780416*w[0][4]*w[1][4] + 0.0004270729270729270725566*var_293 + var_326 + -0.0021241258741258742595570*var_17 + 0.0008742150706436419959483*var_62 + 0.0003427822177822177954730*var_260 + 0.0004214535464535464396284*var_134 + -0.0002191558441558441692066*var_22 + 0.0003227130012844298362178*var_72 + 0.0111263736263736267434465*var_87 + 0.0001348651348651348650179*var_18 + 0.0013823676323676324477485*var_23 + 0.0068556443556443552589386*var_75 + var_325 + -0.0020109354930783500045588*w[0][6]*w[1][6] + 0.0004045954045954045950537*var_237 + var_314 + var_307 + 0.0004656058227486798524117*var_61 + 0.0033395176252319106954825*var_283 + 0.0034278221778221776294693*var_294 + 0.0004607892107892108159162*var_21 + -0.0019049700299700299006150*var_0 + -0.0010716961609818752027695*w[0][5]*w[1][5] + 0.0005057442557442557709221*var_25 + 0.0013871842443271013758238*var_30 + 0.0001164014556871699631029*var_69 + -0.0028939810189810189107462*var_65 + var_324 + -0.0001436955901241615584166*var_13 + 0.0007706579135150563560422*var_191 + var_107 + 0.0037087912087912086253616*var_79 + -0.0002817717996289424839049*var_20 + -0.0018038211788211787247466*var_14; + A[13] = 0.1250000000000000000000000*var_12*var_327; + A[31] = A[13]; + const double var_328 = 0.0009740259740259740251292*var_101; + const double var_329 = 0.0011800699300699300960116*var_269 + -0.0010476131011845296950313*var_43 + var_328 + 0.0023360568003425144674445*var_45 + -0.0016077672327672327522857*var_122 + -0.0065746753246753242630462*var_42 + -0.0002586699015270443684743*var_46; + const double var_330 = var_315 + var_124; + const double var_331 = 0.0010837376908805480650588*var_330 + -0.0000205151990866276556183*var_39 + 0.0005418688454402740325294*var_36 + -0.0000296578421578421578164*w[0][0]*w[1][0] + var_38 + -0.0009211770372484657251957*var_35; + const double var_332 = var_45 + var_43; + const double var_333 = 0.0010114885114885115418443*var_269 + 0.0005960557299843014791504*var_332 + 0.0001482892107892107823059*var_122 + 0.0030344655344655344086924*var_42 + 0.0000162783644926502064378*var_46; + const double var_334 = var_17 + 0.5000000000000000000000000*var_130; + const double var_335 = var_70 + var_84; + const double var_336 = var_21 + var_55; + const double var_337 = var_60 + var_65; + const double var_338 = 0.5000000000000000000000000*var_193 + var_16; + const double var_339 = var_128 + var_235; + const double var_340 = -1.0000000000000000000000000*var_75; + const double var_341 = var_340 + var_99; + const double var_342 = var_72 + var_87; + const double var_343 = 0.0016256065363208220975882*var_80 + 0.0001625606536320822043378*var_126 + 0.0026009704581133152694050*var_28 + 0.0000240830597973455111263*var_85 + 0.0000040138432995575849054*var_197 + 0.0028177179962894246222083*var_32 + 0.0069359212216355070959595*var_29 + 0.0001926644783787640890105*var_341 + 0.0003311420722135007856102*var_337 + 0.0000842907092907092906362*var_58 + -0.0002287890680747823506178*var_22 + 0.0005960557299843014791504*var_18 + 0.0030344655344655344086924*var_63 + 0.0000280969030969030968787*var_91 + var_333 + 0.0010837376908805480650588*var_129 + 0.0006201387897816468784684*var_57 + 0.0003251213072641644086756*var_0 + 0.0060689310689310688173848*var_2 + 0.0004876819608962465859084*var_342 + 0.0004334950763522191934975*var_236 + 0.0052019409162266305388100*var_334 + 0.0000561938061938061937575*var_338 + var_331 + 0.0003191005423148280317411*var_13 + -0.0001384775938347366965996*var_336 + 0.0002950174825174825240029*var_335 + -0.0009211770372484657251957*var_79 + var_212 + 0.0019507278435849863436335*var_339; + const double var_344 = var_65 + var_55; + const double var_345 = var_17 + var_27; + const double var_346 = var_29 + var_31; + const double var_347 = 0.0125874125874125882690313*var_37; + const double var_348 = 0.0460227272727272707086854*var_204 + 0.0092719780219780219970849*var_44 + 0.0131493506493506485260925*var_165 + var_347 + 0.0017701048951048951440174*var_122 + 0.0103677572427572431412734*var_42 + 0.0016608391608391608919304*var_46; + const double var_349 = var_60 + var_20; + const double var_350 = var_76 + var_26; + const double var_351 = var_75 + var_73; + const double var_352 = var_16 + var_15; + const double var_353 = var_25 + var_18; + const double var_354 = var_63 + var_134; + const double var_355 = -1.0000000000000000000000000*var_35; + const double var_356 = 1.8000000000000000444089210*var_52 + 18.7071428571428555187594611*var_48 + 1.2785714285714284699224663*var_51; + const double var_357 = var_14 + var_0; + const double var_358 = -0.5000000000000000000000000*var_357 + var_49; + const double var_359 = var_358 + 1.5000000000000000000000000*var_140; + const double var_360 = -0.0070148601398601394610322*var_344 + 0.0092719780219780219970849*var_36 + 0.0025287212787212785293500*var_119 + -0.0037743506493506493067180*var_349 + -0.0303446553446553440869238*var_345 + 0.0005244755244755244750696*var_97 + -0.0053665084915084917613348*var_352 + 0.0016608391608391608919304*var_39 + var_348 + 0.0849650349650349634433866*var_350 + 0.0103677572427572431412734*var_33 + 0.0144230769230769238775647*var_351 + 0.0017701048951048951440174*var_100 + 0.0275630619380619369673813*var_354 + 0.0460227272727272707086854*var_124 + -0.0017794705294705294960911*var_145 + 0.0896853146853146820927094*var_359 + 0.0131493506493506485260925*var_355 + 0.0115946553446553447808132*var_144 + -0.0045516983016983016130386*var_346 + 0.0012643606393606392646750*var_146 + 0.0133304195804195800556524*w[0][1]*w[1][1] + 0.0105644355644355647516619*var_316 + 0.0008741258741258741251159*var_356 + -0.0006274975024975024563006*var_225 + -0.0116321178821178813217463*var_353 + 0.0118849900099900103456196*var_250; + A[38] = 0.0321428571428571396850771*var_12*var_360; + A[69] = 0.9000000000000000222044605*var_12*var_343; + A[96] = A[69]; + const double var_361 = var_55 + var_67; + const double var_362 = var_57 + var_19; + const double var_363 = var_16 + var_75; + const double var_364 = var_29 + var_26; + const double var_365 = var_76 + var_17; + const double var_366 = var_65 + var_23; + const double var_367 = var_58 + var_73; + const double var_368 = var_0 + var_62; + const double var_369 = var_14 + var_25; + const double var_370 = var_2 + var_79; + const double var_371 = var_63 + var_87; + const double var_372 = var_31 + var_27; + const double var_373 = -1.0000000000000000000000000*var_48; + const double var_374 = var_72 + var_18; + const double var_375 = var_33 + -0.5000000000000000000000000*var_374; + const double var_376 = var_134 + var_162; + const double var_377 = 1.5000000000000000000000000*var_376 + var_375; + const double var_378 = 0.0005244755244755244750696*var_246 + -0.0037743506493506493067180*var_362 + 0.0016608391608391608919304*var_51 + -0.0045516983016983016130386*var_365 + 0.0460227272727272707086854*var_119 + -0.0006274975024975024563006*var_366 + -0.0116321178821178813217463*var_368 + 0.0896853146853146820927094*var_377 + 0.0275630619380619369673813*var_370 + 0.0144230769230769238775647*var_248 + 0.0105644355644355647516619*var_361 + -0.0017794705294705294960911*var_363 + var_348 + 0.0092719780219780219970849*var_52 + 0.0103677572427572431412734*var_49 + 0.0131493506493506485260925*var_373 + 0.0001748251748251748250232*var_272 + -0.0053665084915084917613348*var_367 + 0.0133304195804195800556524*w[0][0]*w[1][0] + 0.0025287212787212785293500*var_124 + 0.0118849900099900103456196*var_371 + 0.0017701048951048951440174*var_170 + -0.0303446553446553440869238*var_364 + -0.0070148601398601394610322*var_247 + 0.0115946553446553447808132*var_141 + 0.0012643606393606392646750*var_369 + 0.0849650349650349634433866*var_372; + A[57] = 0.0321428571428571396850771*var_12*var_378; + A[75] = A[57]; + const double var_379 = var_168 + var_376 + var_140; + const double var_380 = var_316 + var_174 + var_361; + const double var_381 = var_358 + var_167 + var_375; + const double var_382 = var_350 + var_345 + var_346; + const double var_383 = -0.0202297702297702282348002*var_43 + 0.0053946053946053946007155*var_44; + const double var_384 = var_204 + var_164; + const double var_385 = var_122 + var_171; + const double var_386 = var_154 + var_246 + var_97; + const double var_387 = var_270 + -1.0000000000000000000000000*var_98 + 7.3636363636363642015680853*var_386; + const double var_388 = 0.0161838161838161846695083*var_379 + 1.5000000000000000000000000*var_347 + 0.1875000000000000000000000*var_383 + 0.0002060439560439560437773*var_387 + 0.0121378621378621376347695*var_381 + -0.0037930819180819180108655*var_155 + 0.0010114885114885115418443*var_176 + 0.0065746753246753242630462*var_384 + -0.0023601398601398601920232*var_151 + 0.0012643606393606392646750*var_380 + 0.0008304195804195804459652*var_385 + 0.0091033966033966032260771*var_382; + const double var_389 = -0.0089685314685314689031603*var_49 + -0.0000874125874125874125116*var_356 + -0.0013330419580419581356695*var_170 + 0.0002528721278721278854611*var_50; + const double var_390 = -1.0000000000000000000000000*var_100; + const double var_391 = 0.0000874125874125874125116*var_390 + -0.0001130119880119880118900*var_39 + 0.0055126123876123875669486*var_34 + -0.0007754745254745255009579*var_36 + 0.0002528721278721278854611*var_33 + 0.0023769980019980019823878*var_35; + const double var_392 = var_62 + var_264; + const double var_393 = var_60 + var_67; + const double var_394 = var_393 + var_291 + -0.5000000000000000000000000*var_13; + const double var_395 = 0.0018206793206793207319516*var_252 + var_271 + 0.0040459540459540461673771*var_192 + 0.0060689310689310688173848*var_130 + 0.0002528721278721278854611*var_392 + -0.0014666583416583416164120*w[0][7]*w[1][7] + 0.0001048951048951048950139*var_58 + -0.0015640609390609389647148*var_19 + -0.0010733016983016983956351*var_23 + 0.0109240759240759235243479*var_300 + -0.0014029720279720280656788*var_75 + 0.0033379120879120879362978*var_27 + 0.0092045454545454548356265*var_137 + var_389 + -0.0003558941058941059209023*var_57 + -0.0007548701298701298830277*var_21 + 0.0002509990009990010258883*var_394 + 0.0032704795204795203411585*var_0 + 0.0177010489510489518738545*var_226 + 0.0020735514485514484547823*var_25 + -0.0010395854145854145980654*var_24 + 0.0003277972027972028104710*var_65 + 0.0005057442557442557709221*var_127 + 0.0010751748251748250925774*var_55 + 0.0006799450549450549580177*var_15 + 0.0003933566433566433834072*var_16 + -0.0014816433566433567098342*var_73 + 0.0026298701298701297052185*var_3 + var_391 + 0.0005038711288711288571393*var_20 + 0.0056980519480519476946401*var_14; + A[48] = 0.1607142857142856984253854*var_12*var_395; + A[84] = A[48]; + const double var_396 = 0.0005844155844155844150775*var_44 + 0.0008766233766233766768264*var_165 + var_321 + -0.0115759240759240756429849*var_45 + 0.0005221762364619507781893*var_122 + 0.0018206793206793207319516*var_42 + 0.0023684648684648684086040*var_46; + const double var_397 = 0.0008766233766233766768264*var_355 + 0.0005844155844155844150775*var_36 + 0.0137112887112887105178771*var_358 + -0.0010082774368488653729536*var_50 + 0.0221028971028971038537136*var_351 + 0.0002154195011337868440136*var_51 + 0.0009890109890109890101312*var_346 + -0.0002622377622377622375348*var_97 + 0.0023684648684648684086040*var_39 + var_396 + -0.0013711288711288711818920*var_353 + 0.0025367489653203936263159*var_250 + 0.0018206793206793207319516*var_33 + 0.0042707292707292706171462*var_350 + 0.0015659340659340658784976*var_144 + -0.0115759240759240756429849*var_34 + 0.0031468531468531470672578*var_52 + -0.0005694305694305694300755*var_349 + -0.0102647352647352654853030*var_344 + 0.0494838494838494846739252*w[0][1]*w[1][1] + 0.0274225774225774210357542*var_140 + 0.0072827172827172829278064*var_354 + 0.0022552447552447551885890*var_316 + 0.0005221762364619507781893*var_100 + 0.0027872127872127874272101*var_48 + -0.0008541458541458541451133*var_345 + -0.0004495504495504495500596*var_146 + -0.0000388896817468246019977*var_145 + -0.0008016983016983017518164*var_352 + -0.0000410303981732553112367*var_225; + const double var_398 = 0.0017139110889110888147346*var_340; + const double var_399 = -0.0009151562722991294024713*var_36 + 0.0023360568003425144674445*var_50 + 0.0004856750392464678116669*var_141 + -0.0002586699015270443684743*var_51 + 0.0004281432852861424441168*var_229 + -0.0043349507635221922602353*var_364 + -0.0005391929499072356307340*var_247 + 0.0140163408020550876720289*var_34 + 0.0026370950478093332057516*var_368 + -0.0141608391608391611521389*var_371 + 0.0039375802768659906236137*var_369 + -0.0016077672327672327522857*var_170 + -0.0017339803054088767739899*var_365 + -0.0010021228771228771897706*var_367 + -0.0004776473526473526604909*var_366 + 0.0003599079491936634693852*var_248 + 0.0065746753246753242630462*var_313 + 0.0023842229199372059166018*var_372 + -0.0010476131011845296950313*var_48 + -0.0011680284001712572337223*var_376 + 0.0001806229484800913351415*var_374 + var_329 + -0.0001400385328956757372085*w[0][0]*w[1][0] + 0.0007679820179820179542468*var_361 + -0.0028377872127872127983039*var_363 + 0.0014811081775367488343187*var_35 + -0.0003331489938632795598517*var_246 + -0.0007666440702154986991390*var_362 + -0.0064060939060939063594002*var_370 + 0.0003612458969601826702829*var_315 + 0.0011800699300699300960116*var_286; + A[34] = 0.2250000000000000055511151*var_12*var_399; + A[43] = A[34]; + const double var_400 = var_122 + var_46; + const double var_401 = 0.0035402097902097902880347*var_204 + 0.0010596546310832025573206*var_269 + 0.0002435064935064935062823*var_400 + 0.0002889967175681461470683*var_43 + var_178 + 0.0039737048665620094273221*var_42; + const double var_402 = var_80 + var_130; + const double var_403 = var_316 + var_352; + const double var_404 = var_225 + var_349; + const double var_405 = -0.0003558941058941059209023*var_344 + 0.0000945483088340231099750*var_51 + 0.0010596546310832025573206*var_208 + var_401 + 0.0065024261452832883903530*var_345 + 0.0004120879120879120875547*var_97 + 0.0002889967175681461470683*var_35 + -0.0027454688168973883158341*var_50 + 0.0042707292707292706171462*var_52 + 0.0001953403739118024637009*var_404 + 0.0000481661195946910222526*var_373 + 0.0039737048665620094273221*var_33 + 0.0017794705294705294960911*var_351 + 0.0038292065077779359472121*var_354 + 0.0035402097902097902880347*var_124 + 0.0006743256743256743250894*var_359 + 0.0002435064935064935062823*var_285 + 0.0013111888111888112418840*var_170 + 0.0078029113743399453745342*var_346 + 0.0121378621378621376347695*var_402 + 0.0002087198515769944184677*var_403 + -0.0023119737405451691765468*var_353 + 0.0074416654773797625416210*var_250 + -0.0002461823890395318809726*var_147; + A[19] = 0.0750000000000000111022302*var_12*var_405; + const double var_406 = 0.0007080419580419580142389*var_204 + 0.0001240277579563293702727*var_44 + 0.0000176163122591694005592*w[0][2]*w[1][2] + var_120 + -0.0000830865563008420179598*var_43 + 0.0000848927857856429201981*var_42 + 0.0000383991008991008990676*var_46; + const double var_407 = 0.0007080419580419580142389*var_124 + 0.0000383991008991008990676*var_39 + var_120 + 0.0001240277579563293702727*var_36 + 0.0000176163122591694005592*w[0][0]*w[1][0] + 0.0000848927857856429201981*var_33 + -0.0000830865563008420179598*var_35; + const double var_408 = 0.0001904345654345654479528*var_170 + 0.0000122422220636506343426*var_51 + 0.0001318547523904666765506*var_48 + 0.0000168581418581418581272*var_52 + 0.0009609140859140859539100*var_49 + -0.0000584014200085628671071*var_50; + const double var_409 = 0.0002035018552875695566507*var_2; + const double var_410 = 0.0003287337662337662131523*var_126 + 0.0007008170401027544052855*w[0][4]*w[1][4] + 0.0012137862137862138935812*var_76 + 0.0000028096903096903096879*var_108 + var_409 + 0.0003901455687169972687267*var_274 + -0.0000523806550592264833963*var_62 + 0.0000117070429570429570328*var_58 + -0.0000166574496931639793478*var_60 + 0.0000754602540316825972375*var_19 + 0.0000090311474240045670959*var_72 + 0.0038436563436563438156401*var_87 + var_299 + 0.0001212180676466390673611*var_23 + 0.0003090659340659340521135*var_75 + var_115 + var_407 + -0.0000202030112744398468189*var_67 + 0.0000866990152704438359890*var_109 + 0.0000140484515484515484394*var_57 + 0.0001766091051805337595534*var_21 + 0.0000915156272299129402471*w[0][5]*w[1][5] + 0.0001444983587840730735342*var_128 + -0.0000297693378050520878364*var_69 + var_135 + 0.0000828189667475381750697*var_24 + -0.0001842354074496931667232*var_31 + -0.0001418893606393606290732*var_65 + -0.0000529158341658341691764*var_55 + 0.0006321803196803196323375*var_1 + 0.0000089642500356786063734*var_13 + -0.0000558593192521763935330*var_15 + -0.0000238823676323676323469*var_16 + var_408 + 0.0006406093906093906359400*var_79 + 0.0001030219780219780218887*var_73 + -0.0000371280505209076622805*var_20 + 0.0000939239332096474855999*var_221; + const double var_411 = 0.0031468531468531470672578*var_36 + -0.0115759240759240756429849*var_50 + 0.0015659340659340658784976*var_141 + 0.0018206793206793207319516*var_49 + 0.0023684648684648684086040*var_51 + 0.0002154195011337868440136*var_39 + var_396 + -0.0008541458541458541451133*var_364 + 0.0008766233766233766768264*var_373 + -0.0102647352647352654853030*var_247 + -0.0010082774368488653729536*var_34 + 0.0005844155844155844150775*var_52 + -0.0013711288711288711818920*var_368 + 0.0025367489653203936263159*var_371 + -0.0004495504495504495500596*var_369 + 0.0005221762364619507781893*var_170 + 0.0009890109890109890101312*var_365 + -0.0008016983016983017518164*var_367 + -0.0000410303981732553112367*var_366 + 0.0221028971028971038537136*var_248 + 0.0042707292707292706171462*var_372 + 0.0274225774225774210357542*var_376 + 0.0494838494838494846739252*w[0][0]*w[1][0] + 0.0022552447552447551885890*var_361 + -0.0000388896817468246019977*var_363 + 0.0027872127872127874272101*var_35 + -0.0005694305694305694300755*var_362 + -0.0002622377622377622375348*var_246 + 0.0072827172827172829278064*var_370 + 0.0137112887112887105178771*var_375; + A[0] = 0.0312500000000000000000000*var_12*var_411; + const double var_412 = -0.0002004245754245754379541*var_170 + 0.0003914835164835164696244*var_51 + -0.0001011488511488511487634*var_48 + -0.0013799593263878978752907*var_49 + var_53 + -0.0018038211788211787247466*var_50; + const double var_413 = 0.0000505744255744255743817*var_170 + 0.0000127997002997002996892*var_51 + -0.0002095226202369059335853*var_48 + 0.0000638201084629656009272*var_52 + 0.0003203046953046953179700*var_119 + 0.0001968790138432995637068*var_49; + const double var_414 = 0.0000357678036249464801222*var_46; + const double var_415 = 0.0010676823176823176542866*var_44 + var_414 + 0.0055257242757242759634284*w[0][2]*w[1][2] + 0.0013823676323676324477485*var_43 + 0.0006478343085485942448934*var_45 + 0.0037087912087912086253616*var_42; + const double var_416 = var_29 + 0.5000000000000000000000000*var_32; + const double var_417 = var_57 + var_13; + const double var_418 = var_58 + 0.5000000000000000000000000*var_84; + const double var_419 = 0.0146634615384615401428858*var_55 + 0.0519230769230769259592329*var_27; + const double var_420 = 0.0013871842443271013758238*var_80 + var_412 + -0.0021241258741258742595570*var_76 + 0.0004045954045954045950537*var_416 + var_309 + -0.0019049700299700299006150*var_62 + -0.0020109354930783500045588*w[0][8]*w[1][8] + -0.0010716961609818752027695*w[0][7]*w[1][7] + 0.0004214535464535464396284*var_162 + -0.0002817717996289424839049*var_22 + 0.0004607892107892108159162*var_60 + 0.0034278221778221776294693*var_418 + 0.0001348651348651348650179*var_72 + 0.0003227130012844298362178*var_18 + -0.0028939810189810189107462*var_23 + 0.0111263736263736267434465*var_63 + 0.0003427822177822177954730*var_96 + 0.0004270729270729270725566*var_417 + var_132 + 0.0033395176252319106954825*var_419 + 0.0004656058227486798524117*var_86 + var_116 + 0.0008742150706436419959483*var_0 + 0.0037087912087912086253616*var_2 + -0.0018038211788211787247466*var_25 + var_415 + -0.0001436955901241615584166*var_24 + 0.0013823676323676324477485*var_65 + var_324 + 0.0001164014556871699631029*var_15 + 0.0068556443556443552589386*var_16 + -0.0002191558441558441692066*var_20 + 0.0005057442557442557709221*var_14 + 0.0007706579135150563560422*var_340 + -0.0008597652347652347780416*w[0][3]*w[1][3]; + A[24] = 0.1250000000000000000000000*var_12*var_420; + const double var_421 = var_86 + var_199; + const double var_422 = -1.0000000000000000000000000*var_51; + const double var_423 = 0.0016608391608391608919304*var_98 + 0.0008741258741258741251159*var_233 + 0.0105644355644355647516619*var_174 + 0.0092719780219780219970849*var_176 + 0.0017701048951048951440174*var_171 + 0.0115946553446553447808132*var_183 + 0.0025287212787212785293500*var_204 + 0.0275630619380619369673813*var_163 + 0.0144230769230769238775647*var_148 + var_347 + -0.0006274975024975024563006*var_180 + -0.0303446553446553440869238*var_160 + 0.0118849900099900103456196*var_161 + 0.0103677572427572431412734*var_156 + -0.0037743506493506493067180*var_179 + 0.0460227272727272707086854*var_164 + -0.0053665084915084917613348*var_149 + -0.0045516983016983016130386*var_159 + 0.0849650349650349634433866*var_319 + -0.0017794705294705294960911*var_150 + -0.0116321178821178813217463*var_158 + -0.0070148601398601394610322*var_157 + 0.0131493506493506485260925*var_322 + 0.0133304195804195800556524*w[0][2]*w[1][2] + 0.0896853146853146820927094*var_169 + 0.0005244755244755244750696*var_154 + 0.0012643606393606392646750*var_182; + A[46] = 0.0321428571428571396850771*var_12*var_423; + A[64] = A[46]; + const double var_424 = 0.0004281432852861424441168*var_422 + 0.0140163408020550876720289*var_50 + 0.0003599079491936634693852*var_351 + -0.0017339803054088767739899*var_346 + -0.0003331489938632795598517*var_97 + -0.0002586699015270443684743*var_39 + 0.0026370950478093332057516*var_353 + -0.0141608391608391611521389*var_250 + 0.0011800699300699300960116*var_208 + 0.0023842229199372059166018*var_350 + 0.0004856750392464678116669*var_144 + 0.0023360568003425144674445*var_34 + -0.0009151562722991294024713*var_52 + -0.0007666440702154986991390*var_349 + -0.0005391929499072356307340*var_344 + -0.0001400385328956757372085*w[0][1]*w[1][1] + -0.0011680284001712572337223*var_140 + 0.0001806229484800913351415*var_357 + -0.0064060939060939063594002*var_354 + 0.0007679820179820179542468*var_316 + 0.0003612458969601826702829*var_313 + -0.0016077672327672327522857*var_100 + 0.0014811081775367488343187*var_48 + -0.0043349507635221922602353*var_345 + var_329 + -0.0010476131011845296950313*var_35 + 0.0039375802768659906236137*var_146 + -0.0028377872127872127983039*var_145 + -0.0010021228771228771897706*var_352 + -0.0004776473526473526604909*var_225 + 0.0065746753246753242630462*var_315; + A[56] = 0.2250000000000000055511151*var_12*var_424; + A[65] = A[56]; + const double var_425 = var_60 + var_16; + const double var_426 = -0.0002817717996289424839049*var_13; + const double var_427 = var_14 + var_15; + const double var_428 = 0.0021241258741258742595570*var_80 + var_47 + var_261 + 0.0007706579135150563560422*var_197 + -0.0009970386756101041070971*var_29 + 0.0197802197802197793352619*var_201 + 0.0002022977022977022975268*var_130 + -0.0001613565006422149181089*var_62 + var_398 + -0.0051080169830169828634747*w[0][8]*w[1][8] + 0.0043638504352790062623679*w[0][7]*w[1][7] + 0.0001123876123876123875149*var_260 + -0.0001436955901241615584166*var_58 + 0.0004551698301698301829879*var_22 + -0.0004656058227486798524117*var_19 + -0.0013366098187526757878896*var_72 + -0.0013799593263878978752907*var_18 + -0.0007273084058798344854815*var_63 + 0.0022975239046667617417996*var_27 + var_426 + 0.0000489688882546025373702*var_425 + 0.0002873911802483231168331*var_67 + 0.0000288996717568146119963*var_109 + -0.0001453011274439845886518*var_21 + 0.0004214535464535464396284*var_0 + 0.0029814828029113742483003*w[0][5]*w[1][5] + 0.0013823676323676324477485*var_427 + var_90 + 0.0003227130012844298362178*var_142 + 0.0006968031968031968568025*var_65 + 0.0018206793206793207319516*var_55 + var_186 + -0.0028939810189810189107462*var_73 + 0.0004407199942914228566609*var_20 + -0.0019049700299700299006150*w[0][3]*w[1][3]; + const double var_429 = var_362 + var_366; + const double var_430 = var_32 + 0.2500000000000000000000000*var_26; + const double var_431 = 0.0006068931068931069467906*var_29; + const double var_432 = 0.0002035018552875695566507*var_162; + const double var_433 = 0.0001444983587840730735342*var_126 + 0.0000028096903096903096879*var_99 + 0.0012137862137862138935812*var_17 + 0.0000866990152704438359890*var_130 + 0.0003901455687169972687267*var_430 + 0.0000915156272299129402471*w[0][7]*w[1][7] + var_432 + 0.0001030219780219780218887*var_58 + 0.0001766091051805337595534*var_60 + -0.0000371280505209076622805*var_22 + 0.0000140484515484515484394*var_19 + 0.0000090311474240045670959*var_18 + -0.0001418893606393606290732*var_23 + 0.0038436563436563438156401*var_63 + -0.0000238823676323676323469*var_75 + -0.0001842354074496931667232*var_27 + var_302 + 0.0006321803196803196323375*var_129 + var_407 + -0.0000529158341658341691764*var_67 + 0.0000754602540316825972375*var_57 + -0.0000166574496931639793478*var_21 + -0.0000523806550592264833963*var_0 + var_431 + 0.0006406093906093906359400*var_2 + 0.0003287337662337662131523*var_128 + -0.0000558593192521763935330*var_69 + 0.0000089642500356786063734*var_24 + 0.0001212180676466390673611*var_65 + 0.0000939239332096474855999*var_127 + -0.0000202030112744398468189*var_55 + var_413 + 0.0000828189667475381750697*var_13 + -0.0000297693378050520878364*var_15 + var_123 + 0.0003090659340659340521135*var_16 + 0.0000117070429570429570328*var_73 + 0.0007008170401027544052855*w[0][3]*w[1][3]; + A[44] = 4.5000000000000000000000000*var_12*var_433; + const double var_434 = 0.0002528721278721278854611*var_48 + var_228 + 0.0002191558441558441692066*var_422 + -0.0023264235764235766112940*var_49 + -0.0002666083916083915946078*w[0][1]*w[1][1] + 0.0010789210789210789201431*var_286 + 0.0036919330669330668349970*var_50; + const double var_435 = -0.0007754745254745255009579*var_44 + 0.0023769980019980019823878*var_43 + 0.0055126123876123875669486*var_45 + -0.0000874125874125874125116*var_122 + 0.0002528721278721278854611*var_42 + -0.0001130119880119880118900*var_46; + const double var_436 = var_14 + var_64; + const double var_437 = -0.5000000000000000000000000*var_23 + var_425 + var_218; + const double var_438 = 0.0060689310689310688173848*var_28 + 0.0033379120879120879362978*var_29 + 0.0109240759240759235243479*var_430 + 0.0006799450549450549580177*var_58 + -0.0015640609390609389647148*var_22 + 0.0032704795204795203411585*var_72 + var_273 + 0.0056980519480519476946401*var_18 + 0.0001048951048951048950139*var_75 + 0.0026298701298701297052185*var_137 + -0.0014666583416583416164120*w[0][6]*w[1][6] + -0.0010395854145854145980654*var_67 + 0.0005038711288711288571393*var_57 + -0.0003558941058941059209023*var_21 + 0.0020735514485514484547823*var_0 + 0.0040459540459540461673771*var_226 + 0.0002528721278721278854611*var_436 + 0.0005057442557442557709221*var_128 + 0.0092045454545454548356265*var_235 + -0.0014816433566433567098342*var_69 + var_434 + 0.0177010489510489518738545*var_236 + 0.0003277972027972028104710*var_24 + 0.0018206793206793207319516*var_334 + -0.0010733016983016983956351*var_55 + var_435 + 0.0010751748251748250925774*var_13 + -0.0014029720279720280656788*var_15 + 0.0003933566433566433834072*var_73 + -0.0007548701298701298830277*var_20 + 0.0002509990009990010258883*var_437; + A[58] = 0.1607142857142856984253854*var_12*var_438; + A[91] = A[19]; + const double var_439 = var_170 + var_51; + const double var_440 = var_28 + var_32; + const double var_441 = var_367 + var_361; + const double var_442 = 6.7500000000000000000000000*var_369 + var_363 + var_141; + const double var_443 = 0.0010596546310832025573206*var_286 + 0.0042707292707292706171462*var_36 + 0.0004120879120879120875547*var_246 + 0.0121378621378621376347695*var_440 + 0.0002889967175681461470683*var_48 + 0.0078029113743399453745342*var_365 + 0.0035402097902097902880347*var_119 + 0.0002087198515769944184677*var_441 + -0.0027454688168973883158341*var_34 + 0.0001953403739118024637009*var_429 + var_401 + -0.0023119737405451691765468*var_368 + 0.0006743256743256743250894*var_377 + 0.0038292065077779359472121*var_370 + -0.0002461823890395318809726*var_442 + 0.0017794705294705294960911*var_248 + 0.0000945483088340231099750*var_39 + 0.0002435064935064935062823*var_439 + 0.0039737048665620094273221*var_49 + 0.0013111888111888112418840*var_100 + 0.0074416654773797625416210*var_371 + 0.0000481661195946910222526*var_355 + 0.0065024261452832883903530*var_364 + -0.0003558941058941059209023*var_247; + A[9] = 0.0750000000000000111022302*var_12*var_443; + const double var_444 = -0.0002135364635364635362783*var_44 + var_414 + -0.0025661838161838163713258*w[0][2]*w[1][2] + -0.0007273084058798344854815*var_43 + var_38 + -0.0009705473098330240269010*var_45 + -0.0018038211788211787247466*var_42; + const double var_445 = var_22 + var_67; + const double var_446 = -0.0001453011274439845886518*var_75; + const double var_447 = 0.0004045954045954045950537*var_252 + var_412 + var_105 + -0.0010716961609818752027695*w[0][4]*w[1][4] + var_446 + 0.0013871842443271013758238*var_130 + 0.0001348651348651348650179*var_62 + -0.0008597652347652347780416*w[0][8]*w[1][8] + 0.0034278221778221776294693*var_251 + 0.0111263736263736267434465*var_134 + 0.0037087912087912086253616*var_162 + -0.0002191558441558441692066*var_60 + -0.0019049700299700299006150*var_72 + -0.0018038211788211787247466*var_18 + -0.0001436955901241615584166*var_23 + 0.0004656058227486798524117*var_96 + 0.0003427822177822177954730*var_86 + var_314 + -0.0002817717996289424839049*var_57 + 0.0004270729270729270725566*var_445 + 0.0005057442557442557709221*var_0 + 0.0007706579135150563560422*var_196 + -0.0021241258741258742595570*var_26 + 0.0004214535464535464396284*var_2 + 0.0003227130012844298362178*var_25 + -0.0028939810189810189107462*var_24 + 0.0017982017982017982002385*var_202 + var_301 + 0.0013823676323676324477485*var_55 + 0.0068556443556443552589386*var_15 + var_305 + 0.0001164014556871699631029*var_16 + 0.0004607892107892108159162*var_20 + 0.0008742150706436419959483*var_14 + -0.0020109354930783500045588*w[0][3]*w[1][3]; + A[7] = 0.1250000000000000000000000*var_12*var_447; + A[70] = A[7]; + const double var_448 = 0.0000866990152704438359890*var_80 + 0.0000915156272299129402471*w[0][4]*w[1][4] + -0.0001842354074496931667232*var_17 + var_409 + 0.0007008170401027544052855*w[0][8]*w[1][8] + 0.0038436563436563438156401*var_134 + -0.0000558593192521763935330*var_58 + 0.0006406093906093906359400*var_162 + 0.0000754602540316825972375*var_22 + -0.0000166574496931639793478*var_19 + 0.0000089642500356786063734*var_23 + 0.0000117070429570429570328*var_75 + 0.0012137862137862138935812*var_27 + var_406 + 0.0000939239332096474855999*var_129 + var_298 + 0.0000028096903096903096879*var_61 + 0.0000828189667475381750697*var_67 + -0.0000371280505209076622805*var_57 + 0.0000140484515484515484394*var_21 + var_308 + 0.0000090311474240045670959*var_25 + 0.0003901455687169972687267*var_139 + 0.0001030219780219780218887*var_69 + -0.0001418893606393606290732*var_24 + -0.0000202030112744398468189*var_65 + 0.0006321803196803196323375*var_127 + 0.0001212180676466390673611*var_55 + 0.0001444983587840730735342*var_1 + var_413 + -0.0000529158341658341691764*var_13 + 0.0003090659340659340521135*var_15 + var_133 + -0.0000297693378050520878364*var_16 + -0.0000238823676323676323469*var_73 + 0.0001766091051805337595534*var_20 + -0.0000523806550592264833963*var_14 + 0.0003287337662337662131523*var_221; + A[77] = 4.5000000000000000000000000*var_12*var_448; + const double var_449 = -1.0000000000000000000000000*var_156; + const double var_450 = var_119 + var_313; + const double var_451 = -0.0000205151990866276556183*var_51 + -0.0009211770372484657251957*var_48 + 0.0005418688454402740325294*var_52 + -0.0000296578421578421578164*w[0][1]*w[1][1] + var_38 + 0.0010837376908805480650588*var_450; + const double var_452 = var_43 + var_42; + const double var_453 = 0.0004334950763522191934975*var_204 + 0.0006502426145283288173513*var_44 + -0.0001625606536320822043378*var_452 + 0.0000343406593406593406296*var_122 + 0.0000173933209647495371311*var_46; + const double var_454 = 0.0052019409162266305388100*var_252 + 0.0028177179962894246222083*var_80 + 0.0002950174825174825240029*var_198 + -0.0001384775938347366965996*var_276 + 0.0026009704581133152694050*var_130 + 0.0000561938061938061937575*var_251 + 0.0000040138432995575849054*var_112 + 0.0060689310689310688173848*var_134 + 0.0030344655344655344086924*var_162 + var_453 + -0.0002287890680747823506178*var_19 + -0.0009211770372484657251957*var_63 + 0.0069359212216355070959595*var_27 + 0.0001625606536320822043378*var_129 + 0.0000240830597973455111263*var_425 + 0.0016256065363208220975882*var_109 + 0.0003311420722135007856102*var_445 + var_451 + 0.0019507278435849863436335*var_138 + 0.0004334950763522191934975*var_226 + var_210 + 0.0003251213072641644086756*var_25 + 0.0001926644783787640890105*var_421 + 0.0004876819608962465859084*var_312 + 0.0003191005423148280317411*var_55 + 0.0000842907092907092906362*var_15 + 0.0006201387897816468784684*var_20 + 0.0005960557299843014791504*var_14 + 0.0010837376908805480650588*var_221 + 0.0000280969030969030968787*var_340; + A[79] = 0.9000000000000000222044605*var_12*var_454; + A[97] = A[79]; + const double var_455 = -0.0007385471671185956429179*var_44 + 0.0019574175824175824023321*w[0][2]*w[1][2] + var_187 + 0.0032391715427429711160467*var_43 + 0.0043710753532182101965819*var_45 + 0.0149074140145568703741397*var_42 + -0.0000512879977165691441281*var_46; + const double var_456 = var_126 + var_236; + const double var_457 = var_191 + var_108; + const double var_458 = var_63 + var_18; + const double var_459 = 0.0028177179962894246222083*var_28 + 0.0052019409162266305388100*var_110 + -0.0001384775938347366965996*var_393 + 0.0000561938061938061937575*var_113 + 0.0000280969030969030968787*var_70 + 0.0026009704581133152694050*var_32 + 0.0003251213072641644086756*var_62 + 0.0019507278435849863436335*var_456 + var_453 + 0.0006201387897816468784684*var_19 + 0.0005960557299843014791504*var_72 + 0.0030344655344655344086924*var_87 + 0.0000040138432995575849054*var_216 + 0.0001926644783787640890105*var_457 + 0.0004876819608962465859084*var_458 + 0.0003311420722135007856102*var_111 + 0.0069359212216355070959595*var_26 + -0.0009211770372484657251957*var_2 + 0.0001625606536320822043378*var_128 + 0.0016256065363208220975882*var_30 + var_288 + 0.0004334950763522191934975*var_235 + 0.0003191005423148280317411*var_24 + 0.0002950174825174825240029*var_257 + 0.0000240830597973455111263*var_59 + 0.0010837376908805480650588*var_1 + var_331 + 0.0060689310689310688173848*var_79 + 0.0000842907092907092906362*var_73 + -0.0002287890680747823506178*var_20; + A[89] = 0.9000000000000000222044605*var_12*var_459; + A[98] = A[89]; + A[81] = A[18]; + const double var_460 = var_148 + var_154 + var_157; + const double var_461 = 0.0023280291137433993704786*var_204 + 0.0007305194805194805459519*var_44 + var_152 + 0.0002448444412730126800749*var_43 + 0.0029605810855810855107551*var_122 + 0.0021353646353646353085731*var_42 + 0.0002692743764172335482407*var_46; + const double var_462 = var_351 + var_344 + var_97; + const double var_463 = var_461 + 0.0007305194805194805459519*var_36 + 0.0038532895675752816717907*var_119 + 0.0006527202955774384727367*var_51 + 0.0005820072784358498426197*var_48 + -0.0000486121021835307491089*var_349 + -0.0007385471671185956429179*var_345 + 0.0019574175824175824023321*var_352 + 0.0002692743764172335482407*var_318 + 0.0002448444412730126800749*var_35 + 0.0002836449265020693434776*var_52 + 0.0001788390181247324006112*var_462 + 0.0014369559012416153673253*var_358 + 0.0005860211217354073911026*var_350 + 0.0021353646353646353085731*var_33 + 0.0029605810855810855107551*var_100 + 0.0023039460539460540795809*var_354 + 0.0023280291137433993704786*var_124 + 0.0028190559440559440941565*var_145 + -0.0000512879977165691441281*var_144 + 0.0006261595547309833096131*var_346 + -0.0007265056372199228890488*var_146 + 0.0022035999714571140664643*var_140 + -0.0007117882117882118418045*var_316 + -0.0010021228771228771897706*var_225 + -0.0014088589981447123111041*var_353 + 0.0069118381618381618050617*var_250; + A[2] = 0.0250000000000000013877788*var_12*var_463; + const double var_464 = var_122 + var_98; + const double var_465 = -0.0007117882117882118418045*var_174 + 0.0001788390181247324006112*var_460 + 0.0029605810855810855107551*var_171 + 0.0007305194805194805459519*var_176 + 0.0002692743764172335482407*var_464 + -0.0000512879977165691441281*var_183 + 0.0038532895675752816717907*var_204 + 0.0022035999714571140664643*var_168 + 0.0023039460539460540795809*var_163 + -0.0010021228771228771897706*var_180 + -0.0007385471671185956429179*var_160 + 0.0069118381618381618050617*var_161 + 0.0021353646353646353085731*var_156 + 0.0006527202955774384727367*var_46 + -0.0000486121021835307491089*var_179 + 0.0002836449265020693434776*var_44 + 0.0023280291137433993704786*var_164 + var_152 + 0.0002448444412730126800749*var_155 + 0.0019574175824175824023321*var_149 + 0.0005820072784358498426197*var_43 + 0.0006261595547309833096131*var_159 + 0.0005860211217354073911026*var_319 + 0.0014369559012416153673253*var_167 + 0.0028190559440559440941565*var_150 + -0.0014088589981447123111041*var_158 + -0.0007265056372199228890488*var_182; + A[1] = 0.0250000000000000013877788*var_12*var_465; + A[54] = A[45]; + const double var_466 = 0.0314685314685314715399400*var_101; + const double var_467 = var_466 + -0.0586663336663336629217547*var_45 + var_383 + -0.0068181818181818178506437*var_122 + -0.1051948051948051882087398*var_42 + 0.0015234765234765235836223*var_46; + const double var_468 = -0.0586663336663336629217547*var_50 + 0.0015234765234765235836223*var_51 + 0.0201548451548451551529340*var_141 + 0.0036213786213786214839006*var_39 + -0.2063436563436563397910817*var_364 + 0.0202297702297702282348002*var_373 + -0.0226273726273726258351182*var_247 + 0.0008991008991008991001193*var_208 + 0.0829420579420579451301876*var_34 + 0.0053946053946053946007155*var_52 + 0.0068181818181818178506437*var_231 + 0.0101148851148851141174001*var_368 + -0.0930569430569430505739703*var_371 + 0.0950799200799200827649571*var_369 + -0.0364135864135864129043085*var_365 + -0.0031468531468531470672578*var_367 + -0.0142357642357642359687286*var_366 + 0.0430069930069930037030979*var_248 + 0.1051948051948051882087398*var_313 + 0.1335164835164835139824646*var_372 + 0.1476773226773226699304331*var_376 + 0.0216783216783216770018328*w[0][0]*w[1][0] + 0.0271978021978021983207086*var_361 + 0.0041958041958041958005565*var_363 + 0.1024975024975025017504038*var_35 + var_467 + -0.0333416583416583436894065*var_362 + -0.0050199800199800196504052*var_246 + -0.2346653346653346516870187*var_370 + 0.1308191808191808136463408*var_375; + A[68] = 0.0040178571428571424606346*var_12*var_468; + A[86] = A[68]; + const double var_469 = 0.0146634615384615401428858*var_24 + 0.0519230769230769259592329*var_26; + const double var_470 = 0.0013871842443271013758238*var_28 + var_306 + 0.0003427822177822177954730*var_99 + var_446 + 0.0033395176252319106954825*var_469 + 0.0007706579135150563560422*var_70 + 0.0004656058227486798524117*var_108 + -0.0010716961609818752027695*w[0][8]*w[1][8] + -0.0018038211788211787247466*var_62 + -0.0020109354930783500045588*w[0][7]*w[1][7] + 0.0004270729270729270725566*var_337 + 0.0068556443556443552589386*var_58 + -0.0002191558441558441692066*var_19 + 0.0005057442557442557709221*var_72 + 0.0004214535464535464396284*var_87 + 0.0008742150706436419959483*var_18 + 0.0037087912087912086253616*var_63 + var_325 + var_104 + -0.0028939810189810189107462*var_67 + 0.0004607892107892108159162*var_57 + -0.0002817717996289424839049*var_21 + 0.0003227130012844298362178*var_0 + -0.0008597652347652347780416*w[0][5]*w[1][5] + var_431 + 0.0111263736263736267434465*var_2 + -0.0019049700299700299006150*var_25 + var_415 + -0.0021241258741258742595570*var_31 + 0.0004045954045954045950537*var_334 + 0.0034278221778221776294693*var_338 + -0.0001436955901241615584166*var_55 + 0.0013823676323676324477485*var_13 + 0.0001164014556871699631029*var_73 + 0.0001348651348651348650179*var_14; + A[26] = 0.1250000000000000000000000*var_12*var_470; + const double var_471 = var_100 + var_51; + const double var_472 = var_461 + 0.0002836449265020693434776*var_36 + -0.0000486121021835307491089*var_362 + 0.0022035999714571140664643*var_376 + 0.0002448444412730126800749*var_48 + 0.0006261595547309833096131*var_365 + 0.0023280291137433993704786*var_119 + -0.0010021228771228771897706*var_366 + -0.0014088589981447123111041*var_368 + 0.0023039460539460540795809*var_370 + 0.0006527202955774384727367*var_39 + 0.0005820072784358498426197*var_35 + -0.0007117882117882118418045*var_361 + 0.0028190559440559440941565*var_363 + 0.0001788390181247324006112*var_249 + 0.0002692743764172335482407*var_471 + 0.0007305194805194805459519*var_52 + 0.0021353646353646353085731*var_49 + 0.0019574175824175824023321*var_367 + 0.0038532895675752816717907*var_124 + 0.0069118381618381618050617*var_371 + 0.0014369559012416153673253*var_375 + 0.0029605810855810855107551*var_170 + -0.0007385471671185956429179*var_364 + -0.0000512879977165691441281*var_141 + -0.0007265056372199228890488*var_369 + 0.0005860211217354073911026*var_372; + A[12] = 0.0250000000000000013877788*var_12*var_472; + const double var_473 = var_59 + var_292 + -0.5000000000000000000000000*var_67; + const double var_474 = 0.0060689310689310688173848*var_80 + 0.0002528721278721278854611*var_143 + var_230 + -0.0014666583416583416164120*w[0][4]*w[1][4] + 0.0018206793206793207319516*var_416 + 0.0033379120879120879362978*var_17 + -0.0003558941058941059209023*var_22 + 0.0005038711288711288571393*var_60 + 0.0002509990009990010258883*var_473 + -0.0007548701298701298830277*var_19 + 0.0020735514485514484547823*var_18 + -0.0010395854145854145980654*var_23 + -0.0014816433566433567098342*var_75 + 0.0177010489510489518738545*var_137 + 0.0005057442557442557709221*var_129 + var_389 + -0.0015640609390609389647148*var_21 + 0.0109240759240759235243479*var_131 + 0.0056980519480519476946401*var_0 + 0.0092045454545454548356265*var_226 + 0.0040459540459540461673771*var_235 + 0.0001048951048951048950139*var_69 + 0.0026298701298701297052185*var_236 + -0.0010733016983016983956351*var_24 + 0.0010751748251748250925774*var_65 + 0.0003277972027972028104710*var_55 + var_435 + 0.0003933566433566433834072*var_15 + 0.0006799450549450549580177*var_16 + -0.0014029720279720280656788*var_73 + 0.0032704795204795203411585*var_14; + A[33] = 4.5000000000000000000000000*var_12*var_410; + const double var_475 = var_25 + var_69; + const double var_476 = var_62 + var_75; + const double var_477 = var_200 + 0.0022975239046667617417996*var_76 + -0.0051080169830169828634747*w[0][4]*w[1][4] + 0.0001123876123876123875149*var_99 + var_89 + 0.0000288996717568146119963*var_32 + 0.0029814828029113742483003*w[0][8]*w[1][8] + var_262 + 0.0000489688882546025373702*var_291 + 0.0007706579135150563560422*var_112 + -0.0007273084058798344854815*var_162 + -0.0004656058227486798524117*var_60 + 0.0004551698301698301829879*var_19 + -0.0001613565006422149181089*var_18 + 0.0018206793206793207319516*var_23 + -0.0009970386756101041070971*var_27 + var_426 + var_444 + 0.0013823676323676324477485*var_476 + -0.0019049700299700299006150*w[0][6]*w[1][6] + 0.0006968031968031968568025*var_67 + 0.0021241258741258742595570*var_109 + -0.0001453011274439845886518*var_57 + 0.0004407199942914228566609*var_21 + 0.0197802197802197793352619*var_253 + -0.0013366098187526757878896*var_0 + 0.0004214535464535464396284*var_25 + 0.0003227130012844298362178*var_244 + 0.0002022977022977022975268*var_30 + 0.0002873911802483231168331*var_24 + -0.0001436955901241615584166*var_15 + var_54 + -0.0028939810189810189107462*var_16 + -0.0013799593263878978752907*var_14 + 0.0043638504352790062623679*w[0][3]*w[1][3]; + A[23] = 0.1250000000000000000000000*var_12*var_477; + A[17] = 0.1250000000000000000000000*var_12*var_428; + A[71] = A[17]; + A[42] = A[24]; + const double var_478 = -0.0004776473526473526604909*var_180 + -0.0028377872127872127983039*var_150 + -0.0010021228771228771897706*var_149 + -0.0064060939060939063594002*var_163 + -0.0016077672327672327522857*var_171 + 0.0007679820179820179542468*var_174 + 0.0004856750392464678116669*var_183 + 0.0001806229484800913351415*var_166 + 0.0003612458969601826702829*var_205 + -0.0007666440702154986991390*var_179 + 0.0026370950478093332057516*var_158 + -0.0011680284001712572337223*var_168 + 0.0023360568003425144674445*var_320 + 0.0003599079491936634693852*var_148 + -0.0017339803054088767739899*var_159 + 0.0014811081775367488343187*var_43 + 0.0004281432852861424441168*var_270 + -0.0141608391608391611521389*var_161 + -0.0005391929499072356307340*var_157 + 0.0023842229199372059166018*var_319 + var_328 + 0.0039375802768659906236137*var_182 + 0.0140163408020550876720289*var_45 + -0.0043349507635221922602353*var_160 + 0.0065746753246753242630462*var_449 + -0.0009151562722991294024713*var_44 + 0.0011800699300699300960116*var_177 + -0.0010476131011845296950313*var_155 + -0.0002586699015270443684743*var_98 + -0.0003331489938632795598517*var_154 + -0.0001400385328956757372085*w[0][2]*w[1][2]; + A[78] = 0.2250000000000000055511151*var_12*var_478; + A[87] = A[78]; + A[67] = 0.1607142857142856984253854*var_12*var_278; + A[95] = A[59]; + const double var_479 = var_263 + -0.5000000000000000000000000*var_24 + var_336; + const double var_480 = 0.0092045454545454548356265*var_192 + 0.0032704795204795203411585*var_62 + -0.0014816433566433567098342*var_58 + 0.0005038711288711288571393*var_22 + -0.0007548701298701298830277*var_60 + 0.0018206793206793207319516*var_214 + -0.0003558941058941059209023*var_19 + 0.0003277972027972028104710*var_23 + 0.0003933566433566433834072*var_75 + 0.0040459540459540461673771*var_137 + 0.0010751748251748250925774*var_67 + 0.0060689310689310688173848*var_109 + -0.0015640609390609389647148*var_57 + 0.0002509990009990010258883*var_479 + -0.0014666583416583416164120*w[0][5]*w[1][5] + 0.0026298701298701297052185*var_226 + var_234 + 0.0002528721278721278854611*var_245 + 0.0056980519480519476946401*var_25 + 0.0109240759240759235243479*var_139 + 0.0006799450549450549580177*var_69 + var_434 + 0.0033379120879120879362978*var_31 + -0.0010733016983016983956351*var_65 + -0.0010395854145854145980654*var_13 + -0.0014029720279720280656788*var_16 + 0.0001048951048951048950139*var_73 + 0.0177010489510489518738545*var_3 + var_391 + 0.0020735514485514484547823*var_14 + 0.0005057442557442557709221*var_221; + A[36] = 0.1607142857142856984253854*var_12*var_480; + A[63] = A[36]; + const double var_481 = 0.0016135650064221492352989*var_14 + -0.0007184779506208076836626*var_19; + const double var_482 = var_340 + var_193; + const double var_483 = -0.0082364064506921640801407*var_76 + 0.0223249964321392893595863*var_17 + 0.0005619380619380619917846*var_197 + 0.0989010989010989105540972*var_227 + 0.0069359212216355070959595*var_32 + -0.0066830490937633789394479*w[0][8]*w[1][8] + 0.0023280291137433993704786*var_482 + -0.0100546774653917508901557*var_62 + var_189 + var_71 + 0.0025287212787212785293500*var_162 + 0.0031709362066504923581556*var_60 + -0.0022878906807478234519682*var_72 + -0.0029983409447695160386649*var_87 + 0.0317896389324960754185767*var_63 + 0.0010957792207792207105077*var_91 + 0.0166975881261595543447740*var_419 + 0.0135828457257028672316990*w[0][6]*w[1][6] + -0.0007265056372199228890488*var_67 + 0.0014369559012416153673253*var_57 + -0.0012603467960610817161921*var_21 + var_455 + 0.0032391715427429711160467*var_0 + -0.0049851933780505203186451*var_26 + -0.0048527365491651203513457*var_25 + 0.0005057442557442557709221*var_235 + var_481 + var_256 + 0.0022035999714571140664643*var_65 + 0.0022758491508491508065193*var_13 + 0.0023039460539460540795809*var_16 + var_280 + -0.0014088589981447123111041*var_73 + 0.0005820072784358498426197*var_20; + A[20] = A[2]; + const double var_484 = -0.0003277972027972028104710*var_170 + 0.0001788390181247324006112*var_51 + -0.0008067825032110746176495*var_48 + 0.0012362637362637362084539*var_52 + 0.0006743256743256743250894*var_49 + -0.0029983409447695160386649*var_50; + const double var_485 = 0.1205357142857142738190390*var_27 + 0.0215909090909090911614143*var_15; + const double var_486 = 0.0069359212216355070959595*var_80 + -0.0066830490937633789394479*w[0][4]*w[1][4] + 0.0023280291137433993704786*var_217 + -0.0049851933780505203186451*var_17 + -0.0082364064506921640801407*var_29 + 0.0135828457257028672316990*w[0][7]*w[1][7] + 0.0005619380619380619917846*var_112 + 0.0317896389324960754185767*var_162 + 0.0031709362066504923581556*var_22 + var_153 + -0.0048527365491651203513457*var_72 + -0.0100546774653917508901557*var_18 + 0.0989010989010989105540972*var_485 + 0.0005057442557442557709221*var_137 + var_266 + 0.0022035999714571140664643*var_67 + -0.0012603467960610817161921*var_57 + 0.0005820072784358498426197*var_21 + var_188 + 0.0012844298558584272239302*var_310 + -0.0022878906807478234519682*var_0 + -0.0029983409447695160386649*var_2 + 0.0032391715427429711160467*var_25 + 0.0023039460539460540795809*var_69 + var_481 + -0.0007265056372199228890488*var_24 + 0.0223249964321392893595863*var_31 + var_279 + 0.0022758491508491508065193*var_55 + -0.0014088589981447123111041*var_16 + 0.0025287212787212785293500*var_79 + var_484 + 0.0014369559012416153673253*var_20 + 0.0010957792207792207105077*var_340; + A[15] = 0.0250000000000000013877788*var_12*var_486; + const double var_487 = -0.0019049700299700299006150*w[0][4]*w[1][4] + 0.0000288996717568146119963*var_130 + 0.0004214535464535464396284*var_62 + 0.0029814828029113742483003*w[0][7]*w[1][7] + var_66 + -0.0028939810189810189107462*var_58 + var_258 + 0.0004407199942914228566609*var_22 + -0.0001453011274439845886518*var_60 + -0.0013799593263878978752907*var_72 + -0.0007273084058798344854815*var_87 + var_265 + -0.0013366098187526757878896*var_18 + 0.0006968031968031968568025*var_23 + 0.0007706579135150563560422*var_216 + 0.0197802197802197793352619*var_485 + 0.0001123876123876123875149*var_96 + var_444 + 0.0000489688882546025373702*var_213 + var_81 + -0.0051080169830169828634747*w[0][6]*w[1][6] + 0.0018206793206793207319516*var_67 + 0.0002022977022977022975268*var_109 + -0.0004656058227486798524117*var_57 + 0.0013823676323676324477485*var_475 + -0.0001613565006422149181089*var_0 + 0.0043638504352790062623679*w[0][5]*w[1][5] + -0.0009970386756101041070971*var_26 + 0.0003227130012844298362178*var_239 + 0.0021241258741258742595570*var_30 + 0.0022975239046667617417996*var_31 + 0.0002873911802483231168331*var_55 + var_186 + -0.0001436955901241615584166*var_73 + 0.0004551698301698301829879*var_20; + const double var_488 = var_226 + var_129; + const double var_489 = var_14 + var_162; + const double var_490 = 0.0026009704581133152694050*var_80 + 0.0001926644783787640890105*var_317 + 0.0016256065363208220975882*var_28 + 0.0052019409162266305388100*var_416 + 0.0069359212216355070959595*var_17 + 0.0000040138432995575849054*var_56 + 0.0028177179962894246222083*var_130 + 0.0002950174825174825240029*var_482 + 0.0004876819608962465859084*var_489 + -0.0009211770372484657251957*var_134 + 0.0019507278435849863436335*var_488 + 0.0006201387897816468784684*var_60 + 0.0000561938061938061937575*var_418 + 0.0003251213072641644086756*var_18 + 0.0060689310689310688173848*var_63 + -0.0001384775938347366965996*var_241 + 0.0003311420722135007856102*var_417 + var_333 + 0.0004334950763522191934975*var_137 + -0.0002287890680747823506178*var_21 + var_451 + 0.0005960557299843014791504*var_0 + 0.0000280969030969030968787*var_196 + 0.0030344655344655344086924*var_2 + 0.0010837376908805480650588*var_128 + var_290 + 0.0000240830597973455111263*var_263 + 0.0003191005423148280317411*var_65 + 0.0001625606536320822043378*var_127 + 0.0000842907092907092906362*var_16; + A[49] = 0.9000000000000000222044605*var_12*var_490; + A[94] = A[49]; + A[25] = 0.1250000000000000000000000*var_12*var_487; + A[52] = A[25]; + A[5] = 0.1250000000000000000000000*var_12*var_311; + A[50] = A[5]; + A[76] = A[67]; + A[14] = 0.1250000000000000000000000*var_12*var_268; + const double var_491 = 0.0202297702297702282348002*var_355 + 0.0053946053946053946007155*var_36 + 0.1308191808191808136463408*var_358 + 0.0829420579420579451301876*var_50 + 0.0430069930069930037030979*var_351 + 0.0036213786213786214839006*var_51 + -0.0364135864135864129043085*var_346 + -0.0050199800199800196504052*var_97 + 0.0015234765234765235836223*var_39 + 0.0101148851148851141174001*var_353 + -0.0930569430569430505739703*var_250 + 0.1335164835164835139824646*var_350 + 0.0201548451548451551529340*var_144 + -0.0586663336663336629217547*var_34 + 0.0068181818181818178506437*var_390 + -0.0333416583416583436894065*var_349 + -0.0226273726273726258351182*var_344 + 0.0216783216783216770018328*w[0][1]*w[1][1] + 0.1476773226773226699304331*var_140 + -0.2346653346653346516870187*var_354 + 0.0271978021978021983207086*var_316 + 0.1024975024975025017504038*var_48 + -0.2063436563436563397910817*var_345 + var_467 + 0.0950799200799200827649571*var_146 + 0.0041958041958041958005565*var_145 + -0.0031468531468531470672578*var_352 + -0.0142357642357642359687286*var_225 + 0.1051948051948051882087398*var_315 + 0.0008991008991008991001193*var_286; + A[47] = 0.0040178571428571424606346*var_12*var_491; + A[41] = A[14]; + A[85] = A[58]; + const double var_492 = 0.0135828457257028672316990*w[0][4]*w[1][4] + 0.0166975881261595543447740*var_469 + 0.0005619380619380619917846*var_56 + 0.0223249964321392893595863*var_29 + -0.0048527365491651203513457*var_62 + var_398 + 0.0069359212216355070959595*var_130 + -0.0066830490937633789394479*w[0][7]*w[1][7] + 0.0023039460539460540795809*var_58 + -0.0029983409447695160386649*var_162 + -0.0012603467960610817161921*var_22 + 0.0014369559012416153673253*var_60 + 0.0005820072784358498426197*var_19 + 0.0025287212787212785293500*var_87 + 0.0032391715427429711160467*var_18 + -0.0007265056372199228890488*var_23 + var_281 + -0.0049851933780505203186451*var_27 + var_194 + 0.0031709362066504923581556*var_57 + var_455 + 0.0010957792207792207105077*var_196 + 0.0005057442557442557709221*var_226 + 0.0317896389324960754185767*var_2 + -0.0100546774653917508901557*var_25 + 0.0989010989010989105540972*var_94 + -0.0082364064506921640801407*var_31 + 0.0022758491508491508065193*var_65 + var_255 + 0.0022035999714571140664643*var_13 + -0.0014088589981447123111041*var_15 + 0.0023280291137433993704786*var_335 + var_484 + -0.0022878906807478234519682*var_14; + A[4] = 0.0250000000000000013877788*var_12*var_483; + A[40] = A[4]; + A[37] = 0.1607142857142856984253854*var_12*var_474; + A[73] = A[37]; + const double var_493 = -0.0142357642357642359687286*var_180 + 0.0041958041958041958005565*var_150 + -0.0031468531468531470672578*var_149 + -0.2346653346653346516870187*var_163 + -0.0068181818181818178506437*var_171 + 0.0271978021978021983207086*var_174 + 0.0201548451548451551529340*var_183 + -0.0333416583416583436894065*var_179 + 0.0101148851148851141174001*var_158 + 0.1476773226773226699304331*var_168 + -0.0586663336663336629217547*var_320 + 0.0053946053946053946007155*var_176 + 0.0430069930069930037030979*var_148 + -0.0364135864135864129043085*var_159 + 0.1308191808191808136463408*var_167 + 0.1024975024975025017504038*var_43 + -0.0930569430569430505739703*var_161 + -0.0226273726273726258351182*var_157 + 0.1335164835164835139824646*var_319 + 0.0036213786213786214839006*var_46 + 0.0202297702297702282348002*var_322 + 0.0950799200799200827649571*var_182 + var_466 + 0.0829420579420579451301876*var_45 + -0.2063436563436563397910817*var_160 + 0.0008991008991008991001193*var_269 + 0.1051948051948051882087398*var_449 + 0.0015234765234765235836223*var_98 + -0.0050199800199800196504052*var_154 + 0.0216783216783216770018328*w[0][2]*w[1][2]; + A[35] = 0.0040178571428571424606346*var_12*var_493; + A[53] = A[35]; + A[16] = 0.0250000000000000013877788*var_12*var_492; + A[61] = A[16]; + A[83] = A[38]; + A[66] = 4.5000000000000000000000000*var_12*var_136; + const double var_494 = 0.0006321803196803196323375*var_126 + 0.0000866990152704438359890*var_28 + var_303 + var_326 + -0.0001842354074496931667232*var_29 + 0.0000090311474240045670959*var_62 + 0.0007008170401027544052855*w[0][7]*w[1][7] + 0.0000028096903096903096879*var_260 + var_432 + -0.0000297693378050520878364*var_58 + -0.0000371280505209076622805*var_60 + 0.0000140484515484515484394*var_22 + 0.0001766091051805337595534*var_19 + -0.0000523806550592264833963*var_72 + 0.0006406093906093906359400*var_87 + 0.0000828189667475381750697*var_23 + 0.0001030219780219780218887*var_75 + var_406 + 0.0000915156272299129402471*w[0][6]*w[1][6] + 0.0000089642500356786063734*var_67 + 0.0000754602540316825972375*var_21 + 0.0012137862137862138935812*var_26 + 0.0000939239332096474855999*var_128 + var_125 + 0.0000117070429570429570328*var_69 + 0.0001212180676466390673611*var_24 + -0.0000529158341658341691764*var_65 + -0.0001418893606393606290732*var_55 + 0.0003287337662337662131523*var_1 + -0.0000202030112744398468189*var_13 + -0.0000238823676323676323469*var_15 + -0.0000558593192521763935330*var_16 + var_408 + 0.0038436563436563438156401*var_79 + 0.0003090659340659340521135*var_73 + 0.0003901455687169972687267*var_238 + -0.0000166574496931639793478*var_20 + 0.0001444983587840730735342*var_221; + A[74] = A[47]; + A[62] = A[26]; + A[88] = 4.5000000000000000000000000*var_12*var_494; + A[27] = 0.0250000000000000013877788*var_12*var_203; + A[72] = A[27]; + A[11] = 0.0312500000000000000000000*var_12*var_397; + A[32] = A[23]; + A[99] = 0.3857142857142856762209249*var_12*var_388; + A[90] = A[9]; + A[21] = A[12]; + A[10] = A[1]; + A[51] = A[15]; + } + + 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/mass_matrix_2d/mass_matrix_f2_p3_q3_quadrature.h b/mass_matrix_2d/mass_matrix_f2_p3_q3_quadrature.h new file mode 100644 index 0000000..5a8ba2f --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p3_q3_quadrature.h @@ -0,0 +1,3458 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P3_Q3_QUADRATURE_H +#define __MASS_MATRIX_F2_P3_Q3_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p3_q3_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p3_q3_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p3_q3_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p3_q3_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p3_q3_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_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.0*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 mass_matrix_f2_p3_q3_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class mass_matrix_f2_p3_q3_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p3_q3_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Array of quadrature weights. + static const double W49[49] = {0.0036234660797264, 0.00715464377909735, 0.00824760301353097, 0.00693554275373524, 0.00429791008798315, 0.00177448507143835, 0.000337590756711431, 0.00782718664849641, 0.0154550176627367, 0.0178159604006788, 0.0149817292193919, 0.0092840787568901, 0.00383313257348533, 0.000729242610651687, 0.0106850106013168, 0.021097877818156, 0.0243208363749012, 0.0204517846225132, 0.0126738360020949, 0.00523266711568851, 0.000995500091625133, 0.0116960367644213, 0.0230941796709132, 0.0266220977213878, 0.0223869525046108, 0.0138730467715663, 0.00572778720065371, 0.00108969528483177, 0.0106850106013168, 0.021097877818156, 0.0243208363749012, 0.0204517846225133, 0.0126738360020949, 0.00523266711568852, 0.000995500091625133, 0.00782718664849641, 0.0154550176627367, 0.0178159604006788, 0.0149817292193919, 0.0092840787568901, 0.00383313257348533, 0.000729242610651687, 0.00362346607972641, 0.00715464377909737, 0.00824760301353099, 0.00693554275373526, 0.00429791008798316, 0.00177448507143835, 0.000337590756711432}; + // Quadrature points on the UFC reference element: (0.0248740323760607, 0.0224793864387125), (0.0225279156156636, 0.114679053160904), (0.0186827443488427, 0.265789822784589), (0.0139228951565961, 0.452846373669445), (0.00897290400671669, 0.64737528288683), (0.00458641254163789, 0.819759308263108), (0.00143165958133296, 0.943737439463078), (0.126329297019669, 0.0224793864387125), (0.114413927746761, 0.114679053160904), (0.0948852170128628, 0.265789822784589), (0.0707110745463253, 0.452846373669445), (0.045571246280295, 0.64737528288683), (0.0232932989499898, 0.819759308263108), (0.00727105865856026, 0.943737439463078), (0.29039930608799, 0.0224793864387125), (0.263008866575801, 0.114679053160904), (0.218117268350298, 0.265789822784589), (0.16254699001287, 0.452846373669445), (0.104756842708482, 0.64737528288683), (0.0535454404572833, 0.819759308263108), (0.0167143365694675, 0.943737439463078), (0.488760306780644, 0.0224793864387125), (0.442660473419548, 0.114679053160904), (0.367105088607705, 0.265789822784589), (0.273576813165278, 0.452846373669445), (0.176312358556585, 0.64737528288683), (0.0901203458684462, 0.819759308263108), (0.0281312802684611, 0.943737439463078), (0.687121307473297, 0.0224793864387125), (0.622312080263294, 0.114679053160904), (0.516092908865112, 0.265789822784589), (0.384606636317686, 0.452846373669445), (0.247867874404688, 0.64737528288683), (0.126695251279609, 0.819759308263108), (0.0395482239674546, 0.943737439463078), (0.851191316541618, 0.0224793864387125), (0.770907019092334, 0.114679053160904), (0.639324960202548, 0.265789822784589), (0.47644255178423, 0.452846373669445), (0.307053470832875, 0.64737528288683), (0.156947392786903, 0.819759308263108), (0.0489915018783619, 0.943737439463078), (0.952646581185227, 0.0224793864387125), (0.862793031223432, 0.114679053160904), (0.715527432866568, 0.265789822784589), (0.533230731173959, 0.452846373669445), (0.343651813106453, 0.64737528288683), (0.175654279195255, 0.819759308263108), (0.0548309009555892, 0.943737439463078) + + // Value of basis functions at quadrature points. + static const double FE0[49][10] = \ + {{0.759259490549809, 0.0221590586807319, 0.0202565508334599, -0.00232842517935532, -0.00234650132061204, 0.179044261105492, -0.089868278171862, 0.198117184364795, -0.0986755707370276, 0.0143822298745689}, + {0.403169832432288, 0.020295583031815, 0.0622850658315548, -0.0108399544739676, -0.0076260010524023, 0.707224672483947, -0.292066992631152, 0.138929449658773, -0.0815548866260336, 0.060183231345177}, + {0.0601288715882343, 0.0171413871629327, 0.0323851163046929, -0.0210931449040643, -0.00452789572055771, 0.981256130427186, -0.17341315283902, 0.0689738878390519, -0.056784430894179, 0.0959332310357222}, + {-0.0640040756677871, 0.0130627287158153, -0.0520748014962052, -0.0271871272651127, 0.0101725424378916, 0.651638858584826, 0.389596573201606, 0.0200348286650143, -0.0320130900742899, 0.090773562898242}, + {-0.00515429610053729, 0.00861384643795105, -0.0176489825313883, -0.0254361144552718, 0.0246269466012943, 0.0309901900119197, 0.943183482680242, 0.00042953756109863, -0.0135024723402444, 0.0538978621349365}, + {0.061198066754193, 0.00449218837368866, 0.274707138662764, -0.0166861035842363, 0.024689369513165, -0.306515799699927, 0.94557420778192, -0.00171490325731424, -0.0035754220392769, 0.0178312574950235}, + {0.0420437794348034, 0.0014224493649266, 0.718243758548968, -0.00605388489987946, 0.0111337678992377, -0.194553625202202, 0.426410393158711, -0.000295139887384777, -0.000351729145693924, 0.00200023072851307}, + {0.366019955489299, 0.0635858397592476, 0.0202565508334599, -0.00793599005513186, -0.0119173223628164, 0.133769185243817, -0.0802974571296576, 0.7517539315772, -0.300499563967438, 0.0652648706120207}, + {0.158234646728241, 0.0622463008387584, 0.0622850658315548, -0.038777608547051, -0.0387306463807783, 0.522241119924781, -0.260962347302776, 0.521033755638225, -0.260674724708381, 0.273104437977427}, + {-0.0240696255023906, 0.0582150166968705, 0.0323851163046929, -0.0811829011624889, -0.0229961059271973, 0.701945378409426, -0.15494494263238, 0.250589879114876, -0.195275554613315, 0.435333739311908}, + {-0.0583655036819059, 0.049801839277281, -0.0520748014962052, -0.113528168626855, 0.0516639246766598, 0.416833691765261, 0.348105190962837, 0.065087764782121, -0.119443708738743, 0.41191977107955}, + {0.0130582576350319, 0.0366518011112075, -0.0176489825313883, -0.114607849295939, 0.12507440711047, -0.0705223834533175, 0.842736022171066, -0.00496434292377278, -0.0543591002641987, 0.244582170440841}, + {0.0634982330351343, 0.0209085718766358, 0.274707138662764, -0.0799224708936431, 0.125391438239775, -0.306364327912917, 0.84487213905531, -0.00870528191111183, -0.0153015931693676, 0.08091615301742}, + {0.0387198943189268, 0.00703488117358859, 0.718243758548968, -0.0302053001190503, 0.0565457602782775, -0.177478791461603, 0.380998400779671, -0.00136739165938145, -0.0015680240664827, 0.00907681220708495}, + {0.0223759175857751, 0.0211108763763082, 0.0202565508334599, -0.00378368892316171, -0.0273949291750587, 0.0737725345196537, -0.0648198503174152, 0.953028361840235, -0.11565499294401, 0.121109220204214}, + {-0.0358942747511902, 0.0335971702606884, 0.0622850658315548, -0.0286348362908939, -0.0890320226476534, 0.278414597642437, -0.210660971035901, 0.638525569803523, -0.155388486816179, 0.506788188003614}, + {-0.0639101497865511, 0.0507254467671889, 0.0323851163046929, -0.0901727271791658, -0.0528622683853314, 0.338438801699255, -0.125078780174246, 0.277735791976569, -0.175091373261166, 0.807830142038755}, + {-0.0250300738487932, 0.0629764585450424, -0.0520748014962053, -0.169713634674798, 0.118762379193389, 0.120557083126032, 0.281006736446109, 0.0432733750920395, -0.144139368149536, 0.764381845766722}, + {0.0399235182020919, 0.0605470656066382, -0.0176489825313883, -0.209268491422469, 0.287514629552574, -0.185140210770349, 0.680295799728962, -0.0299589812144173, -0.0801249870360447, 0.453860639884402}, + {0.063614187301803, 0.0413342706009022, 0.274707138662764, -0.165795041633989, 0.288243404445893, -0.289728237600496, 0.682020172849192, -0.0189246110887122, -0.0256239169827024, 0.150152633445345}, + {0.0327882963196601, 0.0154781884654098, 0.718243758548968, -0.0674234644917185, 0.129984492389545, -0.148027265853737, 0.307559668668404, -0.00262167997101521, -0.00282544504740342, 0.0168434509718876}, + {-0.0608171838969239, -0.0608171838969239, 0.0202565508334599, 0.0230536948731185, -0.046107389746237, 0.0230536948731185, -0.0461073897462371, 0.501247265326078, 0.501247265326078, 0.144990676054469}, + {-0.0487833107612748, -0.0487833107612748, 0.0622850658315548, 0.0749232484208884, -0.149846496841777, 0.0749232484208885, -0.149846496841777, 0.289203300009696, 0.289203300009696, 0.60672145251338}, + {-0.0167125477659761, -0.0167125477659761, 0.0323851163046929, 0.0444852621398943, -0.0889705242797887, 0.0444852621398941, -0.0889705242797887, 0.061442405613996, 0.0614424056139963, 0.967125692279056}, + {0.0289180452500466, 0.0289180452500465, -0.0520748014962053, -0.0999422789098743, 0.199884557819749, -0.0999422789098745, 0.199884557819749, -0.0603778494306703, -0.0603778494306701, 0.915109852037704}, + {0.0610889883577043, 0.0610889883577042, -0.0176489825313883, -0.241952607320384, 0.483905214640768, -0.241952607320384, 0.483905214640768, -0.0658956805785703, -0.0658956805785701, 0.543357152332352}, + {0.0568664779664872, 0.0568664779664872, 0.274707138662764, -0.242565894323771, 0.485131788647543, -0.242565894323771, 0.485131788647542, -0.026666513050842, -0.0266665130508418, 0.179761142858403}, + {0.0246703000807061, 0.0246703000807061, 0.718243758548968, -0.109386040264487, 0.218772080528974, -0.109386040264487, 0.218772080528975, -0.0032606201973806, -0.00326062019738041, 0.0201648011554063}, + {0.0211108763763083, 0.0223759175857751, 0.0202565508334599, 0.0737725345196536, -0.0648198503174152, -0.00378368892316169, -0.0273949291750588, -0.11565499294401, 0.953028361840235, 0.121109220204214}, + {0.0335971702606883, -0.0358942747511903, 0.0622850658315548, 0.278414597642436, -0.210660971035901, -0.0286348362908939, -0.0890320226476535, -0.155388486816179, 0.638525569803523, 0.506788188003614}, + {0.050725446767189, -0.0639101497865511, 0.0323851163046929, 0.338438801699255, -0.125078780174246, -0.0901727271791658, -0.0528622683853314, -0.175091373261166, 0.277735791976569, 0.807830142038755}, + {0.0629764585450424, -0.0250300738487932, -0.0520748014962053, 0.120557083126032, 0.281006736446109, -0.169713634674798, 0.118762379193389, -0.144139368149536, 0.0432733750920397, 0.764381845766722}, + {0.0605470656066382, 0.0399235182020918, -0.0176489825313883, -0.185140210770349, 0.680295799728962, -0.209268491422469, 0.287514629552574, -0.0801249870360449, -0.0299589812144171, 0.453860639884402}, + {0.0413342706009022, 0.0636141873018031, 0.274707138662764, -0.289728237600496, 0.682020172849192, -0.165795041633989, 0.288243404445893, -0.0256239169827026, -0.018924611088712, 0.150152633445345}, + {0.0154781884654098, 0.0327882963196601, 0.718243758548968, -0.148027265853737, 0.307559668668404, -0.0674234644917187, 0.129984492389545, -0.0028254450474036, -0.00262167997101501, 0.0168434509718876}, + {0.0635858397592477, 0.366019955489299, 0.0202565508334599, 0.133769185243817, -0.0802974571296575, -0.00793599005513192, -0.0119173223628164, -0.300499563967438, 0.7517539315772, 0.0652648706120206}, + {0.0622463008387585, 0.158234646728241, 0.0622850658315548, 0.522241119924781, -0.260962347302776, -0.038777608547051, -0.0387306463807782, -0.260674724708381, 0.521033755638225, 0.273104437977427}, + {0.0582150166968705, -0.0240696255023904, 0.0323851163046929, 0.701945378409426, -0.15494494263238, -0.0811829011624888, -0.0229961059271972, -0.195275554613315, 0.250589879114876, 0.435333739311907}, + {0.049801839277281, -0.0583655036819059, -0.0520748014962053, 0.416833691765261, 0.348105190962837, -0.113528168626855, 0.0516639246766597, -0.119443708738744, 0.0650877647821211, 0.41191977107955}, + {0.0366518011112075, 0.0130582576350319, -0.0176489825313883, -0.0705223834533175, 0.842736022171066, -0.11460784929594, 0.12507440711047, -0.0543591002641988, -0.00496434292377256, 0.244582170440841}, + {0.0209085718766358, 0.0634982330351343, 0.274707138662764, -0.306364327912917, 0.84487213905531, -0.0799224708936432, 0.125391438239775, -0.0153015931693678, -0.00870528191111163, 0.08091615301742}, + {0.00703488117358859, 0.0387198943189267, 0.718243758548968, -0.177478791461603, 0.380998400779671, -0.0302053001190505, 0.0565457602782777, -0.00156802406648289, -0.00136739165938125, 0.00907681220708495}, + {0.0221590586807319, 0.759259490549808, 0.0202565508334599, 0.179044261105492, -0.089868278171862, -0.00232842517935539, -0.00234650132061204, -0.098675570737028, 0.198117184364796, 0.0143822298745689}, + {0.0202955830318151, 0.403169832432288, 0.0622850658315548, 0.707224672483947, -0.292066992631152, -0.0108399544739676, -0.00762600105240233, -0.0815548866260342, 0.138929449658774, 0.0601832313451773}, + {0.0171413871629327, 0.0601288715882344, 0.0323851163046929, 0.981256130427186, -0.17341315283902, -0.0210931449040642, -0.00452789572055766, -0.0567844308941791, 0.0689738878390521, 0.0959332310357222}, + {0.0130627287158153, -0.0640040756677871, -0.0520748014962053, 0.651638858584826, 0.389596573201605, -0.0271871272651128, 0.0101725424378918, -0.0320130900742903, 0.0200348286650146, 0.0907735628982423}, + {0.00861384643795111, -0.00515429610053724, -0.0176489825313883, 0.0309901900119194, 0.943183482680241, -0.025436114455272, 0.0246269466012944, -0.0135024723402447, 0.000429537561098859, 0.0538978621349367}, + {0.00449218837368868, 0.0611980667541931, 0.274707138662764, -0.306515799699927, 0.94557420778192, -0.0166861035842365, 0.0246893695131651, -0.00357542203927705, -0.001714903257314, 0.0178312574950233}, + {0.00142244936492658, 0.0420437794348033, 0.718243758548968, -0.194553625202202, 0.426410393158711, -0.00605388489987951, 0.0111337678992375, -0.000351729145694105, -0.000295139887384555, 0.00200023072851302}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 100; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 16807 + for (unsigned int ip = 0; ip < 49; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + + // Total number of operations to compute function values = 40 + for (unsigned int r = 0; r < 10; r++) + { + F0 += FE0[ip][r]*w[0][r]; + F1 += FE0[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 3 + double I[1]; + // Number of operations: 3 + I[0] = F0*F1*W49[ip]*det; + + + // Number of operations for primary indices: 300 + for (unsigned int j = 0; j < 10; j++) + { + for (unsigned int k = 0; k < 10; k++) + { + // Number of operations to compute entry: 3 + A[j*10 + k] += FE0[ip][j]*FE0[ip][k]*I[0]; + }// 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 mass_matrix_f2_p3_q3_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p3_q3_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p3_q3_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1))), 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 mass_matrix_f2_p3_q3_quadrature_finite_element_0(); + break; + } + case 1: + { + return new mass_matrix_f2_p3_q3_quadrature_finite_element_0(); + break; + } + case 2: + { + return new mass_matrix_f2_p3_q3_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p3_q3_quadrature_finite_element_0(); + 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 mass_matrix_f2_p3_q3_quadrature_dofmap_0(); + break; + } + case 1: + { + return new mass_matrix_f2_p3_q3_quadrature_dofmap_0(); + break; + } + case 2: + { + return new mass_matrix_f2_p3_q3_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p3_q3_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f2_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/mass_matrix_2d/mass_matrix_f2_p3_q3_tensor.h b/mass_matrix_2d/mass_matrix_f2_p3_q3_tensor.h new file mode 100644 index 0000000..9272802 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p3_q3_tensor.h @@ -0,0 +1,3564 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P3_Q3_TENSOR_H +#define __MASS_MATRIX_F2_P3_Q3_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p3_q3_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p3_q3_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p3_q3_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p3_q3_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p3_q3_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_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.0*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 mass_matrix_f2_p3_q3_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class mass_matrix_f2_p3_q3_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p3_q3_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 150 + // Number of operations (multiply-add pairs) for tensor contraction: 5008 + // Total number of operations (multiply-add pairs): 5167 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0 = det*w[0][0]*w[1][0]*(1.0); + const double G0_0_1 = det*w[0][0]*w[1][1]*(1.0); + const double G0_0_2 = det*w[0][0]*w[1][2]*(1.0); + const double G0_0_3 = det*w[0][0]*w[1][3]*(1.0); + const double G0_0_4 = det*w[0][0]*w[1][4]*(1.0); + const double G0_0_5 = det*w[0][0]*w[1][5]*(1.0); + const double G0_0_6 = det*w[0][0]*w[1][6]*(1.0); + const double G0_0_7 = det*w[0][0]*w[1][7]*(1.0); + const double G0_0_8 = det*w[0][0]*w[1][8]*(1.0); + const double G0_0_9 = det*w[0][0]*w[1][9]*(1.0); + const double G0_1_0 = det*w[0][1]*w[1][0]*(1.0); + const double G0_1_1 = det*w[0][1]*w[1][1]*(1.0); + const double G0_1_2 = det*w[0][1]*w[1][2]*(1.0); + const double G0_1_3 = det*w[0][1]*w[1][3]*(1.0); + const double G0_1_4 = det*w[0][1]*w[1][4]*(1.0); + const double G0_1_5 = det*w[0][1]*w[1][5]*(1.0); + const double G0_1_6 = det*w[0][1]*w[1][6]*(1.0); + const double G0_1_7 = det*w[0][1]*w[1][7]*(1.0); + const double G0_1_8 = det*w[0][1]*w[1][8]*(1.0); + const double G0_1_9 = det*w[0][1]*w[1][9]*(1.0); + const double G0_2_0 = det*w[0][2]*w[1][0]*(1.0); + const double G0_2_1 = det*w[0][2]*w[1][1]*(1.0); + const double G0_2_2 = det*w[0][2]*w[1][2]*(1.0); + const double G0_2_3 = det*w[0][2]*w[1][3]*(1.0); + const double G0_2_4 = det*w[0][2]*w[1][4]*(1.0); + const double G0_2_5 = det*w[0][2]*w[1][5]*(1.0); + const double G0_2_6 = det*w[0][2]*w[1][6]*(1.0); + const double G0_2_7 = det*w[0][2]*w[1][7]*(1.0); + const double G0_2_8 = det*w[0][2]*w[1][8]*(1.0); + const double G0_2_9 = det*w[0][2]*w[1][9]*(1.0); + const double G0_3_0 = det*w[0][3]*w[1][0]*(1.0); + const double G0_3_1 = det*w[0][3]*w[1][1]*(1.0); + const double G0_3_2 = det*w[0][3]*w[1][2]*(1.0); + const double G0_3_3 = det*w[0][3]*w[1][3]*(1.0); + const double G0_3_4 = det*w[0][3]*w[1][4]*(1.0); + const double G0_3_5 = det*w[0][3]*w[1][5]*(1.0); + const double G0_3_6 = det*w[0][3]*w[1][6]*(1.0); + const double G0_3_7 = det*w[0][3]*w[1][7]*(1.0); + const double G0_3_8 = det*w[0][3]*w[1][8]*(1.0); + const double G0_3_9 = det*w[0][3]*w[1][9]*(1.0); + const double G0_4_0 = det*w[0][4]*w[1][0]*(1.0); + const double G0_4_1 = det*w[0][4]*w[1][1]*(1.0); + const double G0_4_2 = det*w[0][4]*w[1][2]*(1.0); + const double G0_4_3 = det*w[0][4]*w[1][3]*(1.0); + const double G0_4_4 = det*w[0][4]*w[1][4]*(1.0); + const double G0_4_5 = det*w[0][4]*w[1][5]*(1.0); + const double G0_4_6 = det*w[0][4]*w[1][6]*(1.0); + const double G0_4_7 = det*w[0][4]*w[1][7]*(1.0); + const double G0_4_8 = det*w[0][4]*w[1][8]*(1.0); + const double G0_4_9 = det*w[0][4]*w[1][9]*(1.0); + const double G0_5_0 = det*w[0][5]*w[1][0]*(1.0); + const double G0_5_1 = det*w[0][5]*w[1][1]*(1.0); + const double G0_5_2 = det*w[0][5]*w[1][2]*(1.0); + const double G0_5_3 = det*w[0][5]*w[1][3]*(1.0); + const double G0_5_4 = det*w[0][5]*w[1][4]*(1.0); + const double G0_5_5 = det*w[0][5]*w[1][5]*(1.0); + const double G0_5_6 = det*w[0][5]*w[1][6]*(1.0); + const double G0_5_7 = det*w[0][5]*w[1][7]*(1.0); + const double G0_5_8 = det*w[0][5]*w[1][8]*(1.0); + const double G0_5_9 = det*w[0][5]*w[1][9]*(1.0); + const double G0_6_0 = det*w[0][6]*w[1][0]*(1.0); + const double G0_6_1 = det*w[0][6]*w[1][1]*(1.0); + const double G0_6_2 = det*w[0][6]*w[1][2]*(1.0); + const double G0_6_3 = det*w[0][6]*w[1][3]*(1.0); + const double G0_6_4 = det*w[0][6]*w[1][4]*(1.0); + const double G0_6_5 = det*w[0][6]*w[1][5]*(1.0); + const double G0_6_6 = det*w[0][6]*w[1][6]*(1.0); + const double G0_6_7 = det*w[0][6]*w[1][7]*(1.0); + const double G0_6_8 = det*w[0][6]*w[1][8]*(1.0); + const double G0_6_9 = det*w[0][6]*w[1][9]*(1.0); + const double G0_7_0 = det*w[0][7]*w[1][0]*(1.0); + const double G0_7_1 = det*w[0][7]*w[1][1]*(1.0); + const double G0_7_2 = det*w[0][7]*w[1][2]*(1.0); + const double G0_7_3 = det*w[0][7]*w[1][3]*(1.0); + const double G0_7_4 = det*w[0][7]*w[1][4]*(1.0); + const double G0_7_5 = det*w[0][7]*w[1][5]*(1.0); + const double G0_7_6 = det*w[0][7]*w[1][6]*(1.0); + const double G0_7_7 = det*w[0][7]*w[1][7]*(1.0); + const double G0_7_8 = det*w[0][7]*w[1][8]*(1.0); + const double G0_7_9 = det*w[0][7]*w[1][9]*(1.0); + const double G0_8_0 = det*w[0][8]*w[1][0]*(1.0); + const double G0_8_1 = det*w[0][8]*w[1][1]*(1.0); + const double G0_8_2 = det*w[0][8]*w[1][2]*(1.0); + const double G0_8_3 = det*w[0][8]*w[1][3]*(1.0); + const double G0_8_4 = det*w[0][8]*w[1][4]*(1.0); + const double G0_8_5 = det*w[0][8]*w[1][5]*(1.0); + const double G0_8_6 = det*w[0][8]*w[1][6]*(1.0); + const double G0_8_7 = det*w[0][8]*w[1][7]*(1.0); + const double G0_8_8 = det*w[0][8]*w[1][8]*(1.0); + const double G0_8_9 = det*w[0][8]*w[1][9]*(1.0); + const double G0_9_0 = det*w[0][9]*w[1][0]*(1.0); + const double G0_9_1 = det*w[0][9]*w[1][1]*(1.0); + const double G0_9_2 = det*w[0][9]*w[1][2]*(1.0); + const double G0_9_3 = det*w[0][9]*w[1][3]*(1.0); + const double G0_9_4 = det*w[0][9]*w[1][4]*(1.0); + const double G0_9_5 = det*w[0][9]*w[1][5]*(1.0); + const double G0_9_6 = det*w[0][9]*w[1][6]*(1.0); + const double G0_9_7 = det*w[0][9]*w[1][7]*(1.0); + const double G0_9_8 = det*w[0][9]*w[1][8]*(1.0); + const double G0_9_9 = det*w[0][9]*w[1][9]*(1.0); + + // Compute element tensor + A[73] = -4.28477772227848e-05*G0_0_0 - 1.81626409305012e-05*G0_0_1 - 1.79619487655232e-05*G0_0_2 - 0.000251366936634836*G0_0_3 + 8.0979288568588e-05*G0_0_4 + 1.68581418581446e-05*G0_0_5 + 4.03391251605606e-05*G0_0_6 + 6.32180319680422e-05*G0_0_7 - 0.000172494915798516*G0_0_8 - 0.000173398030540917*G0_0_9 - 1.81626409305012e-05*G0_1_0 - 0.000214238886113923*G0_1_1 - 3.52214749536238e-05*G0_1_2 - 0.000238121253746295*G0_1_3 + 0.000172795954045984*G0_1_4 - 5.71972670187052e-05*G0_1_5 + 4.03391251605606e-05*G0_1_6 + 5.26816933067023e-05*G0_1_7 - 0.000225477647352686*G0_1_8 - 2.52872127872171e-05*G0_1_9 - 1.79619487655232e-05*G0_2_0 - 3.52214749536238e-05*G0_2_1 - 1.40484515484539e-05*G0_2_2 - 0.000167076227344113*G0_2_3 + 0.000109276883830474*G0_2_4 - 2.01695625802803e-05*G0_2_5 + 4.03391251605606e-05*G0_2_6 + 4.03391251605604e-05*G0_2_7 - 0.000121318413729148*G0_2_8 - 0.000124629834451284*G0_2_9 - 0.000251366936634836*G0_3_0 - 0.000238121253746295*G0_3_1 - 0.000167076227344113*G0_3_2 - 0.00284481143856192*G0_3_3 + 0.0005933463857572*G0_3_4 + 0.000382017536035458*G0_3_5 + 4.0640163408027e-05*G0_3_6 + 0.000915758348794218*G0_3_7 - 0.00144137112887137*G0_3_8 - 0.00175565505922678*G0_3_9 + 8.0979288568588e-05*G0_4_0 + 0.000172795954045983*G0_4_1 + 0.000109276883830474*G0_4_2 + 0.0005933463857572*G0_4_3 - 0.000235712947766559*G0_4_4 - 8.1280326816055e-05*G0_4_5 + 4.06401634080277e-05*G0_4_6 - 0.000262806390038577*G0_4_7 + 0.000525612780077154*G0_4_8 + 0.000536450156985962*G0_4_9 + 1.68581418581446e-05*G0_5_0 - 5.71972670187052e-05*G0_5_1 - 2.01695625802803e-05*G0_5_2 + 0.000382017536035458*G0_5_3 - 8.1280326816055e-05*G0_5_4 - 0.000422657699443485*G0_5_5 + 4.06401634080273e-05*G0_5_6 - 0.000373889503353852*G0_5_7 + 0.000333249339945825*G0_5_8 - 0.000146304588268899*G0_5_9 + 4.03391251605606e-05*G0_6_0 + 4.03391251605606e-05*G0_6_1 + 4.03391251605606e-05*G0_6_2 + 4.06401634080271e-05*G0_6_3 + 4.06401634080277e-05*G0_6_4 + 4.06401634080273e-05*G0_6_5 + 4.0640163408028e-05*G0_6_6 + 4.06401634080277e-05*G0_6_7 + 4.06401634080273e-05*G0_6_8 + 0.000292609176537798*G0_6_9 + 6.32180319680422e-05*G0_7_0 + 5.26816933067022e-05*G0_7_1 + 4.03391251605604e-05*G0_7_2 + 0.000915758348794218*G0_7_3 - 0.000262806390038577*G0_7_4 - 0.000373889503353852*G0_7_5 + 4.06401634080277e-05*G0_7_6 - 0.000650242614528441*G0_7_7 + 0.000885955562294997*G0_7_8 + 0.000438913764806695*G0_7_9 - 0.000172494915798516*G0_8_0 - 0.000225477647352686*G0_8_1 - 0.000121318413729148*G0_8_2 - 0.00144137112887137*G0_8_3 + 0.000525612780077154*G0_8_4 + 0.000333249339945825*G0_8_5 + 4.06401634080273e-05*G0_8_6 + 0.000885955562294997*G0_8_7 - 0.0014793019480522*G0_8_8 - 0.000975363921792657*G0_8_9 - 0.000173398030540917*G0_9_0 - 2.52872127872171e-05*G0_9_1 - 0.000124629834451284*G0_9_2 - 0.00175565505922678*G0_9_3 + 0.000536450156985962*G0_9_4 - 0.000146304588268899*G0_9_5 + 0.000292609176537798*G0_9_6 + 0.000438913764806695*G0_9_7 - 0.000975363921792657*G0_9_8 - 0.00234087341230238*G0_9_9; + A[16] = -1.77947052947083e-05*G0_0_0 - 1.28219994291443e-06*G0_0_1 + 4.47097545311907e-06*G0_0_2 - 1.79619487655232e-05*G0_0_3 + 3.59238975310465e-05*G0_0_4 - 5.82007278435948e-05*G0_0_5 + 5.50899992864371e-05*G0_0_6 - 3.52214749536237e-05*G0_0_7 + 6.12111103182634e-06*G0_0_8 + 1.46505280433877e-05*G0_0_9 - 1.28219994291443e-06*G0_1_0 - 8.19493006993136e-06*G0_1_1 - 1.21530255458847e-06*G0_1_2 - 4.28477772227845e-05*G0_1_3 + 5.68962287712384e-05*G0_1_4 - 3.15086699015323e-05*G0_1_5 + 7.92734051662757e-05*G0_1_6 - 1.40484515484539e-05*G0_1_7 - 2.73944805194851e-05*G0_1_8 + 3.09065934065986e-05*G0_1_9 + 4.47097545311907e-06*G0_2_0 - 1.21530255458847e-06*G0_2_1 + 4.89354395604478e-05*G0_2_2 - 1.81626409305011e-05*G0_2_3 + 5.33841158841249e-05*G0_2_4 - 5.82007278435948e-05*G0_2_5 + 5.7598651348661e-05*G0_2_6 - 1.79619487655232e-05*G0_2_7 + 1.45501819608987e-05*G0_2_8 - 1.8463679177968e-05*G0_2_9 - 1.79619487655232e-05*G0_3_0 - 4.28477772227845e-05*G0_3_1 - 1.81626409305011e-05*G0_3_2 + 6.32180319680425e-05*G0_3_3 - 0.000172494915798516*G0_3_4 + 8.0979288568588e-05*G0_3_5 - 0.000251366936634836*G0_3_6 + 4.03391251605606e-05*G0_3_7 + 1.68581418581447e-05*G0_3_8 - 0.000173398030540917*G0_3_9 + 3.59238975310465e-05*G0_4_0 + 5.68962287712384e-05*G0_4_1 + 5.33841158841249e-05*G0_4_2 - 0.000172494915798516*G0_4_3 + 0.000339571143142629*G0_4_4 - 0.000121318413729149*G0_4_5 + 0.000372685350363985*G0_4_6 - 2.01695625802804e-05*G0_4_7 - 5.71972670187053e-05*G0_4_8 + 0.000298027864992201*G0_4_9 - 5.82007278435948e-05*G0_5_0 - 3.15086699015323e-05*G0_5_1 - 5.82007278435948e-05*G0_5_2 + 8.0979288568588e-05*G0_5_3 - 0.000121318413729149*G0_5_4 - 7.49585236192504e-05*G0_5_5 - 7.49585236192507e-05*G0_5_6 - 0.000121318413729148*G0_5_7 + 8.09792885685879e-05*G0_5_8 - 0.000205910161267339*G0_5_9 + 5.50899992864371e-05*G0_6_0 + 7.92734051662757e-05*G0_6_1 + 5.7598651348661e-05*G0_6_2 - 0.000251366936634836*G0_6_3 + 0.000372685350363985*G0_6_4 - 7.49585236192507e-05*G0_6_5 + 0.000794740973312536*G0_6_6 + 4.03391251605603e-05*G0_6_7 - 0.000133962020122757*G0_6_8 + 0.000558124910803576*G0_6_9 - 3.52214749536237e-05*G0_7_0 - 1.40484515484539e-05*G0_7_1 - 1.79619487655232e-05*G0_7_2 + 4.03391251605606e-05*G0_7_3 - 2.01695625802804e-05*G0_7_4 - 0.000121318413729148*G0_7_5 + 4.03391251605603e-05*G0_7_6 - 0.000167076227344112*G0_7_7 + 0.000109276883830474*G0_7_8 - 0.000124629834451284*G0_7_9 + 6.12111103182634e-06*G0_8_0 - 2.73944805194851e-05*G0_8_1 + 1.45501819608987e-05*G0_8_2 + 1.68581418581447e-05*G0_8_3 - 5.71972670187053e-05*G0_8_4 + 8.09792885685878e-05*G0_8_5 - 0.000133962020122757*G0_8_6 + 0.000109276883830474*G0_8_7 - 1.26436063936082e-05*G0_8_8 + 2.16747538176148e-05*G0_8_9 + 1.46505280433877e-05*G0_9_0 + 3.09065934065986e-05*G0_9_1 - 1.8463679177968e-05*G0_9_2 - 0.000173398030540917*G0_9_3 + 0.000298027864992201*G0_9_4 - 0.000205910161267339*G0_9_5 + 0.000558124910803576*G0_9_6 - 0.000124629834451284*G0_9_7 + 2.16747538176148e-05*G0_9_8 + 0.000585218353075595*G0_9_9; + A[69] = A[16] - 8.89735264735413e-06*G0_0_0 + 1.59327279863021e-05*G0_0_1 + 1.11830134151581e-05*G0_0_2 - 0.000106667885685761*G0_0_3 + 0.000262103967461155*G0_0_4 - 0.000207315006422184*G0_0_5 + 0.000232100488796957*G0_0_6 + 9.93426216640662e-06*G0_0_7 + 0.000473031432852942*G0_0_9 + 1.59327279863021e-05*G0_1_0 + 3.910152347653e-05*G0_1_1 - 1.72483766233795e-05*G0_1_2 - 0.000130550253318132*G0_1_3 + 0.000241131636220963*G0_1_4 - 0.000174401491365807*G0_1_5 + 0.000478851505637301*G0_1_6 - 0.00011058138290283*G0_1_7 + 4.90692343370999e-05*G0_1_8 + 0.000554311759668996*G0_1_9 + 1.11830134151581e-05*G0_2_0 - 1.72483766233795e-05*G0_2_1 + 8.45248501498644e-05*G0_2_2 - 7.12457185671585e-06*G0_2_3 - 2.80969030969083e-06*G0_2_4 - 0.000207315006422184*G0_2_5 + 1.82629870129903e-05*G0_2_6 - 0.000155436081775394*G0_2_7 + 7.12457185671581e-06*G0_2_8 - 0.000891875981161846*G0_2_9 - 0.000106667885685761*G0_3_0 - 0.000130550253318133*G0_3_1 - 7.12457185671585e-06*G0_3_2 + 0.000375695732838654*G0_3_3 - 0.000802869005994142*G0_3_4 + 0.000455470868417375*G0_3_5 - 0.00150428812259195*G0_3_6 + 0.000252270051377238*G0_3_7 - 0.000163162730127044*G0_3_8 - 0.00216747538176146*G0_3_9 + 0.000262103967461155*G0_4_0 + 0.000241131636220963*G0_4_1 - 2.80969030969085e-06*G0_4_2 - 0.000802869005994142*G0_4_3 + 0.00239144783787681*G0_4_4 - 0.00085404550806351*G0_4_5 + 0.00235833363065546*G0_4_6 - 0.000126135025688619*G0_4_7 - 8.91073212501928e-05*G0_4_8 + 0.00438371895961256*G0_4_9 - 0.000207315006422184*G0_5_0 - 0.000174401491365807*G0_5_1 - 0.000207315006422184*G0_5_2 + 0.000455470868417375*G0_5_3 - 0.00085404550806351*G0_5_4 - 0.000315187045097812*G0_5_5 - 0.000315187045097814*G0_5_6 - 0.000854045508063509*G0_5_7 + 0.000455470868417374*G0_5_8 - 0.00233003603539357*G0_5_9 + 0.000232100488796957*G0_6_0 + 0.000478851505637301*G0_6_1 + 1.82629870129902e-05*G0_6_2 - 0.00150428812259195*G0_6_3 + 0.00235833363065546*G0_6_4 - 0.000315187045097814*G0_6_5 + 0.00466729698872634*G0_6_6 + 0.000398574639646135*G0_6_7 - 0.000695097313401001*G0_6_8 + 0.00568420418866944*G0_6_9 + 9.93426216640659e-06*G0_7_0 - 0.00011058138290283*G0_7_1 - 0.000155436081775394*G0_7_2 + 0.000252270051377237*G0_7_3 - 0.000126135025688619*G0_7_4 - 0.000854045508063509*G0_7_5 + 0.000398574639646135*G0_7_6 - 0.00158857883188267*G0_7_7 + 0.000427173273155488*G0_7_8 - 0.0022162435778511*G0_7_9 + 4.90692343370999e-05*G0_8_1 + 7.1245718567158e-06*G0_8_2 - 0.000163162730127044*G0_8_3 - 8.91073212501928e-05*G0_8_4 + 0.000455470868417374*G0_8_5 - 0.000695097313401001*G0_8_6 + 0.000427173273155488*G0_8_7 - 0.000816415727130152*G0_8_8 - 0.0014847206365066*G0_8_9 + 0.000473031432852942*G0_9_0 + 0.000554311759668996*G0_9_1 - 0.000891875981161846*G0_9_2 - 0.00216747538176146*G0_9_3 + 0.00438371895961256*G0_9_4 - 0.00233003603539357*G0_9_5 + 0.00568420418866944*G0_9_6 - 0.0022162435778511*G0_9_7 - 0.0014847206365066*G0_9_8 + 0.00292609176537797*G0_9_9; + A[37] = A[73]; + A[40] = A[16] + 9.59977522477694e-06*G0_0_0 - 1.35467211360091e-05*G0_0_3 + 4.33495076352292e-05*G0_0_4 + 1.53529506208103e-05*G0_0_5 + 1.80622948480125e-06*G0_0_6 + 7.82699443413867e-06*G0_0_7 - 2.01695625802803e-05*G0_0_8 + 1.6256065363211e-05*G0_0_9 - 9.59977522477699e-06*G0_1_1 - 1.53529506208104e-05*G0_1_3 - 1.80622948480121e-06*G0_1_4 + 1.35467211360091e-05*G0_1_5 - 4.33495076352292e-05*G0_1_6 + 2.01695625802803e-05*G0_1_7 - 7.82699443413868e-06*G0_1_8 - 1.62560653632109e-05*G0_1_9 - 4.00380869130937e-05*G0_2_3 + 4.21453546453616e-06*G0_2_4 + 4.00380869130937e-05*G0_2_5 - 4.21453546453615e-06*G0_2_6 + 3.25121307264219e-05*G0_2_7 - 3.25121307264219e-05*G0_2_8 - 1.35467211360091e-05*G0_3_0 - 1.53529506208104e-05*G0_3_1 - 4.00380869130937e-05*G0_3_2 - 0.000138176555587293*G0_3_3 + 9.75363921792658e-05*G0_3_4 + 0.000130048522905688*G0_3_6 + 4.06401634080274e-05*G0_3_7 - 0.000138176555587293*G0_3_8 - 3.2512130726422e-05*G0_3_9 + 4.33495076352292e-05*G0_4_0 - 1.80622948480121e-06*G0_4_1 + 4.21453546453615e-06*G0_4_2 + 9.75363921792658e-05*G0_4_3 + 0.000455169830169907*G0_4_4 - 0.000130048522905688*G0_4_5 - 0.000113792457542477*G0_4_7 + 9.75363921792659e-05*G0_4_8 + 0.000260097045811375*G0_4_9 + 1.53529506208103e-05*G0_5_0 + 1.35467211360091e-05*G0_5_1 + 4.00380869130937e-05*G0_5_2 - 0.000130048522905688*G0_5_4 + 0.000138176555587293*G0_5_5 - 9.75363921792657e-05*G0_5_6 + 0.000138176555587293*G0_5_7 - 4.06401634080273e-05*G0_5_8 + 3.25121307264219e-05*G0_5_9 + 1.80622948480125e-06*G0_6_0 - 4.33495076352292e-05*G0_6_1 - 4.21453546453617e-06*G0_6_2 + 0.000130048522905688*G0_6_3 - 9.75363921792657e-05*G0_6_5 - 0.000455169830169907*G0_6_6 - 9.75363921792657e-05*G0_6_7 + 0.000113792457542477*G0_6_8 - 0.000260097045811375*G0_6_9 + 7.82699443413867e-06*G0_7_0 + 2.01695625802803e-05*G0_7_1 + 3.25121307264219e-05*G0_7_2 + 4.06401634080274e-05*G0_7_3 - 0.000113792457542477*G0_7_4 + 0.000138176555587293*G0_7_5 - 9.75363921792657e-05*G0_7_6 + 0.000154432620950504*G0_7_7 + 0.000146304588268899*G0_7_9 - 2.01695625802803e-05*G0_8_0 - 7.82699443413869e-06*G0_8_1 - 3.25121307264219e-05*G0_8_2 - 0.000138176555587293*G0_8_3 + 9.75363921792659e-05*G0_8_4 - 4.06401634080273e-05*G0_8_5 + 0.000113792457542477*G0_8_6 - 0.000154432620950504*G0_8_8 - 0.000146304588268899*G0_8_9 + 1.6256065363211e-05*G0_9_0 - 1.62560653632109e-05*G0_9_1 - 3.25121307264221e-05*G0_9_3 + 0.000260097045811375*G0_9_4 + 3.25121307264219e-05*G0_9_5 - 0.000260097045811375*G0_9_6 + 0.000146304588268899*G0_9_7 - 0.000146304588268899*G0_9_8; + A[4] = A[40]; + A[45] = A[73] + 2.00692164978011e-07*G0_0_1 - 2.00692164977926e-07*G0_0_2 + 0.000332346225203424*G0_0_3 - 0.000332346225203424*G0_0_4 + 4.63598901098981e-05*G0_0_5 - 0.000212834040959077*G0_0_6 - 4.63598901098974e-05*G0_0_7 + 0.000212834040959077*G0_0_8 + 2.00692164978004e-07*G0_1_0 + 0.000200190434565469*G0_1_1 + 0.000347398137576769*G0_1_3 - 0.000339872181390096*G0_1_4 + 9.75363921792658e-05*G0_1_5 - 0.000161657538889709*G0_1_6 - 7.28512558869825e-05*G0_1_7 + 0.000265816772513246*G0_1_8 - 9.93426216640671e-05*G0_1_9 - 2.00692164977923e-07*G0_2_0 - 0.000200190434565468*G0_2_2 + 0.000339872181390096*G0_2_3 - 0.000347398137576768*G0_2_4 + 7.28512558869826e-05*G0_2_5 - 0.000265816772513246*G0_2_6 - 9.75363921792656e-05*G0_2_7 + 0.000161657538889709*G0_2_8 + 9.93426216640672e-05*G0_2_9 + 0.000332346225203424*G0_3_0 + 0.000347398137576768*G0_3_1 + 0.000339872181390096*G0_3_2 + 0.00260909849079536*G0_3_3 - 0.000644823926074035*G0_3_5 + 0.000484972616669128*G0_3_6 - 0.000997038675610273*G0_3_7 + 0.0014820112922794*G0_3_8 + 0.00229210521621275*G0_3_9 - 0.000332346225203424*G0_4_0 - 0.000339872181390096*G0_4_1 - 0.000347398137576768*G0_4_2 - 0.00260909849079536*G0_4_4 + 0.000997038675610273*G0_4_5 - 0.0014820112922794*G0_4_6 + 0.000644823926074035*G0_4_7 - 0.000484972616669127*G0_4_8 - 0.00229210521621275*G0_4_9 + 4.63598901098981e-05*G0_5_0 + 9.75363921792658e-05*G0_5_1 + 7.28512558869826e-05*G0_5_2 - 0.000644823926074035*G0_5_3 + 0.000997038675610273*G0_5_4 - 0.000227584915084954*G0_5_5 + 0.000845315398886971*G0_5_6 - 0.000292609176537797*G0_5_8 + 0.000585218353075596*G0_5_9 - 0.000212834040959077*G0_6_0 - 0.000161657538889709*G0_6_1 - 0.000265816772513246*G0_6_2 + 0.000484972616669128*G0_6_3 - 0.0014820112922794*G0_6_4 + 0.000845315398886971*G0_6_5 - 0.00151994211146023*G0_6_6 + 0.000292609176537798*G0_6_7 - 0.00126797309833046*G0_6_9 - 4.63598901098974e-05*G0_7_0 - 7.28512558869825e-05*G0_7_1 - 9.75363921792656e-05*G0_7_2 - 0.000997038675610273*G0_7_3 + 0.000644823926074035*G0_7_4 + 0.000292609176537798*G0_7_6 + 0.000227584915084956*G0_7_7 - 0.00084531539888697*G0_7_8 - 0.000585218353075593*G0_7_9 + 0.000212834040959077*G0_8_0 + 0.000265816772513246*G0_8_1 + 0.000161657538889709*G0_8_2 + 0.0014820112922794*G0_8_3 - 0.000484972616669127*G0_8_4 - 0.000292609176537797*G0_8_5 - 0.00084531539888697*G0_8_7 + 0.00151994211146022*G0_8_8 + 0.00126797309833045*G0_8_9 - 9.9342621664067e-05*G0_9_1 + 9.93426216640671e-05*G0_9_2 + 0.00229210521621275*G0_9_3 - 0.00229210521621275*G0_9_4 + 0.000585218353075596*G0_9_5 - 0.00126797309833046*G0_9_6 - 0.000585218353075593*G0_9_7 + 0.00126797309833045*G0_9_8; + A[78] = A[73] - 0.000318899850149903*G0_0_0 - 7.81695982588971e-05*G0_0_1 - 4.02387790780715e-05*G0_0_2 + 7.88720208363202e-05*G0_0_3 + 2.82975952618856e-05*G0_0_4 - 0.000242335789210829*G0_0_5 + 0.000132456828885422*G0_0_6 - 0.000701720154845272*G0_0_7 + 6.50242614528431e-05*G0_0_8 - 9.21177037248624e-05*G0_0_9 - 7.81695982588971e-05*G0_1_0 - 0.000147508741258766*G0_1_1 - 2.2979252889971e-05*G0_1_2 + 1.26436063936091e-05*G0_1_3 - 0.000115297648779811*G0_1_5 + 6.89377586699129e-05*G0_1_6 - 0.000160152347652374*G0_1_7 - 0.000413024475524546*G0_1_8 - 0.000240228521478562*G0_1_9 - 4.02387790780715e-05*G0_2_0 - 2.2979252889971e-05*G0_2_1 - 1.74602183530785e-05*G0_2_2 + 4.57578136149644e-05*G0_2_3 - 2.82975952618859e-05*G0_2_4 - 0.000101148851148868*G0_2_5 + 4.06401634080273e-05*G0_2_6 - 0.000115297648779811*G0_2_7 + 4.63598901098979e-05*G0_2_8 - 8.12803268160546e-05*G0_2_9 + 7.88720208363202e-05*G0_3_0 + 1.26436063936091e-05*G0_3_1 + 4.57578136149644e-05*G0_3_2 + 0.00140344030969055*G0_3_3 - 6.77336056800458e-05*G0_3_4 - 4.87681960896329e-05*G0_3_5 - 2.98027864992205e-05*G0_3_7 - 3.79308191808256e-05*G0_3_8 + 0.000780291137434126*G0_3_9 + 2.82975952618856e-05*G0_4_0 - 2.82975952618859e-05*G0_4_2 - 6.77336056800457e-05*G0_4_3 - 2.70934422720185e-05*G0_4_4 + 0.000121920490224082*G0_4_5 - 0.000121920490224082*G0_4_6 + 2.70934422720181e-05*G0_4_7 + 6.77336056800456e-05*G0_4_8 - 0.000242335789210829*G0_5_0 - 0.000115297648779811*G0_5_1 - 0.000101148851148868*G0_5_2 - 4.87681960896329e-05*G0_5_3 + 0.000121920490224082*G0_5_4 - 0.00101871342942788*G0_5_5 + 0.000484972616669126*G0_5_6 - 0.00110541244469834*G0_5_7 + 0.000552706222349172*G0_5_8 - 0.000829059333523757*G0_5_9 + 0.000132456828885422*G0_6_0 + 6.89377586699129e-05*G0_6_1 + 4.06401634080272e-05*G0_6_2 - 0.000121920490224082*G0_6_4 + 0.000484972616669126*G0_6_5 - 0.000303446553446605*G0_6_6 + 0.000552706222349172*G0_6_7 - 0.000276353111174586*G0_6_8 + 0.000243840980448163*G0_6_9 - 0.000701720154845272*G0_7_0 - 0.000160152347652374*G0_7_1 - 0.000115297648779811*G0_7_2 - 2.98027864992203e-05*G0_7_3 + 2.70934422720181e-05*G0_7_4 - 0.00110541244469834*G0_7_5 + 0.000552706222349172*G0_7_6 - 0.0025359461966609*G0_7_7 + 0.00226772111816793*G0_7_8 - 0.000829059333523757*G0_7_9 + 6.50242614528431e-05*G0_8_0 - 0.000413024475524546*G0_8_1 + 4.63598901098979e-05*G0_8_2 - 3.79308191808254e-05*G0_8_3 + 6.77336056800456e-05*G0_8_4 + 0.000552706222349172*G0_8_5 - 0.000276353111174586*G0_8_6 + 0.00226772111816793*G0_8_7 - 0.00170688686313715*G0_8_8 + 0.000585218353075594*G0_8_9 - 9.21177037248624e-05*G0_9_0 - 0.000240228521478562*G0_9_1 - 8.12803268160547e-05*G0_9_2 + 0.000780291137434126*G0_9_3 - 0.000829059333523757*G0_9_5 + 0.000243840980448163*G0_9_6 - 0.000829059333523757*G0_9_7 + 0.000585218353075594*G0_9_8 - 0.000195072784358532*G0_9_9; + A[89] = A[69] + 1.00346082488955e-06*G0_0_1 - 1.00346082488954e-06*G0_0_2 + 0.000422657699443485*G0_0_3 - 0.000422657699443485*G0_0_4 + 0.000240228521478562*G0_0_5 - 0.000290802947052996*G0_0_6 - 0.000240228521478562*G0_0_7 + 0.000290802947052996*G0_0_8 + 1.00346082488955e-06*G0_1_0 + 0.000102553696303714*G0_1_1 + 0.000223972456115351*G0_1_3 - 0.000323315077779418*G0_1_4 + 3.25121307264223e-05*G0_1_5 - 0.000536450156985961*G0_1_6 - 0.000140885899814495*G0_1_7 + 5.41868845440357e-05*G0_1_8 - 0.00149555801341541*G0_1_9 - 1.00346082488954e-06*G0_2_0 - 0.000102553696303714*G0_2_2 + 0.000323315077779418*G0_2_3 - 0.000223972456115351*G0_2_4 + 0.000140885899814495*G0_2_5 - 5.41868845440368e-05*G0_2_6 - 3.2512130726422e-05*G0_2_7 + 0.000536450156985962*G0_2_8 + 0.00149555801341541*G0_2_9 + 0.000422657699443485*G0_3_0 + 0.000223972456115351*G0_3_1 + 0.000323315077779418*G0_3_2 + 0.00229210521621274*G0_3_3 - 0.000682754745254862*G0_3_5 + 0.00160935047095789*G0_3_6 - 0.00126797309833046*G0_3_7 + 0.00287732356928834*G0_3_8 + 0.00702262023690714*G0_3_9 - 0.000422657699443485*G0_4_0 - 0.000323315077779418*G0_4_1 - 0.000223972456115351*G0_4_2 - 0.00229210521621274*G0_4_4 + 0.00126797309833046*G0_4_5 - 0.00287732356928834*G0_4_6 + 0.000682754745254861*G0_4_7 - 0.00160935047095789*G0_4_8 - 0.00702262023690714*G0_4_9 + 0.000240228521478562*G0_5_0 + 3.25121307264223e-05*G0_5_1 + 0.000140885899814495*G0_5_2 - 0.000682754745254862*G0_5_3 + 0.00126797309833046*G0_5_4 - 0.00136550949050972*G0_5_5 + 0.000926595725703027*G0_5_6 - 9.75363921792675e-05*G0_5_8 + 0.000195072784358537*G0_5_9 - 0.000290802947052996*G0_6_0 - 0.000536450156985961*G0_6_1 - 5.41868845440368e-05*G0_6_2 + 0.00160935047095789*G0_6_3 - 0.00287732356928834*G0_6_4 + 0.000926595725703027*G0_6_5 - 0.00629109729556264*G0_6_6 + 9.75363921792665e-05*G0_6_7 - 0.007705374982162*G0_6_9 - 0.000240228521478562*G0_7_0 - 0.000140885899814495*G0_7_1 - 3.2512130726422e-05*G0_7_2 - 0.00126797309833046*G0_7_3 + 0.000682754745254861*G0_7_4 + 9.75363921792664e-05*G0_7_6 + 0.00136550949050972*G0_7_7 - 0.000926595725703025*G0_7_8 - 0.00019507278435853*G0_7_9 + 0.000290802947052996*G0_8_0 + 5.41868845440356e-05*G0_8_1 + 0.000536450156985962*G0_8_2 + 0.00287732356928834*G0_8_3 - 0.00160935047095789*G0_8_4 - 9.75363921792674e-05*G0_8_5 - 0.000926595725703025*G0_8_7 + 0.00629109729556265*G0_8_8 + 0.007705374982162*G0_8_9 - 0.00149555801341541*G0_9_1 + 0.00149555801341541*G0_9_2 + 0.00702262023690714*G0_9_3 - 0.00702262023690714*G0_9_4 + 0.000195072784358535*G0_9_5 - 0.007705374982162*G0_9_6 - 0.00019507278435853*G0_9_7 + 0.007705374982162*G0_9_8; + A[93] = A[89] + 5.7598651348661e-05*G0_0_0 - 3.41176680462452e-05*G0_0_1 + 0.000260097045811375*G0_0_3 - 8.12803268160551e-05*G0_0_4 + 4.69619666048318e-05*G0_0_5 - 0.000121017375481682*G0_0_6 + 9.21177037248624e-05*G0_0_7 + 1.08373769088071e-05*G0_0_8 + 9.75363921792653e-05*G0_0_9 - 3.41176680462452e-05*G0_1_0 + 3.41176680462453e-05*G0_1_2 + 2.5287212787218e-05*G0_1_3 - 0.000240228521478562*G0_1_4 + 0.000195072784358531*G0_1_5 - 0.000195072784358532*G0_1_6 + 0.000240228521478562*G0_1_7 - 2.52872127872165e-05*G0_1_8 + 3.41176680462453e-05*G0_2_1 - 5.75986513486612e-05*G0_2_2 - 1.08373769088071e-05*G0_2_3 - 9.2117703724862e-05*G0_2_4 + 0.000121017375481682*G0_2_5 - 4.69619666048315e-05*G0_2_6 + 8.12803268160547e-05*G0_2_7 - 0.000260097045811376*G0_2_8 - 9.75363921792657e-05*G0_2_9 + 0.000260097045811375*G0_3_0 + 2.52872127872181e-05*G0_3_1 - 1.08373769088071e-05*G0_3_2 + 0.00273101898101944*G0_3_3 + 0.000585218353075595*G0_3_4 - 0.00068275474525486*G0_3_5 + 0.000585218353075596*G0_3_6 - 0.000780291137434126*G0_3_7 + 0.00156058227486825*G0_3_9 - 8.1280326816055e-05*G0_4_0 - 0.000240228521478562*G0_4_1 - 9.2117703724862e-05*G0_4_2 + 0.000585218353075595*G0_4_3 - 0.000829059333523761*G0_4_4 + 0.000243840980448165*G0_4_5 - 0.00082905933352376*G0_4_6 + 0.000780291137434127*G0_4_8 - 0.000195072784358532*G0_4_9 + 4.69619666048318e-05*G0_5_0 + 0.000195072784358531*G0_5_1 + 0.000121017375481682*G0_5_2 - 0.00068275474525486*G0_5_3 + 0.000243840980448165*G0_5_4 + 0.000926595725703023*G0_5_5 + 0.000829059333523757*G0_5_7 - 0.000585218353075593*G0_5_8 + 0.000877827529613391*G0_5_9 - 0.000121017375481682*G0_6_0 - 0.000195072784358532*G0_6_1 - 4.69619666048315e-05*G0_6_2 + 0.000585218353075596*G0_6_3 - 0.00082905933352376*G0_6_4 - 0.000926595725703026*G0_6_6 - 0.000243840980448163*G0_6_7 + 0.000682754745254861*G0_6_8 - 0.000877827529613392*G0_6_9 + 9.21177037248624e-05*G0_7_0 + 0.000240228521478562*G0_7_1 + 8.12803268160547e-05*G0_7_2 - 0.000780291137434126*G0_7_3 + 0.000829059333523757*G0_7_5 - 0.000243840980448163*G0_7_6 + 0.000829059333523757*G0_7_7 - 0.000585218353075594*G0_7_8 + 0.000195072784358533*G0_7_9 + 1.08373769088072e-05*G0_8_0 - 2.52872127872164e-05*G0_8_1 - 0.000260097045811376*G0_8_2 + 0.000780291137434127*G0_8_4 - 0.000585218353075593*G0_8_5 + 0.000682754745254861*G0_8_6 - 0.000585218353075594*G0_8_7 - 0.00273101898101945*G0_8_8 - 0.00156058227486825*G0_8_9 + 9.75363921792654e-05*G0_9_0 - 9.75363921792657e-05*G0_9_2 + 0.00156058227486825*G0_9_3 - 0.000195072784358532*G0_9_4 + 0.000877827529613392*G0_9_5 - 0.000877827529613392*G0_9_6 + 0.000195072784358533*G0_9_7 - 0.00156058227486825*G0_9_8; + A[94] = A[69] + 5.75986513486611e-05*G0_0_0 - 3.41176680462452e-05*G0_0_2 - 8.12803268160549e-05*G0_0_3 + 0.000260097045811375*G0_0_4 + 9.21177037248619e-05*G0_0_5 + 1.08373769088073e-05*G0_0_6 + 4.69619666048316e-05*G0_0_7 - 0.000121017375481681*G0_0_8 + 9.75363921792656e-05*G0_0_9 - 5.75986513486612e-05*G0_1_1 + 3.41176680462452e-05*G0_1_2 - 9.21177037248623e-05*G0_1_3 - 1.08373769088075e-05*G0_1_4 + 8.12803268160549e-05*G0_1_5 - 0.000260097045811375*G0_1_6 + 0.000121017375481682*G0_1_7 - 4.69619666048316e-05*G0_1_8 - 9.75363921792659e-05*G0_1_9 - 3.41176680462452e-05*G0_2_0 + 3.41176680462452e-05*G0_2_1 - 0.000240228521478562*G0_2_3 + 2.5287212787217e-05*G0_2_4 + 0.000240228521478562*G0_2_5 - 2.52872127872173e-05*G0_2_6 + 0.000195072784358531*G0_2_7 - 0.000195072784358531*G0_2_8 - 8.12803268160549e-05*G0_3_0 - 9.21177037248623e-05*G0_3_1 - 0.000240228521478562*G0_3_2 - 0.000829059333523759*G0_3_3 + 0.000585218353075595*G0_3_4 + 0.000780291137434126*G0_3_6 + 0.000243840980448164*G0_3_7 - 0.000829059333523759*G0_3_8 - 0.000195072784358532*G0_3_9 + 0.000260097045811375*G0_4_0 - 1.08373769088074e-05*G0_4_1 + 2.5287212787217e-05*G0_4_2 + 0.000585218353075594*G0_4_3 + 0.00273101898101944*G0_4_4 - 0.000780291137434126*G0_4_5 - 0.000682754745254861*G0_4_7 + 0.000585218353075595*G0_4_8 + 0.00156058227486825*G0_4_9 + 9.21177037248619e-05*G0_5_0 + 8.12803268160549e-05*G0_5_1 + 0.000240228521478562*G0_5_2 - 0.000780291137434127*G0_5_4 + 0.000829059333523759*G0_5_5 - 0.000585218353075594*G0_5_6 + 0.000829059333523759*G0_5_7 - 0.000243840980448165*G0_5_8 + 0.000195072784358533*G0_5_9 + 1.08373769088073e-05*G0_6_0 - 0.000260097045811375*G0_6_1 - 2.52872127872172e-05*G0_6_2 + 0.000780291137434126*G0_6_3 - 0.000585218353075594*G0_6_5 - 0.00273101898101944*G0_6_6 - 0.000585218353075594*G0_6_7 + 0.00068275474525486*G0_6_8 - 0.00156058227486825*G0_6_9 + 4.69619666048316e-05*G0_7_0 + 0.000121017375481682*G0_7_1 + 0.000195072784358531*G0_7_2 + 0.000243840980448164*G0_7_3 - 0.000682754745254861*G0_7_4 + 0.000829059333523759*G0_7_5 - 0.000585218353075594*G0_7_6 + 0.000926595725703025*G0_7_7 + 0.000877827529613392*G0_7_9 - 0.000121017375481681*G0_8_0 - 4.69619666048316e-05*G0_8_1 - 0.000195072784358531*G0_8_2 - 0.000829059333523758*G0_8_3 + 0.000585218353075595*G0_8_4 - 0.000243840980448165*G0_8_5 + 0.00068275474525486*G0_8_6 - 0.000926595725703025*G0_8_8 - 0.000877827529613393*G0_8_9 + 9.75363921792656e-05*G0_9_0 - 9.75363921792658e-05*G0_9_1 - 0.000195072784358532*G0_9_3 + 0.00156058227486825*G0_9_4 + 0.000195072784358533*G0_9_5 - 0.00156058227486825*G0_9_6 + 0.000877827529613391*G0_9_7 - 0.000877827529613393*G0_9_8; + A[51] = -A[16] + 3.11407342657395e-05*G0_0_0 - 3.41176680462455e-06*G0_0_3 + 1.79619487655232e-05*G0_0_4 - 6.02076494933799e-07*G0_0_5 - 3.11072855715763e-06*G0_0_6 + 1.81626409305011e-05*G0_0_7 - 1.20415298986748e-05*G0_0_8 - 3.81315113458034e-06*G0_0_9 - 7.02422577422699e-05*G0_1_3 + 4.28477772227846e-05*G0_1_4 + 4.77647352647433e-05*G0_1_5 + 4.77647352647433e-05*G0_1_6 + 4.28477772227846e-05*G0_1_7 - 7.02422577422699e-05*G0_1_8 + 6.18131868131971e-05*G0_1_9 + 3.11407342657395e-05*G0_2_2 - 1.20415298986748e-05*G0_2_3 + 1.81626409305011e-05*G0_2_4 - 3.11072855715767e-06*G0_2_5 - 6.02076494933758e-07*G0_2_6 + 1.79619487655232e-05*G0_2_7 - 3.41176680462452e-06*G0_2_8 - 3.81315113458032e-06*G0_2_9 - 3.41176680462456e-06*G0_3_0 - 7.02422577422699e-05*G0_3_1 - 1.20415298986748e-05*G0_3_2 + 5.05744255744338e-05*G0_3_3 - 6.32180319680425e-05*G0_3_4 - 5.29827315541689e-05*G0_3_5 - 0.000170387648066248*G0_3_6 - 1.68581418581446e-05*G0_3_7 + 3.37162837162893e-05*G0_3_8 - 0.000151723276723302*G0_3_9 + 1.79619487655232e-05*G0_4_0 + 4.28477772227846e-05*G0_4_1 + 1.81626409305011e-05*G0_4_2 - 6.32180319680425e-05*G0_4_3 + 0.000172494915798516*G0_4_4 - 8.0979288568588e-05*G0_4_5 + 0.000251366936634836*G0_4_6 - 4.03391251605606e-05*G0_4_7 - 1.68581418581447e-05*G0_4_8 + 0.000173398030540917*G0_4_9 - 6.02076494933792e-07*G0_5_0 + 4.77647352647433e-05*G0_5_1 - 3.11072855715767e-06*G0_5_2 - 5.29827315541689e-05*G0_5_3 - 8.0979288568588e-05*G0_5_4 + 0.000719782449693285*G0_5_5 - 0.000149917047238501*G0_5_6 + 0.000251366936634836*G0_5_7 - 0.000170387648066248*G0_5_8 + 0.000352214749536237*G0_5_9 - 3.11072855715761e-06*G0_6_0 + 4.77647352647433e-05*G0_6_1 - 6.02076494933758e-07*G0_6_2 - 0.000170387648066248*G0_6_3 + 0.000251366936634836*G0_6_4 - 0.000149917047238501*G0_6_5 + 0.000719782449693285*G0_6_6 - 8.0979288568588e-05*G0_6_7 - 5.2982731554169e-05*G0_6_8 + 0.000352214749536237*G0_6_9 + 1.8162640930501e-05*G0_7_0 + 4.28477772227846e-05*G0_7_1 + 1.79619487655232e-05*G0_7_2 - 1.68581418581446e-05*G0_7_3 - 4.03391251605606e-05*G0_7_4 + 0.000251366936634836*G0_7_5 - 8.0979288568588e-05*G0_7_6 + 0.000172494915798516*G0_7_7 - 6.32180319680423e-05*G0_7_8 + 0.000173398030540917*G0_7_9 - 1.20415298986748e-05*G0_8_0 - 7.02422577422699e-05*G0_8_1 - 3.41176680462452e-06*G0_8_2 + 3.37162837162892e-05*G0_8_3 - 1.68581418581447e-05*G0_8_4 - 0.000170387648066248*G0_8_5 - 5.2982731554169e-05*G0_8_6 - 6.32180319680423e-05*G0_8_7 + 5.05744255744337e-05*G0_8_8 - 0.000151723276723302*G0_8_9 - 3.81315113458034e-06*G0_9_0 + 6.18131868131971e-05*G0_9_1 - 3.81315113458032e-06*G0_9_2 - 0.000151723276723302*G0_9_3 + 0.000173398030540917*G0_9_4 + 0.000352214749536237*G0_9_5 + 0.000352214749536237*G0_9_6 + 0.000173398030540917*G0_9_7 - 0.000151723276723302*G0_9_8 + 0.00117043670615119*G0_9_9; + A[72] = A[51] - 3.25121307264219e-05*G0_0_3 + 3.25121307264219e-05*G0_0_4 - 4.21453546453616e-06*G0_0_5 + 4.00380869130936e-05*G0_0_6 + 4.21453546453615e-06*G0_0_7 - 4.00380869130936e-05*G0_0_8 - 9.59977522477613e-06*G0_1_1 - 7.82699443413841e-06*G0_1_3 + 2.01695625802802e-05*G0_1_4 - 4.33495076352292e-05*G0_1_5 + 1.35467211360091e-05*G0_1_6 - 1.80622948480144e-06*G0_1_7 - 1.53529506208099e-05*G0_1_8 - 1.62560653632109e-05*G0_1_9 + 9.59977522477657e-06*G0_2_2 - 2.01695625802802e-05*G0_2_3 + 7.82699443413848e-06*G0_2_4 + 1.80622948480128e-06*G0_2_5 + 1.53529506208102e-05*G0_2_6 + 4.33495076352292e-05*G0_2_7 - 1.35467211360091e-05*G0_2_8 + 1.62560653632109e-05*G0_2_9 - 3.25121307264219e-05*G0_3_0 - 7.82699443413841e-06*G0_3_1 - 2.01695625802802e-05*G0_3_2 - 0.000154432620950504*G0_3_3 + 0.000113792457542477*G0_3_5 - 4.06401634080274e-05*G0_3_6 + 9.75363921792656e-05*G0_3_7 - 0.000138176555587293*G0_3_8 - 0.000146304588268899*G0_3_9 + 3.25121307264219e-05*G0_4_0 + 2.01695625802802e-05*G0_4_1 + 7.82699443413848e-06*G0_4_2 + 0.000154432620950504*G0_4_4 - 9.75363921792658e-05*G0_4_5 + 0.000138176555587293*G0_4_6 - 0.000113792457542477*G0_4_7 + 4.06401634080273e-05*G0_4_8 + 0.000146304588268899*G0_4_9 - 4.21453546453617e-06*G0_5_0 - 4.33495076352292e-05*G0_5_1 + 1.80622948480128e-06*G0_5_2 + 0.000113792457542477*G0_5_3 - 9.75363921792658e-05*G0_5_4 - 0.000455169830169906*G0_5_5 - 9.75363921792656e-05*G0_5_6 + 0.000130048522905688*G0_5_8 - 0.000260097045811375*G0_5_9 + 4.00380869130936e-05*G0_6_0 + 1.35467211360091e-05*G0_6_1 + 1.53529506208102e-05*G0_6_2 - 4.06401634080274e-05*G0_6_3 + 0.000138176555587293*G0_6_4 - 9.75363921792656e-05*G0_6_5 + 0.000138176555587293*G0_6_6 - 0.000130048522905688*G0_6_7 + 3.25121307264223e-05*G0_6_9 + 4.21453546453617e-06*G0_7_0 - 1.80622948480144e-06*G0_7_1 + 4.33495076352292e-05*G0_7_2 + 9.75363921792656e-05*G0_7_3 - 0.000113792457542477*G0_7_4 - 0.000130048522905688*G0_7_6 + 0.000455169830169906*G0_7_7 + 9.75363921792656e-05*G0_7_8 + 0.000260097045811375*G0_7_9 - 4.00380869130936e-05*G0_8_0 - 1.53529506208099e-05*G0_8_1 - 1.35467211360091e-05*G0_8_2 - 0.000138176555587293*G0_8_3 + 4.06401634080273e-05*G0_8_4 + 0.000130048522905688*G0_8_5 + 9.75363921792656e-05*G0_8_7 - 0.000138176555587292*G0_8_8 - 3.2512130726422e-05*G0_8_9 - 1.62560653632109e-05*G0_9_1 + 1.62560653632109e-05*G0_9_2 - 0.000146304588268899*G0_9_3 + 0.000146304588268899*G0_9_4 - 0.000260097045811375*G0_9_5 + 3.25121307264223e-05*G0_9_6 + 0.000260097045811375*G0_9_7 - 3.25121307264219e-05*G0_9_8; + A[7] = A[72] + 0.000641780094905203*G0_0_0 + 6.60054231482914e-05*G0_0_1 + 5.01507421150362e-05*G0_0_2 - 2.48858284572616e-05*G0_0_3 - 4.19446624803838e-05*G0_0_4 + 0.000375093656343719*G0_0_5 - 0.000196076245183421*G0_0_6 + 0.000799356893107027*G0_0_7 - 0.000303546899529093*G0_0_8 + 0.00015192396888828*G0_0_9 + 6.60054231482914e-05*G0_1_0 - 7.25836663336794e-06*G0_1_1 + 1.70588340231226e-05*G0_1_3 + 1.74602183530783e-05*G0_1_5 - 1.72595261881005e-05*G0_1_6 + 0.000117705954759546*G0_1_7 - 3.81315113458036e-05*G0_1_8 + 1.00346082488957e-06*G0_1_9 + 5.01507421150362e-05*G0_2_0 - 3.91349721706937e-06*G0_2_3 + 4.1944662480384e-05*G0_2_4 - 3.51211288711361e-06*G0_2_5 + 2.46851362922835e-05*G0_2_6 - 2.16747538176147e-05*G0_2_7 - 2.66920579420624e-05*G0_2_8 - 4.93702725845665e-05*G0_2_9 - 2.48858284572616e-05*G0_3_0 + 1.70588340231226e-05*G0_3_1 - 3.91349721706937e-06*G0_3_2 - 8.42907092907236e-05*G0_3_3 - 2.82975952618858e-05*G0_3_4 + 3.70277044384249e-05*G0_3_5 + 2.28789068074818e-05*G0_3_7 - 5.11765020693677e-05*G0_3_8 - 4.87681960896328e-05*G0_3_9 - 4.19446624803838e-05*G0_4_0 + 4.1944662480384e-05*G0_4_2 - 2.82975952618858e-05*G0_4_3 - 0.000121318413729148*G0_4_4 + 7.405540887685e-05*G0_4_5 - 7.405540887685e-05*G0_4_6 + 0.000121318413729149*G0_4_7 + 2.82975952618857e-05*G0_4_8 + 0.000375093656343719*G0_5_0 + 1.74602183530784e-05*G0_5_1 - 3.51211288711362e-06*G0_5_2 + 3.70277044384249e-05*G0_5_3 + 7.405540887685e-05*G0_5_4 + 0.00012402775795635*G0_5_5 - 5.29827315541689e-05*G0_5_6 + 9.09135507349943e-05*G0_5_7 - 0.000104159233623536*G0_5_8 - 0.000247453439417767*G0_5_9 - 0.000196076245183421*G0_6_0 - 1.72595261881005e-05*G0_6_1 + 2.46851362922835e-05*G0_6_2 - 7.405540887685e-05*G0_6_4 - 5.29827315541689e-05*G0_6_5 - 1.05363386613404e-05*G0_6_6 + 1.32456828885424e-05*G0_6_7 + 9.18166654773951e-05*G0_6_8 + 0.0001481108177537*G0_6_9 + 0.000799356893107027*G0_7_0 + 0.000117705954759546*G0_7_1 - 2.16747538176146e-05*G0_7_2 + 2.28789068074818e-05*G0_7_3 + 0.000121318413729149*G0_7_4 + 9.09135507349943e-05*G0_7_5 + 1.32456828885425e-05*G0_7_6 + 0.000596055729984402*G0_7_7 - 0.000563543599257979*G0_7_8 - 0.000482263272441924*G0_7_9 - 0.000303546899529093*G0_8_0 - 3.81315113458036e-05*G0_8_1 - 2.66920579420624e-05*G0_8_2 - 5.11765020693677e-05*G0_8_3 + 2.82975952618857e-05*G0_8_4 - 0.000104159233623536*G0_8_5 + 9.18166654773951e-05*G0_8_6 - 0.000563543599257979*G0_8_7 - 3.25121307264224e-05*G0_8_8 - 5.96055729984405e-05*G0_8_9 + 0.00015192396888828*G0_9_0 + 1.00346082488957e-06*G0_9_1 - 4.93702725845665e-05*G0_9_2 - 4.87681960896328e-05*G0_9_3 - 0.000247453439417767*G0_9_5 + 0.0001481108177537*G0_9_6 - 0.000482263272441924*G0_9_7 - 5.96055729984405e-05*G0_9_8 - 0.00149555801341541*G0_9_9; + A[82] = -A[72] + 3.11407342657395e-05*G0_0_0 + 1.79619487655232e-05*G0_0_3 - 3.41176680462452e-06*G0_0_4 + 1.81626409305011e-05*G0_0_5 - 1.20415298986748e-05*G0_0_6 - 6.02076494933785e-07*G0_0_7 - 3.11072855715763e-06*G0_0_8 - 3.81315113458032e-06*G0_0_9 + 3.11407342657395e-05*G0_1_1 + 1.81626409305011e-05*G0_1_3 - 1.20415298986748e-05*G0_1_4 + 1.79619487655232e-05*G0_1_5 - 3.41176680462451e-06*G0_1_6 - 3.11072855715769e-06*G0_1_7 - 6.02076494933819e-07*G0_1_8 - 3.81315113458041e-06*G0_1_9 + 4.28477772227844e-05*G0_2_3 - 7.02422577422696e-05*G0_2_4 + 4.28477772227845e-05*G0_2_5 - 7.02422577422696e-05*G0_2_6 + 4.77647352647433e-05*G0_2_7 + 4.77647352647433e-05*G0_2_8 + 6.18131868131972e-05*G0_2_9 + 1.79619487655232e-05*G0_3_0 + 1.81626409305011e-05*G0_3_1 + 4.28477772227844e-05*G0_3_2 + 0.000172494915798516*G0_3_3 - 6.32180319680425e-05*G0_3_4 - 4.03391251605606e-05*G0_3_5 - 1.68581418581447e-05*G0_3_6 - 8.09792885685879e-05*G0_3_7 + 0.000251366936634836*G0_3_8 + 0.000173398030540917*G0_3_9 - 3.41176680462452e-06*G0_4_0 - 1.20415298986748e-05*G0_4_1 - 7.02422577422696e-05*G0_4_2 - 6.32180319680425e-05*G0_4_3 + 5.05744255744341e-05*G0_4_4 - 1.68581418581447e-05*G0_4_5 + 3.37162837162894e-05*G0_4_6 - 5.2982731554169e-05*G0_4_7 - 0.000170387648066248*G0_4_8 - 0.000151723276723302*G0_4_9 + 1.81626409305011e-05*G0_5_0 + 1.79619487655232e-05*G0_5_1 + 4.28477772227845e-05*G0_5_2 - 4.03391251605606e-05*G0_5_3 - 1.68581418581447e-05*G0_5_4 + 0.000172494915798516*G0_5_5 - 6.32180319680426e-05*G0_5_6 + 0.000251366936634836*G0_5_7 - 8.0979288568588e-05*G0_5_8 + 0.000173398030540917*G0_5_9 - 1.20415298986748e-05*G0_6_0 - 3.4117668046245e-06*G0_6_1 - 7.02422577422696e-05*G0_6_2 - 1.68581418581447e-05*G0_6_3 + 3.37162837162894e-05*G0_6_4 - 6.32180319680426e-05*G0_6_5 + 5.05744255744341e-05*G0_6_6 - 0.000170387648066248*G0_6_7 - 5.29827315541691e-05*G0_6_8 - 0.000151723276723302*G0_6_9 - 6.02076494933785e-07*G0_7_0 - 3.1107285571577e-06*G0_7_1 + 4.77647352647433e-05*G0_7_2 - 8.09792885685879e-05*G0_7_3 - 5.2982731554169e-05*G0_7_4 + 0.000251366936634836*G0_7_5 - 0.000170387648066248*G0_7_6 + 0.000719782449693284*G0_7_7 - 0.000149917047238501*G0_7_8 + 0.000352214749536237*G0_7_9 - 3.11072855715763e-06*G0_8_0 - 6.02076494933819e-07*G0_8_1 + 4.77647352647433e-05*G0_8_2 + 0.000251366936634836*G0_8_3 - 0.000170387648066248*G0_8_4 - 8.0979288568588e-05*G0_8_5 - 5.29827315541691e-05*G0_8_6 - 0.000149917047238501*G0_8_7 + 0.000719782449693285*G0_8_8 + 0.000352214749536238*G0_8_9 - 3.81315113458033e-06*G0_9_0 - 3.81315113458042e-06*G0_9_1 + 6.18131868131972e-05*G0_9_2 + 0.000173398030540917*G0_9_3 - 0.000151723276723302*G0_9_4 + 0.000173398030540917*G0_9_5 - 0.000151723276723302*G0_9_6 + 0.000352214749536237*G0_9_7 + 0.000352214749536238*G0_9_8 + 0.00117043670615119*G0_9_9; + A[15] = A[51]; + A[36] = A[45] + 2.87993256743307e-05*G0_0_0 - 1.70588340231226e-05*G0_0_2 - 4.06401634080274e-05*G0_0_3 + 0.000130048522905688*G0_0_4 + 4.60588518624311e-05*G0_0_5 + 5.4186884544036e-06*G0_0_6 + 2.34809833024159e-05*G0_0_7 - 6.05086877408408e-05*G0_0_8 + 4.8768196089633e-05*G0_0_9 - 2.87993256743307e-05*G0_1_1 + 1.70588340231226e-05*G0_1_2 - 4.60588518624313e-05*G0_1_3 - 5.41868845440363e-06*G0_1_4 + 4.06401634080274e-05*G0_1_5 - 0.000130048522905688*G0_1_6 + 6.05086877408409e-05*G0_1_7 - 2.34809833024159e-05*G0_1_8 - 4.87681960896328e-05*G0_1_9 - 1.70588340231226e-05*G0_2_0 + 1.70588340231226e-05*G0_2_1 - 0.000120114260739281*G0_2_3 + 1.26436063936087e-05*G0_2_4 + 0.000120114260739281*G0_2_5 - 1.26436063936084e-05*G0_2_6 + 9.75363921792658e-05*G0_2_7 - 9.75363921792658e-05*G0_2_8 - 4.06401634080274e-05*G0_3_0 - 4.60588518624313e-05*G0_3_1 - 0.000120114260739281*G0_3_2 - 0.000414529666761878*G0_3_3 + 0.000292609176537797*G0_3_4 + 0.000390145568717063*G0_3_6 + 0.000121920490224082*G0_3_7 - 0.000414529666761879*G0_3_8 - 9.7536392179266e-05*G0_3_9 + 0.000130048522905688*G0_4_0 - 5.41868845440366e-06*G0_4_1 + 1.26436063936087e-05*G0_4_2 + 0.000292609176537797*G0_4_3 + 0.00136550949050972*G0_4_4 - 0.000390145568717063*G0_4_5 - 0.00034137737262743*G0_4_7 + 0.000292609176537797*G0_4_8 + 0.000780291137434127*G0_4_9 + 4.60588518624311e-05*G0_5_0 + 4.06401634080274e-05*G0_5_1 + 0.000120114260739281*G0_5_2 - 0.000390145568717063*G0_5_4 + 0.00041452966676188*G0_5_5 - 0.000292609176537797*G0_5_6 + 0.00041452966676188*G0_5_7 - 0.000121920490224082*G0_5_8 + 9.7536392179266e-05*G0_5_9 + 5.4186884544036e-06*G0_6_0 - 0.000130048522905688*G0_6_1 - 1.26436063936084e-05*G0_6_2 + 0.000390145568717063*G0_6_3 - 0.000292609176537797*G0_6_5 - 0.00136550949050972*G0_6_6 - 0.000292609176537797*G0_6_7 + 0.00034137737262743*G0_6_8 - 0.000780291137434126*G0_6_9 + 2.34809833024159e-05*G0_7_0 + 6.05086877408409e-05*G0_7_1 + 9.75363921792658e-05*G0_7_2 + 0.000121920490224082*G0_7_3 - 0.000341377372627431*G0_7_4 + 0.00041452966676188*G0_7_5 - 0.000292609176537797*G0_7_6 + 0.000463297862851513*G0_7_7 + 0.000438913764806696*G0_7_9 - 6.05086877408408e-05*G0_8_0 - 2.34809833024159e-05*G0_8_1 - 9.75363921792658e-05*G0_8_2 - 0.00041452966676188*G0_8_3 + 0.000292609176537798*G0_8_4 - 0.000121920490224082*G0_8_5 + 0.00034137737262743*G0_8_6 - 0.000463297862851513*G0_8_8 - 0.000438913764806696*G0_8_9 + 4.8768196089633e-05*G0_9_0 - 4.87681960896328e-05*G0_9_1 - 9.75363921792659e-05*G0_9_3 + 0.000780291137434127*G0_9_4 + 9.75363921792661e-05*G0_9_5 - 0.000780291137434126*G0_9_6 + 0.000438913764806696*G0_9_7 - 0.000438913764806696*G0_9_8; + A[85] = A[36] - 0.000200190434565468*G0_0_0 - 2.00692164977882e-07*G0_0_1 - 9.75363921792658e-05*G0_0_3 + 0.000161657538889709*G0_0_4 - 0.000347398137576767*G0_0_5 + 0.000339872181390096*G0_0_6 - 0.000265816772513245*G0_0_7 + 7.28512558869821e-05*G0_0_8 + 9.9342621664067e-05*G0_0_9 - 2.00692164977892e-07*G0_1_0 + 2.00692164977902e-07*G0_1_2 - 4.6359890109898e-05*G0_1_3 + 0.000212834040959077*G0_1_4 - 0.000332346225203424*G0_1_5 + 0.000332346225203424*G0_1_6 - 0.000212834040959076*G0_1_7 + 4.63598901098972e-05*G0_1_8 + 2.00692164977906e-07*G0_2_1 + 0.000200190434565468*G0_2_2 - 7.28512558869824e-05*G0_2_3 + 0.000265816772513246*G0_2_4 - 0.000339872181390096*G0_2_5 + 0.000347398137576767*G0_2_6 - 0.000161657538889709*G0_2_7 + 9.75363921792657e-05*G0_2_8 - 9.93426216640671e-05*G0_2_9 - 9.75363921792658e-05*G0_3_0 - 4.6359890109898e-05*G0_3_1 - 7.28512558869824e-05*G0_3_2 + 0.000227584915084952*G0_3_3 - 0.00084531539888697*G0_3_4 + 0.000644823926074035*G0_3_5 - 0.000997038675610273*G0_3_6 + 0.000292609176537798*G0_3_7 - 0.000585218353075596*G0_3_9 + 0.000161657538889709*G0_4_0 + 0.000212834040959077*G0_4_1 + 0.000265816772513246*G0_4_2 - 0.000845315398886971*G0_4_3 + 0.00151994211146022*G0_4_4 - 0.000484972616669127*G0_4_5 + 0.0014820112922794*G0_4_6 - 0.000292609176537797*G0_4_8 + 0.00126797309833046*G0_4_9 - 0.000347398137576767*G0_5_0 - 0.000332346225203424*G0_5_1 - 0.000339872181390096*G0_5_2 + 0.000644823926074035*G0_5_3 - 0.000484972616669127*G0_5_4 - 0.00260909849079535*G0_5_5 - 0.0014820112922794*G0_5_7 + 0.00099703867561027*G0_5_8 - 0.00229210521621274*G0_5_9 + 0.000339872181390096*G0_6_0 + 0.000332346225203424*G0_6_1 + 0.000347398137576767*G0_6_2 - 0.000997038675610273*G0_6_3 + 0.0014820112922794*G0_6_4 + 0.00260909849079536*G0_6_6 + 0.000484972616669126*G0_6_7 - 0.000644823926074034*G0_6_8 + 0.00229210521621275*G0_6_9 - 0.000265816772513245*G0_7_0 - 0.000212834040959076*G0_7_1 - 0.000161657538889709*G0_7_2 + 0.000292609176537798*G0_7_3 - 0.0014820112922794*G0_7_5 + 0.000484972616669126*G0_7_6 - 0.00151994211146022*G0_7_7 + 0.00084531539888697*G0_7_8 - 0.00126797309833045*G0_7_9 + 7.28512558869821e-05*G0_8_0 + 4.63598901098972e-05*G0_8_1 + 9.75363921792656e-05*G0_8_2 - 0.000292609176537797*G0_8_4 + 0.00099703867561027*G0_8_5 - 0.000644823926074034*G0_8_6 + 0.00084531539888697*G0_8_7 - 0.000227584915084956*G0_8_8 + 0.000585218353075593*G0_8_9 + 9.9342621664067e-05*G0_9_0 - 9.93426216640671e-05*G0_9_2 - 0.000585218353075596*G0_9_3 + 0.00126797309833046*G0_9_4 - 0.00229210521621274*G0_9_5 + 0.00229210521621275*G0_9_6 - 0.00126797309833045*G0_9_7 + 0.000585218353075593*G0_9_8; + A[58] = A[85]; + A[67] = A[85] - 1.70588340231226e-05*G0_0_1 + 1.70588340231226e-05*G0_0_2 + 9.75363921792659e-05*G0_0_3 - 9.75363921792659e-05*G0_0_4 + 1.26436063936085e-05*G0_0_5 - 0.000120114260739281*G0_0_6 - 1.26436063936087e-05*G0_0_7 + 0.000120114260739281*G0_0_8 - 1.70588340231226e-05*G0_1_0 + 2.87993256743309e-05*G0_1_1 + 2.34809833024161e-05*G0_1_3 - 6.05086877408409e-05*G0_1_4 + 0.000130048522905688*G0_1_5 - 4.06401634080275e-05*G0_1_6 + 5.41868845440338e-06*G0_1_7 + 4.60588518624316e-05*G0_1_8 + 4.87681960896326e-05*G0_1_9 + 1.70588340231226e-05*G0_2_0 - 2.87993256743307e-05*G0_2_2 + 6.05086877408409e-05*G0_2_3 - 2.34809833024159e-05*G0_2_4 - 5.41868845440352e-06*G0_2_5 - 4.60588518624311e-05*G0_2_6 - 0.000130048522905688*G0_2_7 + 4.06401634080275e-05*G0_2_8 - 4.87681960896327e-05*G0_2_9 + 9.75363921792659e-05*G0_3_0 + 2.34809833024161e-05*G0_3_1 + 6.05086877408409e-05*G0_3_2 + 0.000463297862851512*G0_3_3 - 0.00034137737262743*G0_3_5 + 0.000121920490224083*G0_3_6 - 0.000292609176537797*G0_3_7 + 0.00041452966676188*G0_3_8 + 0.000438913764806697*G0_3_9 - 9.75363921792659e-05*G0_4_0 - 6.05086877408409e-05*G0_4_1 - 2.34809833024159e-05*G0_4_2 - 0.000463297862851513*G0_4_4 + 0.000292609176537798*G0_4_5 - 0.00041452966676188*G0_4_6 + 0.00034137737262743*G0_4_7 - 0.000121920490224082*G0_4_8 - 0.000438913764806697*G0_4_9 + 1.26436063936085e-05*G0_5_0 + 0.000130048522905688*G0_5_1 - 5.41868845440352e-06*G0_5_2 - 0.00034137737262743*G0_5_3 + 0.000292609176537798*G0_5_4 + 0.00136550949050972*G0_5_5 + 0.000292609176537798*G0_5_6 - 0.000390145568717062*G0_5_8 + 0.000780291137434124*G0_5_9 - 0.000120114260739281*G0_6_0 - 4.06401634080275e-05*G0_6_1 - 4.60588518624311e-05*G0_6_2 + 0.000121920490224083*G0_6_3 - 0.00041452966676188*G0_6_4 + 0.000292609176537798*G0_6_5 - 0.000414529666761883*G0_6_6 + 0.000390145568717063*G0_6_7 - 9.75363921792669e-05*G0_6_9 - 1.26436063936087e-05*G0_7_0 + 5.41868845440338e-06*G0_7_1 - 0.000130048522905688*G0_7_2 - 0.000292609176537797*G0_7_3 + 0.00034137737262743*G0_7_4 + 0.000390145568717063*G0_7_6 - 0.00136550949050972*G0_7_7 - 0.000292609176537798*G0_7_8 - 0.000780291137434127*G0_7_9 + 0.000120114260739281*G0_8_0 + 4.60588518624316e-05*G0_8_1 + 4.06401634080275e-05*G0_8_2 + 0.00041452966676188*G0_8_3 - 0.000121920490224082*G0_8_4 - 0.000390145568717062*G0_8_5 - 0.000292609176537798*G0_8_7 + 0.000414529666761882*G0_8_8 + 9.75363921792668e-05*G0_8_9 + 4.87681960896327e-05*G0_9_1 - 4.87681960896326e-05*G0_9_2 + 0.000438913764806697*G0_9_3 - 0.000438913764806697*G0_9_4 + 0.000780291137434124*G0_9_5 - 9.75363921792669e-05*G0_9_6 - 0.000780291137434126*G0_9_7 + 9.75363921792668e-05*G0_9_8; + A[76] = A[67]; + A[86] = A[51] + 3.81649600399665e-05*G0_0_0 - 3.4719744541179e-05*G0_0_3 - 2.20761381475698e-06*G0_0_4 + 0.000115197302697322*G0_0_5 - 3.27128228913997e-05*G0_0_6 + 0.000119411838161858*G0_0_7 - 7.27509098044934e-05*G0_0_8 + 1.48512202083655e-05*G0_0_9 - 1.91995504495529e-05*G0_1_1 + 1.58323819038132e-05*G0_1_2 + 4.42526223776301e-05*G0_1_3 - 4.31488154702514e-05*G0_1_4 + 1.70588340231222e-06*G0_1_5 - 0.000102453350221225*G0_1_6 + 5.2380655059235e-05*G0_1_7 + 3.02041708291766e-05*G0_1_8 - 9.23183958898373e-06*G0_1_9 + 1.58323819038132e-05*G0_2_1 - 9.59977522477669e-06*G0_2_2 - 6.33183780505316e-05*G0_2_3 + 5.20796168117686e-05*G0_2_4 + 5.41868845440363e-05*G0_2_5 + 4.55571214499865e-05*G0_2_6 + 4.50553910375414e-05*G0_2_7 - 0.000116000071357234*G0_2_8 + 7.02422577422684e-06*G0_2_9 - 3.4719744541179e-05*G0_3_0 + 4.42526223776301e-05*G0_3_1 - 6.33183780505316e-05*G0_3_2 - 0.000361245896960243*G0_3_3 + 0.000223972456115351*G0_3_4 + 5.26816933067022e-05*G0_3_5 + 0.000301038247466869*G0_3_6 + 9.78374304267324e-05*G0_3_7 - 0.000439515841301629*G0_3_8 - 0.000167979342086514*G0_3_9 - 2.20761381475698e-06*G0_4_0 - 4.31488154702514e-05*G0_4_1 + 5.20796168117686e-05*G0_4_2 + 0.000223972456115351*G0_4_3 - 0.000206813276009739*G0_4_4 + 3.01038247466598e-07*G0_4_5 - 0.000301339285714336*G0_4_6 - 6.11107642357745e-05*G0_4_7 + 0.000341678410874897*G0_4_8 - 2.16747538176138e-05*G0_4_9 + 0.000115197302697322*G0_5_0 + 1.70588340231222e-06*G0_5_1 + 5.41868845440363e-05*G0_5_2 + 5.26816933067022e-05*G0_5_3 + 3.01038247466584e-07*G0_5_4 - 0.000201394587555335*G0_5_5 - 0.000160754424147308*G0_5_6 + 0.00015292742971317*G0_5_7 - 1.14394534037409e-05*G0_5_8 - 2.16747538176138e-05*G0_5_9 - 3.27128228913997e-05*G0_6_0 - 0.000102453350221225*G0_6_1 + 4.55571214499865e-05*G0_6_2 + 0.000301038247466869*G0_6_3 - 0.000301339285714336*G0_6_4 - 0.000160754424147308*G0_6_5 - 0.000867893267446983*G0_6_6 - 0.000141487976309428*G0_6_7 + 0.00033084103396609*G0_6_8 - 0.000623149172256419*G0_6_9 + 0.000119411838161858*G0_7_0 + 5.2380655059235e-05*G0_7_1 + 4.50553910375414e-05*G0_7_2 + 9.78374304267324e-05*G0_7_3 - 6.11107642357745e-05*G0_7_4 + 0.00015292742971317*G0_7_5 - 0.000141487976309428*G0_7_6 + 0.000253775242614571*G0_7_7 - 6.32180319680428e-05*G0_7_8 + 0.000238422291993761*G0_7_9 - 7.27509098044934e-05*G0_8_0 + 3.02041708291766e-05*G0_8_1 - 0.000116000071357234*G0_8_2 - 0.000439515841301629*G0_8_3 + 0.000341678410874897*G0_8_4 - 1.14394534037409e-05*G0_8_5 + 0.00033084103396609*G0_8_6 - 6.32180319680428e-05*G0_8_7 - 0.00100606982303428*G0_8_8 - 0.000655661302982843*G0_8_9 + 1.48512202083656e-05*G0_9_0 - 9.23183958898371e-06*G0_9_1 + 7.02422577422684e-06*G0_9_2 - 0.000167979342086514*G0_9_3 - 2.16747538176139e-05*G0_9_4 - 2.16747538176138e-05*G0_9_5 - 0.000623149172256419*G0_9_6 + 0.000238422291993761*G0_9_7 - 0.000655661302982843*G0_9_8 - 0.00204826423576458*G0_9_9; + A[97] = A[94] + 0.000102553696303713*G0_0_0 + 1.00346082488955e-06*G0_0_1 + 3.25121307264222e-05*G0_0_3 - 0.000536450156985962*G0_0_4 + 0.000223972456115351*G0_0_5 - 0.000323315077779418*G0_0_6 + 5.41868845440371e-05*G0_0_7 - 0.000140885899814495*G0_0_8 - 0.00149555801341541*G0_0_9 + 1.00346082488956e-06*G0_1_0 - 1.00346082488959e-06*G0_1_2 + 0.000240228521478562*G0_1_3 - 0.000290802947052996*G0_1_4 + 0.000422657699443485*G0_1_5 - 0.000422657699443485*G0_1_6 + 0.000290802947052996*G0_1_7 - 0.000240228521478562*G0_1_8 - 1.00346082488958e-06*G0_2_1 - 0.000102553696303714*G0_2_2 + 0.000140885899814495*G0_2_3 - 5.41868845440363e-05*G0_2_4 + 0.000323315077779418*G0_2_5 - 0.000223972456115351*G0_2_6 + 0.000536450156985961*G0_2_7 - 3.25121307264218e-05*G0_2_8 + 0.00149555801341541*G0_2_9 + 3.25121307264221e-05*G0_3_0 + 0.000240228521478562*G0_3_1 + 0.000140885899814495*G0_3_2 - 0.00136550949050972*G0_3_3 + 0.000926595725703026*G0_3_4 - 0.000682754745254862*G0_3_5 + 0.00126797309833046*G0_3_6 - 9.75363921792669e-05*G0_3_7 + 0.000195072784358534*G0_3_9 - 0.000536450156985962*G0_4_0 - 0.000290802947052996*G0_4_1 - 5.41868845440364e-05*G0_4_2 + 0.000926595725703026*G0_4_3 - 0.00629109729556264*G0_4_4 + 0.00160935047095789*G0_4_5 - 0.00287732356928834*G0_4_6 + 9.75363921792646e-05*G0_4_8 - 0.007705374982162*G0_4_9 + 0.000223972456115351*G0_5_0 + 0.000422657699443485*G0_5_1 + 0.000323315077779418*G0_5_2 - 0.000682754745254862*G0_5_3 + 0.00160935047095789*G0_5_4 + 0.00229210521621274*G0_5_5 + 0.00287732356928834*G0_5_7 - 0.00126797309833045*G0_5_8 + 0.00702262023690714*G0_5_9 - 0.000323315077779418*G0_6_0 - 0.000422657699443485*G0_6_1 - 0.000223972456115351*G0_6_2 + 0.00126797309833046*G0_6_3 - 0.00287732356928834*G0_6_4 - 0.00229210521621275*G0_6_6 - 0.00160935047095788*G0_6_7 + 0.000682754745254859*G0_6_8 - 0.00702262023690714*G0_6_9 + 5.41868845440371e-05*G0_7_0 + 0.000290802947052996*G0_7_1 + 0.000536450156985961*G0_7_2 - 9.75363921792669e-05*G0_7_3 + 0.00287732356928834*G0_7_5 - 0.00160935047095788*G0_7_6 + 0.00629109729556263*G0_7_7 - 0.000926595725703023*G0_7_8 + 0.007705374982162*G0_7_9 - 0.000140885899814495*G0_8_0 - 0.000240228521478562*G0_8_1 - 3.25121307264217e-05*G0_8_2 + 9.75363921792647e-05*G0_8_4 - 0.00126797309833045*G0_8_5 + 0.000682754745254859*G0_8_6 - 0.000926595725703023*G0_8_7 + 0.00136550949050972*G0_8_8 - 0.000195072784358531*G0_8_9 - 0.00149555801341541*G0_9_0 + 0.00149555801341541*G0_9_2 + 0.000195072784358534*G0_9_3 - 0.007705374982162*G0_9_4 + 0.00702262023690714*G0_9_5 - 0.00702262023690714*G0_9_6 + 0.007705374982162*G0_9_7 - 0.000195072784358531*G0_9_8; + A[54] = A[45]; + A[35] = A[16] - 9.59977522477706e-06*G0_0_0 + 1.58323819038131e-05*G0_0_1 - 0.000116000071357234*G0_0_3 + 4.50553910375416e-05*G0_0_4 + 4.5557121449986e-05*G0_0_5 + 5.41868845440366e-05*G0_0_6 + 5.20796168117683e-05*G0_0_7 - 6.33183780505316e-05*G0_0_8 + 7.02422577422697e-06*G0_0_9 + 1.58323819038131e-05*G0_1_0 - 1.9199550449554e-05*G0_1_1 + 3.02041708291757e-05*G0_1_3 + 5.23806550592355e-05*G0_1_4 - 0.000102453350221225*G0_1_5 + 1.70588340231236e-06*G0_1_6 - 4.31488154702512e-05*G0_1_7 + 4.42526223776296e-05*G0_1_8 - 9.23183958898394e-06*G0_1_9 + 3.81649600399665e-05*G0_2_2 - 7.27509098044935e-05*G0_2_3 + 0.000119411838161858*G0_2_4 - 3.27128228913999e-05*G0_2_5 + 0.000115197302697322*G0_2_6 - 2.20761381475711e-06*G0_2_7 - 3.4719744541179e-05*G0_2_8 + 1.48512202083654e-05*G0_2_9 - 0.000116000071357234*G0_3_0 + 3.02041708291757e-05*G0_3_1 - 7.27509098044935e-05*G0_3_2 - 0.00100606982303428*G0_3_3 - 6.32180319680429e-05*G0_3_4 + 0.00033084103396609*G0_3_5 - 1.14394534037413e-05*G0_3_6 + 0.000341678410874897*G0_3_7 - 0.00043951584130163*G0_3_8 - 0.000655661302982842*G0_3_9 + 4.50553910375416e-05*G0_4_0 + 5.23806550592355e-05*G0_4_1 + 0.000119411838161858*G0_4_2 - 6.32180319680429e-05*G0_4_3 + 0.000253775242614572*G0_4_4 - 0.000141487976309429*G0_4_5 + 0.00015292742971317*G0_4_6 - 6.11107642357747e-05*G0_4_7 + 9.78374304267328e-05*G0_4_8 + 0.000238422291993762*G0_4_9 + 4.5557121449986e-05*G0_5_0 - 0.000102453350221225*G0_5_1 - 3.27128228913999e-05*G0_5_2 + 0.00033084103396609*G0_5_3 - 0.000141487976309429*G0_5_4 - 0.000867893267446984*G0_5_5 - 0.000160754424147308*G0_5_6 - 0.000301339285714336*G0_5_7 + 0.000301038247466869*G0_5_8 - 0.00062314917225642*G0_5_9 + 5.41868845440366e-05*G0_6_0 + 1.70588340231235e-06*G0_6_1 + 0.000115197302697322*G0_6_2 - 1.14394534037413e-05*G0_6_3 + 0.00015292742971317*G0_6_4 - 0.000160754424147308*G0_6_5 - 0.000201394587555335*G0_6_6 + 3.01038247466991e-07*G0_6_7 + 5.26816933067021e-05*G0_6_8 - 2.16747538176135e-05*G0_6_9 + 5.20796168117683e-05*G0_7_0 - 4.31488154702512e-05*G0_7_1 - 2.2076138147571e-06*G0_7_2 + 0.000341678410874897*G0_7_3 - 6.11107642357747e-05*G0_7_4 - 0.000301339285714336*G0_7_5 + 3.01038247466991e-07*G0_7_6 - 0.00020681327600974*G0_7_7 + 0.000223972456115351*G0_7_8 - 2.16747538176147e-05*G0_7_9 - 6.33183780505316e-05*G0_8_0 + 4.42526223776296e-05*G0_8_1 - 3.4719744541179e-05*G0_8_2 - 0.00043951584130163*G0_8_3 + 9.78374304267328e-05*G0_8_4 + 0.000301038247466869*G0_8_5 + 5.26816933067021e-05*G0_8_6 + 0.000223972456115351*G0_8_7 - 0.000361245896960244*G0_8_8 - 0.000167979342086514*G0_8_9 + 7.02422577422697e-06*G0_9_0 - 9.23183958898396e-06*G0_9_1 + 1.48512202083654e-05*G0_9_2 - 0.000655661302982842*G0_9_3 + 0.000238422291993762*G0_9_4 - 0.000623149172256419*G0_9_5 - 2.16747538176134e-05*G0_9_6 - 2.16747538176148e-05*G0_9_7 - 0.000167979342086514*G0_9_8 - 0.00204826423576458*G0_9_9; + A[27] = A[72]; + A[61] = A[16]; + A[74] = A[82] - 9.59977522477682e-06*G0_0_0 + 1.58323819038131e-05*G0_0_2 + 4.50553910375416e-05*G0_0_3 - 0.000116000071357234*G0_0_4 + 5.20796168117685e-05*G0_0_5 - 6.33183780505317e-05*G0_0_6 + 4.55571214499864e-05*G0_0_7 + 5.41868845440365e-05*G0_0_8 + 7.02422577422681e-06*G0_0_9 + 3.81649600399666e-05*G0_1_1 + 0.000119411838161859*G0_1_3 - 7.27509098044937e-05*G0_1_4 - 2.20761381475701e-06*G0_1_5 - 3.47197445411791e-05*G0_1_6 - 3.27128228913998e-05*G0_1_7 + 0.000115197302697322*G0_1_8 + 1.48512202083655e-05*G0_1_9 + 1.58323819038131e-05*G0_2_0 - 1.91995504495541e-05*G0_2_2 + 5.23806550592355e-05*G0_2_3 + 3.02041708291757e-05*G0_2_4 - 4.31488154702512e-05*G0_2_5 + 4.42526223776296e-05*G0_2_6 - 0.000102453350221225*G0_2_7 + 1.70588340231222e-06*G0_2_8 - 9.23183958898402e-06*G0_2_9 + 4.50553910375416e-05*G0_3_0 + 0.000119411838161859*G0_3_1 + 5.23806550592355e-05*G0_3_2 + 0.000253775242614571*G0_3_3 - 6.32180319680422e-05*G0_3_4 - 6.11107642357748e-05*G0_3_5 + 9.78374304267331e-05*G0_3_6 - 0.000141487976309429*G0_3_7 + 0.00015292742971317*G0_3_8 + 0.000238422291993761*G0_3_9 - 0.000116000071357234*G0_4_0 - 7.27509098044937e-05*G0_4_1 + 3.02041708291757e-05*G0_4_2 - 6.32180319680422e-05*G0_4_3 - 0.00100606982303428*G0_4_4 + 0.000341678410874898*G0_4_5 - 0.000439515841301631*G0_4_6 + 0.00033084103396609*G0_4_7 - 1.14394534037411e-05*G0_4_8 - 0.000655661302982843*G0_4_9 + 5.20796168117685e-05*G0_5_0 - 2.20761381475701e-06*G0_5_1 - 4.31488154702512e-05*G0_5_2 - 6.11107642357748e-05*G0_5_3 + 0.000341678410874898*G0_5_4 - 0.00020681327600974*G0_5_5 + 0.000223972456115352*G0_5_6 - 0.000301339285714337*G0_5_7 + 3.01038247466944e-07*G0_5_8 - 2.16747538176142e-05*G0_5_9 - 6.33183780505317e-05*G0_6_0 - 3.47197445411791e-05*G0_6_1 + 4.42526223776296e-05*G0_6_2 + 9.7837430426733e-05*G0_6_3 - 0.000439515841301631*G0_6_4 + 0.000223972456115352*G0_6_5 - 0.000361245896960245*G0_6_6 + 0.00030103824746687*G0_6_7 + 5.26816933067022e-05*G0_6_8 - 0.000167979342086514*G0_6_9 + 4.55571214499864e-05*G0_7_0 - 3.27128228913998e-05*G0_7_1 - 0.000102453350221225*G0_7_2 - 0.000141487976309429*G0_7_3 + 0.00033084103396609*G0_7_4 - 0.000301339285714337*G0_7_5 + 0.00030103824746687*G0_7_6 - 0.000867893267446984*G0_7_7 - 0.000160754424147309*G0_7_8 - 0.00062314917225642*G0_7_9 + 5.41868845440365e-05*G0_8_0 + 0.000115197302697322*G0_8_1 + 1.70588340231222e-06*G0_8_2 + 0.00015292742971317*G0_8_3 - 1.14394534037411e-05*G0_8_4 + 3.0103824746695e-07*G0_8_5 + 5.26816933067022e-05*G0_8_6 - 0.000160754424147309*G0_8_7 - 0.000201394587555336*G0_8_8 - 2.16747538176149e-05*G0_8_9 + 7.0242257742268e-06*G0_9_0 + 1.48512202083656e-05*G0_9_1 - 9.23183958898402e-06*G0_9_2 + 0.000238422291993761*G0_9_3 - 0.000655661302982843*G0_9_4 - 2.1674753817614e-05*G0_9_5 - 0.000167979342086514*G0_9_6 - 0.00062314917225642*G0_9_7 - 2.16747538176148e-05*G0_9_8 - 0.00204826423576458*G0_9_9; + A[2] = 7.40145271395397e-05*G0_0_0 + 6.73185941043197e-06*G0_0_1 + 1.63180073894387e-05*G0_0_2 - 1.28219994291447e-06*G0_0_3 - 1.21530255458847e-06*G0_0_4 + 7.04763986014106e-05*G0_0_5 - 2.50530719280762e-05*G0_0_6 + 4.89354395604477e-05*G0_0_7 - 1.77947052947082e-05*G0_0_8 + 1.82629870129901e-05*G0_0_9 + 6.73185941043197e-06*G0_1_0 + 6.73185941043198e-06*G0_1_1 + 6.73185941043197e-06*G0_1_2 + 4.47097545311908e-06*G0_1_3 + 4.47097545311906e-06*G0_1_4 + 4.47097545311905e-06*G0_1_5 + 4.47097545311907e-06*G0_1_6 + 4.47097545311904e-06*G0_1_7 + 4.47097545311907e-06*G0_1_8 + 7.09112316255293e-06*G0_1_9 + 1.63180073894387e-05*G0_2_0 + 6.73185941043197e-06*G0_2_1 + 7.40145271395396e-05*G0_2_2 - 1.77947052947083e-05*G0_2_3 + 4.89354395604478e-05*G0_2_4 - 2.50530719280762e-05*G0_2_5 + 7.04763986014105e-05*G0_2_6 - 1.2153025545885e-06*G0_2_7 - 1.28219994291443e-06*G0_2_8 + 1.82629870129901e-05*G0_2_9 - 1.28219994291447e-06*G0_3_0 + 4.47097545311908e-06*G0_3_1 - 1.77947052947083e-05*G0_3_2 + 5.50899992864372e-05*G0_3_3 - 5.82007278435948e-05*G0_3_4 + 6.12111103182635e-06*G0_3_5 - 3.52214749536238e-05*G0_3_6 - 1.79619487655232e-05*G0_3_7 + 3.59238975310464e-05*G0_3_8 + 1.46505280433877e-05*G0_3_9 - 1.21530255458848e-06*G0_4_0 + 4.47097545311906e-06*G0_4_1 + 4.89354395604478e-05*G0_4_2 - 5.82007278435948e-05*G0_4_3 + 5.7598651348661e-05*G0_4_4 - 1.81626409305012e-05*G0_4_5 + 5.33841158841249e-05*G0_4_6 + 1.45501819608987e-05*G0_4_7 - 1.79619487655232e-05*G0_4_8 - 1.8463679177968e-05*G0_4_9 + 7.04763986014106e-05*G0_5_0 + 4.47097545311905e-06*G0_5_1 - 2.50530719280762e-05*G0_5_2 + 6.12111103182635e-06*G0_5_3 - 1.81626409305012e-05*G0_5_4 + 0.000172795954045983*G0_5_5 - 9.63322391893984e-05*G0_5_6 + 5.33841158841248e-05*G0_5_7 - 3.52214749536237e-05*G0_5_8 + 1.56539888682772e-05*G0_5_9 - 2.50530719280762e-05*G0_6_0 + 4.47097545311907e-06*G0_6_1 + 7.04763986014105e-05*G0_6_2 - 3.52214749536238e-05*G0_6_3 + 5.33841158841249e-05*G0_6_4 - 9.63322391893984e-05*G0_6_5 + 0.000172795954045983*G0_6_6 - 1.81626409305011e-05*G0_6_7 + 6.12111103182635e-06*G0_6_8 + 1.56539888682772e-05*G0_6_9 + 4.89354395604477e-05*G0_7_0 + 4.47097545311904e-06*G0_7_1 - 1.2153025545885e-06*G0_7_2 - 1.79619487655232e-05*G0_7_3 + 1.45501819608987e-05*G0_7_4 + 5.33841158841248e-05*G0_7_5 - 1.81626409305011e-05*G0_7_6 + 5.75986513486609e-05*G0_7_7 - 5.82007278435947e-05*G0_7_8 - 1.8463679177968e-05*G0_7_9 - 1.77947052947082e-05*G0_8_0 + 4.47097545311908e-06*G0_8_1 - 1.28219994291443e-06*G0_8_2 + 3.59238975310464e-05*G0_8_3 - 1.79619487655232e-05*G0_8_4 - 3.52214749536237e-05*G0_8_5 + 6.12111103182635e-06*G0_8_6 - 5.82007278435947e-05*G0_8_7 + 5.50899992864371e-05*G0_8_8 + 1.46505280433877e-05*G0_8_9 + 1.82629870129901e-05*G0_9_0 + 7.09112316255293e-06*G0_9_1 + 1.82629870129901e-05*G0_9_2 + 1.46505280433877e-05*G0_9_3 - 1.8463679177968e-05*G0_9_4 + 1.56539888682772e-05*G0_9_5 + 1.56539888682772e-05*G0_9_6 - 1.8463679177968e-05*G0_9_7 + 1.46505280433877e-05*G0_9_8 - 7.94740973312536e-05*G0_9_9; + A[25] = A[2] - 3.53812853812913e-06*G0_0_0 - 4.13710793175149e-05*G0_0_2 - 1.69473383759127e-05*G0_0_4 + 0.000102319555444573*G0_0_5 - 7.12791672613222e-05*G0_0_6 + 4.44867632367708e-06*G0_0_7 - 1.74267696589154e-05*G0_0_8 - 2.60899814471285e-06*G0_0_9 - 2.45265647051403e-05*G0_1_2 - 3.96924504067428e-05*G0_1_4 + 5.06190238333181e-05*G0_1_5 - 6.26717032967139e-05*G0_1_6 + 3.14529220779274e-05*G0_1_7 - 2.24329242186423e-05*G0_1_8 + 7.55940488083473e-06*G0_1_9 - 4.13710793175149e-05*G0_2_0 - 2.45265647051403e-05*G0_2_1 - 0.00039478750416257*G0_2_2 + 0.000104895104895123*G0_2_3 - 0.00026317432567437*G0_2_4 + 0.00025263798701303*G0_2_5 - 0.000432224025974099*G0_2_6 + 5.81115313258269e-05*G0_2_7 - 1.27662516055395e-05*G0_2_8 - 4.49550449550527e-05*G0_2_9 + 0.000104895104895123*G0_3_2 - 0.000146003550021432*G0_3_3 + 0.000230996681889578*G0_3_4 - 9.70346617668211e-05*G0_3_5 + 0.000208017428999607*G0_3_6 - 2.20761381475709e-06*G0_3_7 - 5.60934601113267e-05*G0_3_8 - 1.82629870129902e-05*G0_3_9 - 1.69473383759127e-05*G0_4_0 - 3.96924504067428e-05*G0_4_1 - 0.00026317432567437*G0_4_2 + 0.000230996681889578*G0_4_3 - 0.000295719905094955*G0_4_4 + 7.08443342372034e-05*G0_4_5 - 0.00027886176323681*G0_4_6 - 7.17474489796039e-05*G0_4_7 + 5.83010739260837e-05*G0_4_8 - 6.82353360924885e-06*G0_4_9 + 0.000102319555444573*G0_5_0 + 5.06190238333181e-05*G0_5_1 + 0.00025263798701303*G0_5_2 - 9.70346617668211e-05*G0_5_3 + 7.08443342372034e-05*G0_5_4 + 0.000372685350363984*G0_5_5 - 1.11384151562737e-05*G0_5_6 + 0.000286187027258504*G0_5_7 - 0.000131854752390489*G0_5_8 + 0.000271536499215116*G0_5_9 - 7.12791672613222e-05*G0_6_0 - 6.26717032967139e-05*G0_6_1 - 0.000432224025974099*G0_6_2 + 0.000208017428999607*G0_6_3 - 0.00027886176323681*G0_6_4 - 1.11384151562737e-05*G0_6_5 - 0.000811298076923214*G0_6_6 - 0.000154332274868015*G0_6_7 + 0.000103155772798647*G0_6_8 - 0.000281169723134056*G0_6_9 + 4.44867632367708e-06*G0_7_0 + 3.14529220779274e-05*G0_7_1 + 5.81115313258269e-05*G0_7_2 - 2.2076138147571e-06*G0_7_3 - 7.17474489796039e-05*G0_7_4 + 0.000286187027258504*G0_7_5 - 0.000154332274868015*G0_7_6 + 0.000315086699015323*G0_7_7 - 6.31176858855536e-05*G0_7_8 + 0.000316491544170169*G0_7_9 - 1.74267696589154e-05*G0_8_0 - 2.24329242186423e-05*G0_8_1 - 1.27662516055395e-05*G0_8_2 - 5.60934601113267e-05*G0_8_3 + 5.83010739260837e-05*G0_8_4 - 0.000131854752390489*G0_8_5 + 0.000103155772798647*G0_8_6 - 6.31176858855536e-05*G0_8_7 - 1.47508741258768e-05*G0_8_8 - 0.000139280362494672*G0_8_9 - 2.60899814471284e-06*G0_9_0 + 7.55940488083473e-06*G0_9_1 - 4.49550449550526e-05*G0_9_2 - 1.82629870129902e-05*G0_9_3 - 6.82353360924884e-06*G0_9_4 + 0.000271536499215116*G0_9_5 - 0.000281169723134056*G0_9_6 + 0.000316491544170169*G0_9_7 - 0.000139280362494672*G0_9_8 + 0.000567156058227583*G0_9_9; + A[90] = A[2] + 2.43246336996379e-05*G0_0_0 + 1.15311276025581e-05*G0_0_1 + 1.94497962355136e-06*G0_0_2 + 3.2188793349513e-05*G0_0_3 + 3.21218959611871e-05*G0_0_4 + 6.29838911089015e-05*G0_0_5 - 1.63898601398623e-06*G0_0_6 + 8.45248501498644e-05*G0_0_7 - 8.89735264735412e-06*G0_0_8 + 0.000302041708291759*G0_0_9 + 1.15311276025581e-05*G0_1_0 + 1.15311276025581e-05*G0_1_1 - 2.29346546310871e-05*G0_1_3 + 1.01795525902686e-05*G0_1_4 - 2.29346546310871e-05*G0_1_5 + 1.01795525902686e-05*G0_1_6 + 1.11830134151582e-05*G0_1_7 + 1.11830134151582e-05*G0_1_8 - 8.65652204938065e-05*G0_1_9 + 1.94497962355136e-06*G0_2_0 - 5.57515401265495e-05*G0_2_2 + 3.24452333380959e-05*G0_2_3 - 6.73991187384158e-05*G0_2_4 + 4.07070607963534e-05*G0_2_5 - 5.48224097331333e-05*G0_2_6 - 1.72483766233795e-05*G0_2_7 + 1.59327279863021e-05*G0_2_8 - 9.77370843442438e-05*G0_2_9 + 3.2188793349513e-05*G0_3_0 - 2.29346546310871e-05*G0_3_1 + 3.2445233338096e-05*G0_3_2 + 0.000503034911517139*G0_3_3 - 0.000147709433423744*G0_3_4 + 1.55536427857883e-05*G0_3_5 - 8.94083594976604e-05*G0_3_6 - 0.000155436081775394*G0_3_7 + 0.000262103967461154*G0_3_8 + 0.000570567825032207*G0_3_9 + 3.21218959611871e-05*G0_4_0 + 1.01795525902686e-05*G0_4_1 - 6.73991187384158e-05*G0_4_2 - 0.000147709433423744*G0_4_3 + 0.000500526259454915*G0_4_4 - 0.000155235389610416*G0_4_5 + 0.000244643749108076*G0_4_6 + 7.12457185671575e-06*G0_4_7 - 0.000106667885685761*G0_4_8 + 0.000603682032253563*G0_4_9 + 6.29838911089015e-05*G0_5_0 - 2.29346546310871e-05*G0_5_1 + 4.07070607963534e-05*G0_5_2 + 1.55536427857883e-05*G0_5_3 - 0.000155235389610416*G0_5_4 - 9.69343156843318e-05*G0_5_5 - 0.000169183495076381*G0_5_6 - 2.80969030969055e-06*G0_5_7 + 9.93426216640656e-06*G0_5_8 - 0.000925993649208091*G0_5_9 - 1.63898601398621e-06*G0_6_0 + 1.01795525902686e-05*G0_6_1 - 5.48224097331333e-05*G0_6_2 - 8.94083594976604e-05*G0_6_3 + 0.000244643749108076*G0_6_4 - 0.000169183495076381*G0_6_5 + 0.000114394534037411*G0_6_6 - 7.12457185671601e-06*G0_6_7 + 0.000472027972028052*G0_6_9 + 8.45248501498643e-05*G0_7_0 + 1.11830134151582e-05*G0_7_1 - 1.72483766233795e-05*G0_7_2 - 0.000155436081775394*G0_7_3 + 7.12457185671576e-06*G0_7_4 - 2.80969030969055e-06*G0_7_5 - 7.12457185671597e-06*G0_7_6 + 1.82629870129906e-05*G0_7_7 - 0.000207315006422184*G0_7_8 - 0.000891875981161846*G0_7_9 - 8.89735264735412e-06*G0_8_0 + 1.11830134151582e-05*G0_8_1 + 1.59327279863021e-05*G0_8_2 + 0.000262103967461154*G0_8_3 - 0.000106667885685761*G0_8_4 + 9.93426216640658e-06*G0_8_5 - 0.000207315006422184*G0_8_7 + 0.000232100488796957*G0_8_8 + 0.000473031432852941*G0_8_9 + 0.000302041708291759*G0_9_0 - 8.65652204938065e-05*G0_9_1 - 9.77370843442438e-05*G0_9_2 + 0.000570567825032207*G0_9_3 + 0.000603682032253563*G0_9_4 - 0.000925993649208091*G0_9_5 + 0.000472027972028052*G0_9_6 - 0.000891875981161846*G0_9_7 + 0.000473031432852941*G0_9_8 + 0.00046961966604832*G0_9_9; + A[11] = A[2] - 5.76965197501009e-05*G0_0_0 + 6.7282667729108e-05*G0_0_1 - 9.58614797900673e-06*G0_0_2 + 5.02176395033624e-05*G0_0_3 - 1.65794027401199e-05*G0_0_4 - 7.16917011559991e-05*G0_0_5 + 2.37708719851618e-05*G0_0_6 - 7.3988511488524e-05*G0_0_7 + 8.8271103896119e-05*G0_0_8 + 6.7282667729108e-05*G0_1_0 + 0.00153963843696013*G0_1_1 + 6.72826677291077e-05*G0_1_2 + 0.000686244559012533*G0_1_3 - 0.000325243952476151*G0_1_4 - 0.000325243952476151*G0_1_7 + 0.000686244559012534*G0_1_8 + 9.12480376766248e-05*G0_1_9 - 9.58614797900673e-06*G0_2_0 + 6.72826677291077e-05*G0_2_1 - 5.76965197501008e-05*G0_2_2 + 8.82711038961188e-05*G0_2_3 - 7.39885114885239e-05*G0_2_4 + 2.37708719851617e-05*G0_2_5 - 7.1691701155999e-05*G0_2_6 - 1.65794027401198e-05*G0_2_7 + 5.02176395033623e-05*G0_2_8 + 5.02176395033624e-05*G0_3_0 + 0.000686244559012533*G0_3_1 + 8.82711038961188e-05*G0_3_2 + 0.000801865545169253*G0_3_3 - 0.000303546899529094*G0_3_4 - 3.35155915513117e-05*G0_3_5 - 7.62630226916073e-06*G0_3_6 - 0.0001962769373484*G0_3_7 + 0.000392553874696799*G0_3_8 + 0.000118809761666925*G0_3_9 - 1.65794027401199e-05*G0_4_0 - 0.00032524395247615*G0_4_1 - 7.39885114885239e-05*G0_4_2 - 0.000303546899529094*G0_4_3 + 0.000169986263736293*G0_4_4 + 4.11418938204734e-06*G0_4_5 + 3.51211288711351e-06*G0_4_6 + 7.25502176395158e-05*G0_4_7 - 0.000196276937348399*G0_4_8 - 8.22837876409452e-06*G0_4_9 - 7.16917011559991e-05*G0_5_0 + 2.37708719851617e-05*G0_5_2 - 3.35155915513117e-05*G0_5_3 + 4.11418938204734e-06*G0_5_4 - 9.35225488797077e-05*G0_5_5 + 6.4823569287866e-05*G0_5_6 + 3.5121128871137e-06*G0_5_7 - 7.62630226916117e-06*G0_5_8 + 1.52526045383213e-05*G0_5_9 + 2.37708719851618e-05*G0_6_0 - 7.1691701155999e-05*G0_6_2 - 7.62630226916073e-06*G0_6_3 + 3.5121128871135e-06*G0_6_4 + 6.4823569287866e-05*G0_6_5 - 9.35225488797076e-05*G0_6_6 + 4.11418938204719e-06*G0_6_7 - 3.35155915513114e-05*G0_6_8 + 1.52526045383214e-05*G0_6_9 - 7.3988511488524e-05*G0_7_0 - 0.000325243952476151*G0_7_1 - 1.65794027401198e-05*G0_7_2 - 0.0001962769373484*G0_7_3 + 7.25502176395158e-05*G0_7_4 + 3.5121128871137e-06*G0_7_5 + 4.1141893820472e-06*G0_7_6 + 0.000169986263736293*G0_7_7 - 0.000303546899529094*G0_7_8 - 8.22837876409462e-06*G0_7_9 + 8.8271103896119e-05*G0_8_0 + 0.000686244559012534*G0_8_1 + 5.02176395033623e-05*G0_8_2 + 0.000392553874696799*G0_8_3 - 0.000196276937348399*G0_8_4 - 7.62630226916116e-06*G0_8_5 - 3.35155915513114e-05*G0_8_6 - 0.000303546899529094*G0_8_7 + 0.000801865545169253*G0_8_8 + 0.000118809761666925*G0_8_9 + 9.12480376766248e-05*G0_9_1 + 0.000118809761666925*G0_9_3 - 8.22837876409452e-06*G0_9_4 + 1.52526045383213e-05*G0_9_5 + 1.52526045383214e-05*G0_9_6 - 8.22837876409462e-06*G0_9_7 + 0.000118809761666925*G0_9_8 + 0.000399778792636003*G0_9_9; + A[32] = A[25] - 7.1758598544325e-05*G0_0_0 + 7.25836663336786e-06*G0_0_2 + 4.89688882546108e-05*G0_0_3 - 4.00380869130937e-05*G0_0_4 - 0.000166674843014157*G0_0_5 + 6.11107642357746e-05*G0_0_6 - 7.1346064649648e-05*G0_0_7 + 7.11453724846701e-05*G0_0_8 - 1.00346082488956e-06*G0_0_9 + 7.17585985443251e-05*G0_1_1 - 7.25836663336782e-06*G0_1_2 + 0.000166674843014157*G0_1_3 - 6.11107642357746e-05*G0_1_4 - 4.89688882546108e-05*G0_1_5 + 4.00380869130937e-05*G0_1_6 - 7.11453724846702e-05*G0_1_7 + 7.13460646496481e-05*G0_1_8 + 1.0034608248896e-06*G0_1_9 + 7.25836663336786e-06*G0_2_0 - 7.25836663336783e-06*G0_2_1 + 0.000140484515484539*G0_2_3 - 0.000147508741258766*G0_2_4 - 0.000140484515484539*G0_2_5 + 0.000147508741258766*G0_2_6 - 7.09446803196923e-05*G0_2_7 + 7.09446803196923e-05*G0_2_8 + 4.89688882546108e-05*G0_3_0 + 0.000166674843014157*G0_3_1 + 0.000140484515484539*G0_3_2 + 0.000636394855144963*G0_3_3 - 0.000280266608391656*G0_3_4 - 0.000120114260739281*G0_3_6 - 0.000146906664763832*G0_3_7 + 0.000359740705722909*G0_3_8 + 0.000290802947052996*G0_3_9 - 4.00380869130937e-05*G0_4_0 - 6.11107642357746e-05*G0_4_1 - 0.000147508741258766*G0_4_2 - 0.000280266608391656*G0_4_3 - 0.000400380869130937*G0_4_4 + 0.000120114260739281*G0_4_5 + 0.000166474150849179*G0_4_7 - 0.000212834040959077*G0_4_8 - 0.000240228521478562*G0_4_9 - 0.000166674843014157*G0_5_0 - 4.89688882546108e-05*G0_5_1 - 0.000140484515484539*G0_5_2 + 0.000120114260739281*G0_5_4 - 0.000636394855144962*G0_5_5 + 0.000280266608391655*G0_5_6 - 0.000359740705722909*G0_5_7 + 0.000146906664763832*G0_5_8 - 0.000290802947052996*G0_5_9 + 6.11107642357746e-05*G0_6_0 + 4.00380869130937e-05*G0_6_1 + 0.000147508741258766*G0_6_2 - 0.000120114260739281*G0_6_3 + 0.000280266608391655*G0_6_5 + 0.000400380869130937*G0_6_6 + 0.000212834040959077*G0_6_7 - 0.000166474150849179*G0_6_8 + 0.000240228521478562*G0_6_9 - 7.1346064649648e-05*G0_7_0 - 7.11453724846702e-05*G0_7_1 - 7.09446803196923e-05*G0_7_2 - 0.000146906664763832*G0_7_3 + 0.000166474150849179*G0_7_4 - 0.000359740705722909*G0_7_5 + 0.000212834040959077*G0_7_6 - 0.000332346225203424*G0_7_7 - 0.000422657699443485*G0_7_9 + 7.11453724846701e-05*G0_8_0 + 7.13460646496482e-05*G0_8_1 + 7.09446803196923e-05*G0_8_2 + 0.000359740705722909*G0_8_3 - 0.000212834040959077*G0_8_4 + 0.000146906664763832*G0_8_5 - 0.000166474150849179*G0_8_6 + 0.000332346225203424*G0_8_8 + 0.000422657699443485*G0_8_9 - 1.00346082488957e-06*G0_9_0 + 1.0034608248896e-06*G0_9_1 + 0.000290802947052996*G0_9_3 - 0.000240228521478562*G0_9_4 - 0.000290802947052996*G0_9_5 + 0.000240228521478562*G0_9_6 - 0.000422657699443485*G0_9_7 + 0.000422657699443485*G0_9_8; + A[1] = A[2] + 9.58614797900677e-06*G0_0_1 - 9.58614797900675e-06*G0_0_2 - 2.15409590409628e-05*G0_0_5 + 7.25836663336791e-06*G0_0_6 + 2.15409590409627e-05*G0_0_7 - 7.25836663336784e-06*G0_0_8 + 9.58614797900677e-06*G0_1_0 + 6.7282667729108e-05*G0_1_1 + 4.44644641073289e-05*G0_1_3 - 2.22656807478274e-05*G0_1_4 - 2.95240473811953e-05*G0_1_7 + 6.60054231482916e-05*G0_1_8 + 1.11718638504372e-05*G0_1_9 - 9.58614797900675e-06*G0_2_0 - 6.72826677291076e-05*G0_2_2 + 2.22656807478274e-05*G0_2_3 - 4.44644641073287e-05*G0_2_4 + 2.95240473811952e-05*G0_2_5 - 6.60054231482915e-05*G0_2_6 - 1.11718638504372e-05*G0_2_9 + 4.44644641073289e-05*G0_3_1 + 2.22656807478274e-05*G0_3_2 + 2.50865206222411e-06*G0_3_3 + 8.42907092907233e-06*G0_3_5 + 1.72595261881005e-05*G0_3_6 - 2.00692164978004e-07*G0_3_7 + 1.74602183530786e-05*G0_3_8 - 3.31142072213556e-05*G0_3_9 - 2.22656807478274e-05*G0_4_1 - 4.44644641073287e-05*G0_4_2 - 2.50865206222386e-06*G0_4_4 + 2.00692164977923e-07*G0_4_5 - 1.74602183530784e-05*G0_4_6 - 8.42907092907232e-06*G0_4_7 - 1.72595261881005e-05*G0_4_8 + 3.31142072213557e-05*G0_4_9 - 2.15409590409628e-05*G0_5_0 + 2.95240473811952e-05*G0_5_2 + 8.42907092907233e-06*G0_5_3 + 2.00692164977926e-07*G0_5_4 - 0.000115197302697322*G0_5_5 + 3.81315113458036e-05*G0_5_6 + 1.70588340231226e-05*G0_5_8 - 3.41176680462452e-05*G0_5_9 + 7.25836663336791e-06*G0_6_0 - 6.60054231482915e-05*G0_6_2 + 1.72595261881005e-05*G0_6_3 - 1.74602183530784e-05*G0_6_4 + 3.81315113458036e-05*G0_6_5 - 0.000117705954759546*G0_6_6 - 1.70588340231226e-05*G0_6_7 - 1.00346082488952e-06*G0_6_9 + 2.15409590409627e-05*G0_7_0 - 2.95240473811953e-05*G0_7_1 - 2.00692164978004e-07*G0_7_3 - 8.42907092907233e-06*G0_7_4 - 1.70588340231226e-05*G0_7_6 + 0.000115197302697322*G0_7_7 - 3.81315113458036e-05*G0_7_8 + 3.41176680462452e-05*G0_7_9 - 7.25836663336784e-06*G0_8_0 + 6.60054231482917e-05*G0_8_1 + 1.74602183530785e-05*G0_8_3 - 1.72595261881005e-05*G0_8_4 + 1.70588340231226e-05*G0_8_5 - 3.81315113458036e-05*G0_8_7 + 0.000117705954759546*G0_8_8 + 1.00346082488956e-06*G0_8_9 + 1.11718638504372e-05*G0_9_1 - 1.11718638504372e-05*G0_9_2 - 3.31142072213556e-05*G0_9_3 + 3.31142072213557e-05*G0_9_4 - 3.41176680462452e-05*G0_9_5 - 1.00346082488953e-06*G0_9_6 + 3.41176680462452e-05*G0_9_7 + 1.00346082488956e-06*G0_9_8; + A[31] = -A[1] + 7.27992245849513e-05*G0_0_0 + 6.52534469498867e-05*G0_0_1 + 5.63833487940728e-05*G0_0_3 - 5.94829277865093e-05*G0_0_4 + 6.34856215213464e-05*G0_0_5 - 3.57566540602315e-05*G0_0_6 + 5.23137576709092e-05*G0_0_7 + 2.83310439560489e-05*G0_0_8 - 2.00692164977882e-07*G0_0_9 + 6.52534469498867e-05*G0_1_0 + 0.000764730061605192*G0_1_1 + 7.72082580118425e-05*G0_1_2 + 0.000905890984016138*G0_1_3 - 0.000379542332667397*G0_1_4 - 2.86097830740739e-05*G0_1_5 - 4.41299771656989e-05*G0_1_6 - 0.000239291958041999*G0_1_7 + 0.000498954170829256*G0_1_8 + 0.000151723276723303*G0_1_9 + 7.72082580118425e-05*G0_2_1 - 1.83212125176442e-05*G0_2_2 + 0.000177266929499103*G0_2_3 - 9.18612637362794e-05*G0_2_4 - 1.36916654773821e-05*G0_2_6 - 3.07504995005047e-05*G0_2_7 + 5.7855091337244e-05*G0_2_8 + 2.27451120308302e-05*G0_2_9 + 5.63833487940728e-05*G0_3_0 + 0.000905890984016138*G0_3_1 + 0.000177266929499103*G0_3_2 + 0.0014483953546456*G0_3_3 - 0.000696702850720826*G0_3_4 + 1.9065755672899e-06*G0_3_5 + 4.52560832025193e-05*G0_3_6 - 0.000256283894676796*G0_3_7 + 0.000516983016983105*G0_3_8 + 5.73979591836841e-05*G0_3_9 - 5.94829277865093e-05*G0_4_0 - 0.000379542332667397*G0_4_1 - 9.18612637362794e-05*G0_4_2 - 0.000696702850720826*G0_4_3 - 5.23806550592353e-05*G0_4_4 + 9.13149350649506e-05*G0_4_5 - 0.00013657101826747*G0_4_6 + 0.00017891706507781*G0_4_7 - 0.000260699122306309*G0_4_8 - 0.000250865206222392*G0_4_9 + 6.34856215213464e-05*G0_5_0 - 2.86097830740739e-05*G0_5_1 + 1.9065755672899e-06*G0_5_3 + 9.13149350649507e-05*G0_5_4 - 7.6363368774096e-05*G0_5_5 + 2.27785607249933e-05*G0_5_6 - 3.81315113458039e-06*G0_5_7 - 1.30449907235657e-06*G0_5_8 + 3.21107463964666e-06*G0_5_9 - 3.57566540602315e-05*G0_6_0 - 4.41299771656989e-05*G0_6_1 - 1.36916654773821e-05*G0_6_2 + 4.52560832025193e-05*G0_6_3 - 0.00013657101826747*G0_6_4 + 2.27785607249933e-05*G0_6_5 - 0.000196276937348399*G0_6_6 + 5.11765020693689e-06*G0_6_7 + 2.2979252889971e-05*G0_6_8 - 0.000158747502497529*G0_6_9 + 5.23137576709092e-05*G0_7_0 - 0.000239291958041999*G0_7_1 - 3.07504995005047e-05*G0_7_2 - 0.000256283894676796*G0_7_3 + 0.00017891706507781*G0_7_4 - 3.8131511345804e-06*G0_7_5 + 5.11765020693689e-06*G0_7_6 + 0.000225477647352685*G0_7_7 - 0.000321809886542084*G0_7_8 - 9.63322391893986e-06*G0_7_9 + 2.83310439560489e-05*G0_8_0 + 0.000498954170829256*G0_8_1 + 5.7855091337244e-05*G0_8_2 + 0.000516983016983105*G0_8_3 - 0.000260699122306309*G0_8_4 - 1.30449907235657e-06*G0_8_5 + 2.2979252889971e-05*G0_8_6 - 0.000321809886542084*G0_8_7 + 0.000636394855144963*G0_8_8 + 6.62284144427113e-05*G0_8_9 - 2.00692164977889e-07*G0_9_0 + 0.000151723276723303*G0_9_1 + 2.27451120308302e-05*G0_9_2 + 5.73979591836841e-05*G0_9_3 - 0.000250865206222392*G0_9_4 + 3.21107463964666e-06*G0_9_5 - 0.000158747502497529*G0_9_6 - 9.63322391893985e-06*G0_9_7 + 6.62284144427113e-05*G0_9_8 - 0.000989813757671067*G0_9_9; + A[99] = -A[11] + 0.000336622702694188*G0_0_0 - 5.45957019171362e-06*G0_0_1 - 7.27422379208217e-05*G0_0_2 + 0.000634153792636042*G0_0_3 + 0.000567423647780886*G0_0_4 - 0.000911554962894402*G0_0_5 + 0.000486399760953415*G0_0_6 - 0.00093539273226789*G0_0_7 + 0.00055815835949774*G0_0_8 + 0.000408408555730056*G0_0_9 - 5.45957019171362e-06*G0_1_0 + 0.00186667499167531*G0_1_1 - 5.459570191714e-06*G0_1_2 - 0.000219624125874161*G0_1_3 + 0.000166908983873298*G0_1_4 + 0.000577023423005662*G0_1_5 + 0.000577023423005663*G0_1_6 + 0.000166908983873296*G0_1_7 - 0.000219624125874161*G0_1_8 + 0.000488484729556239*G0_1_9 - 7.27422379208217e-05*G0_2_0 - 5.45957019171402e-06*G0_2_1 + 0.000336622702694188*G0_2_2 + 0.000558158359497739*G0_2_3 - 0.00093539273226789*G0_2_4 + 0.000486399760953415*G0_2_5 - 0.000911554962894403*G0_2_6 + 0.000567423647780886*G0_2_7 + 0.000634153792636042*G0_2_8 + 0.000408408555730053*G0_2_9 + 0.000634153792636042*G0_3_0 - 0.000219624125874161*G0_3_1 + 0.000558158359497739*G0_3_2 + 0.00709928464392869*G0_3_3 - 0.0028976938240336*G0_3_4 - 0.00149044036320847*G0_3_5 - 0.00238372118952516*G0_3_6 - 0.0025551122984163*G0_3_7 + 0.0051102245968326*G0_3_8 + 0.00364477040816387*G0_3_9 + 0.000567423647780886*G0_4_0 + 0.000166908983873298*G0_4_1 - 0.00093539273226789*G0_4_2 - 0.0028976938240336*G0_4_3 + 0.00646991401455796*G0_4_4 - 0.00235492186385083*G0_4_5 + 0.004738643053376*G0_4_6 - 0.00137594548308857*G0_4_7 - 0.0025551122984163*G0_4_8 + 0.00348461806051151*G0_4_9 - 0.000911554962894403*G0_5_0 + 0.000577023423005662*G0_5_1 + 0.000486399760953415*G0_5_2 - 0.00149044036320847*G0_5_3 - 0.00235492186385083*G0_5_4 + 0.00632160250463928*G0_5_5 - 0.00256745486656245*G0_5_6 + 0.00473864305337599*G0_5_7 - 0.00238372118952516*G0_5_8 + 0.00354221671186015*G0_5_9 + 0.000486399760953415*G0_6_0 + 0.000577023423005663*G0_6_1 - 0.000911554962894403*G0_6_2 - 0.00238372118952516*G0_6_3 + 0.004738643053376*G0_6_4 - 0.00256745486656245*G0_6_5 + 0.00632160250463929*G0_6_6 - 0.00235492186385083*G0_6_7 - 0.00149044036320847*G0_6_8 + 0.00354221671186016*G0_6_9 - 0.00093539273226789*G0_7_0 + 0.000166908983873296*G0_7_1 + 0.000567423647780886*G0_7_2 - 0.0025551122984163*G0_7_3 - 0.00137594548308857*G0_7_4 + 0.00473864305337599*G0_7_5 - 0.00235492186385083*G0_7_6 + 0.00646991401455796*G0_7_7 - 0.0028976938240336*G0_7_8 + 0.00348461806051149*G0_7_9 + 0.00055815835949774*G0_8_0 - 0.000219624125874161*G0_8_1 + 0.000634153792636042*G0_8_2 + 0.0051102245968326*G0_8_3 - 0.0025551122984163*G0_8_4 - 0.00238372118952516*G0_8_5 - 0.00149044036320847*G0_8_6 - 0.0028976938240336*G0_8_7 + 0.0070992846439287*G0_8_8 + 0.00364477040816389*G0_8_9 + 0.000408408555730056*G0_9_0 + 0.000488484729556239*G0_9_1 + 0.000408408555730053*G0_9_2 + 0.00364477040816387*G0_9_3 + 0.00348461806051151*G0_9_4 + 0.00354221671186015*G0_9_5 + 0.00354221671186017*G0_9_6 + 0.00348461806051149*G0_9_7 + 0.00364477040816389*G0_9_8 + 0.0845917475381904*G0_9_9; + A[21] = A[2] - 6.72826677291077e-05*G0_0_0 - 9.58614797900674e-06*G0_0_2 - 6.60054231482915e-05*G0_0_5 + 2.95240473811953e-05*G0_0_6 - 4.44644641073287e-05*G0_0_7 + 2.22656807478273e-05*G0_0_8 - 1.11718638504372e-05*G0_0_9 + 6.72826677291077e-05*G0_1_1 + 9.58614797900675e-06*G0_1_2 + 6.60054231482915e-05*G0_1_3 - 2.95240473811952e-05*G0_1_4 - 2.22656807478274e-05*G0_1_7 + 4.44644641073288e-05*G0_1_8 + 1.11718638504372e-05*G0_1_9 - 9.58614797900674e-06*G0_2_0 + 9.58614797900675e-06*G0_2_1 - 7.25836663336786e-06*G0_2_3 + 2.15409590409628e-05*G0_2_4 + 7.25836663336784e-06*G0_2_5 - 2.15409590409627e-05*G0_2_6 + 6.60054231482915e-05*G0_3_1 - 7.25836663336785e-06*G0_3_2 + 0.000117705954759546*G0_3_3 - 3.81315113458036e-05*G0_3_4 + 1.70588340231226e-05*G0_3_6 - 1.72595261881006e-05*G0_3_7 + 1.74602183530785e-05*G0_3_8 + 1.00346082488959e-06*G0_3_9 - 2.95240473811952e-05*G0_4_1 + 2.15409590409627e-05*G0_4_2 - 3.81315113458036e-05*G0_4_3 + 0.000115197302697322*G0_4_4 - 1.70588340231226e-05*G0_4_5 - 8.42907092907235e-06*G0_4_7 - 2.00692164977902e-07*G0_4_8 + 3.41176680462453e-05*G0_4_9 - 6.60054231482915e-05*G0_5_0 + 7.25836663336784e-06*G0_5_2 - 1.70588340231226e-05*G0_5_4 - 0.000117705954759546*G0_5_5 + 3.81315113458036e-05*G0_5_6 - 1.74602183530784e-05*G0_5_7 + 1.72595261881005e-05*G0_5_8 - 1.00346082488957e-06*G0_5_9 + 2.95240473811953e-05*G0_6_0 - 2.15409590409627e-05*G0_6_2 + 1.70588340231226e-05*G0_6_3 + 3.81315113458036e-05*G0_6_5 - 0.000115197302697322*G0_6_6 + 2.00692164977909e-07*G0_6_7 + 8.42907092907237e-06*G0_6_8 - 3.41176680462452e-05*G0_6_9 - 4.44644641073287e-05*G0_7_0 - 2.22656807478274e-05*G0_7_1 - 1.72595261881006e-05*G0_7_3 - 8.42907092907235e-06*G0_7_4 - 1.74602183530784e-05*G0_7_5 + 2.00692164977916e-07*G0_7_6 - 2.50865206222389e-06*G0_7_7 + 3.31142072213556e-05*G0_7_9 + 2.22656807478273e-05*G0_8_0 + 4.44644641073288e-05*G0_8_1 + 1.74602183530785e-05*G0_8_3 - 2.00692164977899e-07*G0_8_4 + 1.72595261881005e-05*G0_8_5 + 8.42907092907237e-06*G0_8_6 + 2.50865206222383e-06*G0_8_8 - 3.31142072213557e-05*G0_8_9 - 1.11718638504371e-05*G0_9_0 + 1.11718638504372e-05*G0_9_1 + 1.00346082488959e-06*G0_9_3 + 3.41176680462453e-05*G0_9_4 - 1.00346082488957e-06*G0_9_5 - 3.41176680462452e-05*G0_9_6 + 3.31142072213556e-05*G0_9_7 - 3.31142072213557e-05*G0_9_8; + A[26] = -A[21] - 1.83212125176442e-05*G0_0_0 + 7.72082580118425e-05*G0_0_2 - 3.07504995005047e-05*G0_0_3 + 5.7855091337244e-05*G0_0_4 - 9.18612637362793e-05*G0_0_5 + 0.000177266929499102*G0_0_6 - 1.36916654773821e-05*G0_0_7 + 2.27451120308301e-05*G0_0_9 + 7.27992245849512e-05*G0_1_1 + 6.52534469498865e-05*G0_1_2 + 5.23137576709094e-05*G0_1_3 + 2.83310439560487e-05*G0_1_4 - 5.94829277865093e-05*G0_1_5 + 5.63833487940726e-05*G0_1_6 - 3.57566540602316e-05*G0_1_7 + 6.34856215213466e-05*G0_1_8 - 2.00692164977858e-07*G0_1_9 + 7.72082580118425e-05*G0_2_0 + 6.52534469498865e-05*G0_2_1 + 0.00076473006160519*G0_2_2 - 0.000239291958041998*G0_2_3 + 0.000498954170829255*G0_2_4 - 0.000379542332667397*G0_2_5 + 0.000905890984016137*G0_2_6 - 4.41299771656991e-05*G0_2_7 - 2.86097830740735e-05*G0_2_8 + 0.000151723276723302*G0_2_9 - 3.07504995005047e-05*G0_3_0 + 5.23137576709094e-05*G0_3_1 - 0.000239291958041998*G0_3_2 + 0.000225477647352686*G0_3_3 - 0.000321809886542084*G0_3_4 + 0.00017891706507781*G0_3_5 - 0.000256283894676795*G0_3_6 + 5.11765020693681e-06*G0_3_7 - 3.81315113458038e-06*G0_3_8 - 9.63322391893972e-06*G0_3_9 + 5.7855091337244e-05*G0_4_0 + 2.83310439560487e-05*G0_4_1 + 0.000498954170829255*G0_4_2 - 0.000321809886542084*G0_4_3 + 0.000636394855144962*G0_4_4 - 0.000260699122306309*G0_4_5 + 0.000516983016983104*G0_4_6 + 2.29792528899709e-05*G0_4_7 - 1.30449907235629e-06*G0_4_8 + 6.62284144427113e-05*G0_4_9 - 9.18612637362793e-05*G0_5_0 - 5.94829277865093e-05*G0_5_1 - 0.000379542332667397*G0_5_2 + 0.00017891706507781*G0_5_3 - 0.000260699122306309*G0_5_4 - 5.2380655059235e-05*G0_5_5 - 0.000696702850720826*G0_5_6 - 0.00013657101826747*G0_5_7 + 9.13149350649502e-05*G0_5_8 - 0.000250865206222391*G0_5_9 + 0.000177266929499102*G0_6_0 + 5.63833487940726e-05*G0_6_1 + 0.000905890984016137*G0_6_2 - 0.000256283894676795*G0_6_3 + 0.000516983016983104*G0_6_4 - 0.000696702850720826*G0_6_5 + 0.0014483953546456*G0_6_6 + 4.52560832025191e-05*G0_6_7 + 1.90657556729041e-06*G0_6_8 + 5.73979591836833e-05*G0_6_9 - 1.36916654773821e-05*G0_7_0 - 3.57566540602316e-05*G0_7_1 - 4.41299771656991e-05*G0_7_2 + 5.11765020693681e-06*G0_7_3 + 2.29792528899709e-05*G0_7_4 - 0.00013657101826747*G0_7_5 + 4.52560832025191e-05*G0_7_6 - 0.000196276937348399*G0_7_7 + 2.27785607249931e-05*G0_7_8 - 0.000158747502497529*G0_7_9 + 6.34856215213466e-05*G0_8_1 - 2.86097830740735e-05*G0_8_2 - 3.81315113458037e-06*G0_8_3 - 1.30449907235629e-06*G0_8_4 + 9.13149350649502e-05*G0_8_5 + 1.90657556729043e-06*G0_8_6 + 2.27785607249931e-05*G0_8_7 - 7.6363368774096e-05*G0_8_8 + 3.21107463964644e-06*G0_8_9 + 2.27451120308301e-05*G0_9_0 - 2.00692164977865e-07*G0_9_1 + 0.000151723276723302*G0_9_2 - 9.63322391893972e-06*G0_9_3 + 6.62284144427113e-05*G0_9_4 - 0.000250865206222391*G0_9_5 + 5.73979591836833e-05*G0_9_6 - 0.000158747502497529*G0_9_7 + 3.21107463964644e-06*G0_9_8 - 0.000989813757671068*G0_9_9; + A[22] = A[1] - 5.7696519750101e-05*G0_0_0 - 9.58614797900677e-06*G0_0_1 + 6.72826677291076e-05*G0_0_2 - 1.65794027401198e-05*G0_0_3 + 5.02176395033622e-05*G0_0_4 - 7.39885114885239e-05*G0_0_5 + 8.82711038961188e-05*G0_0_6 - 7.16917011559989e-05*G0_0_7 + 2.37708719851617e-05*G0_0_8 - 9.58614797900676e-06*G0_1_0 - 5.76965197501012e-05*G0_1_1 + 6.72826677291076e-05*G0_1_2 - 7.39885114885241e-05*G0_1_3 + 8.82711038961189e-05*G0_1_4 - 1.65794027401198e-05*G0_1_5 + 5.02176395033622e-05*G0_1_6 + 2.37708719851618e-05*G0_1_7 - 7.16917011559992e-05*G0_1_8 + 6.72826677291076e-05*G0_2_0 + 6.72826677291076e-05*G0_2_1 + 0.00153963843696012*G0_2_2 - 0.00032524395247615*G0_2_3 + 0.000686244559012531*G0_2_4 - 0.00032524395247615*G0_2_5 + 0.000686244559012531*G0_2_6 + 9.12480376766244e-05*G0_2_9 - 1.65794027401198e-05*G0_3_0 - 7.39885114885241e-05*G0_3_1 - 0.00032524395247615*G0_3_2 + 0.000169986263736292*G0_3_3 - 0.000303546899529093*G0_3_4 + 7.25502176395156e-05*G0_3_5 - 0.000196276937348399*G0_3_6 + 4.11418938204738e-06*G0_3_7 + 3.51211288711332e-06*G0_3_8 - 8.2283787640945e-06*G0_3_9 + 5.02176395033622e-05*G0_4_0 + 8.82711038961189e-05*G0_4_1 + 0.000686244559012531*G0_4_2 - 0.000303546899529093*G0_4_3 + 0.000801865545169252*G0_4_4 - 0.000196276937348399*G0_4_5 + 0.000392553874696798*G0_4_6 - 3.35155915513117e-05*G0_4_7 - 7.62630226916056e-06*G0_4_8 + 0.000118809761666925*G0_4_9 - 7.39885114885239e-05*G0_5_0 - 1.65794027401198e-05*G0_5_1 - 0.00032524395247615*G0_5_2 + 7.25502176395156e-05*G0_5_3 - 0.000196276937348399*G0_5_4 + 0.000169986263736293*G0_5_5 - 0.000303546899529094*G0_5_6 + 3.51211288711363e-06*G0_5_7 + 4.11418938204717e-06*G0_5_8 - 8.22837876409453e-06*G0_5_9 + 8.82711038961188e-05*G0_6_0 + 5.02176395033622e-05*G0_6_1 + 0.000686244559012531*G0_6_2 - 0.000196276937348399*G0_6_3 + 0.000392553874696798*G0_6_4 - 0.000303546899529094*G0_6_5 + 0.000801865545169252*G0_6_6 - 7.62630226916091e-06*G0_6_7 - 3.35155915513113e-05*G0_6_8 + 0.000118809761666925*G0_6_9 - 7.16917011559989e-05*G0_7_0 + 2.37708719851618e-05*G0_7_1 + 4.11418938204738e-06*G0_7_3 - 3.35155915513117e-05*G0_7_4 + 3.51211288711364e-06*G0_7_5 - 7.62630226916091e-06*G0_7_6 - 9.35225488797075e-05*G0_7_7 + 6.4823569287866e-05*G0_7_8 + 1.52526045383213e-05*G0_7_9 + 2.37708719851617e-05*G0_8_0 - 7.16917011559992e-05*G0_8_1 + 3.51211288711333e-06*G0_8_3 - 7.62630226916056e-06*G0_8_4 + 4.11418938204718e-06*G0_8_5 - 3.35155915513113e-05*G0_8_6 + 6.4823569287866e-05*G0_8_7 - 9.35225488797078e-05*G0_8_8 + 1.52526045383215e-05*G0_8_9 + 9.12480376766244e-05*G0_9_2 - 8.2283787640945e-06*G0_9_3 + 0.000118809761666925*G0_9_4 - 8.22837876409453e-06*G0_9_5 + 0.000118809761666925*G0_9_6 + 1.52526045383213e-05*G0_9_7 + 1.52526045383215e-05*G0_9_8 + 0.000399778792636003*G0_9_9; + A[71] = A[25] - 2.95240473811953e-05*G0_0_1 + 2.95240473811952e-05*G0_0_2 - 2.42837519623276e-05*G0_0_3 + 2.42837519623275e-05*G0_0_4 - 0.000119411838161858*G0_0_5 + 6.11107642357746e-05*G0_0_6 + 0.000119411838161858*G0_0_7 - 6.11107642357746e-05*G0_0_8 - 2.95240473811953e-05*G0_1_0 - 0.000319490777080118*G0_1_1 - 0.000220359997145749*G0_1_3 + 0.000122321874554038*G0_1_4 + 1.80622948480136e-06*G0_1_5 + 4.41522762951409e-05*G0_1_6 + 0.000191661017553907*G0_1_7 - 0.000343785678607166*G0_1_8 - 4.13425859854503e-05*G0_1_9 + 2.95240473811952e-05*G0_2_0 + 0.000319490777080116*G0_2_2 - 0.000122321874554038*G0_2_3 + 0.000220359997145749*G0_2_4 - 0.000191661017553907*G0_2_5 + 0.000343785678607165*G0_2_6 - 1.80622948480136e-06*G0_2_7 - 4.41522762951408e-05*G0_2_8 + 4.13425859854502e-05*G0_2_9 - 2.42837519623276e-05*G0_3_0 - 0.000220359997145749*G0_3_1 - 0.000122321874554038*G0_3_2 - 0.0001472077030113*G0_3_3 + 3.37162837162895e-05*G0_3_5 - 0.000132456828885423*G0_3_6 + 7.28512558869826e-05*G0_3_7 - 0.000205308084772405*G0_3_8 - 2.16747538176145e-05*G0_3_9 + 2.42837519623275e-05*G0_4_0 + 0.000122321874554038*G0_4_1 + 0.000220359997145749*G0_4_2 + 0.000147207703011299*G0_4_4 - 7.28512558869825e-05*G0_4_5 + 0.000205308084772405*G0_4_6 - 3.37162837162894e-05*G0_4_7 + 0.000132456828885423*G0_4_8 + 2.16747538176144e-05*G0_4_9 - 0.000119411838161858*G0_5_0 + 1.80622948480137e-06*G0_5_1 - 0.000191661017553907*G0_5_2 + 3.37162837162895e-05*G0_5_3 - 7.28512558869825e-05*G0_5_4 - 0.000172795954045983*G0_5_5 - 1.38477593834763e-05*G0_5_6 - 5.41868845440333e-06*G0_5_8 + 1.08373769088072e-05*G0_5_9 + 6.11107642357746e-05*G0_6_0 + 4.41522762951409e-05*G0_6_1 + 0.000343785678607165*G0_6_2 - 0.000132456828885423*G0_6_3 + 0.000205308084772405*G0_6_4 - 1.38477593834762e-05*G0_6_5 + 0.000678841248037791*G0_6_6 + 5.41868845440363e-06*G0_6_7 + 0.000140885899814495*G0_6_9 + 0.000119411838161858*G0_7_0 + 0.000191661017553907*G0_7_1 - 1.80622948480136e-06*G0_7_2 + 7.28512558869826e-05*G0_7_3 - 3.37162837162894e-05*G0_7_4 + 5.41868845440363e-06*G0_7_6 + 0.000172795954045982*G0_7_7 + 1.38477593834766e-05*G0_7_8 - 1.08373769088075e-05*G0_7_9 - 6.11107642357746e-05*G0_8_0 - 0.000343785678607166*G0_8_1 - 4.41522762951408e-05*G0_8_2 - 0.000205308084772405*G0_8_3 + 0.000132456828885423*G0_8_4 - 5.41868845440333e-06*G0_8_5 + 1.38477593834766e-05*G0_8_7 - 0.000678841248037792*G0_8_8 - 0.000140885899814495*G0_8_9 - 4.13425859854503e-05*G0_9_1 + 4.13425859854502e-05*G0_9_2 - 2.16747538176145e-05*G0_9_3 + 2.16747538176144e-05*G0_9_4 + 1.0837376908807e-05*G0_9_5 + 0.000140885899814495*G0_9_6 - 1.08373769088075e-05*G0_9_7 - 0.000140885899814495*G0_9_8; + A[41] = A[71] - 7.17585985443248e-05*G0_0_0 + 7.25836663336792e-06*G0_0_1 - 4.00380869130937e-05*G0_0_3 + 4.89688882546108e-05*G0_0_4 - 7.1346064649648e-05*G0_0_5 + 7.11453724846702e-05*G0_0_6 - 0.000166674843014157*G0_0_7 + 6.11107642357746e-05*G0_0_8 - 1.00346082488956e-06*G0_0_9 + 7.25836663336792e-06*G0_1_0 - 7.25836663336783e-06*G0_1_2 - 0.000147508741258766*G0_1_3 + 0.000140484515484539*G0_1_4 - 7.09446803196923e-05*G0_1_5 + 7.09446803196923e-05*G0_1_6 - 0.000140484515484539*G0_1_7 + 0.000147508741258766*G0_1_8 - 7.25836663336784e-06*G0_2_1 + 7.1758598544325e-05*G0_2_2 - 6.11107642357746e-05*G0_2_3 + 0.000166674843014157*G0_2_4 - 7.11453724846702e-05*G0_2_5 + 7.13460646496481e-05*G0_2_6 - 4.89688882546107e-05*G0_2_7 + 4.00380869130936e-05*G0_2_8 + 1.00346082488959e-06*G0_2_9 - 4.00380869130937e-05*G0_3_0 - 0.000147508741258766*G0_3_1 - 6.11107642357746e-05*G0_3_2 - 0.000400380869130937*G0_3_3 - 0.000280266608391656*G0_3_4 + 0.000166474150849179*G0_3_5 - 0.000212834040959077*G0_3_6 + 0.000120114260739281*G0_3_7 - 0.000240228521478562*G0_3_9 + 4.89688882546108e-05*G0_4_0 + 0.000140484515484539*G0_4_1 + 0.000166674843014157*G0_4_2 - 0.000280266608391656*G0_4_3 + 0.000636394855144963*G0_4_4 - 0.000146906664763833*G0_4_5 + 0.000359740705722909*G0_4_6 - 0.000120114260739281*G0_4_8 + 0.000290802947052996*G0_4_9 - 7.1346064649648e-05*G0_5_0 - 7.09446803196923e-05*G0_5_1 - 7.11453724846702e-05*G0_5_2 + 0.000166474150849179*G0_5_3 - 0.000146906664763833*G0_5_4 - 0.000332346225203423*G0_5_5 - 0.000359740705722908*G0_5_7 + 0.000212834040959076*G0_5_8 - 0.000422657699443485*G0_5_9 + 7.11453724846702e-05*G0_6_0 + 7.09446803196923e-05*G0_6_1 + 7.13460646496481e-05*G0_6_2 - 0.000212834040959077*G0_6_3 + 0.000359740705722909*G0_6_4 + 0.000332346225203424*G0_6_6 + 0.000146906664763832*G0_6_7 - 0.000166474150849179*G0_6_8 + 0.000422657699443485*G0_6_9 - 0.000166674843014157*G0_7_0 - 0.000140484515484539*G0_7_1 - 4.89688882546107e-05*G0_7_2 + 0.000120114260739281*G0_7_3 - 0.000359740705722908*G0_7_5 + 0.000146906664763832*G0_7_6 - 0.000636394855144961*G0_7_7 + 0.000280266608391655*G0_7_8 - 0.000290802947052996*G0_7_9 + 6.11107642357746e-05*G0_8_0 + 0.000147508741258766*G0_8_1 + 4.00380869130936e-05*G0_8_2 - 0.000120114260739281*G0_8_4 + 0.000212834040959076*G0_8_5 - 0.000166474150849179*G0_8_6 + 0.000280266608391655*G0_8_7 + 0.000400380869130938*G0_8_8 + 0.000240228521478562*G0_8_9 - 1.00346082488956e-06*G0_9_0 + 1.00346082488959e-06*G0_9_2 - 0.000240228521478562*G0_9_3 + 0.000290802947052996*G0_9_4 - 0.000422657699443485*G0_9_5 + 0.000422657699443485*G0_9_6 - 0.000290802947052996*G0_9_7 + 0.000240228521478562*G0_9_8; + A[60] = A[41] - 0.000319490777080117*G0_0_0 - 2.95240473811953e-05*G0_0_2 + 4.41522762951411e-05*G0_0_3 + 1.80622948480121e-06*G0_0_4 - 0.000343785678607166*G0_0_5 + 0.000191661017553907*G0_0_6 - 0.000220359997145749*G0_0_7 + 0.000122321874554038*G0_0_8 - 4.13425859854501e-05*G0_0_9 + 0.000319490777080117*G0_1_1 + 2.95240473811952e-05*G0_1_2 + 0.000343785678607166*G0_1_3 - 0.000191661017553907*G0_1_4 - 4.4152276295141e-05*G0_1_5 - 1.80622948480125e-06*G0_1_6 - 0.000122321874554038*G0_1_7 + 0.000220359997145749*G0_1_8 + 4.13425859854502e-05*G0_1_9 - 2.95240473811953e-05*G0_2_0 + 2.95240473811952e-05*G0_2_1 + 6.11107642357747e-05*G0_2_3 - 0.000119411838161858*G0_2_4 - 6.11107642357746e-05*G0_2_5 + 0.000119411838161858*G0_2_6 - 2.42837519623275e-05*G0_2_7 + 2.42837519623275e-05*G0_2_8 + 4.41522762951411e-05*G0_3_0 + 0.000343785678607166*G0_3_1 + 6.11107642357747e-05*G0_3_2 + 0.000678841248037792*G0_3_3 - 1.38477593834761e-05*G0_3_4 + 5.41868845440357e-06*G0_3_6 - 0.000132456828885423*G0_3_7 + 0.000205308084772405*G0_3_8 + 0.000140885899814495*G0_3_9 + 1.80622948480121e-06*G0_4_0 - 0.000191661017553907*G0_4_1 - 0.000119411838161858*G0_4_2 - 1.38477593834761e-05*G0_4_3 - 0.000172795954045984*G0_4_4 - 5.41868845440366e-06*G0_4_5 + 3.37162837162895e-05*G0_4_7 - 7.28512558869825e-05*G0_4_8 + 1.08373769088077e-05*G0_4_9 - 0.000343785678607166*G0_5_0 - 4.4152276295141e-05*G0_5_1 - 6.11107642357746e-05*G0_5_2 - 5.41868845440366e-06*G0_5_4 - 0.000678841248037792*G0_5_5 + 1.38477593834762e-05*G0_5_6 - 0.000205308084772405*G0_5_7 + 0.000132456828885422*G0_5_8 - 0.000140885899814495*G0_5_9 + 0.000191661017553907*G0_6_0 - 1.80622948480125e-06*G0_6_1 + 0.000119411838161858*G0_6_2 + 5.41868845440357e-06*G0_6_3 + 1.38477593834762e-05*G0_6_5 + 0.000172795954045983*G0_6_6 + 7.28512558869824e-05*G0_6_7 - 3.37162837162892e-05*G0_6_8 - 1.08373769088071e-05*G0_6_9 - 0.000220359997145749*G0_7_0 - 0.000122321874554038*G0_7_1 - 2.42837519623275e-05*G0_7_2 - 0.000132456828885423*G0_7_3 + 3.37162837162895e-05*G0_7_4 - 0.000205308084772405*G0_7_5 + 7.28512558869824e-05*G0_7_6 - 0.000147207703011299*G0_7_7 - 2.16747538176146e-05*G0_7_9 + 0.000122321874554038*G0_8_0 + 0.000220359997145749*G0_8_1 + 2.42837519623275e-05*G0_8_2 + 0.000205308084772405*G0_8_3 - 7.28512558869825e-05*G0_8_4 + 0.000132456828885422*G0_8_5 - 3.37162837162892e-05*G0_8_6 + 0.000147207703011299*G0_8_8 + 2.16747538176143e-05*G0_8_9 - 4.13425859854501e-05*G0_9_0 + 4.13425859854502e-05*G0_9_1 + 0.000140885899814495*G0_9_3 + 1.08373769088078e-05*G0_9_4 - 0.000140885899814495*G0_9_5 - 1.08373769088071e-05*G0_9_6 - 2.16747538176146e-05*G0_9_7 + 2.16747538176143e-05*G0_9_8; + A[55] = A[60] + 0.00117772852147872*G0_0_0 + 7.53933566433692e-05*G0_0_1 + 0.000197849025974059*G0_0_2 + 1.40484515484509e-06*G0_0_3 + 6.32180319680427e-06*G0_0_4 + 0.00175254433066963*G0_0_5 - 0.000866087037962185*G0_0_6 + 0.0006778377872129*G0_0_7 - 0.000325221653346708*G0_0_8 + 0.000102553696303714*G0_0_9 + 7.53933566433692e-05*G0_1_0 + 8.05556051091901e-05*G0_1_1 + 5.06190238333181e-05*G0_1_2 - 0.000116000071357234*G0_1_3 + 4.41522762951417e-06*G0_1_4 + 0.00085294170115613*G0_1_5 - 0.000130048522905688*G0_1_6 + 0.000407906825317608*G0_1_7 - 0.000257488047666662*G0_1_8 + 0.000543474382760188*G0_1_9 + 0.000197849025974059*G0_2_0 + 5.06190238333181e-05*G0_2_1 + 0.000157108516483543*G0_2_2 - 5.5692075781371e-05*G0_2_3 - 7.02422577422667e-07*G0_2_4 + 0.000641813543599366*G0_2_5 - 0.000280266608391655*G0_2_6 + 0.00035773378407313*G0_2_7 - 0.000173197338375939*G0_2_8 + 0.000271536499215116*G0_2_9 + 1.40484515484509e-06*G0_3_0 - 0.000116000071357234*G0_3_1 - 5.5692075781371e-05*G0_3_2 + 0.000371481197374117*G0_3_3 - 0.000141487976309429*G0_3_4 - 0.00105212867489671*G0_3_5 - 6.86367204224462e-05*G0_3_6 - 0.000462996824604045*G0_3_7 + 0.000402187098615738*G0_3_8 - 0.000704429499072474*G0_3_9 + 6.32180319680428e-06*G0_4_0 + 4.41522762951417e-06*G0_4_1 - 7.02422577422654e-07*G0_4_2 - 0.000141487976309429*G0_4_3 + 0.000543072998430233*G0_4_4 - 0.000477747698729922*G0_4_5 + 0.000546384419152369*G0_4_6 - 0.000316692236335147*G0_4_7 + 6.08097259883076e-05*G0_4_8 + 0.000140885899814495*G0_4_9 + 0.00175254433066963*G0_5_0 + 0.00085294170115613*G0_5_1 + 0.000641813543599366*G0_5_2 - 0.00105212867489671*G0_5_3 - 0.000477747698729922*G0_5_4 + 0.0179349556693337*G0_5_5 - 0.00307871815684368*G0_5_6 + 0.00454959103396679*G0_5_7 - 0.00301760739260789*G0_5_8 + 0.00572755369630466*G0_5_9 - 0.000866087037962185*G0_6_0 - 0.000130048522905688*G0_6_1 - 0.000280266608391655*G0_6_2 - 6.86367204224462e-05*G0_6_3 + 0.000546384419152369*G0_6_4 - 0.00307871815684368*G0_6_5 + 0.00260819537605296*G0_6_6 - 0.0015319836413589*G0_6_7 + 0.000684259936492194*G0_6_8 - 0.000677336056800456*G0_6_9 + 0.0006778377872129*G0_7_0 + 0.000407906825317608*G0_7_1 + 0.00035773378407313*G0_7_2 - 0.000462996824604045*G0_7_3 - 0.000316692236335147*G0_7_4 + 0.00454959103396679*G0_7_5 - 0.0015319836413589*G0_7_6 + 0.00312086351148903*G0_7_7 - 0.00161416708291735*G0_7_8 + 0.00275630619380666*G0_7_9 - 0.000325221653346708*G0_8_0 - 0.000257488047666662*G0_8_1 - 0.000173197338375939*G0_8_2 + 0.000402187098615738*G0_8_3 + 6.08097259883076e-05*G0_8_4 - 0.0030176073926079*G0_8_5 + 0.000684259936492194*G0_8_6 - 0.00161416708291735*G0_8_7 + 0.00100667189952921*G0_8_8 - 0.00175204260025718*G0_8_9 + 0.000102553696303714*G0_9_0 + 0.000543474382760188*G0_9_1 + 0.000271536499215116*G0_9_2 - 0.000704429499072474*G0_9_3 + 0.000140885899814495*G0_9_4 + 0.00572755369630466*G0_9_5 - 0.000677336056800456*G0_9_6 + 0.00275630619380666*G0_9_7 - 0.00175204260025718*G0_9_8 + 0.00575464713857668*G0_9_9; + A[75] = -A[60] + 0.000107704795204812*G0_0_0 + 3.55894105894165e-05*G0_0_1 + 2.83310439560486e-05*G0_0_2 + 2.80969030969078e-06*G0_0_3 + 7.37543706293832e-05*G0_0_4 + 0.000101851273726289*G0_0_5 + 2.10726773226886e-06*G0_0_6 + 0.000249360014985056*G0_0_7 - 0.000138377247752271*G0_0_8 + 2.38823676323718e-05*G0_0_9 + 3.55894105894165e-05*G0_1_0 + 5.56140288283241e-05*G0_1_1 + 4.03948729841655e-05*G0_1_2 - 7.51592157842284e-05*G0_1_3 + 1.57543349507662e-05*G0_1_4 + 0.000314484622520389*G0_1_5 - 6.62284144427112e-05*G0_1_6 + 0.000304349668189005*G0_1_7 - 0.000166373804766689*G0_1_8 + 0.000312678393035588*G0_1_9 + 2.83310439560486e-05*G0_2_0 + 4.03948729841655e-05*G0_2_1 + 0.000127372627372649*G0_2_2 - 5.53910375339041e-05*G0_2_3 - 3.81315113458031e-06*G0_2_4 + 0.00024323890395323*G0_2_5 + 3.01038247467255e-07*G0_2_6 + 0.000354522709433483*G0_2_7 - 0.000115197302697322*G0_2_8 + 0.000313681853860478*G0_2_9 + 2.80969030969078e-06*G0_3_0 - 7.51592157842284e-05*G0_3_1 - 5.53910375339041e-05*G0_3_2 + 0.000422356661196018*G0_3_3 - 0.000202598740545204*G0_3_4 - 0.000313380815613011*G0_3_5 - 0.000126436063936085*G0_3_6 - 0.000333550378193292*G0_3_7 + 0.000313079777365545*G0_3_8 - 0.000270934422720183*G0_3_9 + 7.37543706293832e-05*G0_4_0 + 1.57543349507662e-05*G0_4_1 - 3.81315113458032e-06*G0_4_2 - 0.000202598740545204*G0_4_3 + 0.000754702886399443*G0_4_4 - 0.000546384419152369*G0_4_5 + 0.000672820483088454*G0_4_6 - 0.00047985496646219*G0_4_7 + 2.04706008277471e-05*G0_4_8 + 0.000151723276723303*G0_4_9 + 0.000101851273726289*G0_5_0 + 0.000314484622520389*G0_5_1 + 0.00024323890395323*G0_5_2 - 0.000313380815613011*G0_5_3 - 0.000546384419152369*G0_5_4 + 0.00368561126373688*G0_5_5 - 0.00158677260239787*G0_5_6 + 0.00265726461039006*G0_5_7 - 0.00126857517482539*G0_5_8 + 0.00246550324675366*G0_5_9 + 2.10726773226892e-06*G0_6_0 - 6.62284144427112e-05*G0_6_1 + 3.01038247467282e-07*G0_6_2 - 0.000126436063936085*G0_6_3 + 0.000672820483088454*G0_6_4 - 0.00158677260239787*G0_6_5 + 0.00143143686670497*G0_6_6 - 0.00138868943556467*G0_6_7 + 0.000434699229342159*G0_6_8 - 0.000688173433709263*G0_6_9 + 0.000249360014985056*G0_7_0 + 0.000304349668189005*G0_7_1 + 0.000354522709433483*G0_7_2 - 0.000333550378193292*G0_7_3 - 0.00047985496646219*G0_7_4 + 0.00265726461039006*G0_7_5 - 0.00138868943556467*G0_7_6 + 0.00408599213286782*G0_7_7 - 0.00130650599400621*G0_7_8 + 0.00270573176823222*G0_7_9 - 0.000138377247752271*G0_8_0 - 0.000166373804766689*G0_8_1 - 0.000115197302697322*G0_8_2 + 0.000313079777365545*G0_8_3 + 2.04706008277471e-05*G0_8_4 - 0.00126857517482539*G0_8_5 + 0.000434699229342159*G0_8_6 - 0.00130650599400621*G0_8_7 + 0.000795042011560003*G0_8_8 - 0.000978976380762259*G0_8_9 + 2.38823676323719e-05*G0_9_0 + 0.000312678393035588*G0_9_1 + 0.000313681853860478*G0_9_2 - 0.000270934422720183*G0_9_3 + 0.000151723276723303*G0_9_4 + 0.00246550324675366*G0_9_5 - 0.000688173433709264*G0_9_6 + 0.00270573176823222*G0_9_7 - 0.000978976380762259*G0_9_8 + 0.00516942878550108*G0_9_9; + A[64] = A[75] - 0.000371581543456605*G0_0_0 - 1.74602183530783e-05*G0_0_1 - 0.000138176555587293*G0_0_3 + 0.00035582720850584*G0_0_4 - 0.000636093816897495*G0_0_5 + 0.000565048790495314*G0_0_6 - 0.000520796168117684*G0_0_7 + 0.000205308084772405*G0_0_8 + 0.000247453439417767*G0_0_9 - 1.74602183530783e-05*G0_1_0 + 1.74602183530785e-05*G0_1_2 - 0.000115297648779811*G0_1_3 + 0.000359740705722909*G0_1_4 - 0.000494003764093133*G0_1_5 + 0.000494003764093133*G0_1_6 - 0.000359740705722909*G0_1_7 + 0.000115297648779811*G0_1_8 + 1.74602183530785e-05*G0_2_1 + 0.000371581543456606*G0_2_2 - 0.000205308084772405*G0_2_3 + 0.000520796168117684*G0_2_4 - 0.000565048790495314*G0_2_5 + 0.000636093816897495*G0_2_6 - 0.00035582720850584*G0_2_7 + 0.000138176555587293*G0_2_8 - 0.000247453439417767*G0_2_9 - 0.000138176555587293*G0_3_0 - 0.000115297648779811*G0_3_1 - 0.000205308084772405*G0_3_2 + 0.00050393802625954*G0_3_3 - 0.00139802162123614*G0_3_4 + 0.00094827047952064*G0_3_5 - 0.0014820112922794*G0_3_6 + 0.00041452966676188*G0_3_7 - 0.000829059333523759*G0_3_9 + 0.00035582720850584*G0_4_0 + 0.000359740705722909*G0_4_1 + 0.000520796168117684*G0_4_2 - 0.00139802162123614*G0_4_3 + 0.00394209585057866*G0_4_4 - 0.00106748162551752*G0_4_5 + 0.00254949291779692*G0_4_6 - 0.000414529666761879*G0_4_8 + 0.00287732356928834*G0_4_9 - 0.000636093816897495*G0_5_0 - 0.000494003764093133*G0_5_1 - 0.000565048790495314*G0_5_2 + 0.00094827047952064*G0_5_3 - 0.00106748162551752*G0_5_4 - 0.00343815782431911*G0_5_5 - 0.00254949291779692*G0_5_7 + 0.0014820112922794*G0_5_8 - 0.0037063829028121*G0_5_9 + 0.000565048790495314*G0_6_0 + 0.000494003764093133*G0_6_1 + 0.000636093816897495*G0_6_2 - 0.0014820112922794*G0_6_3 + 0.00254949291779692*G0_6_4 + 0.00343815782431912*G0_6_6 + 0.00106748162551752*G0_6_7 - 0.000948270479520638*G0_6_8 + 0.0037063829028121*G0_6_9 - 0.000520796168117684*G0_7_0 - 0.000359740705722909*G0_7_1 - 0.00035582720850584*G0_7_2 + 0.00041452966676188*G0_7_3 - 0.00254949291779692*G0_7_5 + 0.00106748162551752*G0_7_6 - 0.00394209585057865*G0_7_7 + 0.00139802162123614*G0_7_8 - 0.00287732356928834*G0_7_9 + 0.000205308084772405*G0_8_0 + 0.000115297648779811*G0_8_1 + 0.000138176555587293*G0_8_2 - 0.000414529666761879*G0_8_4 + 0.0014820112922794*G0_8_5 - 0.000948270479520638*G0_8_6 + 0.00139802162123614*G0_8_7 - 0.000503938026259539*G0_8_8 + 0.000829059333523758*G0_8_9 + 0.000247453439417767*G0_9_0 - 0.000247453439417767*G0_9_2 - 0.000829059333523759*G0_9_3 + 0.00287732356928834*G0_9_4 - 0.0037063829028121*G0_9_5 + 0.0037063829028121*G0_9_6 - 0.00287732356928834*G0_9_7 + 0.000829059333523758*G0_9_8; + A[5] = -A[1] + 0.000764730061605192*G0_0_0 + 6.52534469498865e-05*G0_0_1 + 7.72082580118425e-05*G0_0_2 - 2.86097830740738e-05*G0_0_3 - 4.41299771656989e-05*G0_0_4 + 0.000905890984016138*G0_0_5 - 0.000379542332667397*G0_0_6 + 0.000498954170829254*G0_0_7 - 0.000239291958041998*G0_0_8 + 0.000151723276723302*G0_0_9 + 6.52534469498865e-05*G0_1_0 + 7.27992245849514e-05*G0_1_1 + 6.34856215213466e-05*G0_1_3 - 3.57566540602316e-05*G0_1_4 + 5.63833487940724e-05*G0_1_5 - 5.94829277865092e-05*G0_1_6 + 2.83310439560485e-05*G0_1_7 + 5.23137576709096e-05*G0_1_8 - 2.00692164977882e-07*G0_1_9 + 7.72082580118425e-05*G0_2_0 - 1.83212125176442e-05*G0_2_2 - 1.36916654773821e-05*G0_2_4 + 0.000177266929499102*G0_2_5 - 9.18612637362793e-05*G0_2_6 + 5.78550913372438e-05*G0_2_7 - 3.07504995005046e-05*G0_2_8 + 2.27451120308302e-05*G0_2_9 - 2.86097830740738e-05*G0_3_0 + 6.34856215213466e-05*G0_3_1 - 7.63633687740958e-05*G0_3_3 + 2.27785607249931e-05*G0_3_4 + 1.90657556728994e-06*G0_3_5 + 9.13149350649505e-05*G0_3_6 - 1.30449907235663e-06*G0_3_7 - 3.81315113458023e-06*G0_3_8 + 3.21107463964667e-06*G0_3_9 - 4.41299771656989e-05*G0_4_0 - 3.57566540602316e-05*G0_4_1 - 1.36916654773821e-05*G0_4_2 + 2.27785607249931e-05*G0_4_3 - 0.000196276937348399*G0_4_4 + 4.52560832025194e-05*G0_4_5 - 0.00013657101826747*G0_4_6 + 2.29792528899711e-05*G0_4_7 + 5.11765020693677e-06*G0_4_8 - 0.000158747502497529*G0_4_9 + 0.000905890984016138*G0_5_0 + 5.63833487940724e-05*G0_5_1 + 0.000177266929499102*G0_5_2 + 1.90657556728994e-06*G0_5_3 + 4.52560832025195e-05*G0_5_4 + 0.0014483953546456*G0_5_5 - 0.000696702850720826*G0_5_6 + 0.000516983016983103*G0_5_7 - 0.000256283894676795*G0_5_8 + 5.73979591836835e-05*G0_5_9 - 0.000379542332667397*G0_6_0 - 5.94829277865092e-05*G0_6_1 - 9.18612637362793e-05*G0_6_2 + 9.13149350649505e-05*G0_6_3 - 0.00013657101826747*G0_6_4 - 0.000696702850720826*G0_6_5 - 5.23806550592352e-05*G0_6_6 - 0.000260699122306309*G0_6_7 + 0.000178917065077809*G0_6_8 - 0.000250865206222392*G0_6_9 + 0.000498954170829254*G0_7_0 + 2.83310439560485e-05*G0_7_1 + 5.78550913372438e-05*G0_7_2 - 1.30449907235663e-06*G0_7_3 + 2.29792528899711e-05*G0_7_4 + 0.000516983016983103*G0_7_5 - 0.000260699122306309*G0_7_6 + 0.000636394855144962*G0_7_7 - 0.000321809886542083*G0_7_8 + 6.62284144427115e-05*G0_7_9 - 0.000239291958041998*G0_8_0 + 5.23137576709096e-05*G0_8_1 - 3.07504995005046e-05*G0_8_2 - 3.81315113458024e-06*G0_8_3 + 5.11765020693677e-06*G0_8_4 - 0.000256283894676795*G0_8_5 + 0.000178917065077809*G0_8_6 - 0.000321809886542083*G0_8_7 + 0.000225477647352685*G0_8_8 - 9.63322391893994e-06*G0_8_9 + 0.000151723276723302*G0_9_0 - 2.00692164977889e-07*G0_9_1 + 2.27451120308302e-05*G0_9_2 + 3.21107463964663e-06*G0_9_3 - 0.000158747502497529*G0_9_4 + 5.73979591836835e-05*G0_9_5 - 0.000250865206222391*G0_9_6 + 6.62284144427115e-05*G0_9_7 - 9.63322391893992e-06*G0_9_8 - 0.000989813757671068*G0_9_9; + A[10] = A[1]; + A[8] = A[32] - 0.000319490777080117*G0_0_0 - 2.95240473811952e-05*G0_0_1 + 1.80622948480135e-06*G0_0_3 + 4.41522762951409e-05*G0_0_4 - 0.000220359997145748*G0_0_5 + 0.000122321874554038*G0_0_6 - 0.000343785678607165*G0_0_7 + 0.000191661017553907*G0_0_8 - 4.134258598545e-05*G0_0_9 - 2.95240473811952e-05*G0_1_0 + 2.95240473811952e-05*G0_1_2 - 0.000119411838161858*G0_1_3 + 6.11107642357747e-05*G0_1_4 - 2.42837519623275e-05*G0_1_5 + 2.42837519623275e-05*G0_1_6 - 6.11107642357745e-05*G0_1_7 + 0.000119411838161859*G0_1_8 + 2.95240473811952e-05*G0_2_1 + 0.000319490777080116*G0_2_2 - 0.000191661017553907*G0_2_3 + 0.000343785678607165*G0_2_4 - 0.000122321874554038*G0_2_5 + 0.000220359997145749*G0_2_6 - 4.41522762951409e-05*G0_2_7 - 1.80622948480119e-06*G0_2_8 + 4.13425859854501e-05*G0_2_9 + 1.80622948480136e-06*G0_3_0 - 0.000119411838161858*G0_3_1 - 0.000191661017553907*G0_3_2 - 0.000172795954045984*G0_3_3 - 1.3847759383476e-05*G0_3_4 + 3.37162837162895e-05*G0_3_5 - 7.28512558869825e-05*G0_3_6 - 5.41868845440336e-06*G0_3_7 + 1.08373769088072e-05*G0_3_9 + 4.41522762951409e-05*G0_4_0 + 6.11107642357747e-05*G0_4_1 + 0.000343785678607165*G0_4_2 - 1.3847759383476e-05*G0_4_3 + 0.000678841248037792*G0_4_4 - 0.000132456828885423*G0_4_5 + 0.000205308084772405*G0_4_6 + 5.41868845440374e-06*G0_4_8 + 0.000140885899814495*G0_4_9 - 0.000220359997145748*G0_5_0 - 2.42837519623275e-05*G0_5_1 - 0.000122321874554038*G0_5_2 + 3.37162837162895e-05*G0_5_3 - 0.000132456828885423*G0_5_4 - 0.000147207703011299*G0_5_5 - 0.000205308084772404*G0_5_7 + 7.2851255886982e-05*G0_5_8 - 2.16747538176146e-05*G0_5_9 + 0.000122321874554038*G0_6_0 + 2.42837519623275e-05*G0_6_1 + 0.000220359997145749*G0_6_2 - 7.28512558869824e-05*G0_6_3 + 0.000205308084772405*G0_6_4 + 0.000147207703011299*G0_6_6 + 0.000132456828885422*G0_6_7 - 3.37162837162892e-05*G0_6_8 + 2.16747538176145e-05*G0_6_9 - 0.000343785678607165*G0_7_0 - 6.11107642357745e-05*G0_7_1 - 4.41522762951409e-05*G0_7_2 - 5.41868845440336e-06*G0_7_3 - 0.000205308084772404*G0_7_5 + 0.000132456828885422*G0_7_6 - 0.00067884124803779*G0_7_7 + 1.38477593834754e-05*G0_7_8 - 0.000140885899814495*G0_7_9 + 0.000191661017553907*G0_8_0 + 0.000119411838161859*G0_8_1 - 1.80622948480119e-06*G0_8_2 + 5.41868845440374e-06*G0_8_4 + 7.2851255886982e-05*G0_8_5 - 3.37162837162892e-05*G0_8_6 + 1.38477593834754e-05*G0_8_7 + 0.000172795954045984*G0_8_8 - 1.0837376908807e-05*G0_8_9 - 4.134258598545e-05*G0_9_0 + 4.13425859854501e-05*G0_9_2 + 1.08373769088072e-05*G0_9_3 + 0.000140885899814495*G0_9_4 - 2.16747538176146e-05*G0_9_5 + 2.16747538176145e-05*G0_9_6 - 0.000140885899814495*G0_9_7 - 1.0837376908807e-05*G0_9_8; + A[83] = A[75] - 0.000371581543456605*G0_0_0 - 1.74602183530784e-05*G0_0_2 + 0.00035582720850584*G0_0_3 - 0.000138176555587293*G0_0_4 - 0.000520796168117684*G0_0_5 + 0.000205308084772405*G0_0_6 - 0.000636093816897495*G0_0_7 + 0.000565048790495314*G0_0_8 + 0.000247453439417767*G0_0_9 + 0.000371581543456607*G0_1_1 + 1.74602183530785e-05*G0_1_2 + 0.000520796168117685*G0_1_3 - 0.000205308084772405*G0_1_4 - 0.00035582720850584*G0_1_5 + 0.000138176555587293*G0_1_6 - 0.000565048790495314*G0_1_7 + 0.000636093816897495*G0_1_8 - 0.000247453439417767*G0_1_9 - 1.74602183530784e-05*G0_2_0 + 1.74602183530785e-05*G0_2_1 + 0.000359740705722909*G0_2_3 - 0.000115297648779811*G0_2_4 - 0.000359740705722909*G0_2_5 + 0.000115297648779811*G0_2_6 - 0.000494003764093133*G0_2_7 + 0.000494003764093133*G0_2_8 + 0.00035582720850584*G0_3_0 + 0.000520796168117685*G0_3_1 + 0.000359740705722909*G0_3_2 + 0.00394209585057866*G0_3_3 - 0.00139802162123614*G0_3_4 - 0.000414529666761879*G0_3_6 - 0.00106748162551752*G0_3_7 + 0.00254949291779692*G0_3_8 + 0.00287732356928834*G0_3_9 - 0.000138176555587293*G0_4_0 - 0.000205308084772405*G0_4_1 - 0.000115297648779811*G0_4_2 - 0.00139802162123614*G0_4_3 + 0.000503938026259539*G0_4_4 + 0.00041452966676188*G0_4_5 + 0.000948270479520639*G0_4_7 - 0.0014820112922794*G0_4_8 - 0.000829059333523759*G0_4_9 - 0.000520796168117684*G0_5_0 - 0.00035582720850584*G0_5_1 - 0.000359740705722909*G0_5_2 + 0.00041452966676188*G0_5_4 - 0.00394209585057865*G0_5_5 + 0.00139802162123614*G0_5_6 - 0.00254949291779692*G0_5_7 + 0.00106748162551752*G0_5_8 - 0.00287732356928834*G0_5_9 + 0.000205308084772405*G0_6_0 + 0.000138176555587293*G0_6_1 + 0.000115297648779811*G0_6_2 - 0.000414529666761879*G0_6_3 + 0.00139802162123614*G0_6_5 - 0.000503938026259541*G0_6_6 + 0.0014820112922794*G0_6_7 - 0.000948270479520639*G0_6_8 + 0.000829059333523758*G0_6_9 - 0.000636093816897495*G0_7_0 - 0.000565048790495314*G0_7_1 - 0.000494003764093133*G0_7_2 - 0.00106748162551752*G0_7_3 + 0.000948270479520639*G0_7_4 - 0.00254949291779692*G0_7_5 + 0.0014820112922794*G0_7_6 - 0.00343815782431911*G0_7_7 - 0.0037063829028121*G0_7_9 + 0.000565048790495314*G0_8_0 + 0.000636093816897495*G0_8_1 + 0.000494003764093133*G0_8_2 + 0.00254949291779692*G0_8_3 - 0.0014820112922794*G0_8_4 + 0.00106748162551752*G0_8_5 - 0.000948270479520639*G0_8_6 + 0.00343815782431912*G0_8_8 + 0.0037063829028121*G0_8_9 + 0.000247453439417767*G0_9_0 - 0.000247453439417767*G0_9_1 + 0.00287732356928834*G0_9_3 - 0.000829059333523759*G0_9_4 - 0.00287732356928834*G0_9_5 + 0.000829059333523758*G0_9_6 - 0.0037063829028121*G0_9_7 + 0.0037063829028121*G0_9_8; + A[46] = A[64]; + A[92] = A[2] - 5.57515401265496e-05*G0_0_0 + 1.9449796235514e-06*G0_0_2 + 1.59327279863021e-05*G0_0_3 - 1.72483766233796e-05*G0_0_4 - 5.48224097331333e-05*G0_0_5 + 4.07070607963534e-05*G0_0_6 - 6.73991187384157e-05*G0_0_7 + 3.24452333380959e-05*G0_0_8 - 9.77370843442437e-05*G0_0_9 + 1.15311276025581e-05*G0_1_1 + 1.15311276025581e-05*G0_1_2 + 1.11830134151582e-05*G0_1_3 + 1.11830134151582e-05*G0_1_4 + 1.01795525902686e-05*G0_1_5 - 2.2934654631087e-05*G0_1_6 + 1.01795525902686e-05*G0_1_7 - 2.29346546310871e-05*G0_1_8 - 8.65652204938066e-05*G0_1_9 + 1.94497962355139e-06*G0_2_0 + 1.15311276025581e-05*G0_2_1 + 2.43246336996378e-05*G0_2_2 - 8.89735264735419e-06*G0_2_3 + 8.45248501498645e-05*G0_2_4 - 1.63898601398639e-06*G0_2_5 + 6.29838911089017e-05*G0_2_6 + 3.2121895961187e-05*G0_2_7 + 3.21887933495131e-05*G0_2_8 + 0.000302041708291759*G0_2_9 + 1.59327279863021e-05*G0_3_0 + 1.11830134151582e-05*G0_3_1 - 8.89735264735419e-06*G0_3_2 + 0.000232100488796956*G0_3_3 - 0.000207315006422184*G0_3_4 + 9.93426216640676e-06*G0_3_6 - 0.000106667885685761*G0_3_7 + 0.000262103967461154*G0_3_8 + 0.000473031432852941*G0_3_9 - 1.72483766233796e-05*G0_4_0 + 1.11830134151582e-05*G0_4_1 + 8.45248501498645e-05*G0_4_2 - 0.000207315006422184*G0_4_3 + 1.826298701299e-05*G0_4_4 - 7.12457185671576e-06*G0_4_5 - 2.80969030969084e-06*G0_4_6 + 7.12457185671595e-06*G0_4_7 - 0.000155436081775394*G0_4_8 - 0.000891875981161846*G0_4_9 - 5.48224097331333e-05*G0_5_0 + 1.01795525902686e-05*G0_5_1 - 1.63898601398639e-06*G0_5_2 - 7.12457185671576e-06*G0_5_4 + 0.00011439453403741*G0_5_5 - 0.00016918349507638*G0_5_6 + 0.000244643749108076*G0_5_7 - 8.94083594976604e-05*G0_5_8 + 0.000472027972028052*G0_5_9 + 4.07070607963534e-05*G0_6_0 - 2.29346546310871e-05*G0_6_1 + 6.29838911089017e-05*G0_6_2 + 9.93426216640676e-06*G0_6_3 - 2.80969030969085e-06*G0_6_4 - 0.000169183495076381*G0_6_5 - 9.6934315684332e-05*G0_6_6 - 0.000155235389610416*G0_6_7 + 1.55536427857882e-05*G0_6_8 - 0.000925993649208091*G0_6_9 - 6.73991187384157e-05*G0_7_0 + 1.01795525902686e-05*G0_7_1 + 3.2121895961187e-05*G0_7_2 - 0.000106667885685761*G0_7_3 + 7.12457185671596e-06*G0_7_4 + 0.000244643749108076*G0_7_5 - 0.000155235389610416*G0_7_6 + 0.000500526259454915*G0_7_7 - 0.000147709433423744*G0_7_8 + 0.000603682032253563*G0_7_9 + 3.24452333380959e-05*G0_8_0 - 2.29346546310871e-05*G0_8_1 + 3.21887933495131e-05*G0_8_2 + 0.000262103967461154*G0_8_3 - 0.000155436081775394*G0_8_4 - 8.94083594976604e-05*G0_8_5 + 1.55536427857882e-05*G0_8_6 - 0.000147709433423744*G0_8_7 + 0.000503034911517139*G0_8_8 + 0.000570567825032207*G0_8_9 - 9.77370843442437e-05*G0_9_0 - 8.65652204938066e-05*G0_9_1 + 0.000302041708291759*G0_9_2 + 0.000473031432852941*G0_9_3 - 0.000891875981161846*G0_9_4 + 0.000472027972028052*G0_9_5 - 0.000925993649208091*G0_9_6 + 0.000603682032253563*G0_9_7 + 0.000570567825032207*G0_9_8 + 0.000469619666048316*G0_9_9; + A[57] = A[75]; + A[13] = A[31]; + A[48] = A[73] + 2.87993256743308e-05*G0_0_0 - 1.70588340231225e-05*G0_0_1 + 0.000130048522905688*G0_0_3 - 4.06401634080274e-05*G0_0_4 + 2.34809833024159e-05*G0_0_5 - 6.05086877408408e-05*G0_0_6 + 4.60588518624314e-05*G0_0_7 + 5.41868845440349e-06*G0_0_8 + 4.87681960896329e-05*G0_0_9 - 1.70588340231225e-05*G0_1_0 + 1.70588340231227e-05*G0_1_2 + 1.26436063936091e-05*G0_1_3 - 0.000120114260739281*G0_1_4 + 9.75363921792658e-05*G0_1_5 - 9.75363921792659e-05*G0_1_6 + 0.000120114260739281*G0_1_7 - 1.26436063936081e-05*G0_1_8 + 1.70588340231227e-05*G0_2_1 - 2.87993256743305e-05*G0_2_2 - 5.4186884544036e-06*G0_2_3 - 4.6058851862431e-05*G0_2_4 + 6.05086877408408e-05*G0_2_5 - 2.34809833024158e-05*G0_2_6 + 4.06401634080275e-05*G0_2_7 - 0.000130048522905688*G0_2_8 - 4.87681960896329e-05*G0_2_9 + 0.000130048522905688*G0_3_0 + 1.26436063936091e-05*G0_3_1 - 5.4186884544036e-06*G0_3_2 + 0.00136550949050972*G0_3_3 + 0.000292609176537797*G0_3_4 - 0.00034137737262743*G0_3_5 + 0.000292609176537797*G0_3_6 - 0.000390145568717064*G0_3_7 + 0.000780291137434126*G0_3_9 - 4.06401634080274e-05*G0_4_0 - 0.000120114260739281*G0_4_1 - 4.6058851862431e-05*G0_4_2 + 0.000292609176537797*G0_4_3 - 0.000414529666761878*G0_4_4 + 0.000121920490224082*G0_4_5 - 0.000414529666761879*G0_4_6 + 0.000390145568717063*G0_4_8 - 9.75363921792651e-05*G0_4_9 + 2.34809833024159e-05*G0_5_0 + 9.75363921792658e-05*G0_5_1 + 6.05086877408408e-05*G0_5_2 - 0.00034137737262743*G0_5_3 + 0.000121920490224082*G0_5_4 + 0.000463297862851512*G0_5_5 + 0.00041452966676188*G0_5_7 - 0.000292609176537797*G0_5_8 + 0.000438913764806696*G0_5_9 - 6.05086877408409e-05*G0_6_0 - 9.75363921792659e-05*G0_6_1 - 2.34809833024158e-05*G0_6_2 + 0.000292609176537797*G0_6_3 - 0.000414529666761879*G0_6_4 - 0.000463297862851512*G0_6_6 - 0.000121920490224082*G0_6_7 + 0.00034137737262743*G0_6_8 - 0.000438913764806696*G0_6_9 + 4.60588518624314e-05*G0_7_0 + 0.000120114260739281*G0_7_1 + 4.06401634080275e-05*G0_7_2 - 0.000390145568717063*G0_7_3 + 0.00041452966676188*G0_7_5 - 0.000121920490224082*G0_7_6 + 0.000414529666761882*G0_7_7 - 0.000292609176537798*G0_7_8 + 9.75363921792663e-05*G0_7_9 + 5.41868845440352e-06*G0_8_0 - 1.26436063936081e-05*G0_8_1 - 0.000130048522905688*G0_8_2 + 0.000390145568717063*G0_8_4 - 0.000292609176537797*G0_8_5 + 0.00034137737262743*G0_8_6 - 0.000292609176537798*G0_8_7 - 0.00136550949050972*G0_8_8 - 0.000780291137434127*G0_8_9 + 4.87681960896329e-05*G0_9_0 - 4.8768196089633e-05*G0_9_2 + 0.000780291137434126*G0_9_3 - 9.75363921792652e-05*G0_9_4 + 0.000438913764806696*G0_9_5 - 0.000438913764806696*G0_9_6 + 9.75363921792663e-05*G0_9_7 - 0.000780291137434127*G0_9_8; + A[30] = A[82] + 9.59977522477619e-06*G0_0_0 + 4.33495076352293e-05*G0_0_3 - 1.35467211360092e-05*G0_0_4 + 7.82699443413835e-06*G0_0_5 - 2.01695625802802e-05*G0_0_6 + 1.53529506208099e-05*G0_0_7 + 1.80622948480143e-06*G0_0_8 + 1.62560653632109e-05*G0_0_9 + 4.21453546453634e-06*G0_1_3 - 4.00380869130938e-05*G0_1_4 + 3.25121307264219e-05*G0_1_5 - 3.25121307264219e-05*G0_1_6 + 4.00380869130935e-05*G0_1_7 - 4.21453546453597e-06*G0_1_8 - 9.59977522477704e-06*G0_2_2 - 1.80622948480112e-06*G0_2_3 - 1.53529506208105e-05*G0_2_4 + 2.01695625802803e-05*G0_2_5 - 7.82699443413875e-06*G0_2_6 + 1.35467211360091e-05*G0_2_7 - 4.33495076352292e-05*G0_2_8 - 1.6256065363211e-05*G0_2_9 + 4.33495076352293e-05*G0_3_0 + 4.21453546453634e-06*G0_3_1 - 1.80622948480112e-06*G0_3_2 + 0.000455169830169908*G0_3_3 + 9.75363921792657e-05*G0_3_4 - 0.000113792457542477*G0_3_5 + 9.75363921792659e-05*G0_3_6 - 0.000130048522905688*G0_3_7 + 0.000260097045811376*G0_3_9 - 1.35467211360092e-05*G0_4_0 - 4.00380869130938e-05*G0_4_1 - 1.53529506208105e-05*G0_4_2 + 9.75363921792657e-05*G0_4_3 - 0.000138176555587293*G0_4_4 + 4.06401634080275e-05*G0_4_5 - 0.000138176555587293*G0_4_6 + 0.000130048522905688*G0_4_8 - 3.25121307264221e-05*G0_4_9 + 7.82699443413835e-06*G0_5_0 + 3.25121307264219e-05*G0_5_1 + 2.01695625802803e-05*G0_5_2 - 0.000113792457542477*G0_5_3 + 4.06401634080275e-05*G0_5_4 + 0.000154432620950504*G0_5_5 + 0.000138176555587293*G0_5_7 - 9.75363921792656e-05*G0_5_8 + 0.000146304588268899*G0_5_9 - 2.01695625802802e-05*G0_6_0 - 3.25121307264219e-05*G0_6_1 - 7.82699443413875e-06*G0_6_2 + 9.75363921792659e-05*G0_6_3 - 0.000138176555587293*G0_6_4 - 0.000154432620950505*G0_6_6 - 4.06401634080272e-05*G0_6_7 + 0.000113792457542477*G0_6_8 - 0.000146304588268899*G0_6_9 + 1.53529506208099e-05*G0_7_0 + 4.00380869130935e-05*G0_7_1 + 1.35467211360091e-05*G0_7_2 - 0.000130048522905688*G0_7_3 + 0.000138176555587293*G0_7_5 - 4.06401634080272e-05*G0_7_6 + 0.000138176555587292*G0_7_7 - 9.75363921792656e-05*G0_7_8 + 3.25121307264219e-05*G0_7_9 + 1.80622948480142e-06*G0_8_0 - 4.21453546453597e-06*G0_8_1 - 4.33495076352292e-05*G0_8_2 + 0.000130048522905688*G0_8_4 - 9.75363921792656e-05*G0_8_5 + 0.000113792457542477*G0_8_6 - 9.75363921792656e-05*G0_8_7 - 0.000455169830169907*G0_8_8 - 0.000260097045811376*G0_8_9 + 1.62560653632109e-05*G0_9_0 - 1.6256065363211e-05*G0_9_2 + 0.000260097045811376*G0_9_3 - 3.25121307264221e-05*G0_9_4 + 0.000146304588268899*G0_9_5 - 0.000146304588268899*G0_9_6 + 3.25121307264219e-05*G0_9_7 - 0.000260097045811376*G0_9_8; + A[28] = A[82]; + A[98] = A[89]; + A[80] = A[8]; + A[62] = A[26]; + A[50] = A[5]; + A[14] = A[41]; + A[39] = A[93]; + A[23] = A[32]; + A[19] = A[1] - 5.57515401265496e-05*G0_0_0 + 1.94497962355138e-06*G0_0_1 - 1.72483766233795e-05*G0_0_3 + 1.59327279863021e-05*G0_0_4 - 6.73991187384157e-05*G0_0_5 + 3.2445233338096e-05*G0_0_6 - 5.48224097331332e-05*G0_0_7 + 4.07070607963533e-05*G0_0_8 - 9.77370843442437e-05*G0_0_9 + 1.94497962355139e-06*G0_1_0 + 2.43246336996378e-05*G0_1_1 + 1.15311276025581e-05*G0_1_2 + 8.45248501498645e-05*G0_1_3 - 8.89735264735421e-06*G0_1_4 + 3.21218959611871e-05*G0_1_5 + 3.2188793349513e-05*G0_1_6 - 1.63898601398632e-06*G0_1_7 + 6.29838911089018e-05*G0_1_8 + 0.000302041708291759*G0_1_9 + 1.15311276025581e-05*G0_2_1 + 1.15311276025581e-05*G0_2_2 + 1.11830134151582e-05*G0_2_3 + 1.11830134151582e-05*G0_2_4 + 1.01795525902686e-05*G0_2_5 - 2.29346546310871e-05*G0_2_6 + 1.01795525902686e-05*G0_2_7 - 2.29346546310871e-05*G0_2_8 - 8.65652204938066e-05*G0_2_9 - 1.72483766233795e-05*G0_3_0 + 8.45248501498645e-05*G0_3_1 + 1.11830134151582e-05*G0_3_2 + 1.82629870129908e-05*G0_3_3 - 0.000207315006422184*G0_3_4 + 7.12457185671598e-06*G0_3_5 - 0.000155436081775394*G0_3_6 - 7.12457185671587e-06*G0_3_7 - 2.8096903096909e-06*G0_3_8 - 0.000891875981161846*G0_3_9 + 1.59327279863021e-05*G0_4_0 - 8.89735264735421e-06*G0_4_1 + 1.11830134151582e-05*G0_4_2 - 0.000207315006422184*G0_4_3 + 0.000232100488796956*G0_4_4 - 0.000106667885685761*G0_4_5 + 0.000262103967461155*G0_4_6 + 9.93426216640694e-06*G0_4_8 + 0.000473031432852941*G0_4_9 - 6.73991187384157e-05*G0_5_0 + 3.21218959611871e-05*G0_5_1 + 1.01795525902686e-05*G0_5_2 + 7.12457185671602e-06*G0_5_3 - 0.000106667885685761*G0_5_4 + 0.000500526259454915*G0_5_5 - 0.000147709433423744*G0_5_6 + 0.000244643749108076*G0_5_7 - 0.000155235389610416*G0_5_8 + 0.000603682032253562*G0_5_9 + 3.2445233338096e-05*G0_6_0 + 3.2188793349513e-05*G0_6_1 - 2.29346546310871e-05*G0_6_2 - 0.000155436081775394*G0_6_3 + 0.000262103967461155*G0_6_4 - 0.000147709433423744*G0_6_5 + 0.000503034911517139*G0_6_6 - 8.94083594976604e-05*G0_6_7 + 1.55536427857885e-05*G0_6_8 + 0.000570567825032207*G0_6_9 - 5.48224097331332e-05*G0_7_0 - 1.63898601398632e-06*G0_7_1 + 1.01795525902686e-05*G0_7_2 - 7.12457185671587e-06*G0_7_3 + 0.000244643749108076*G0_7_5 - 8.94083594976604e-05*G0_7_6 + 0.00011439453403741*G0_7_7 - 0.00016918349507638*G0_7_8 + 0.000472027972028051*G0_7_9 + 4.07070607963533e-05*G0_8_0 + 6.29838911089018e-05*G0_8_1 - 2.29346546310871e-05*G0_8_2 - 2.8096903096909e-06*G0_8_3 + 9.93426216640695e-06*G0_8_4 - 0.000155235389610416*G0_8_5 + 1.55536427857885e-05*G0_8_6 - 0.00016918349507638*G0_8_7 - 9.6934315684333e-05*G0_8_8 - 0.000925993649208092*G0_8_9 - 9.77370843442437e-05*G0_9_0 + 0.000302041708291759*G0_9_1 - 8.65652204938066e-05*G0_9_2 - 0.000891875981161846*G0_9_3 + 0.000473031432852941*G0_9_4 + 0.000603682032253562*G0_9_5 + 0.000570567825032207*G0_9_6 + 0.000472027972028051*G0_9_7 - 0.000925993649208092*G0_9_8 + 0.000469619666048315*G0_9_9; + A[87] = A[78]; + A[42] = -A[2] + 7.27992245849512e-05*G0_0_0 + 6.52534469498865e-05*G0_0_2 - 5.94829277865093e-05*G0_0_3 + 5.63833487940726e-05*G0_0_4 + 5.23137576709094e-05*G0_0_5 + 2.83310439560487e-05*G0_0_6 + 6.34856215213464e-05*G0_0_7 - 3.57566540602315e-05*G0_0_8 - 2.00692164977957e-07*G0_0_9 - 1.83212125176442e-05*G0_1_1 + 7.72082580118425e-05*G0_1_2 - 9.18612637362794e-05*G0_1_3 + 0.000177266929499102*G0_1_4 - 3.07504995005047e-05*G0_1_5 + 5.7855091337244e-05*G0_1_6 - 1.3691665477382e-05*G0_1_8 + 2.27451120308302e-05*G0_1_9 + 6.52534469498865e-05*G0_2_0 + 7.72082580118425e-05*G0_2_1 + 0.00076473006160519*G0_2_2 - 0.000379542332667397*G0_2_3 + 0.000905890984016136*G0_2_4 - 0.000239291958041998*G0_2_5 + 0.000498954170829255*G0_2_6 - 2.86097830740738e-05*G0_2_7 - 4.41299771656987e-05*G0_2_8 + 0.000151723276723302*G0_2_9 - 5.94829277865093e-05*G0_3_0 - 9.18612637362794e-05*G0_3_1 - 0.000379542332667397*G0_3_2 - 5.23806550592353e-05*G0_3_3 - 0.000696702850720826*G0_3_4 + 0.00017891706507781*G0_3_5 - 0.000260699122306309*G0_3_6 + 9.13149350649506e-05*G0_3_7 - 0.00013657101826747*G0_3_8 - 0.000250865206222391*G0_3_9 + 5.63833487940726e-05*G0_4_0 + 0.000177266929499102*G0_4_1 + 0.000905890984016137*G0_4_2 - 0.000696702850720826*G0_4_3 + 0.0014483953546456*G0_4_4 - 0.000256283894676795*G0_4_5 + 0.000516983016983104*G0_4_6 + 1.90657556729002e-06*G0_4_7 + 4.52560832025196e-05*G0_4_8 + 5.7397959183683e-05*G0_4_9 + 5.23137576709094e-05*G0_5_0 - 3.07504995005047e-05*G0_5_1 - 0.000239291958041998*G0_5_2 + 0.00017891706507781*G0_5_3 - 0.000256283894676795*G0_5_4 + 0.000225477647352686*G0_5_5 - 0.000321809886542084*G0_5_6 - 3.81315113458041e-06*G0_5_7 + 5.11765020693681e-06*G0_5_8 - 9.63322391893966e-06*G0_5_9 + 2.83310439560487e-05*G0_6_0 + 5.7855091337244e-05*G0_6_1 + 0.000498954170829255*G0_6_2 - 0.000260699122306309*G0_6_3 + 0.000516983016983104*G0_6_4 - 0.000321809886542084*G0_6_5 + 0.000636394855144962*G0_6_6 - 1.30449907235652e-06*G0_6_7 + 2.29792528899712e-05*G0_6_8 + 6.62284144427113e-05*G0_6_9 + 6.34856215213464e-05*G0_7_0 - 2.86097830740738e-05*G0_7_2 + 9.13149350649506e-05*G0_7_3 + 1.90657556729003e-06*G0_7_4 - 3.8131511345804e-06*G0_7_5 - 1.30449907235653e-06*G0_7_6 - 7.6363368774096e-05*G0_7_7 + 2.27785607249932e-05*G0_7_8 + 3.21107463964667e-06*G0_7_9 - 3.57566540602315e-05*G0_8_0 - 1.3691665477382e-05*G0_8_1 - 4.41299771656987e-05*G0_8_2 - 0.00013657101826747*G0_8_3 + 4.52560832025196e-05*G0_8_4 + 5.11765020693681e-06*G0_8_5 + 2.29792528899712e-05*G0_8_6 + 2.27785607249932e-05*G0_8_7 - 0.000196276937348399*G0_8_8 - 0.000158747502497529*G0_8_9 - 2.0069216497797e-07*G0_9_0 + 2.27451120308302e-05*G0_9_1 + 0.000151723276723302*G0_9_2 - 0.000250865206222391*G0_9_3 + 5.7397959183683e-05*G0_9_4 - 9.63322391893968e-06*G0_9_5 + 6.62284144427112e-05*G0_9_6 + 3.21107463964668e-06*G0_9_7 - 0.000158747502497529*G0_9_8 - 0.000989813757671068*G0_9_9; + A[96] = A[69]; + A[65] = A[78] + 3.81315113458036e-05*G0_0_1 - 3.81315113458037e-05*G0_0_2 + 0.00028177179962899*G0_0_3 - 0.00028177179962899*G0_0_4 - 0.000413024475524546*G0_0_5 - 0.000280266608391655*G0_0_6 + 0.000413024475524545*G0_0_7 + 0.000280266608391656*G0_0_8 + 3.81315113458036e-05*G0_1_0 + 0.000330238957471157*G0_1_1 + 0.000306456935921274*G0_1_3 - 0.000294114367775132*G0_1_4 + 9.75363921792653e-05*G0_1_5 - 0.000184235407449724*G0_1_6 - 1.38477593834766e-05*G0_1_7 + 0.000719481411445819*G0_1_8 + 5.96055729984398e-05*G0_1_9 - 3.81315113458037e-05*G0_2_0 - 0.000330238957471156*G0_2_2 + 0.000294114367775132*G0_2_3 - 0.000306456935921273*G0_2_4 + 1.38477593834763e-05*G0_2_5 - 0.000719481411445819*G0_2_6 - 9.75363921792658e-05*G0_2_7 + 0.000184235407449724*G0_2_8 - 5.96055729984402e-05*G0_2_9 + 0.00028177179962899*G0_3_0 + 0.000306456935921274*G0_3_1 + 0.000294114367775132*G0_3_2 + 0.00117856473883279*G0_3_3 - 0.000568962287712384*G0_3_5 + 0.000552706222349174*G0_3_6 - 0.00084531539888697*G0_3_7 + 0.00139802162123614*G0_3_8 + 0.00151181407877862*G0_3_9 - 0.00028177179962899*G0_4_0 - 0.000294114367775132*G0_4_1 - 0.000306456935921273*G0_4_2 - 0.0011785647388328*G0_4_4 + 0.000845315398886971*G0_4_5 - 0.00139802162123614*G0_4_6 + 0.000568962287712384*G0_4_7 - 0.000552706222349173*G0_4_8 - 0.00151181407877862*G0_4_9 - 0.000413024475524546*G0_5_0 + 9.75363921792653e-05*G0_5_1 + 1.38477593834761e-05*G0_5_2 - 0.000568962287712384*G0_5_3 + 0.000845315398886971*G0_5_4 - 0.00174481768231798*G0_5_5 + 0.00262806390038577*G0_5_6 - 0.000292609176537797*G0_5_8 + 0.000585218353075594*G0_5_9 - 0.000280266608391655*G0_6_0 - 0.000184235407449724*G0_6_1 - 0.000719481411445819*G0_6_2 + 0.000552706222349174*G0_6_3 - 0.00139802162123614*G0_6_4 + 0.00262806390038577*G0_6_5 - 0.00292338242115078*G0_6_6 + 0.000292609176537799*G0_6_7 - 0.000926595725703026*G0_6_9 + 0.000413024475524545*G0_7_0 - 1.38477593834766e-05*G0_7_1 - 9.75363921792658e-05*G0_7_2 - 0.00084531539888697*G0_7_3 + 0.000568962287712384*G0_7_4 + 0.000292609176537799*G0_7_6 + 0.00174481768231797*G0_7_7 - 0.00262806390038577*G0_7_8 - 0.000585218353075596*G0_7_9 + 0.000280266608391656*G0_8_0 + 0.000719481411445819*G0_8_1 + 0.000184235407449724*G0_8_2 + 0.00139802162123614*G0_8_3 - 0.000552706222349173*G0_8_4 - 0.000292609176537798*G0_8_5 - 0.00262806390038577*G0_8_7 + 0.00292338242115077*G0_8_8 + 0.000926595725703026*G0_8_9 + 5.96055729984397e-05*G0_9_1 - 5.96055729984402e-05*G0_9_2 + 0.00151181407877862*G0_9_3 - 0.00151181407877862*G0_9_4 + 0.000585218353075593*G0_9_5 - 0.000926595725703026*G0_9_6 - 0.000585218353075596*G0_9_7 + 0.000926595725703026*G0_9_8; + A[53] = A[35]; + A[70] = A[7]; + A[68] = A[86]; + A[6] = A[60]; + A[17] = A[71]; + A[9] = A[90]; + A[34] = A[78] + 0.000330238957471156*G0_0_0 + 3.81315113458034e-05*G0_0_1 + 9.75363921792655e-05*G0_0_3 - 0.000184235407449724*G0_0_4 + 0.000306456935921273*G0_0_5 - 0.000294114367775131*G0_0_6 + 0.000719481411445818*G0_0_7 - 1.38477593834754e-05*G0_0_8 + 5.96055729984402e-05*G0_0_9 + 3.81315113458034e-05*G0_1_0 - 3.81315113458037e-05*G0_1_2 - 0.000413024475524546*G0_1_3 - 0.000280266608391656*G0_1_4 + 0.00028177179962899*G0_1_5 - 0.00028177179962899*G0_1_6 + 0.000280266608391655*G0_1_7 + 0.000413024475524546*G0_1_8 - 3.81315113458037e-05*G0_2_1 - 0.000330238957471156*G0_2_2 + 1.38477593834759e-05*G0_2_3 - 0.000719481411445819*G0_2_4 + 0.000294114367775132*G0_2_5 - 0.000306456935921273*G0_2_6 + 0.000184235407449724*G0_2_7 - 9.75363921792658e-05*G0_2_8 - 5.96055729984402e-05*G0_2_9 + 9.75363921792655e-05*G0_3_0 - 0.000413024475524546*G0_3_1 + 1.38477593834759e-05*G0_3_2 - 0.00174481768231798*G0_3_3 + 0.00262806390038577*G0_3_4 - 0.000568962287712384*G0_3_5 + 0.000845315398886971*G0_3_6 - 0.000292609176537797*G0_3_7 + 0.000585218353075595*G0_3_9 - 0.000184235407449724*G0_4_0 - 0.000280266608391656*G0_4_1 - 0.000719481411445819*G0_4_2 + 0.00262806390038577*G0_4_3 - 0.00292338242115077*G0_4_4 + 0.000552706222349173*G0_4_5 - 0.00139802162123614*G0_4_6 + 0.000292609176537797*G0_4_8 - 0.000926595725703025*G0_4_9 + 0.000306456935921273*G0_5_0 + 0.00028177179962899*G0_5_1 + 0.000294114367775132*G0_5_2 - 0.000568962287712384*G0_5_3 + 0.000552706222349173*G0_5_4 + 0.00117856473883279*G0_5_5 + 0.00139802162123614*G0_5_7 - 0.00084531539888697*G0_5_8 + 0.00151181407877862*G0_5_9 - 0.000294114367775131*G0_6_0 - 0.00028177179962899*G0_6_1 - 0.000306456935921273*G0_6_2 + 0.000845315398886971*G0_6_3 - 0.00139802162123614*G0_6_4 - 0.0011785647388328*G0_6_6 - 0.000552706222349172*G0_6_7 + 0.000568962287712383*G0_6_8 - 0.00151181407877862*G0_6_9 + 0.000719481411445818*G0_7_0 + 0.000280266608391655*G0_7_1 + 0.000184235407449724*G0_7_2 - 0.000292609176537797*G0_7_3 + 0.00139802162123614*G0_7_5 - 0.000552706222349172*G0_7_6 + 0.00292338242115077*G0_7_7 - 0.00262806390038577*G0_7_8 + 0.000926595725703024*G0_7_9 - 1.38477593834755e-05*G0_8_0 + 0.000413024475524546*G0_8_1 - 9.75363921792658e-05*G0_8_2 + 0.000292609176537797*G0_8_4 - 0.00084531539888697*G0_8_5 + 0.000568962287712383*G0_8_6 - 0.00262806390038577*G0_8_7 + 0.00174481768231798*G0_8_8 - 0.000585218353075594*G0_8_9 + 5.96055729984402e-05*G0_9_0 - 5.96055729984402e-05*G0_9_2 + 0.000585218353075595*G0_9_3 - 0.000926595725703025*G0_9_4 + 0.00151181407877862*G0_9_5 - 0.00151181407877862*G0_9_6 + 0.000926595725703024*G0_9_7 - 0.000585218353075594*G0_9_8; + A[24] = A[42]; + A[84] = A[48]; + A[59] = A[93] + 0.000102553696303713*G0_0_0 + 1.00346082488956e-06*G0_0_2 - 0.000536450156985962*G0_0_3 + 3.25121307264219e-05*G0_0_4 + 5.41868845440368e-05*G0_0_5 - 0.000140885899814495*G0_0_6 + 0.000223972456115351*G0_0_7 - 0.000323315077779418*G0_0_8 - 0.00149555801341541*G0_0_9 - 0.000102553696303714*G0_1_1 - 1.00346082488958e-06*G0_1_2 - 5.41868845440374e-05*G0_1_3 + 0.000140885899814495*G0_1_4 + 0.000536450156985961*G0_1_5 - 3.25121307264221e-05*G0_1_6 + 0.000323315077779418*G0_1_7 - 0.000223972456115351*G0_1_8 + 0.00149555801341541*G0_1_9 + 1.00346082488956e-06*G0_2_0 - 1.0034608248896e-06*G0_2_1 - 0.000290802947052996*G0_2_3 + 0.000240228521478562*G0_2_4 + 0.000290802947052996*G0_2_5 - 0.000240228521478562*G0_2_6 + 0.000422657699443485*G0_2_7 - 0.000422657699443485*G0_2_8 - 0.000536450156985962*G0_3_0 - 5.41868845440374e-05*G0_3_1 - 0.000290802947052996*G0_3_2 - 0.00629109729556264*G0_3_3 + 0.000926595725703025*G0_3_4 + 9.7536392179266e-05*G0_3_6 + 0.00160935047095788*G0_3_7 - 0.00287732356928834*G0_3_8 - 0.00770537498216199*G0_3_9 + 3.25121307264219e-05*G0_4_0 + 0.000140885899814495*G0_4_1 + 0.000240228521478562*G0_4_2 + 0.000926595725703025*G0_4_3 - 0.00136550949050972*G0_4_4 - 9.7536392179266e-05*G0_4_5 - 0.00068275474525486*G0_4_7 + 0.00126797309833046*G0_4_8 + 0.000195072784358531*G0_4_9 + 5.41868845440369e-05*G0_5_0 + 0.000536450156985961*G0_5_1 + 0.000290802947052996*G0_5_2 - 9.75363921792659e-05*G0_5_4 + 0.00629109729556263*G0_5_5 - 0.000926595725703025*G0_5_6 + 0.00287732356928834*G0_5_7 - 0.00160935047095788*G0_5_8 + 0.00770537498216199*G0_5_9 - 0.000140885899814495*G0_6_0 - 3.25121307264221e-05*G0_6_1 - 0.000240228521478562*G0_6_2 + 9.7536392179266e-05*G0_6_3 - 0.000926595725703026*G0_6_5 + 0.00136550949050972*G0_6_6 - 0.00126797309833046*G0_6_7 + 0.000682754745254861*G0_6_8 - 0.000195072784358534*G0_6_9 + 0.000223972456115351*G0_7_0 + 0.000323315077779418*G0_7_1 + 0.000422657699443485*G0_7_2 + 0.00160935047095788*G0_7_3 - 0.00068275474525486*G0_7_4 + 0.00287732356928834*G0_7_5 - 0.00126797309833046*G0_7_6 + 0.00229210521621274*G0_7_7 + 0.00702262023690713*G0_7_9 - 0.000323315077779418*G0_8_0 - 0.000223972456115351*G0_8_1 - 0.000422657699443485*G0_8_2 - 0.00287732356928834*G0_8_3 + 0.00126797309833046*G0_8_4 - 0.00160935047095788*G0_8_5 + 0.000682754745254861*G0_8_6 - 0.00229210521621275*G0_8_8 - 0.00702262023690713*G0_8_9 - 0.00149555801341541*G0_9_0 + 0.00149555801341541*G0_9_1 - 0.00770537498216199*G0_9_3 + 0.000195072784358531*G0_9_4 + 0.00770537498216199*G0_9_5 - 0.000195072784358534*G0_9_6 + 0.00702262023690713*G0_9_7 - 0.00702262023690713*G0_9_8; + A[47] = A[74]; + A[91] = A[19]; + A[66] = A[55] - 0.000629370629370736*G0_0_0 - 2.50865206222381e-06*G0_0_1 - 0.000154432620950504*G0_0_3 + 0.000276353111174586*G0_0_4 - 0.00149826735764261*G0_0_5 + 0.0011839834272872*G0_0_6 - 0.000410917207792276*G0_0_7 + 0.000147207703011299*G0_0_8 + 0.000211328849721742*G0_0_9 - 2.50865206222381e-06*G0_1_0 + 2.50865206222392e-06*G0_1_2 - 0.000117404916512079*G0_1_3 + 0.000332346225203424*G0_1_4 - 0.000869699496931786*G0_1_5 + 0.000869699496931786*G0_1_6 - 0.000332346225203424*G0_1_7 + 0.000117404916512079*G0_1_8 + 2.50865206222391e-06*G0_2_1 + 0.000629370629370735*G0_2_2 - 0.000147207703011299*G0_2_3 + 0.000410917207792277*G0_2_4 - 0.0011839834272872*G0_2_5 + 0.00149826735764261*G0_2_6 - 0.000276353111174586*G0_2_7 + 0.000154432620950504*G0_2_8 - 0.000211328849721742*G0_2_9 - 0.000154432620950504*G0_3_0 - 0.000117404916512079*G0_3_1 - 0.000147207703011299*G0_3_2 + 0.00050393802625954*G0_3_3 - 0.00117856473883279*G0_3_4 + 0.00153619817682344*G0_3_5 - 0.00260909849079536*G0_3_6 + 0.000463297862851513*G0_3_7 - 0.000926595725703026*G0_3_9 + 0.000276353111174586*G0_4_0 + 0.000332346225203424*G0_4_1 + 0.000410917207792277*G0_4_2 - 0.00117856473883279*G0_4_3 + 0.00196698390894853*G0_4_4 - 0.00082905933352376*G0_4_5 + 0.00343815782431912*G0_4_6 - 0.000463297862851512*G0_4_8 + 0.00229210521621275*G0_4_9 - 0.00149826735764261*G0_5_0 - 0.000869699496931786*G0_5_1 - 0.0011839834272872*G0_5_2 + 0.00153619817682344*G0_5_3 - 0.00082905933352376*G0_5_4 - 0.0141427768659935*G0_5_5 - 0.00343815782431911*G0_5_7 + 0.00260909849079535*G0_5_8 - 0.00585218353075594*G0_5_9 + 0.0011839834272872*G0_6_0 + 0.000869699496931786*G0_6_1 + 0.00149826735764261*G0_6_2 - 0.00260909849079536*G0_6_3 + 0.00343815782431912*G0_6_4 + 0.0141427768659935*G0_6_6 + 0.000829059333523755*G0_6_7 - 0.00153619817682343*G0_6_8 + 0.00585218353075594*G0_6_9 - 0.000410917207792276*G0_7_0 - 0.000332346225203424*G0_7_1 - 0.000276353111174586*G0_7_2 + 0.000463297862851513*G0_7_3 - 0.00343815782431911*G0_7_5 + 0.000829059333523755*G0_7_6 - 0.00196698390894852*G0_7_7 + 0.00117856473883279*G0_7_8 - 0.00229210521621274*G0_7_9 + 0.000147207703011299*G0_8_0 + 0.000117404916512079*G0_8_1 + 0.000154432620950504*G0_8_2 - 0.000463297862851512*G0_8_4 + 0.00260909849079535*G0_8_5 - 0.00153619817682343*G0_8_6 + 0.00117856473883279*G0_8_7 - 0.000503938026259538*G0_8_8 + 0.000926595725703024*G0_8_9 + 0.000211328849721742*G0_9_0 - 0.000211328849721742*G0_9_2 - 0.000926595725703026*G0_9_3 + 0.00229210521621275*G0_9_4 - 0.00585218353075594*G0_9_5 + 0.00585218353075594*G0_9_6 - 0.00229210521621274*G0_9_7 + 0.000926595725703023*G0_9_8; + A[56] = A[65]; + A[77] = A[55] + 0.000115197302697322*G0_0_1 - 0.000115197302697322*G0_0_2 + 7.58616383616509e-05*G0_0_3 - 7.5861638361651e-05*G0_0_4 - 0.000927197802197961*G0_0_5 + 0.000400380869130938*G0_0_6 + 0.000927197802197958*G0_0_7 - 0.000400380869130936*G0_0_8 + 0.000115197302697322*G0_1_0 + 0.000148311509918678*G0_1_1 + 0.000186643713429459*G0_1_3 - 0.000131252675895555*G0_1_4 - 0.000455169830169907*G0_1_5 - 9.21177037248619e-05*G0_1_6 + 0.000172795954045982*G0_1_7 + 0.000143896282289164*G0_1_8 - 0.000270934422720182*G0_1_9 - 0.000115197302697322*G0_2_0 - 0.000148311509918678*G0_2_2 + 0.000131252675895555*G0_2_3 - 0.000186643713429459*G0_2_4 - 0.000172795954045983*G0_2_5 - 0.000143896282289164*G0_2_6 + 0.000455169830169906*G0_2_7 + 9.21177037248623e-05*G0_2_8 + 0.000270934422720182*G0_2_9 + 7.58616383616509e-05*G0_3_0 + 0.000186643713429459*G0_3_1 + 0.000131252675895555*G0_3_2 + 0.00050393802625954*G0_3_3 + 0.000568962287712382*G0_3_5 + 0.000276353111174587*G0_3_6 - 0.000227584915084957*G0_3_7 + 0.00050393802625954*G0_3_8 + 0.00126797309833045*G0_3_9 - 7.5861638361651e-05*G0_4_0 - 0.000131252675895555*G0_4_1 - 0.000186643713429459*G0_4_2 - 0.00050393802625954*G0_4_4 + 0.000227584915084954*G0_4_5 - 0.000503938026259541*G0_4_6 - 0.000568962287712381*G0_4_7 - 0.000276353111174587*G0_4_8 - 0.00126797309833046*G0_4_9 - 0.00092719780219796*G0_5_0 - 0.000455169830169907*G0_5_1 - 0.000172795954045983*G0_5_2 + 0.000568962287712382*G0_5_3 + 0.000227584915084954*G0_5_4 - 0.0144137112887137*G0_5_5 + 0.00174481768231798*G0_5_6 + 0.00136550949050972*G0_5_8 - 0.00273101898101944*G0_5_9 + 0.000400380869130938*G0_6_0 - 9.21177037248619e-05*G0_6_1 - 0.000143896282289164*G0_6_2 + 0.000276353111174587*G0_6_3 - 0.000503938026259541*G0_6_4 + 0.00174481768231798*G0_6_5 - 0.00223791833166871*G0_6_6 - 0.00136550949050972*G0_6_7 - 0.00136550949050972*G0_6_9 + 0.000927197802197958*G0_7_0 + 0.000172795954045982*G0_7_1 + 0.000455169830169906*G0_7_2 - 0.000227584915084957*G0_7_3 - 0.000568962287712381*G0_7_4 - 0.00136550949050972*G0_7_6 + 0.0144137112887137*G0_7_7 - 0.00174481768231797*G0_7_8 + 0.00273101898101944*G0_7_9 - 0.000400380869130936*G0_8_0 + 0.000143896282289164*G0_8_1 + 9.21177037248623e-05*G0_8_2 + 0.00050393802625954*G0_8_3 - 0.000276353111174586*G0_8_4 + 0.00136550949050972*G0_8_5 - 0.00174481768231797*G0_8_7 + 0.00223791833166871*G0_8_8 + 0.00136550949050972*G0_8_9 - 0.000270934422720182*G0_9_1 + 0.000270934422720182*G0_9_2 + 0.00126797309833045*G0_9_3 - 0.00126797309833046*G0_9_4 - 0.00273101898101944*G0_9_5 - 0.00136550949050972*G0_9_6 + 0.00273101898101944*G0_9_7 + 0.00136550949050972*G0_9_8; + A[3] = A[30]; + A[12] = A[21]; + A[49] = A[94]; + A[33] = A[55] - 0.000777682139289414*G0_0_0 - 0.000117705954759546*G0_0_2 + 0.000807384579706146*G0_0_3 - 0.000138176555587293*G0_0_4 - 0.0015247587234197*G0_0_5 + 0.000678841248037792*G0_0_6 - 0.000714965837733815*G0_0_7 + 0.000610806604110278*G0_0_8 + 0.000482263272441925*G0_0_9 + 0.000777682139289414*G0_1_1 + 0.000117705954759546*G0_1_2 + 0.0015247587234197*G0_1_3 - 0.000678841248037792*G0_1_4 - 0.000807384579706144*G0_1_5 + 0.000138176555587293*G0_1_6 - 0.000610806604110279*G0_1_7 + 0.000714965837733816*G0_1_8 - 0.000482263272441924*G0_1_9 - 0.000117705954759546*G0_2_0 + 0.000117705954759546*G0_2_1 + 0.000636394855144963*G0_2_3 - 0.000160152347652375*G0_2_4 - 0.000636394855144962*G0_2_5 + 0.000160152347652374*G0_2_6 - 0.000506647370486742*G0_2_7 + 0.000506647370486741*G0_2_8 + 0.000807384579706146*G0_3_0 + 0.0015247587234197*G0_3_1 + 0.000636394855144964*G0_3_2 + 0.0168846332239218*G0_3_3 - 0.00292338242115078*G0_3_4 - 0.000414529666761878*G0_3_6 - 0.00242215373911844*G0_3_7 + 0.00394209585057866*G0_3_8 + 0.00629109729556264*G0_3_9 - 0.000138176555587293*G0_4_0 - 0.000678841248037792*G0_4_1 - 0.000160152347652375*G0_4_2 - 0.00292338242115078*G0_4_3 + 0.00223791833166871*G0_4_4 + 0.00041452966676188*G0_4_5 + 0.000967235889111052*G0_4_7 - 0.00151994211146022*G0_4_8 - 0.000829059333523759*G0_4_9 - 0.0015247587234197*G0_5_0 - 0.000807384579706144*G0_5_1 - 0.000636394855144962*G0_5_2 + 0.00041452966676188*G0_5_4 - 0.0168846332239218*G0_5_5 + 0.00292338242115077*G0_5_6 - 0.00394209585057865*G0_5_7 + 0.00242215373911843*G0_5_8 - 0.00629109729556264*G0_5_9 + 0.000678841248037792*G0_6_0 + 0.000138176555587293*G0_6_1 + 0.000160152347652374*G0_6_2 - 0.000414529666761878*G0_6_3 + 0.00292338242115077*G0_6_5 - 0.00223791833166871*G0_6_6 + 0.00151994211146022*G0_6_7 - 0.000967235889111052*G0_6_8 + 0.000829059333523759*G0_6_9 - 0.000714965837733815*G0_7_0 - 0.000610806604110279*G0_7_1 - 0.000506647370486742*G0_7_2 - 0.00242215373911844*G0_7_3 + 0.000967235889111052*G0_7_4 - 0.00394209585057865*G0_7_5 + 0.00151994211146022*G0_7_6 - 0.00196698390894852*G0_7_7 - 0.00448667404024622*G0_7_9 + 0.000610806604110278*G0_8_0 + 0.000714965837733816*G0_8_1 + 0.000506647370486741*G0_8_2 + 0.00394209585057866*G0_8_3 - 0.00151994211146022*G0_8_4 + 0.00242215373911843*G0_8_5 - 0.000967235889111052*G0_8_6 + 0.00196698390894853*G0_8_8 + 0.00448667404024622*G0_8_9 + 0.000482263272441925*G0_9_0 - 0.000482263272441924*G0_9_1 + 0.00629109729556264*G0_9_3 - 0.000829059333523759*G0_9_4 - 0.00629109729556264*G0_9_5 + 0.000829059333523759*G0_9_6 - 0.00448667404024622*G0_9_7 + 0.00448667404024622*G0_9_8; + A[29] = A[92]; + A[81] = -A[21] - 1.83212125176441e-05*G0_0_0 + 7.72082580118427e-05*G0_0_1 + 5.78550913372441e-05*G0_0_3 - 3.07504995005047e-05*G0_0_4 - 1.36916654773821e-05*G0_0_5 - 9.18612637362793e-05*G0_0_7 + 0.000177266929499102*G0_0_8 + 2.27451120308302e-05*G0_0_9 + 7.72082580118427e-05*G0_1_0 + 0.000764730061605193*G0_1_1 + 6.52534469498866e-05*G0_1_2 + 0.000498954170829256*G0_1_3 - 0.000239291958041999*G0_1_4 - 4.41299771656993e-05*G0_1_5 - 2.86097830740735e-05*G0_1_6 - 0.000379542332667397*G0_1_7 + 0.000905890984016138*G0_1_8 + 0.000151723276723303*G0_1_9 + 6.52534469498866e-05*G0_2_1 + 7.27992245849511e-05*G0_2_2 + 2.83310439560488e-05*G0_2_3 + 5.23137576709094e-05*G0_2_4 - 3.57566540602315e-05*G0_2_5 + 6.34856215213465e-05*G0_2_6 - 5.94829277865092e-05*G0_2_7 + 5.63833487940725e-05*G0_2_8 - 2.00692164977974e-07*G0_2_9 + 5.78550913372441e-05*G0_3_0 + 0.000498954170829256*G0_3_1 + 2.83310439560488e-05*G0_3_2 + 0.000636394855144964*G0_3_3 - 0.000321809886542084*G0_3_4 + 2.29792528899709e-05*G0_3_5 - 1.30449907235644e-06*G0_3_6 - 0.000260699122306309*G0_3_7 + 0.000516983016983104*G0_3_8 + 6.62284144427113e-05*G0_3_9 - 3.07504995005047e-05*G0_4_0 - 0.000239291958041999*G0_4_1 + 5.23137576709094e-05*G0_4_2 - 0.000321809886542084*G0_4_3 + 0.000225477647352686*G0_4_4 + 5.1176502069368e-06*G0_4_5 - 3.81315113458035e-06*G0_4_6 + 0.00017891706507781*G0_4_7 - 0.000256283894676795*G0_4_8 - 9.63322391893957e-06*G0_4_9 - 1.36916654773821e-05*G0_5_0 - 4.41299771656993e-05*G0_5_1 - 3.57566540602315e-05*G0_5_2 + 2.29792528899709e-05*G0_5_3 + 5.1176502069368e-06*G0_5_4 - 0.000196276937348399*G0_5_5 + 2.27785607249931e-05*G0_5_6 - 0.000136571018267469*G0_5_7 + 4.52560832025187e-05*G0_5_8 - 0.000158747502497529*G0_5_9 - 2.86097830740735e-05*G0_6_1 + 6.34856215213465e-05*G0_6_2 - 1.30449907235645e-06*G0_6_3 - 3.81315113458035e-06*G0_6_4 + 2.27785607249931e-05*G0_6_5 - 7.63633687740958e-05*G0_6_6 + 9.13149350649503e-05*G0_6_7 + 1.9065755672905e-06*G0_6_8 + 3.21107463964682e-06*G0_6_9 - 9.18612637362793e-05*G0_7_0 - 0.000379542332667397*G0_7_1 - 5.94829277865092e-05*G0_7_2 - 0.000260699122306309*G0_7_3 + 0.00017891706507781*G0_7_4 - 0.000136571018267469*G0_7_5 + 9.13149350649503e-05*G0_7_6 - 5.23806550592346e-05*G0_7_7 - 0.000696702850720826*G0_7_8 - 0.000250865206222391*G0_7_9 + 0.000177266929499103*G0_8_0 + 0.000905890984016138*G0_8_1 + 5.63833487940725e-05*G0_8_2 + 0.000516983016983104*G0_8_3 - 0.000256283894676795*G0_8_4 + 4.52560832025187e-05*G0_8_5 + 1.9065755672905e-06*G0_8_6 - 0.000696702850720826*G0_8_7 + 0.0014483953546456*G0_8_8 + 5.73979591836824e-05*G0_8_9 + 2.27451120308302e-05*G0_9_0 + 0.000151723276723303*G0_9_1 - 2.00692164977963e-07*G0_9_2 + 6.62284144427113e-05*G0_9_3 - 9.63322391893957e-06*G0_9_4 - 0.000158747502497529*G0_9_5 + 3.21107463964685e-06*G0_9_6 - 0.000250865206222391*G0_9_7 + 5.73979591836824e-05*G0_9_8 - 0.000989813757671068*G0_9_9; + A[44] = A[33] - 2.50865206222408e-06*G0_0_1 + 2.50865206222387e-06*G0_0_2 - 0.000869699496931787*G0_0_3 + 0.000869699496931786*G0_0_4 - 0.000117404916512079*G0_0_5 + 0.000332346225203424*G0_0_6 + 0.000117404916512079*G0_0_7 - 0.000332346225203424*G0_0_8 - 2.5086520622241e-06*G0_1_0 - 0.000629370629370736*G0_1_1 - 0.00149826735764261*G0_1_3 + 0.0011839834272872*G0_1_4 - 0.000154432620950504*G0_1_5 + 0.000276353111174586*G0_1_6 + 0.0001472077030113*G0_1_7 - 0.000410917207792278*G0_1_8 + 0.000211328849721741*G0_1_9 + 2.50865206222389e-06*G0_2_0 + 0.000629370629370735*G0_2_2 - 0.0011839834272872*G0_2_3 + 0.00149826735764261*G0_2_4 - 0.000147207703011299*G0_2_5 + 0.000410917207792277*G0_2_6 + 0.000154432620950504*G0_2_7 - 0.000276353111174586*G0_2_8 - 0.000211328849721743*G0_2_9 - 0.000869699496931787*G0_3_0 - 0.00149826735764261*G0_3_1 - 0.0011839834272872*G0_3_2 - 0.0141427768659935*G0_3_3 + 0.00153619817682344*G0_3_5 - 0.00082905933352376*G0_3_6 + 0.00260909849079536*G0_3_7 - 0.00343815782431912*G0_3_8 - 0.00585218353075594*G0_3_9 + 0.000869699496931787*G0_4_0 + 0.0011839834272872*G0_4_1 + 0.00149826735764261*G0_4_2 + 0.0141427768659935*G0_4_4 - 0.00260909849079536*G0_4_5 + 0.00343815782431912*G0_4_6 - 0.00153619817682344*G0_4_7 + 0.00082905933352376*G0_4_8 + 0.00585218353075594*G0_4_9 - 0.000117404916512079*G0_5_0 - 0.000154432620950504*G0_5_1 - 0.000147207703011299*G0_5_2 + 0.00153619817682344*G0_5_3 - 0.00260909849079536*G0_5_4 + 0.00050393802625954*G0_5_5 - 0.0011785647388328*G0_5_6 + 0.000463297862851512*G0_5_8 - 0.000926595725703026*G0_5_9 + 0.000332346225203424*G0_6_0 + 0.000276353111174586*G0_6_1 + 0.000410917207792277*G0_6_2 - 0.00082905933352376*G0_6_3 + 0.00343815782431912*G0_6_4 - 0.0011785647388328*G0_6_5 + 0.00196698390894853*G0_6_6 - 0.000463297862851513*G0_6_7 + 0.00229210521621275*G0_6_9 + 0.000117404916512079*G0_7_0 + 0.0001472077030113*G0_7_1 + 0.000154432620950504*G0_7_2 + 0.00260909849079536*G0_7_3 - 0.00153619817682344*G0_7_4 - 0.000463297862851513*G0_7_6 - 0.00050393802625954*G0_7_7 + 0.00117856473883279*G0_7_8 + 0.000926595725703023*G0_7_9 - 0.000332346225203424*G0_8_0 - 0.000410917207792278*G0_8_1 - 0.000276353111174586*G0_8_2 - 0.00343815782431912*G0_8_3 + 0.00082905933352376*G0_8_4 + 0.000463297862851512*G0_8_5 + 0.00117856473883279*G0_8_7 - 0.00196698390894852*G0_8_8 - 0.00229210521621274*G0_8_9 + 0.000211328849721741*G0_9_1 - 0.000211328849721743*G0_9_2 - 0.00585218353075594*G0_9_3 + 0.00585218353075595*G0_9_4 - 0.000926595725703026*G0_9_5 + 0.00229210521621275*G0_9_6 + 0.000926595725703023*G0_9_7 - 0.00229210521621274*G0_9_8; + A[63] = A[36]; + A[0] = A[21] + 0.00153963843696013*G0_0_0 + 6.72826677291077e-05*G0_0_1 + 6.72826677291077e-05*G0_0_2 + 0.000686244559012533*G0_0_5 - 0.000325243952476151*G0_0_6 + 0.000686244559012532*G0_0_7 - 0.00032524395247615*G0_0_8 + 9.12480376766247e-05*G0_0_9 + 6.72826677291078e-05*G0_1_0 - 5.76965197501009e-05*G0_1_1 - 9.58614797900676e-06*G0_1_2 - 7.16917011559991e-05*G0_1_3 + 2.37708719851617e-05*G0_1_4 + 5.02176395033622e-05*G0_1_5 - 1.65794027401198e-05*G0_1_6 + 8.82711038961187e-05*G0_1_7 - 7.3988511488524e-05*G0_1_8 + 6.72826677291077e-05*G0_2_0 - 9.58614797900676e-06*G0_2_1 - 5.76965197501009e-05*G0_2_2 + 2.37708719851617e-05*G0_2_3 - 7.1691701155999e-05*G0_2_4 + 8.82711038961189e-05*G0_2_5 - 7.3988511488524e-05*G0_2_6 + 5.02176395033622e-05*G0_2_7 - 1.65794027401198e-05*G0_2_8 - 7.16917011559991e-05*G0_3_1 + 2.37708719851617e-05*G0_3_2 - 9.35225488797077e-05*G0_3_3 + 6.48235692878661e-05*G0_3_4 - 3.35155915513117e-05*G0_3_5 + 4.11418938204731e-06*G0_3_6 - 7.62630226916102e-06*G0_3_7 + 3.51211288711361e-06*G0_3_8 + 1.52526045383213e-05*G0_3_9 + 2.37708719851617e-05*G0_4_1 - 7.1691701155999e-05*G0_4_2 + 6.48235692878661e-05*G0_4_3 - 9.35225488797077e-05*G0_4_4 - 7.6263022691607e-06*G0_4_5 + 3.51211288711349e-06*G0_4_6 - 3.35155915513114e-05*G0_4_7 + 4.11418938204716e-06*G0_4_8 + 1.52526045383214e-05*G0_4_9 + 0.000686244559012533*G0_5_0 + 5.02176395033622e-05*G0_5_1 + 8.82711038961189e-05*G0_5_2 - 3.35155915513117e-05*G0_5_3 - 7.6263022691607e-06*G0_5_4 + 0.000801865545169253*G0_5_5 - 0.000303546899529094*G0_5_6 + 0.000392553874696797*G0_5_7 - 0.000196276937348399*G0_5_8 + 0.000118809761666924*G0_5_9 - 0.000325243952476151*G0_6_0 - 1.65794027401198e-05*G0_6_1 - 7.3988511488524e-05*G0_6_2 + 4.11418938204732e-06*G0_6_3 + 3.51211288711349e-06*G0_6_4 - 0.000303546899529094*G0_6_5 + 0.000169986263736293*G0_6_6 - 0.000196276937348399*G0_6_7 + 7.25502176395155e-05*G0_6_8 - 8.22837876409443e-06*G0_6_9 + 0.000686244559012532*G0_7_0 + 8.82711038961187e-05*G0_7_1 + 5.02176395033622e-05*G0_7_2 - 7.62630226916102e-06*G0_7_3 - 3.35155915513114e-05*G0_7_4 + 0.000392553874696797*G0_7_5 - 0.000196276937348399*G0_7_6 + 0.000801865545169251*G0_7_7 - 0.000303546899529093*G0_7_8 + 0.000118809761666924*G0_7_9 - 0.00032524395247615*G0_8_0 - 7.3988511488524e-05*G0_8_1 - 1.65794027401198e-05*G0_8_2 + 3.51211288711361e-06*G0_8_3 + 4.11418938204715e-06*G0_8_4 - 0.000196276937348399*G0_8_5 + 7.25502176395155e-05*G0_8_6 - 0.000303546899529093*G0_8_7 + 0.000169986263736292*G0_8_8 - 8.22837876409433e-06*G0_8_9 + 9.12480376766247e-05*G0_9_0 + 1.52526045383213e-05*G0_9_3 + 1.52526045383214e-05*G0_9_4 + 0.000118809761666924*G0_9_5 - 8.22837876409445e-06*G0_9_6 + 0.000118809761666924*G0_9_7 - 8.22837876409434e-06*G0_9_8 + 0.000399778792636003*G0_9_9; + A[79] = A[97]; + A[38] = A[83]; + A[20] = A[2]; + A[18] = A[81]; + A[88] = A[77] - 0.000629370629370735*G0_0_0 - 2.50865206222384e-06*G0_0_2 + 0.000276353111174587*G0_0_3 - 0.000154432620950504*G0_0_4 - 0.000410917207792277*G0_0_5 + 0.000147207703011299*G0_0_6 - 0.00149826735764261*G0_0_7 + 0.0011839834272872*G0_0_8 + 0.000211328849721742*G0_0_9 + 0.000629370629370736*G0_1_1 + 2.50865206222389e-06*G0_1_2 + 0.000410917207792277*G0_1_3 - 0.000147207703011299*G0_1_4 - 0.000276353111174586*G0_1_5 + 0.000154432620950504*G0_1_6 - 0.0011839834272872*G0_1_7 + 0.00149826735764261*G0_1_8 - 0.000211328849721743*G0_1_9 - 2.50865206222385e-06*G0_2_0 + 2.50865206222389e-06*G0_2_1 + 0.000332346225203424*G0_2_3 - 0.000117404916512079*G0_2_4 - 0.000332346225203424*G0_2_5 + 0.000117404916512079*G0_2_6 - 0.000869699496931785*G0_2_7 + 0.000869699496931786*G0_2_8 + 0.000276353111174587*G0_3_0 + 0.000410917207792277*G0_3_1 + 0.000332346225203424*G0_3_2 + 0.00196698390894852*G0_3_3 - 0.00117856473883279*G0_3_4 - 0.000463297862851513*G0_3_6 - 0.000829059333523756*G0_3_7 + 0.00343815782431911*G0_3_8 + 0.00229210521621275*G0_3_9 - 0.000154432620950504*G0_4_0 - 0.000147207703011299*G0_4_1 - 0.000117404916512079*G0_4_2 - 0.00117856473883279*G0_4_3 + 0.000503938026259539*G0_4_4 + 0.000463297862851513*G0_4_5 + 0.00153619817682343*G0_4_7 - 0.00260909849079536*G0_4_8 - 0.000926595725703026*G0_4_9 - 0.000410917207792277*G0_5_0 - 0.000276353111174586*G0_5_1 - 0.000332346225203424*G0_5_2 + 0.000463297862851513*G0_5_4 - 0.00196698390894852*G0_5_5 + 0.00117856473883279*G0_5_6 - 0.00343815782431911*G0_5_7 + 0.000829059333523755*G0_5_8 - 0.00229210521621274*G0_5_9 + 0.000147207703011299*G0_6_0 + 0.000154432620950504*G0_6_1 + 0.000117404916512079*G0_6_2 - 0.000463297862851513*G0_6_3 + 0.00117856473883279*G0_6_5 - 0.000503938026259539*G0_6_6 + 0.00260909849079536*G0_6_7 - 0.00153619817682343*G0_6_8 + 0.000926595725703023*G0_6_9 - 0.00149826735764261*G0_7_0 - 0.0011839834272872*G0_7_1 - 0.000869699496931785*G0_7_2 - 0.000829059333523756*G0_7_3 + 0.00153619817682343*G0_7_4 - 0.00343815782431911*G0_7_5 + 0.00260909849079536*G0_7_6 - 0.0141427768659935*G0_7_7 - 0.00585218353075594*G0_7_9 + 0.0011839834272872*G0_8_0 + 0.00149826735764261*G0_8_1 + 0.000869699496931786*G0_8_2 + 0.00343815782431911*G0_8_3 - 0.00260909849079536*G0_8_4 + 0.000829059333523755*G0_8_5 - 0.00153619817682343*G0_8_6 + 0.0141427768659936*G0_8_8 + 0.00585218353075595*G0_8_9 + 0.000211328849721742*G0_9_0 - 0.000211328849721743*G0_9_1 + 0.00229210521621275*G0_9_3 - 0.000926595725703026*G0_9_4 - 0.00229210521621274*G0_9_5 + 0.000926595725703023*G0_9_6 - 0.00585218353075594*G0_9_7 + 0.00585218353075595*G0_9_8; + A[43] = A[34]; + A[95] = A[59]; + A[52] = A[25]; + } + + /// 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 mass_matrix_f2_p3_q3_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p3_q3_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p3_q3_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1))), 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 mass_matrix_f2_p3_q3_tensor_finite_element_0(); + break; + } + case 1: + { + return new mass_matrix_f2_p3_q3_tensor_finite_element_0(); + break; + } + case 2: + { + return new mass_matrix_f2_p3_q3_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p3_q3_tensor_finite_element_0(); + 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 mass_matrix_f2_p3_q3_tensor_dofmap_0(); + break; + } + case 1: + { + return new mass_matrix_f2_p3_q3_tensor_dofmap_0(); + break; + } + case 2: + { + return new mass_matrix_f2_p3_q3_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p3_q3_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f2_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/mass_matrix_2d/mass_matrix_f2_p3_q4_excafe.h b/mass_matrix_2d/mass_matrix_f2_p3_q4_excafe.h new file mode 100644 index 0000000..a6991d9 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p3_q4_excafe.h @@ -0,0 +1,1105 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 165 minutes and 31.60 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 = -1.0000000000000000000000000*x[0][1]; + const double var_1 = var_0 + x[1][1]; + const double var_2 = -1.0000000000000000000000000*x[0][0]; + const double var_3 = var_2 + x[2][0]; + const double var_4 = x[2][1] + var_0; + const double var_5 = var_2 + x[1][0]; + const double var_6 = -1.0000000000000000000000000*var_1*var_3 + var_4*var_5; + const double var_7 = std::abs(var_6); + const double var_8 = w[0][8]*w[1][0] + w[0][0]*w[1][8]; + const double var_9 = w[0][1]*w[1][7] + w[0][7]*w[1][1]; + const double var_10 = w[0][2]*w[1][5] + w[0][5]*w[1][2]; + const double var_11 = w[0][3]*w[1][2] + w[0][2]*w[1][3]; + const double var_12 = w[0][1]*w[1][4] + w[0][4]*w[1][1]; + const double var_13 = w[0][6]*w[1][0] + w[0][0]*w[1][6]; + const double var_14 = w[0][8]*w[1][2] + w[0][2]*w[1][8]; + const double var_15 = w[0][4]*w[1][0] + w[0][0]*w[1][4]; + const double var_16 = w[0][2]*w[1][7] + w[0][7]*w[1][2]; + const double var_17 = w[0][6]*w[1][1] + w[0][1]*w[1][6]; + const double var_18 = w[0][1]*w[1][5] + w[0][5]*w[1][1]; + const double var_19 = w[0][0]*w[1][3] + w[0][3]*w[1][0]; + const double var_20 = w[0][2]*w[1][6] + w[0][6]*w[1][2]; + const double var_21 = w[0][1]*w[1][8] + w[0][8]*w[1][1]; + const double var_22 = w[0][5]*w[1][0] + w[0][0]*w[1][5]; + const double var_23 = w[0][1]*w[1][3] + w[0][3]*w[1][1]; + const double var_24 = w[0][8]*w[1][5] + w[0][5]*w[1][8]; + const double var_25 = w[0][7]*w[1][6] + w[0][6]*w[1][7]; + const double var_26 = w[0][6]*w[1][3] + w[0][3]*w[1][6]; + const double var_27 = w[0][5]*w[1][4] + w[0][4]*w[1][5]; + const double var_28 = w[0][4]*w[1][8] + w[0][8]*w[1][4]; + const double var_29 = w[0][9]*w[1][3] + w[0][3]*w[1][9]; + const double var_30 = w[0][6]*w[1][9] + w[0][9]*w[1][6]; + const double var_31 = w[0][8]*w[1][9] + w[0][9]*w[1][8]; + const double var_32 = w[0][7]*w[1][9] + w[0][9]*w[1][7]; + const double var_33 = w[0][5]*w[1][9] + w[0][9]*w[1][5]; + const double var_34 = w[0][8]*w[1][8]; + const double var_35 = -1.0000000000000000000000000*var_34; + const double var_36 = w[0][5]*w[1][5]; + const double var_37 = -1.0000000000000000000000000*var_36; + const double var_38 = w[0][0]*w[1][7] + w[0][7]*w[1][0]; + const double var_39 = -1.0000000000000000000000000*var_38; + const double var_40 = w[0][2]*w[1][0] + w[0][0]*w[1][2]; + const double var_41 = w[0][6]*w[1][5] + w[0][5]*w[1][6]; + const double var_42 = w[0][7]*w[1][4] + w[0][4]*w[1][7]; + const double var_43 = w[0][1]*w[1][9] + w[0][9]*w[1][1]; + const double var_44 = -1.0000000000000000000000000*var_43; + const double var_45 = w[0][3]*w[1][8] + w[0][8]*w[1][3]; + const double var_46 = -1.0000000000000000000000000*var_45; + const double var_47 = 9.0000000000000000000000000*w[0][9]*w[1][9]; + const double var_48 = -0.0000599400599400599400080*var_47; + const double var_49 = 43.0000000000000000000000000*w[0][1]*w[1][1]; + const double var_50 = 0.0000649350649350649350086*var_42 + 0.0010406260406260407335582*var_41 + 0.0000732600732600732600097*var_44 + 0.0000008633341966675299531*var_49 + 0.0000699300699300699300093*var_46 + -0.0000659217325883992535029*var_40 + var_48; + const double var_51 = w[0][9]*w[1][0] + w[0][0]*w[1][9]; + const double var_52 = w[0][2]*w[1][1] + w[0][1]*w[1][2]; + const double var_53 = w[0][6]*w[1][8] + w[0][8]*w[1][6]; + const double var_54 = w[0][3]*w[1][4] + w[0][4]*w[1][3]; + const double var_55 = w[0][5]*w[1][7] + w[0][7]*w[1][5]; + const double var_56 = 0.0004778554778554778550634*var_54 + -0.0000407205962761518296643*var_52 + 0.0001115551115551115550148*var_53 + -0.0001642801642801642800218*var_51 + -0.0001235801235801235980864*w[0][0]*w[1][0] + -0.0002430902430902430900322*var_55; + const double var_57 = w[0][9]*w[1][2] + w[0][2]*w[1][9]; + const double var_58 = w[0][0]*w[1][1] + w[0][1]*w[1][0]; + const double var_59 = w[0][7]*w[1][8] + w[0][8]*w[1][7]; + const double var_60 = w[0][4]*w[1][6] + w[0][6]*w[1][4]; + const double var_61 = w[0][3]*w[1][5] + w[0][5]*w[1][3]; + const double var_62 = -1.0000000000000000000000000*var_61; + const double var_63 = -0.0001309801309801309800174*var_57 + -0.0003467725689947911906115*w[0][2]*w[1][2] + -0.0011621711621711621701541*var_60 + -0.0000257150257150257172622*var_58 + 0.0002680652680652680650356*var_62 + 0.0001548451548451548450205*var_59; + const double var_64 = w[0][2]*w[1][4] + w[0][4]*w[1][2]; + const double var_65 = w[0][4]*w[1][9] + w[0][9]*w[1][4]; + const double var_66 = w[0][7]*w[1][3] + w[0][3]*w[1][7]; + const double var_67 = -1.0000000000000000000000000*var_66; + const double var_68 = -0.0005694305694305694300755*var_65 + 0.0000249750249750249750033*var_67 + -0.0003570503570503570319773*var_64; + const double var_69 = 0.0001748251748251748250232*var_35 + 0.0001790801790801790709887*var_11 + -0.0001206201206201206290510*var_13 + 0.0000299700299700299700040*var_31 + -0.0001655751655751655569519*var_17 + -0.0009690309690309690301285*var_30 + -0.0009207459207459207451221*w[0][4]*w[1][4] + 0.0000899100899100899100119*var_32 + 0.0000828800828800828754935*var_21 + 0.0001824101824101824280942*var_10 + 0.0001061901061901061854966*var_23 + var_63 + 0.0004811854811854811850638*var_27 + 0.0000416250416250416250055*var_24 + -0.0000917600917600917690472*var_22 + 0.0004095904095904095900543*var_33 + -0.0002047952047952047950272*w[0][7]*w[1][7] + var_50 + 0.0001443001443001443000191*var_39 + var_68 + 0.0000949050949050949050126*var_28 + 0.0000799200799200799200106*var_8 + var_56 + -0.0028854478854478853369625*w[0][6]*w[1][6] + -0.0000514300514300514345243*var_9 + -0.0001369001369001368909831*var_12 + 0.0004578754578754578750607*var_37 + -0.0004847004847004846819943*var_20 + 0.0006809856809856809850903*var_26 + 0.0000697450697450697495268*var_19 + 0.0002697302697302697300358*var_29 + 0.0002014652014652014650267*var_25 + -0.0000057350057350057355654*var_16 + -0.0000989750989750989704956*var_15 + 0.0000297850297850297827452*var_14 + 0.0000475450475450475495238*var_18 + -0.0002214452214452214450294*w[0][3]*w[1][3]; + A[23] = 0.1428571428571428492126927*var_69*var_7; + const double var_70 = 0.0001027543884686741789986*var_30; + const double var_71 = -1.0000000000000000000000000*var_14; + const double var_72 = var_71 + var_24; + const double var_73 = -1.0000000000000000000000000*var_28; + const double var_74 = var_25 + var_73; + const double var_75 = var_15 + var_16; + const double var_76 = -1.0000000000000000000000000*var_30; + const double var_77 = -1.0000000000000000000000000*var_33; + const double var_78 = var_76 + var_77; + const double var_79 = -1.0000000000000000000000000*var_42; + const double var_80 = var_79 + 4.0000000000000000000000000*var_46; + const double var_81 = w[0][4]*w[1][4]; + const double var_82 = -1.0000000000000000000000000*var_81; + const double var_83 = w[0][7]*w[1][7]; + const double var_84 = -1.0000000000000000000000000*var_83; + const double var_85 = var_84 + var_82; + const double var_86 = 2.0000000000000000000000000*var_85 + var_41; + const double var_87 = 0.0071928071928071928009540*var_78 + 0.0023976023976023976003180*var_44 + 0.0011988011988011988001590*var_86 + 0.0017982017982017982002385*var_80 + 0.0003996003996003996000530*var_75; + const double var_88 = var_30 + var_31; + const double var_89 = var_18 + var_17; + const double var_90 = var_57 + var_43; + const double var_91 = w[0][6]*w[1][6]; + const double var_92 = var_34 + var_91; + const double var_93 = -1.0000000000000000000000000*var_27; + const double var_94 = var_67 + var_93; + const double var_95 = -1.0000000000000000000000000*var_29; + const double var_96 = -1.0000000000000000000000000*var_65; + const double var_97 = var_95 + var_96; + const double var_98 = 3.0000000000000000000000000*w[0][9]*w[1][9]; + const double var_99 = 8.0000000000000000000000000*var_98; + const double var_100 = -1.0000000000000000000000000*var_51; + const double var_101 = var_45 + var_60; + const double var_102 = var_100 + var_101; + const double var_103 = var_97 + 2.0000000000000000000000000*var_92 + var_94 + var_102 + var_99 + var_90; + const double var_104 = -0.0012330526616240902564037*w[0][9]*w[1][9]; + const double var_105 = w[0][1]*w[1][1]; + const double var_106 = 0.0001741116026830312620531*var_42 + 0.0015812758669901526720897*var_41 + -0.0000247371675943104528839*var_105 + 0.0001332001332001332000177*var_44 + 0.0000742115027829313484873*var_46 + -0.0001444058586915729900692*var_40 + var_104; + const double var_107 = -1.0000000000000000000000000*var_25; + const double var_108 = -1.0000000000000000000000000*var_26; + const double var_109 = -1.0000000000000000000000000*var_32; + const double var_110 = -1.0000000000000000000000000*var_22; + const double var_111 = -1.0000000000000000000000000*var_59; + const double var_112 = 0.0004795204795204795200636*var_98; + const double var_113 = 0.0002264402264402264400300*var_111 + 0.0005994005994005994000795*var_61 + 0.0003196803196803196800424*var_57 + var_112 + 0.0026373626373626373603498*var_60 + 0.0008633341966675300242079*w[0][2]*w[1][2] + 0.0000498267164933831585008*var_58; + const double var_114 = -1.0000000000000000000000000*var_53; + const double var_115 = -1.0000000000000000000000000*var_54; + const double var_116 = 0.0003862803862803862800512*var_114 + 0.0013320013320013320001767*var_115 + 0.0001147823370045592141333*var_52 + 0.0002575202575202575200342*var_51 + 0.0000606800606800606822668*w[0][0]*w[1][0] + 0.0001332001332001332000177*var_55; + const double var_117 = -1.0000000000000000000000000*var_41; + const double var_118 = 0.0004528804528804528800601*var_45 + 0.0019980019980019980002650*var_117 + 0.0002042402042402042400271*var_43 + 0.0000955423177645399831657*w[0][1]*w[1][1] + 0.0001302401302401302309823*var_40 + 0.0000666000666000666000088*var_79; + const double var_119 = var_9 + var_16; + const double var_120 = 2.0000000000000000000000000*var_30; + const double var_121 = var_120 + var_93; + const double var_122 = -1.0000000000000000000000000*var_8; + const double var_123 = 2.0000000000000000000000000*var_38 + var_122; + const double var_124 = var_71 + var_123; + const double var_125 = 1.9428571428571428381104624*w[0][3]*w[1][3]; + const double var_126 = 2.0000000000000000000000000*var_65; + const double var_127 = 2.0000000000000000000000000*var_31; + const double var_128 = var_116 + -0.0003981203981203981561929*var_11 + 0.0003996003996003996000530*var_13 + 0.0001021201021201021200135*var_110 + 0.0023043623043623043603056*w[0][4]*w[1][4] + 0.0003892403892403892761917*var_17 + 0.0000799200799200799200106*var_127 + 0.0000562400562400562422662*var_21 + -0.0005224405224405224762094*var_10 + -0.0000458800458800458845236*var_23 + 0.0003196803196803196800424*var_109 + 0.0000932400932400932400124*var_24 + 0.0005994005994005994000795*var_126 + 0.0015584415584415584402067*var_108 + -0.0009590409590409590401272*var_33 + 0.0000666000666000666000088*var_67 + var_118 + var_113 + 0.0060339660339660339608003*w[0][6]*w[1][6] + 0.0004795204795204795200636*var_95 + 0.0000014800014800014800708*var_124 + -0.0000547600547600547645248*var_119 + 0.0002338402338402338490660*var_12 + 0.0006393606393606393600848*w[0][5]*w[1][5] + 0.0011914011914011914724382*var_20 + -0.0001080401080401080445318*var_19 + 0.0001332001332001332000177*var_83 + 0.0008806008806008806723969*var_64 + 0.0002264402264402264400300*var_107 + 0.0010789210789210789201431*var_121 + 0.0002294002294002293819604*var_15 + 0.0006127206127206127200813*var_34 + 0.0003862803862803862800512*var_73 + 0.0004662004662004662000618*var_125 + -0.0001613201613201613380914*var_18; + const double var_129 = -1.0000000000000000000000000*var_24; + const double var_130 = -1.0000000000000000000000000*var_64; + const double var_131 = 0.0005994005994005994000795*var_42 + var_112 + 0.0026373626373626373603498*var_45 + 0.0003196803196803196800424*var_43 + 0.0002264402264402264400300*var_117 + 0.0008633341966675300242079*w[0][1]*w[1][1] + 0.0000498267164933831585008*var_40; + const double var_132 = 0.0013320013320013320001767*var_111 + 0.0002575202575202575200342*var_57 + 0.0001332001332001332000177*var_60 + 0.0000606800606800606822668*w[0][2]*w[1][2] + 0.0001147823370045592141333*var_58 + 0.0003862803862803862800512*var_62; + const double var_133 = 0.0000666000666000666000088*var_114 + 0.0019980019980019980002650*var_115 + 0.0001302401302401302309823*var_52 + 0.0000955423177645399831657*w[0][0]*w[1][0] + 0.0002042402042402042400271*var_51 + 0.0004528804528804528800601*var_55; + const double var_134 = var_17 + var_13; + const double var_135 = 2.0000000000000000000000000*var_29; + const double var_136 = var_135 + var_73; + const double var_137 = -1.0000000000000000000000000*var_18; + const double var_138 = -1.0000000000000000000000000*var_10; + const double var_139 = var_138 + 2.0000000000000000000000000*var_20; + const double var_140 = var_139 + var_137; + const double var_141 = 1.9428571428571428381104624*w[0][7]*w[1][7]; + const double var_142 = 2.0000000000000000000000000*var_33; + const double var_143 = 0.0003996003996003996000530*var_11 + -0.0000547600547600547645248*var_134 + 0.0005994005994005994000795*var_127 + 0.0006393606393606393600848*w[0][4]*w[1][4] + 0.0008806008806008806723969*var_21 + 0.0004795204795204795200636*var_109 + 0.0011914011914011914724382*var_23 + 0.0000932400932400932400124*var_27 + 0.0000562400562400562422662*var_22 + 0.0023043623043623043603056*w[0][8]*w[1][8] + 0.0002264402264402264400300*var_108 + 0.0000014800014800014800708*var_140 + 0.0001021201021201021200135*var_130 + 0.0003862803862803862800512*var_129 + 0.0001332001332001332000177*var_91 + 0.0015584415584415584402067*var_67 + var_131 + -0.0009590409590409590401272*var_65 + -0.0000458800458800458845236*var_38 + 0.0002338402338402338490660*var_8 + -0.0003981203981203981561929*var_9 + -0.0005224405224405224762094*var_12 + 0.0003892403892403892761917*var_19 + var_132 + 0.0003196803196803196800424*var_76 + -0.0001080401080401080445318*var_16 + 0.0000666000666000666000088*var_107 + -0.0001613201613201613380914*var_15 + 0.0002294002294002293819604*var_14 + var_133 + 0.0000799200799200799200106*var_142 + 0.0006127206127206127200813*var_36 + 0.0010789210789210789201431*var_136 + 0.0060339660339660339608003*w[0][3]*w[1][3] + 0.0004662004662004662000618*var_141; + A[54] = 0.2857142857142856984253854*var_143*var_7; + const double var_144 = w[0][3]*w[1][3]; + const double var_145 = -1.0000000000000000000000000*var_144; + const double var_146 = -1.0000000000000000000000000*var_23; + const double var_147 = -1.0000000000000000000000000*var_21; + const double var_148 = 0.0001213072641644070195086*var_47; + const double var_149 = -0.0002640216925931211720650*var_42 + -0.0002720493791922363232411*var_41 + 0.0001665001665001665000221*var_44 + 0.0006868131868131868668012*var_46 + var_148 + -0.0023726273726273725168945*w[0][1]*w[1][1] + 0.0000096794739651882502488*var_40; + const double var_150 = 0.0001480662194947909154896*var_61 + 0.0000011892869035726177968*var_57 + 0.0006324033109747394720487*var_60 + 0.0002169127169127169215638*w[0][2]*w[1][2] + -0.0001134667801334468030267*var_58 + 0.0003746253746253746250497*var_59; + const double var_151 = 0.0005619380619380619917846*var_54 + -0.0001495418162084828780315*var_52 + -0.0001079277864992150782943*var_53 + -0.0000029291695958362626886*w[0][0]*w[1][0] + 0.0000576804148232719612389*var_51 + 0.0000178393035535892673755*var_55; + const double var_152 = var_84 + var_77; + const double var_153 = -4.5000000000000000000000000*w[0][8]*w[1][8]; + const double var_154 = -0.0003127824556395984809815*var_11 + 0.0000720509649081077632521*var_13 + -0.0000963322391893820445053*var_32 + 0.0001193251193251193250158*var_17 + 0.0006047523904666762036703*var_30 + 0.0009098044812330525988806*w[0][4]*w[1][4] + -0.0000882054453483024930192*var_10 + 0.0000205151990866276556183*var_24 + -0.0000465804037232608680137*var_22 + var_149 + var_150 + 0.0001248751248751248750166*var_153 + 0.0002497502497502497500331*var_28 + 0.0006529185100613672191466*var_65 + 0.0000286419929277072138807*var_38 + -0.0000831509760081188632535*var_8 + var_151 + 0.0009722420436706150905989*w[0][6]*w[1][6] + 0.0004370629370629370625580*var_66 + 0.0003746253746253746250497*var_95 + 0.0005133755133755133750681*var_9 + 0.0024350649350649354422937*var_145 + 0.0008741258741258741251159*var_12 + 0.0001657073085644514059619*var_20 + -0.0003041601255886970363654*var_26 + 0.0003282431853860424898935*var_93 + -0.0001277492348920920503270*var_19 + 0.0002140716426430712220584*var_152 + -0.0000383545026402169229938*var_25 + 0.0000307232450089592985191*var_16 + 0.0003288378288378288375436*var_64 + 0.0010683760683760684835619*var_147 + 0.0017898767898767899836576*var_146 + 0.0001273528059242345032969*var_15 + -0.0000653116724545295992662*var_14 + 0.0001855287569573283779946*var_36 + 0.0000111000111000111000015*var_18; + A[19] = 0.2000000000000000111022302*var_154*var_7; + const double var_155 = 0.0009818752675895532720102*var_59 + 0.0000713572142143570695020*var_61; + const double var_156 = -1.0000000000000000000000000*var_13; + const double var_157 = -1.0000000000000000000000000*var_12; + const double var_158 = -1.0000000000000000000000000*var_57; + const double var_159 = 0.0011988011988011988001590*var_98; + const double var_160 = 0.0000599400599400599400080*var_111 + -0.0011388611388611388601511*var_61 + 0.0007992007992007992001060*var_158 + var_159 + -0.0020379620379620379602703*var_60 + -0.0011637744971078303919676*w[0][2]*w[1][2] + -0.0000717800717800717890445*var_58; + const double var_161 = 0.1111111111111111049432054*w[0][0]*w[1][0]; + const double var_162 = 0.0031968031968031968004240*var_54 + -0.0001593468260134926739978*var_52 + 0.0001798201798201798200239*var_53 + 0.0001998001998001998000265*var_51 + 0.0006371406371406371400845*var_161 + 0.0003596403596403596400477*var_55; + const double var_163 = 0.1111111111111111049432054*w[0][1]*w[1][1]; + const double var_164 = -0.0008547008547008547001134*var_163 + 0.0013186813186813186801749*var_41 + 0.0000399600399600399600053*var_46 + -0.0004129204129204129200548*var_43 + -0.0001766135099468432679767*var_40 + 0.0004595404595404595400610*var_79; + const double var_165 = var_38 + 0.5000000000000000000000000*var_122; + const double var_166 = var_28 + 0.6000000000000000888178420*var_129; + const double var_167 = var_76 + var_83; + const double var_168 = -4.5000000000000000000000000*w[0][6]*w[1][6]; + const double var_169 = var_31 + -2.0000000000000000000000000*var_32; + const double var_170 = 9.0000000000000000000000000*var_29 + var_37 + var_169; + const double var_171 = 0.0001198801198801198800159*var_35 + 0.0004817404817404817400639*var_11 + -0.0005794205794205794200769*w[0][4]*w[1][4] + -0.0002908202908202908200386*var_17 + 0.0003596403596403596400477*var_167 + -0.0001909201909201909200253*var_21 + 0.0007836607836607836601039*var_10 + 0.0004995004995004995000663*var_166 + -0.0002863802863802863800380*var_23 + 0.0006593406593406593400875*var_27 + 0.0003774003774003774000501*var_156 + 0.0002153402153402153400286*var_22 + var_160 + 0.0004662004662004662000618*var_157 + var_162 + var_164 + 0.0004595404595404595400610*var_67 + 0.0010789210789210789201431*var_65 + 0.0005194805194805194800689*var_168 + 0.0002397602397602397600318*var_170 + 0.0001887001887001887000250*var_119 + -0.0015473415473415473402052*var_20 + 0.0013786213786213786201829*var_26 + 0.0003219003219003219000427*var_19 + -0.0018093018093018093002400*var_64 + 0.0000599400599400599400080*var_107 + -0.0000510600510600510600068*var_15 + 0.0010389610389610389601378*var_144 + 0.0000022200022200022200003*var_14 + 0.0002686202686202686200356*var_18 + 0.0000488400488400488400065*var_165; + A[66] = 0.1428571428571428492126927*var_171*var_7; + A[94] = A[66]; + const double var_172 = 0.0123305266162409016966750*w[0][9]*w[1][9]; + const double var_173 = w[0][2]*w[1][2]; + const double var_174 = 0.0016269444840873411358556*var_111 + -0.0035107749393463675430249*var_61 + -0.0010846296560582274239037*var_57 + -0.0078778364492650201911239*var_60 + -0.0011988011988011988001590*var_173 + var_172 + -0.0001384858527715670519984*var_58; + const double var_175 = 0.0012844298558584272239302*var_42 + 0.0073640645069216496484965*var_41 + 0.0005137719423433708678881*var_45 + 0.0010275438846867417357761*var_43 + 0.0000486286200571914802352*w[0][1]*w[1][1] + -0.0000909143766286623299620*var_40; + const double var_176 = 0.0022263450834879407527755*var_100 + 0.0041958041958041958005565*var_54 + 0.0007706579135150563560422*var_114 + -0.0003372289086574801141548*var_52 + 0.0002812002812002811638972*w[0][0]*w[1][0] + 0.0030826316540602254241688*var_55; + const double var_177 = -1.0000000000000000000000000*var_31; + const double var_178 = 2.0000000000000000000000000*var_32; + const double var_179 = var_177 + var_178; + const double var_180 = var_28 + var_107; + const double var_181 = var_147 + 0.3333333333333333148296163*var_23; + const double var_182 = var_145 + var_34; + const double var_183 = 0.0013415156272299129120579*var_11 + -0.0020075162932305786953058*var_13 + -0.0001617430188858760169764*var_17 + -0.0160981875267589558120562*w[0][4]*w[1][4] + 0.0008087150944293801119872*var_10 + 0.0062508919651776788384279*var_27 + 0.0006184291898577613322621*var_22 + 0.0123305266162409016966750*var_33 + 0.0019980019980019980002650*var_130 + 0.0028257456828885401528551*var_129 + var_174 + 0.0006850292564578278238507*var_91 + 0.0035964035964035964004770*var_179 + 0.0007706579135150563560422*var_67 + var_175 + -0.0092478949621806767061871*var_65 + 0.0004566861709718852339705*var_181 + 0.0005137719423433708678881*var_38 + 0.0015413158270301127120844*var_95 + 0.0002568859711716854339440*var_180 + 0.0005423148280291137119519*var_9 + -0.0009038580467151895560599*var_12 + -0.0035298035298035298004682*var_20 + 0.0016269444840873411358556*var_26 + 0.0006374577803149231560245*var_19 + 0.0017125731411445697764673*var_182 + 0.0004662004662004662000618*var_16 + -0.0017030588459159886477456*var_15 + 0.0002949431520860091898890*var_14 + 0.0047952047952047952006360*var_36 + var_176 + 0.0013224870367727510882955*var_18 + 0.0000285428856857428271232*var_122 + 0.0029970029970029970003975*var_141; + const double var_184 = 0.1111111111111111049432054*w[0][2]*w[1][2]; + const double var_185 = 0.0000218828790257361705104*var_61 + 0.0000111000111000111000015*var_57 + 0.0000532800532800532800071*var_60 + 0.0018981018981018981002518*var_184 + -0.0000057643708437359238579*var_58 + 0.0000687407830264973160241*var_59; + const double var_186 = -1.0000000000000000000000000*var_98; + const double var_187 = 0.0000285428856857428271232*var_186; + const double var_188 = 0.0000366300366300366300049*var_114 + -0.0000290186004471718747501*var_54 + var_187 + 0.0000088976279452469916214*var_52 + -0.0000675456231011786501503*w[0][0]*w[1][0] + -0.0000183943041085898257637*var_51 + -0.0001315351315351315350174*var_55; + const double var_189 = w[0][0]*w[1][0]; + const double var_190 = var_189 + var_173; + const double var_191 = var_14 + var_19; + const double var_192 = var_22 + var_20; + const double var_193 = var_58 + var_52; + const double var_194 = var_23 + var_21; + const double var_195 = var_144 + var_34; + const double var_196 = var_11 + var_8; + const double var_197 = var_9 + var_12; + const double var_198 = var_55 + var_60; + const double var_199 = var_25 + var_27; + const double var_200 = var_10 + var_13; + const double var_201 = var_53 + var_61; + const double var_202 = var_65 + var_32; + const double var_203 = var_54 + var_59; + const double var_204 = var_26 + var_24; + const double var_205 = var_177 + var_95; + const double var_206 = var_66 + var_28; + const double var_207 = -0.5000000000000000000000000*var_206 + var_45; + const double var_208 = 0.0014235764235764236836090*w[0][9]*w[1][9]; + const double var_209 = var_100 + var_158; + const double var_210 = -1.0000000000000000000000000*var_91; + const double var_211 = var_210 + var_37; + const double var_212 = var_38 + var_64; + const double var_213 = -1.0000000000000000000000000*var_212; + const double var_214 = var_208 + 0.0001123876123876123875149*var_78 + 0.0001498501498501498500199*var_203 + 0.0004120879120879120875547*var_205 + 0.0014938764938764938390581*var_196 + -0.0014131701631701631960425*var_198 + 0.0004023754023754023750534*var_43 + -0.0000800125800125800034756*var_75 + 0.0002411939911939912028170*var_191 + -0.0004671254671254670889219*var_197 + 0.0003933566433566433834072*var_85 + 0.0028490028490028491449382*var_213 + -0.0002578697023141467603753*var_193 + 0.0005661005661005661000751*var_199 + 0.0059003496503496500463770*var_211 + -0.0001736689236689236597380*var_89 + 0.0015068265068265069336201*var_200 + 0.0003733920400587067370962*w[0][1]*w[1][1] + -0.0002643190143190143458901*var_201 + 0.0004495504495504495500596*var_202 + 0.0007517945017945017486746*var_194 + -0.0057217473884140545095645*var_190 + 0.0035776723276723276963296*var_41 + 0.0001685814185814185812724*var_195 + 0.0008470695970695970959674*var_204 + -0.0039238539238539236336800*var_192 + -0.0008263598541376319678992*var_40 + 0.0000770063270063270062602*var_42 + 0.0005272505272505272500699*var_209 + 0.0007950382950382950918156*var_207; + const double var_215 = 0.0000694191170381646489775*var_40 + 0.0000337933671267004592516*w[0][1]*w[1][1] + 0.0001769658912516055410385*var_45 + 0.0000818229389657961105184*var_43; + const double var_216 = var_105 + var_173; + const double var_217 = var_14 + var_17; + const double var_218 = var_18 + var_16; + const double var_219 = var_40 + var_58; + const double var_220 = var_21 + var_20; + const double var_221 = var_38 + var_22; + const double var_222 = var_83 + var_36; + const double var_223 = var_10 + var_9; + const double var_224 = var_15 + var_19; + const double var_225 = var_8 + var_13; + const double var_226 = var_26 + var_28; + const double var_227 = var_11 + var_12; + const double var_228 = var_65 + var_29; + const double var_229 = var_32 + var_33; + const double var_230 = var_41 + var_59; + const double var_231 = var_210 + var_35; + const double var_232 = var_76 + var_177; + const double var_233 = var_25 + var_24; + const double var_234 = -0.5000000000000000000000000*var_233 + var_55; + const double var_235 = var_79 + var_62; + const double var_236 = var_23 + var_64; + const double var_237 = -1.0000000000000000000000000*var_236; + const double var_238 = var_145 + var_82; + const double var_239 = 0.0012587412587412587401670*var_186; + const double var_240 = var_239 + 0.0003296703296703296700437*var_46; + const double var_241 = -1.0000000000000000000000000*var_60; + const double var_242 = 0.0003296703296703296700437*var_241; + const double var_243 = 0.0017982017982017982002385*var_232 + 0.0000149850149850149850020*var_235 + 0.0003596403596403596400477*var_228 + 0.0001298701298701298700172*var_90 + var_240 + -0.0005211455211455211450691*var_217 + -0.0001615051615051615050214*var_224 + -0.0002147852147852147850285*var_220 + var_242 + 0.0007042957042957042950934*var_226 + 0.0002097902097902097900278*var_238 + -0.0000194250194250194250026*var_216 + 0.0000899100899100899100119*var_229 + 0.0038211788211788212839271*var_222 + -0.0013936063936063937136051*var_225 + 0.0044655344655344653137519*var_234 + 0.0004578754578754578750607*var_218 + 0.0003233803233803233981129*var_219 + 0.0014585414585414585401935*var_51 + 0.0000366300366300366300049*var_237 + 0.0025097125097125099271733*w[0][0]*w[1][0] + 0.0033916083916083914970296*var_221 + -0.0001215451215451215450161*var_227 + 0.0001004551004551004550133*var_52 + 0.0008991008991008991001193*var_223 + 0.0019930069930069928968441*var_53 + 0.0003746253746253746250497*var_94 + 0.0001798201798201798200239*var_231 + -0.0040459540459540461673771*var_230 + 0.0004645354645354645350616*var_54; + A[115] = 0.1428571428571428492126927*var_243*var_7; + A[157] = A[115]; + const double var_244 = -1.0000000000000000000000000*var_11; + const double var_245 = -0.0011388611388611388601511*var_42 + 0.0007992007992007992001060*var_44 + var_159 + -0.0020379620379620379602703*var_45 + 0.0000599400599400599400080*var_117 + -0.0011637744971078303919676*w[0][1]*w[1][1] + -0.0000717800717800717890445*var_40; + const double var_246 = -0.0004129204129204129200548*var_57 + -0.0008547008547008547001134*var_184 + -0.0001766135099468432679767*var_58 + 0.0000399600399600399600053*var_241 + 0.0004595404595404595400610*var_62 + 0.0013186813186813186801749*var_59; + const double var_247 = var_18 + var_10; + const double var_248 = var_22 + 0.5000000000000000000000000*var_156; + const double var_249 = var_26 + 0.6000000000000000888178420*var_107; + const double var_250 = var_177 + var_36; + const double var_251 = var_30 + -2.0000000000000000000000000*var_33; + const double var_252 = 9.0000000000000000000000000*var_65 + var_251 + var_84; + const double var_253 = 0.0000022200022200022200003*var_17 + -0.0015473415473415473402052*var_21 + -0.0018093018093018093002400*var_23 + 0.0004662004662004662000618*var_244 + 0.0000599400599400599400080*var_129 + var_246 + var_162 + 0.0004995004995004995000663*var_249 + 0.0005194805194805194800689*var_153 + 0.0013786213786213786201829*var_28 + 0.0003596403596403596400477*var_250 + 0.0002153402153402153400286*var_38 + 0.0006593406593406593400875*var_66 + 0.0007836607836607836601039*var_9 + 0.0001198801198801198800159*var_210 + 0.0004817404817404817400639*var_12 + -0.0001909201909201909200253*var_20 + 0.0004595404595404595400610*var_93 + -0.0000510600510600510600068*var_19 + 0.0010789210789210789201431*var_29 + 0.0000488400488400488400065*var_248 + 0.0002686202686202686200356*var_16 + -0.0002863802863802863800380*var_64 + var_245 + 0.0002397602397602397600318*var_252 + 0.0003219003219003219000427*var_15 + 0.0010389610389610389601378*var_81 + -0.0002908202908202908200386*var_14 + 0.0001887001887001887000250*var_247 + 0.0003774003774003774000501*var_122 + -0.0005794205794205794200769*w[0][3]*w[1][3]; + const double var_254 = var_41 + var_199; + const double var_255 = -1.0000000000000000000000000*var_55; + const double var_256 = -0.0000513771942343370894993*var_98; + const double var_257 = 0.0000009514295228580943010*var_100; + const double var_258 = -0.0000228343085485942623762*var_54 + var_256 + 0.0002426145283288140390172*var_255 + var_257 + -0.0000056028627457198890965*var_52 + -0.0000413871842443270994980*var_53 + -0.0000260233593566926892505*w[0][0]*w[1][0]; + const double var_259 = 0.0000727843584986442089946*var_42 + 0.0001427144284287141390039*var_41 + 0.0000085628657057228488146*var_45 + 0.0000256885971171685447497*var_43 + 0.0000037176227652418131736*w[0][1]*w[1][1] + -0.0000052504814409576312814*var_40; + const double var_260 = 43.0000000000000000000000000*w[0][2]*w[1][2]; + const double var_261 = 0.0000014271442842871413985*var_61 + 0.0000666000666000666000088*var_158 + -0.0000012333345666679000237*var_260 + -0.0000047395285490523587200*var_58 + 0.0000199800199800199800027*var_241 + 0.0000727843584986442089946*var_59; + const double var_262 = -1.0000000000000000000000000*var_15; + const double var_263 = -1.0000000000000000000000000*var_20; + const double var_264 = var_138 + var_263; + const double var_265 = var_145 + var_157; + const double var_266 = 4.6000000000000005329070518*w[0][5]*w[1][5]; + const double var_267 = 0.0000277500277500277500037*var_11 + 0.0000095142952285809423744*var_13 + 0.0000093557236414379276281*var_17 + 0.0002140716426430712220584*var_30 + 0.0000513771942343370894993*var_177 + 0.0000288600288600288600038*var_21 + 0.0003596403596403596400477*var_109 + 0.0000204557347414490276296*var_23 + 0.0000271157414014556876305*var_27 + 0.0001198801198801198800159*var_77 + 0.0000613672042243470795006*var_24 + -0.0000461443318586175757674*var_22 + 0.0000071357214214357067808*var_108 + -0.0005223348080490937319492*w[0][7]*w[1][7] + 0.0000388500388500388500052*var_130 + 0.0000171257314114456976291*var_153 + var_258 + 0.0000166500166500166500022*var_264 + 0.0000256885971171685447497*var_39 + -0.0000128442985585842723748*var_28 + 0.0001455687169972884179893*var_65 + 0.0000309214594928880652579*var_8 + -0.0000285428856857428271232*var_266 + 0.0000042814328528614244073*var_66 + 0.0000856286570572284779813*var_95 + -0.0000287014572728858452576*var_9 + var_261 + 0.0001098901098901098900146*var_210 + var_259 + 0.0000055500055500055500007*var_19 + 0.0001812473241044669459640*var_25 + -0.0000534386248671963015296*var_16 + 0.0000020614306328592044070*var_262 + 0.0000057085771371485655940*var_265 + 0.0000499500499500499500066*var_81 + 0.0000112585826871541164418*var_14 + -0.0000134785849071563364421*var_18; + A[42] = var_267*var_7; + A[182] = A[42]; + const double var_268 = 0.0001332001332001332000177*var_100 + 0.0015812758669901526720897*var_54 + 0.0000742115027829313484873*var_255 + -0.0001444058586915729900692*var_52 + -0.0000247371675943104528839*var_189 + 0.0001741116026830312620531*var_53 + var_104; + const double var_269 = 0.0005965463108320250397790*var_41 + -0.0006536320822035107279066*var_45 + -0.0001008515294229580020434*var_43 + -0.0002703469370136036740125*w[0][1]*w[1][1] + -0.0000738943596086453325473*var_40 + 0.0000285428856857428271232*var_79; + const double var_270 = -0.0002283430854859426169853*var_61 + -0.0002530802530802530800336*var_57 + -0.0008337341670675003880639*w[0][2]*w[1][2] + -0.0000369647988695607745057*var_58 + 0.0012987012987012987001723*var_241 + 0.0002654488368774082980052*var_59; + const double var_271 = -0.0000463029034457605905136*var_14; + const double var_272 = 0.0000028542885685742827970*var_24; + const double var_273 = 0.0348508634222919957967868*var_30 + 0.0299145299145299192744574*var_20; + const double var_274 = -1.0000000000000000000000000*var_126; + const double var_275 = -1.0000000000000000000000000*var_135; + const double var_276 = 0.0008391608391608391601113*var_35 + 0.0002226345083487940590145*var_274 + var_271 + var_268 + 0.0004528804528804528800601*var_11 + 0.0001198801198801198800159*var_275 + -0.0181818181818181809350499*var_273 + -0.0004623947481090337919413*var_31 + -0.0001366887081172795650932*var_13 + -0.0001509601509601509600200*var_17 + 0.0002568859711716854339440*var_32 + -0.0001563515849230135020508*var_21 + 0.0002886002886002886000383*var_10 + -0.0001411287125572839779887*var_23 + 0.0006022548879691736519598*var_27 + 0.0000754800754800754800100*var_22 + 0.0003938918224632510420823*var_33 + 0.0003824746681889538719307*var_28 + var_270 + 0.0000488400488400488400065*var_38 + -0.0000567686281971996315300*var_8 + 0.0002711574140145568559759*var_66 + var_272 + 0.0000976800976800976800130*var_9 + 0.0013986013986013986001855*var_210 + -0.0001477887192172906650946*var_12 + 0.0002854288568574282780078*var_37 + 0.0006964464107321250482124*var_26 + -0.0000091971520542949128818*var_19 + 0.0000713572142143570695020*var_25 + -0.0001712573141144569559627*var_83 + 0.0000574029145457716905151*var_16 + -0.0012321012321012321001634*var_64 + var_269 + -0.0001195629767058338505234*var_15 + 0.0019980019980019980002650*var_82 + 0.0000802372230943659495031*var_18 + -0.0019294990723562150877757*w[0][3]*w[1][3]; + A[65] = var_276*var_7; + const double var_277 = -0.0002640216925931211720650*var_61 + 0.0001665001665001665000221*var_158 + -0.0023726273726273725168945*w[0][2]*w[1][2] + 0.0000096794739651882502488*var_58 + 0.0006868131868131868668012*var_241 + -0.0002720493791922363232411*var_59; + const double var_278 = 4.0000000000000000000000000*var_60 + var_61; + const double var_279 = 0.0000266400266400266400035*var_57 + 0.0001998001998001998000265*var_278 + 0.0008880008880008880001178*var_184 + 0.0000096552477504858455004*var_58 + 0.0000513771942343370894993*var_59; + const double var_280 = 0.0000649350649350649350086*var_61 + 0.0000732600732600732600097*var_158 + 0.0000008633341966675299531*var_260 + -0.0000659217325883992535029*var_58 + 0.0000699300699300699300093*var_241 + 0.0010406260406260407335582*var_59 + var_48; + const double var_281 = 0.0001115551115551115550148*var_42 + 0.0004778554778554778550634*var_41 + -0.0002430902430902430900322*var_45 + -0.0001642801642801642800218*var_43 + -0.0001235801235801235980864*w[0][1]*w[1][1] + -0.0000407205962761518296643*var_40; + const double var_282 = 0.0002680652680652680650356*var_114 + 0.0001548451548451548450205*var_54 + -0.0000257150257150257172622*var_52 + -0.0003467725689947911906115*w[0][0]*w[1][0] + -0.0001309801309801309800174*var_51 + -0.0011621711621711621701541*var_55; + const double var_283 = -0.0003570503570503570319773*var_22 + 0.0000249750249750249750033*var_108 + -0.0005694305694305694300755*var_33; + const double var_284 = 0.0004578754578754578750607*var_35 + -0.0000514300514300514345243*var_11 + 0.0004095904095904095900543*var_31 + 0.0001790801790801790709887*var_13 + -0.0009690309690309690301285*var_32 + 0.0000697450697450697495268*var_17 + 0.0002697302697302697300358*var_30 + -0.0000917600917600917690472*var_21 + -0.0001369001369001368909831*var_10 + 0.0000949050949050949050126*var_27 + 0.0004811854811854811850638*var_24 + -0.0028854478854478853369625*w[0][7]*w[1][7] + var_283 + 0.0000416250416250416250055*var_28 + 0.0000299700299700299700040*var_65 + var_282 + -0.0004847004847004846819943*var_38 + 0.0001824101824101824280942*var_8 + -0.0002214452214452214450294*w[0][6]*w[1][6] + 0.0002014652014652014650267*var_66 + -0.0001206201206201206290510*var_9 + var_280 + 0.0000799200799200799200106*var_12 + -0.0009207459207459207451221*w[0][5]*w[1][5] + 0.0001061901061901061854966*var_20 + -0.0000057350057350057355654*var_19 + 0.0000899100899100899100119*var_29 + 0.0006809856809856809850903*var_25 + -0.0001655751655751655569519*var_16 + 0.0000828800828800828754935*var_64 + 0.0001443001443001443000191*var_146 + 0.0000297850297850297827452*var_15 + 0.0001748251748251748250232*var_82 + 0.0000475450475450475495238*var_14 + var_281 + -0.0000989750989750989704956*var_18 + -0.0002047952047952047950272*w[0][3]*w[1][3]; + const double var_285 = -1.0000000000000000000000000*var_17; + const double var_286 = 2.0000000000000000000000000*var_22 + var_156; + const double var_287 = var_285 + var_286; + const double var_288 = -2.0000000000000000000000000*var_65 + var_29; + const double var_289 = var_15 + var_17; + const double var_290 = -0.0000799200799200799200106*var_98; + const double var_291 = var_108 + var_93; + const double var_292 = 0.0000566100566100566100075*var_61 + 0.0000555000555000555000074*var_57 + var_290 + 0.0000832500832500832500110*var_291 + 0.0001665001665001665000221*var_60 + 0.0000197950197950197961320*var_289 + 0.0006857340190673524241843*w[0][2]*w[1][2] + 0.0000002496034242065987916*var_58 + 0.0000325864611578897302581*var_59; + const double var_293 = 0.0000218828790257361705104*var_255 + 0.0002497502497502497500331*var_115 + 0.0000523756079311634846658*var_52 + 0.0000116550116550116550015*var_53 + -0.0000068185782471496764412*var_51 + -0.0000007282546965086647396*w[0][0]*w[1][0]; + const double var_294 = 0.0000009514295228580943010*var_44; + const double var_295 = -0.0000663622092193520745013*var_45 + var_294 + 0.0000832500832500832500110*var_117 + -0.0000159276349752540227517*w[0][1]*w[1][1] + 0.0000321078098855876600749*var_40; + const double var_296 = 0.5000000000000000000000000*var_138 + var_20; + const double var_297 = 0.0004995004995004995000663*var_81 + 0.0000349650349650349650046*var_28; + const double var_298 = 0.0000349650349650349650046*var_25 + 0.0004995004995004995000663*var_91; + const double var_299 = -0.0002571502571502571319641*var_11 + -0.0000670757813614956510239*var_31 + 0.0000197950197950197961320*var_13 + var_293 + -0.0000137957280814423676287*var_21 + -0.0000483643340786197957677*var_23 + 0.0000028542885685742827970*var_109 + 0.0000102278673707245138148*var_24 + -0.0000084307227164370031927*var_22 + var_297 + -0.0001279672708244136930620*w[0][8]*w[1][8] + -0.0000637457780314923210235*w[0][7]*w[1][7] + var_292 + 0.0000048100048100048102830*var_38 + -0.0000058935773221487511588*var_8 + 0.0002849002849002848819678*var_296 + 0.0000313971742543171094967*var_66 + 0.0000072942930085787232211*var_9 + var_295 + 0.0000710400710400710400094*var_12 + -0.0000184207327064469914999*var_19 + -0.0000599400599400599400080*var_29 + -0.0000118400118400118405663*var_16 + 0.0005698005698005697639355*var_64 + 0.0000199800199800199800027*var_144 + -0.0000196100196100196122614*var_14 + 0.3333333333333333148296163*var_298 + 0.0000266400266400266400035*var_36 + -0.0000113642970785827912453*var_18; + const double var_300 = var_98 + var_228; + const double var_301 = var_255 + var_229; + const double var_302 = -4.0000000000000000000000000*var_88 + var_233 + 2.0000000000000000000000000*var_301 + var_53 + -16.0000000000000000000000000*var_300; + const double var_303 = -0.0001079277864992150782943*var_42 + 0.0005619380619380619917846*var_41 + 0.0000178393035535892673755*var_45 + var_148 + 0.0000576804148232719612389*var_43 + -0.0000029291695958362626886*w[0][1]*w[1][1] + -0.0001495418162084828780315*var_40; + const double var_304 = -1.0000000000000000000000000*var_9; + const double var_305 = 0.0073640645069216496484965*var_54 + -0.0000909143766286623299620*var_52 + 0.0012844298558584272239302*var_53 + 0.0000486286200571914802352*w[0][0]*w[1][0] + 0.0010275438846867417357761*var_51 + 0.0005137719423433708678881*var_55; + const double var_306 = 0.0041958041958041958005565*var_41 + 0.0022263450834879407527755*var_44 + 0.0030826316540602254241688*var_45 + 0.0002812002812002811638972*w[0][1]*w[1][1] + -0.0003372289086574801141548*var_40 + 0.0007706579135150563560422*var_79; + const double var_307 = var_109 + var_127; + const double var_308 = 0.3333333333333333148296163*var_22 + var_39; + const double var_309 = var_37 + var_83; + const double var_310 = 1.9428571428571428381104624*w[0][8]*w[1][8]; + const double var_311 = 0.0008087150944293801119872*var_11 + -0.0009038580467151895560599*var_13 + -0.0092478949621806767061871*var_30 + -0.0017030588459159886477456*var_17 + 0.0005137719423433708678881*var_21 + 0.0006184291898577613322621*var_23 + 0.0013415156272299129120579*var_10 + 0.0004566861709718852339705*var_308 + 0.0016269444840873411358556*var_27 + var_305 + 0.0015413158270301127120844*var_77 + 0.0000285428856857428271232*var_304 + 0.0007706579135150563560422*var_129 + 0.0035964035964035964004770*var_307 + var_174 + 0.0028257456828885401528551*var_67 + 0.0005423148280291137119519*var_8 + 0.0002568859711716854339440*var_74 + -0.0160981875267589558120562*w[0][6]*w[1][6] + -0.0020075162932305786953058*var_12 + 0.0062508919651776788384279*var_26 + var_306 + 0.0013224870367727510882955*var_19 + 0.0123305266162409016966750*var_29 + 0.0002949431520860091898890*var_16 + -0.0035298035298035298004682*var_64 + -0.0001617430188858760169764*var_15 + 0.0006850292564578278238507*var_81 + 0.0047952047952047952006360*var_144 + 0.0004662004662004662000618*var_14 + 0.0029970029970029970003975*var_310 + 0.0006374577803149231560245*var_18 + 0.0017125731411445697764673*var_309 + 0.0019980019980019980002650*var_263; + A[74] = 0.2000000000000000111022302*var_311*var_7; + A[214] = A[74]; + const double var_312 = var_112 + 0.0002264402264402264400300*var_115 + 0.0000498267164933831585008*var_52 + 0.0005994005994005994000795*var_53 + 0.0008633341966675300242079*w[0][0]*w[1][0] + 0.0003196803196803196800424*var_51 + 0.0026373626373626373603498*var_55; + const double var_313 = 0.0001332001332001332000177*var_45 + 0.0013320013320013320001767*var_117 + 0.0002575202575202575200342*var_43 + 0.0000606800606800606822668*w[0][1]*w[1][1] + 0.0001147823370045592141333*var_40 + 0.0003862803862803862800512*var_79; + const double var_314 = 0.0019980019980019980002650*var_111 + 0.0002042402042402042400271*var_57 + 0.0004528804528804528800601*var_60 + 0.0000955423177645399831657*w[0][2]*w[1][2] + 0.0001302401302401302309823*var_58 + 0.0000666000666000666000088*var_62; + const double var_315 = var_11 + var_19; + const double var_316 = var_178 + var_129; + const double var_317 = 2.0000000000000000000000000*var_23 + var_157; + const double var_318 = var_317 + var_262; + const double var_319 = 1.9428571428571428381104624*w[0][6]*w[1][6]; + const double var_320 = -0.0009590409590409590401272*var_31 + -0.0003981203981203981561929*var_13 + -0.0001080401080401080445318*var_17 + 0.0004662004662004662000618*var_319 + 0.0002338402338402338490660*var_10 + 0.0008806008806008806723969*var_22 + 0.0000799200799200799200106*var_126 + 0.0006393606393606393600848*w[0][8]*w[1][8] + 0.0000666000666000666000088*var_108 + 0.0060339660339660339608003*w[0][7]*w[1][7] + 0.0010789210789210789201431*var_316 + 0.0002264402264402264400300*var_67 + 0.0000932400932400932400124*var_28 + 0.0011914011914011914724382*var_38 + -0.0005224405224405224762094*var_8 + 0.0003196803196803196800424*var_95 + 0.0003996003996003996000530*var_9 + 0.0023043623043623043603056*w[0][5]*w[1][5] + -0.0000458800458800458845236*var_20 + 0.0003862803862803862800512*var_93 + 0.0004795204795204795200636*var_76 + 0.0003892403892403892761917*var_16 + 0.0000562400562400562422662*var_64 + -0.0000547600547600547645248*var_315 + 0.0015584415584415584402067*var_107 + 0.0001021201021201021200135*var_147 + 0.0000014800014800014800708*var_318 + var_313 + 0.0006127206127206127200813*var_81 + 0.0001332001332001332000177*var_144 + -0.0001613201613201613380914*var_14 + 0.0005994005994005994000795*var_142 + var_314 + 0.0002294002294002293819604*var_18 + var_312; + const double var_321 = -1.0000000000000000000000000*var_163; + const double var_322 = 0.0000135578707007278438152*var_42 + 0.0000423386137671851947519*var_41 + 0.0000118928690357261788150*var_44 + 0.0000057085771371485655940*var_46 + 0.0000062723872247681772512*var_40 + 0.0000156985871271585547483*var_321; + const double var_323 = -0.0003570503570503570319773*var_38 + 0.0000249750249750249750033*var_73 + -0.0005694305694305694300755*var_32; + const double var_324 = 0.0000428143285286142389907*var_31 + 0.0000577200577200577200077*var_13 + 0.0000485229056657628105139*var_30 + 0.0000168350168350168338729*var_17 + 0.0001084629656058227505219*var_110 + 0.0000041757184614327470627*var_21 + -0.0000066335780621494908765*var_23 + 0.0000713572142143570695020*var_77 + 0.0000632700632700632700084*var_24 + 0.0000481000481000480977476*var_244 + -0.0000304457447314590176309*w[0][8]*w[1][8] + var_185 + -0.0001660244517387374490070*w[0][7]*w[1][7] + -0.0000085628657057228488146*var_65 + 0.0000254243111385968535059*var_8 + 0.0001565101565101565100208*w[0][6]*w[1][6] + 0.0000092764378478664185609*var_66 + -0.0000141392998535855662456*var_9 + 0.0000096992954135811279391*var_12 + -0.0001703058845915988810376*w[0][5]*w[1][5] + -0.0000409114694828980552592*var_26 + 0.0001646501646501646409868*var_20 + 0.0000123685837971552264420*var_93 + 0.0000001057143914286771460*var_19 + 0.0000171257314114456976291*var_29 + 0.0000682650682650682650091*var_25 + 0.0000962000962000961954953*var_138 + -0.0000195571624143052706245*var_16 + 0.0001017501017501017454960*var_64 + var_322 + var_188 + 0.0000073207216064358923455*var_15 + 0.0000366300366300366300049*var_81 + 0.0000209314495028780752565*var_144 + 0.0000043871472442901017518*var_14 + 0.1428571428571428492126927*var_323 + -0.0000178921607493036056242*var_18; + A[36] = var_324*var_7; + const double var_325 = 0.0001141715427429713084926*var_44; + const double var_326 = 0.0005137719423433708678881*var_169 + 0.0003330003330003330000442*var_110 + var_325 + 0.0002220002220002220000294*var_39 + 0.0000856286570572284779813*var_73 + 0.0006850292564578278238507*var_251; + const double var_327 = 0.0002568859711716854339440*var_114; + const double var_328 = 0.0000285428856857428271232*var_54 + var_327 + -0.0000165619213238260851249*var_52 + 0.0000570857713714856542463*var_51 + -0.0001480001480001479909846*w[0][0]*w[1][0] + -0.0010275438846867417357761*var_55; + const double var_329 = var_62 + 4.0000000000000000000000000*var_241; + const double var_330 = 0.0000285428856857428271232*var_329 + 0.0002093144950287807390128*var_158 + -0.0004566861709718852339705*var_184 + -0.0000313619361238408862562*var_58 + 0.0001998001998001998000265*var_59; + const double var_331 = var_42 + 4.0000000000000000000000000*var_45; + const double var_332 = -0.0000387619435238482885160*var_40 + 0.0000444000444000444000059*var_163 + 0.0009704581133152561560687*var_41 + 0.0000856286570572284779813*var_331; + const double var_333 = 0.0000729429300857872305172*var_11 + 0.0002283430854859426169853*var_210; + const double var_334 = var_25 + 0.6000000000000000888178420*var_67; + const double var_335 = var_135 + var_334; + const double var_336 = var_332 + 0.0000570857713714856542463*var_35 + 0.0001046572475143903695064*var_13 + 0.0000539143396286253457684*var_17 + 0.0000761143618286475389951*var_21 + -0.0001363715649429935220481*var_10 + 0.0001427144284287141390039*var_27 + 0.0005994005994005994000795*var_24 + 0.0000856286570572284779813*var_304 + var_326 + 0.0000285428856857428271232*var_108 + 0.0000475714761429047152601*var_157 + 0.0003425146282289139119254*var_65 + 0.0005708577137148565560157*var_84 + 0.0001490572919144347830648*var_8 + var_328 + 0.0029684601113172540479135*var_37 + -0.0000602572031143459762768*var_20 + 0.0001300287014572728779872*var_19 + -0.0000983143840286697525506*var_16 + -0.0001078286792572506915368*var_64 + 0.0000031714317428603144071*var_262 + 0.0001554001554001554000206*var_137 + var_330 + var_333 + 0.0001141715427429713084926*var_81 + 0.0009704581133152561560687*var_144 + 0.0000729429300857872305172*var_14 + 0.0004281432852861424441168*var_335; + A[103] = 0.8000000000000000444089210*var_336*var_7; + const double var_337 = var_109 + var_84; + const double var_338 = 0.3076923076923077093880465*var_91 + 0.0395604395604395586705238*var_337; + const double var_339 = 0.0000627943485086342189933*var_40 + 0.0000188523998047807549942*w[0][1]*w[1][1] + 0.0001046572475143903695064*var_43 + 0.0000399600399600399600053*var_45; + const double var_340 = 0.0001141715427429713084926*var_158; + const double var_341 = 0.0006850292564578278238507*var_169 + 0.0002220002220002220000294*var_110 + var_340 + 0.0000856286570572284779813*var_108 + 0.0003330003330003330000442*var_39 + 0.0005137719423433708678881*var_251; + const double var_342 = -0.0004566861709718852339705*var_163 + 0.0001998001998001998000265*var_41 + 0.0002093144950287807390128*var_44 + 0.0000285428856857428271232*var_80 + -0.0000313619361238408862562*var_40; + const double var_343 = 0.0000444000444000444000059*var_184 + 0.0000856286570572284779813*var_278 + -0.0000387619435238482885160*var_58 + 0.0009704581133152561560687*var_59; + const double var_344 = -1.0000000000000000000000000*var_16; + const double var_345 = -1.0000000000000000000000000*var_19; + const double var_346 = 0.0002283430854859426169853*var_35 + 0.0000729429300857872305172*var_12; + const double var_347 = var_24 + 0.6000000000000000888178420*var_93; + const double var_348 = var_347 + var_126; + const double var_349 = 0.0001490572919144347830648*var_13 + 0.0000729429300857872305172*var_17 + -0.0000602572031143459762768*var_21 + -0.0001078286792572506915368*var_23 + 0.0000475714761429047152601*var_244 + var_343 + var_346 + 0.0029684601113172540479135*var_84 + 0.0001046572475143903695064*var_8 + 0.0000031714317428603144071*var_345 + var_342 + 0.0001427144284287141390039*var_66 + -0.0001363715649429935220481*var_9 + 0.0000570857713714856542463*var_210 + var_328 + 0.0005708577137148565560157*var_37 + 0.0000761143618286475389951*var_20 + 0.0003425146282289139119254*var_29 + 0.0005994005994005994000795*var_25 + 0.0000856286570572284779813*var_138 + 0.0001300287014572728779872*var_15 + 0.0004281432852861424441168*var_348 + 0.0009704581133152561560687*var_81 + var_341 + 0.0001141715427429713084926*var_144 + 0.0000285428856857428271232*var_73 + 0.0000539143396286253457684*var_14 + -0.0000983143840286697525506*var_18 + 0.0001554001554001554000206*var_344; + A[149] = 0.8000000000000000444089210*var_349*var_7; + A[219] = A[149]; + const double var_350 = var_237 + var_220; + const double var_351 = 0.0000116550116550116550015*var_42 + 0.0000218828790257361705104*var_46 + 0.0002497502497502497500331*var_117 + -0.0000068185782471496764412*var_43 + -0.0000007282546965086647396*w[0][1]*w[1][1] + 0.0000523756079311634846658*var_40; + const double var_352 = var_257 + 0.0000832500832500832500110*var_115 + 0.0000321078098855876600749*var_52 + -0.0000159276349752540227517*w[0][0]*w[1][0] + -0.0000663622092193520745013*var_55; + const double var_353 = 0.5000000000000000000000000*var_244 + var_64; + const double var_354 = 0.0000710400710400710400094*var_13 + 0.0000028542885685742827970*var_177 + -0.0000670757813614956510239*var_32 + var_351 + 0.0000048100048100048102830*var_21 + -0.0002571502571502571319641*var_10 + -0.0000084307227164370031927*var_23 + var_352 + 0.0000313971742543171094967*var_24 + -0.0000483643340786197957677*var_22 + 0.0002849002849002848819678*var_353 + 0.3333333333333333148296163*var_297 + -0.0000637457780314923210235*w[0][8]*w[1][8] + -0.0001279672708244136930620*w[0][7]*w[1][7] + -0.0000599400599400599400080*var_33 + var_292 + -0.0000137957280814423676287*var_38 + 0.0000072942930085787232211*var_8 + 0.0000102278673707245138148*var_66 + -0.0000058935773221487511588*var_9 + 0.0000197950197950197961320*var_12 + 0.0005698005698005697639355*var_20 + -0.0000113642970785827912453*var_19 + -0.0000196100196100196122614*var_16 + 0.0000266400266400266400035*var_144 + -0.0000118400118400118405663*var_14 + var_298 + 0.0000199800199800199800027*var_36 + -0.0000184207327064469914999*var_18; + const double var_355 = var_105 + var_189; + const double var_356 = var_64 + var_20; + const double var_357 = var_40 + var_52; + const double var_358 = var_12 + var_13; + const double var_359 = 4.0000000000000000000000000*var_255 + var_114; + const double var_360 = var_54 + 2.0000000000000000000000000*var_231; + const double var_361 = 0.0071928071928071928009540*var_97 + 0.0003996003996003996000530*var_217 + 0.0023976023976023976003180*var_100 + 0.0011988011988011988001590*var_360 + 0.0017982017982017982002385*var_359; + const double var_362 = var_9 + var_8; + const double var_363 = var_244 + var_138; + const double var_364 = var_145 + var_37; + const double var_365 = var_59 + 2.0000000000000000000000000*var_364; + const double var_366 = var_18 + var_19; + const double var_367 = -1.0000000000000000000000000*var_366; + const double var_368 = var_66 + var_24; + const double var_369 = var_31 + var_32; + const double var_370 = var_369 + var_368; + const double var_371 = var_22 + var_23; + const double var_372 = var_38 + var_21; + const double var_373 = -1.0000000000000000000000000*var_372; + const double var_374 = var_371 + var_373; + const double var_375 = 0.0053946053946053946007155*var_61 + 0.0008658008658008658001148*var_358 + 0.0019980019980019980002650*var_367 + 0.0001628001628001628090566*var_58 + -0.0005180005180005180362088*var_355 + 0.0083916083916083916011130*var_365 + 0.0005328005328005328000707*var_356 + -0.0012654012654012654001678*var_362 + var_87 + 0.0002664002664002664000353*var_374 + 0.0004662004662004662000618*var_363 + 0.0023976023976023976003180*var_57 + 0.0001332001332001332000177*var_184 + -0.0002220002220002220000294*var_357 + 0.0071928071928071928009540*var_370 + var_361; + const double var_376 = 0.0011873840445269015757973*var_47; + const double var_377 = var_235 + var_94; + const double var_378 = var_107 + var_129; + const double var_379 = var_378 + 2.0000000000000000000000000*var_55; + const double var_380 = var_109 + var_77; + const double var_381 = -1.0000000000000000000000000*var_224; + const double var_382 = 0.0727272727272727237401995*var_223 + 0.0666666666666666657414808*var_218 + 0.0060606060606060606008039*var_381; + const double var_383 = var_81 + var_144; + const double var_384 = var_42 + var_61; + const double var_385 = var_244 + var_157; + const double var_386 = var_226 + var_54; + const double var_387 = var_216 + 6.5714285714285711748061658*var_101 + 0.6031746031746031411202580*var_236 + -0.8412698412698412786525637*var_225 + -4.1428571428571423496123316*var_386 + 0.0158730158730158721347436*var_385 + 6.7142857142857135244184974*var_222 + 0.6666666666666666296592325*var_219 + var_384 + 3.1005291005291004680088918*w[0][0]*w[1][0] + -9.1428571428571423496123316*var_230 + 4.8571428571428567622092487*var_383 + 2.4285714285714283811046243*var_94; + const double var_388 = 0.0093240093240093240012367*var_92 + 0.0013320013320013320001767*var_51 + 0.0005994005994005994000795*var_220 + 0.0013986013986013986001855*var_379 + 0.0012210012210012210001620*var_382 + 0.0017390017390017389279505*var_221 + 0.0023976023976023976003180*var_88 + 0.0007992007992007992001060*var_300 + 0.0001603334936668270060446*var_52 + 0.0001998001998001998000265*var_114 + 0.0004884004884004884000648*var_90 + 0.0011988011988011988001590*var_380 + 0.0002590002590002590181044*var_217 + 0.0004662004662004662000618*var_387; + A[131] = 0.0571428571428571410728559*var_388*var_7; + const double var_389 = var_30 + var_65; + const double var_390 = var_109 + var_177; + const double var_391 = 0.0017982017982017982002385*var_329 + 0.0023976023976023976003180*var_158 + 0.0011988011988011988001590*var_365 + 0.0003996003996003996000530*var_366 + 0.0071928071928071928009540*var_390; + const double var_392 = var_157 + var_304; + const double var_393 = -1.0000000000000000000000000*var_75; + const double var_394 = -1.0000000000000000000000000*var_192; + const double var_395 = var_212 + var_394; + const double var_396 = var_30 + var_33; + const double var_397 = var_396 + var_199; + const double var_398 = 0.0002664002664002664000353*var_395 + -0.0012654012654012654001678*var_200 + 0.0001628001628001628090566*var_40 + 0.0019980019980019980002650*var_393 + -0.0005180005180005180362088*var_190 + 0.0083916083916083916011130*var_86 + var_391 + 0.0071928071928071928009540*var_397 + 0.0053946053946053946007155*var_42 + 0.0001332001332001332000177*var_163 + 0.0023976023976023976003180*var_43 + 0.0008658008658008658001148*var_196 + -0.0002220002220002220000294*var_193 + 0.0004662004662004662000618*var_392 + 0.0005328005328005328000707*var_194 + var_361; + A[194] = 0.2285714285714285642914234*var_398*var_7; + A[222] = A[194]; + const double var_399 = var_15 + var_12; + const double var_400 = var_107 + var_142; + const double var_401 = var_244 + 2.0000000000000000000000000*var_64; + const double var_402 = var_345 + var_401; + const double var_403 = 0.0000799200799200799200106*var_135 + -0.0005224405224405224762094*var_13 + 0.0004795204795204795200636*var_177 + -0.0009590409590409590401272*var_30 + -0.0001613201613201613380914*var_17 + -0.0000458800458800458845236*var_21 + -0.0000547600547600547645248*var_399 + 0.0000562400562400562422662*var_23 + 0.0003996003996003996000530*var_10 + 0.0011914011914011914724382*var_22 + 0.0023043623043623043603056*w[0][7]*w[1][7] + 0.0015584415584415584402067*var_129 + 0.0000014800014800014800708*var_402 + 0.0003862803862803862800512*var_67 + var_118 + 0.0008806008806008806723969*var_38 + -0.0003981203981203981561929*var_8 + 0.0006393606393606393600848*w[0][6]*w[1][6] + 0.0002338402338402338490660*var_9 + 0.0005994005994005994000795*var_178 + 0.0060339660339660339608003*w[0][5]*w[1][5] + 0.0000932400932400932400124*var_26 + 0.0002264402264402264400300*var_93 + var_132 + 0.0003196803196803196800424*var_96 + 0.0002294002294002293819604*var_16 + 0.0001332001332001332000177*var_81 + 0.0006127206127206127200813*var_144 + 0.0000666000666000666000088*var_73 + -0.0001080401080401080445318*var_14 + 0.0010789210789210789201431*var_400 + 0.0004662004662004662000618*var_310 + 0.0003892403892403892761917*var_18 + 0.0001021201021201021200135*var_263 + var_312; + const double var_404 = 0.0001027543884686741789986*var_47; + const double var_405 = 0.1333333333333333314829616*var_43 + var_45; + const double var_406 = var_40 + 15.5714285714285711748061658*var_42; + const double var_407 = var_404 + 0.0000199800199800199800027*var_406 + 0.0005155338488671821518816*w[0][1]*w[1][1] + 0.0013986013986013986001855*var_405; + const double var_408 = 0.0000627943485086342189933*var_58 + 0.0001046572475143903695064*var_57 + 0.0000188523998047807549942*w[0][2]*w[1][2] + 0.0000399600399600399600053*var_60; + const double var_409 = 0.0000337933671267004592516*w[0][0]*w[1][0] + 0.0000818229389657961105184*var_51 + 0.0000694191170381646489775*var_52 + 0.0001769658912516055410385*var_55; + const double var_410 = 0.0001027543884686741789986*var_33; + const double var_411 = 0.0348508634222919957967868*var_31 + 0.0299145299145299192744574*var_21; + const double var_412 = var_409 + 0.0012987012987012987001723*var_34 + 0.0000656486370772084979787*var_27 + 0.0002051916337630623420572*var_19 + 0.0004681033252461824041221*w[0][7]*w[1][7] + 0.0003539317825032110820770*w[0][4]*w[1][4] + var_407 + 0.0010446696160981874638984*var_29 + 0.0002568859711716854339440*var_36 + 0.0001366887081172795650932*var_14 + 0.0000513771942343370894993*var_91 + var_410 + 0.0006771006771006771000898*var_23 + var_408 + 0.0001509601509601509600200*var_8 + 0.0181818181818181809350499*var_411 + 0.0002220002220002220000294*var_11 + 0.0028971028971028971003843*w[0][3]*w[1][3]; + const double var_413 = 0.0009818752675895532720102*var_54 + 0.0000713572142143570695020*var_53; + const double var_414 = 0.0006964464107321250482124*var_59 + 0.0002083630655059226369826*var_61; + const double var_415 = 0.0000028542885685742827970*var_25; + const double var_416 = 0.0000256885971171685447497*var_41; + const double var_417 = 0.0000260057402914545776303*var_20 + 0.0001056086770372484579840*var_26 + 0.0000840429411857983305187*var_15 + var_414 + 0.0000031714317428603144071*var_22 + var_70 + 0.0005965463108320250397790*var_28 + 0.0001741116026830312620531*var_24 + 0.0000707229278657850105169*var_38 + 0.0000948258091115234010276*var_64 + var_416 + 0.0000231514517228802952568*var_13 + 0.0000269571698143126728842*var_17 + 0.0003085803085803085800409*var_12 + var_415 + 0.0002397602397602397600318*var_32 + 0.0004452690166975881180290*var_65 + 0.0000612086326372040715306*var_16 + 0.0008020550877693734519863*var_66 + -1.0000000000000000000000000*var_412 + var_413 + 0.0000041228612657184088140*var_18 + 0.0002553002553002553000339*var_9 + 0.0000003171431742860314513*var_10; + A[55] = var_417*var_7; + const double var_418 = var_44 + var_158; + const double var_419 = 0.0016269444840873411358556*var_115 + -0.0001384858527715670519984*var_52 + -0.0011988011988011988001590*var_189 + var_172 + -0.0035107749393463675430249*var_53 + -0.0010846296560582274239037*var_51 + -0.0078778364492650201911239*var_55; + const double var_420 = 0.0012844298558584272239302*var_61 + 0.0010275438846867417357761*var_57 + 0.0005137719423433708678881*var_60 + 0.0000486286200571914802352*w[0][2]*w[1][2] + -0.0000909143766286623299620*var_58 + 0.0073640645069216496484965*var_59; + const double var_421 = var_135 + var_96; + const double var_422 = var_67 + var_27; + const double var_423 = var_130 + 0.3333333333333333148296163*var_20; + const double var_424 = var_81 + var_210; + const double var_425 = 0.0005423148280291137119519*var_11 + 0.0004566861709718852339705*var_423 + 0.0123305266162409016966750*var_31 + 0.0013415156272299129120579*var_13 + 0.0006374577803149231560245*var_17 + 0.0019980019980019980002650*var_110 + 0.0006184291898577613322621*var_21 + -0.0009038580467151895560599*var_10 + 0.0005137719423433708678881*var_23 + 0.0062508919651776788384279*var_24 + 0.0007706579135150563560422*var_108 + 0.0000285428856857428271232*var_157 + -0.0092478949621806767061871*var_33 + var_420 + 0.0002568859711716854339440*var_422 + 0.0035964035964035964004770*var_421 + -0.0035298035298035298004682*var_38 + 0.0008087150944293801119872*var_8 + -0.0020075162932305786953058*var_9 + 0.0017125731411445697764673*var_424 + -0.0160981875267589558120562*w[0][5]*w[1][5] + var_306 + 0.0004662004662004662000618*var_19 + 0.0016269444840873411358556*var_25 + 0.0015413158270301127120844*var_76 + 0.0006850292564578278238507*var_83 + -0.0001617430188858760169764*var_16 + 0.0002949431520860091898890*var_15 + 0.0047952047952047952006360*var_34 + 0.0028257456828885401528551*var_73 + 0.0013224870367727510882955*var_14 + 0.0029970029970029970003975*var_125 + -0.0017030588459159886477456*var_18 + var_419; + A[162] = 0.2000000000000000111022302*var_425*var_7; + const double var_426 = 0.0002093144950287807390128*var_57 + 0.0001427144284287141390039*var_329 + -0.0000986667653334319985073*w[0][2]*w[1][2] + 0.0000271333604666937992507*var_58 + -0.0005423148280291137119519*var_59; + const double var_427 = var_187 + -0.0000290186004471718747501*var_41 + -0.0001315351315351315350174*var_45 + -0.0000183943041085898257637*var_43 + -0.0000675456231011786501503*w[0][1]*w[1][1] + 0.0000088976279452469916214*var_40 + 0.0000366300366300366300049*var_79; + const double var_428 = -1.0000000000000000000000000*var_161; + const double var_429 = 0.0000118928690357261788150*var_100 + 0.0000423386137671851947519*var_54 + 0.0000057085771371485655940*var_255 + 0.0000062723872247681772512*var_52 + 0.0000156985871271585547483*var_428 + 0.0000135578707007278438152*var_53; + const double var_430 = -0.0005694305694305694300755*var_31 + 0.0000249750249750249750033*var_107 + -0.0003570503570503570319773*var_21; + const double var_431 = 0.0000096992954135811279391*var_13 + 0.0001565101565101565100208*w[0][4]*w[1][4] + -0.0000085628657057228488146*var_30 + 0.0000073207216064358923455*var_17 + 0.0000428143285286142389907*var_32 + -0.0000409114694828980552592*var_27 + var_429 + 0.0000092764378478664185609*var_24 + -0.0000066335780621494908765*var_22 + 0.0000962000962000961954953*var_244 + -0.0001660244517387374490070*w[0][8]*w[1][8] + var_185 + 0.0000123685837971552264420*var_108 + -0.0000304457447314590176309*w[0][7]*w[1][7] + 0.0000171257314114456976291*var_33 + 0.0000366300366300366300049*var_91 + 0.0000682650682650682650091*var_28 + 0.0000485229056657628105139*var_65 + 0.0000041757184614327470627*var_38 + -0.0000141392998535855662456*var_8 + 0.1428571428571428492126927*var_430 + 0.0000632700632700632700084*var_66 + 0.0000713572142143570695020*var_95 + 0.0000254243111385968535059*var_9 + 0.0000577200577200577200077*var_12 + 0.0001017501017501017454960*var_20 + -0.0000178921607493036056242*var_19 + 0.0000481000481000480977476*var_138 + var_427 + 0.0000043871472442901017518*var_16 + 0.0001646501646501646409868*var_64 + 0.0001084629656058227505219*var_146 + 0.0000168350168350168338729*var_15 + -0.0000195571624143052706245*var_14 + 0.0000209314495028780752565*var_36 + 0.0000001057143914286771460*var_18 + -0.0001703058845915988810376*w[0][3]*w[1][3]; + A[33] = var_431*var_7; + A[47] = A[33]; + const double var_432 = var_122 + 3.0000000000000000000000000*var_107; + A[38] = var_354*var_7; + const double var_433 = var_66 + var_27; + const double var_434 = -0.0001733980305408876719780*w[0][9]*w[1][9]; + const double var_435 = 0.0006993006993006993000928*var_255 + 0.0003496503496503496500464*var_233; + const double var_436 = 43.0000000000000000000000000*w[0][0]*w[1][0]; + const double var_437 = var_434 + -0.0000845582988440131335262*var_228 + 0.0000321107463964606792430*var_90 + 0.0000062437562437562437508*var_114 + 0.0000067987567987567987509*var_217 + -0.0000074726860441146156577*var_224 + 0.0000433693290836148007670*var_220 + -0.0000487012987012987012565*var_226 + 0.0000332691999358666055161*var_216 + 0.0000203368060510917648758*var_229 + 0.0000544296972868401487760*var_236 + 0.0000003964289678575393009*var_385 + 0.0035714285714285713170535*var_435 + 0.0000162337662337662337522*var_222 + 0.0000054707197564340426276*var_225 + -0.0000126659055230483799382*var_383 + -0.0000098512598512598512513*var_218 + 0.0000075035194082813135342*var_219 + -0.0000076114361828647544077*var_51 + 0.0000010703582132153561018*var_88 + 0.0000545882688739831567460*var_101 + -0.0000058869701726844580306*var_433 + 0.0000401384329955758507478*var_384 + 0.0000708220351077493972744*var_92 + 0.0000033300033300033300004*var_221 + 0.0000001233334566667899971*var_436 + 0.0000084505441648298791889*var_52 + -0.0000228739514453800177568*var_223 + -0.0000415655772798629902405*var_230 + -0.0001667974882260596467421*var_54; + A[4] = var_437*var_7; + const double var_438 = -0.0000183943041085898257637*var_57 + var_187 + -0.0001315351315351315350174*var_60 + -0.0000675456231011786501503*w[0][2]*w[1][2] + 0.0000088976279452469916214*var_58 + 0.0000366300366300366300049*var_62 + -0.0000290186004471718747501*var_59; + const double var_439 = 0.0018981018981018981002518*var_163 + 0.0000218828790257361705104*var_42 + 0.0000687407830264973160241*var_41 + 0.0000532800532800532800071*var_45 + 0.0000111000111000111000015*var_43 + -0.0000057643708437359238579*var_40; + const double var_440 = -0.0005694305694305694300755*var_30 + 0.0000249750249750249750033*var_129 + -0.0003570503570503570319773*var_20; + const double var_441 = var_438 + 0.0000577200577200577200077*var_11 + -0.0000141392998535855662456*var_13 + -0.0000085628657057228488146*var_31 + -0.0000195571624143052706245*var_17 + -0.0001703058845915988810376*w[0][4]*w[1][4] + 0.0000171257314114456976291*var_32 + 0.0001017501017501017454960*var_21 + 0.0001646501646501646409868*var_23 + 0.0000254243111385968535059*var_10 + var_429 + 0.0000632700632700632700084*var_27 + 0.0000041757184614327470627*var_22 + 0.0000481000481000480977476*var_304 + 0.0000962000962000961954953*var_157 + 0.0000428143285286142389907*var_33 + 0.0001084629656058227505219*var_130 + -0.0000066335780621494908765*var_38 + 0.0000096992954135811279391*var_8 + -0.0001660244517387374490070*w[0][6]*w[1][6] + -0.0000409114694828980552592*var_66 + -0.0000304457447314590176309*w[0][5]*w[1][5] + 0.0000682650682650682650091*var_26 + 0.0000168350168350168338729*var_19 + 0.0000485229056657628105139*var_29 + 0.0000092764378478664185609*var_25 + 0.0000209314495028780752565*var_83 + 0.0000713572142143570695020*var_96 + 0.0000001057143914286771460*var_16 + -0.0000178921607493036056242*var_15 + 0.0000366300366300366300049*var_34 + 0.0000123685837971552264420*var_73 + 0.0000073207216064358923455*var_14 + 0.1428571428571428492126927*var_440 + var_439 + 0.0000043871472442901017518*var_18 + 0.0001565101565101565100208*w[0][3]*w[1][3]; + A[20] = var_441*var_7; + A[76] = A[20]; + const double var_442 = 0.0000729429300857872305172*var_8 + 0.0002283430854859426169853*var_37; + const double var_443 = 0.0001427144284287141390039*var_54 + -0.0000052504814409576312814*var_52 + 0.0000727843584986442089946*var_53 + 0.0000037176227652418131736*w[0][0]*w[1][0] + 0.0000256885971171685447497*var_51 + 0.0000513771942343370894993*var_186 + 0.0000085628657057228488146*var_55; + const double var_444 = -0.0000413871842443270994980*var_42 + -0.0000228343085485942623762*var_41 + 0.0002426145283288140390172*var_46 + var_294 + -0.0000260233593566926892505*w[0][1]*w[1][1] + -0.0000056028627457198890965*var_40; + const double var_445 = var_244 + var_130; + const double var_446 = var_156 + var_37; + const double var_447 = -4.5000000000000000000000000*w[0][7]*w[1][7]; + const double var_448 = 4.6000000000000005329070518*w[0][3]*w[1][3]; + const double var_449 = 0.0003596403596403596400477*var_177 + 0.0001455687169972884179893*var_30 + var_443 + 0.0000277500277500277500037*var_10 + 0.0000513771942343370894993*var_109 + -0.0000461443318586175757674*var_23 + 0.0000042814328528614244073*var_24 + 0.0000204557347414490276296*var_22 + 0.0000856286570572284779813*var_77 + -0.0005223348080490937319492*w[0][8]*w[1][8] + 0.0000499500499500499500066*var_91 + 0.0000057085771371485655940*var_446 + 0.0001812473241044669459640*var_28 + 0.0002140716426430712220584*var_65 + 0.0000288600288600288600038*var_38 + -0.0000287014572728858452576*var_8 + 0.0000613672042243470795006*var_66 + 0.0001198801198801198800159*var_95 + 0.0000166500166500166500022*var_445 + 0.0000309214594928880652579*var_9 + var_261 + var_444 + 0.0000095142952285809423744*var_12 + 0.0000271157414014556876305*var_26 + 0.0000071357214214357067808*var_93 + -0.0000134785849071563364421*var_19 + -0.0000128442985585842723748*var_25 + 0.0000020614306328592044070*var_285 + 0.0000112585826871541164418*var_16 + 0.0000256885971171685447497*var_147 + 0.0000093557236414379276281*var_15 + 0.0001098901098901098900146*var_82 + -0.0000534386248671963015296*var_14 + 0.0000171257314114456976291*var_447 + 0.0000055500055500055500007*var_18 + -0.0000285428856857428271232*var_448 + 0.0000388500388500388500052*var_263; + A[43] = var_449*var_7; + A[197] = A[43]; + const double var_450 = 0.0001115551115551115550148*var_61 + -0.0001642801642801642800218*var_57 + -0.0002430902430902430900322*var_60 + -0.0001235801235801235980864*w[0][2]*w[1][2] + -0.0000407205962761518296643*var_58 + 0.0004778554778554778550634*var_59; + const double var_451 = var_450 + 0.0000799200799200799200106*var_11 + 0.0001824101824101824280942*var_13 + 0.0002697302697302697300358*var_31 + 0.0000475450475450475495238*var_17 + 0.0004095904095904095900543*var_30 + -0.0002047952047952047950272*w[0][4]*w[1][4] + 0.0001061901061901061854966*var_21 + 0.0000828800828800828754935*var_23 + -0.0001206201206201206290510*var_10 + 0.0002014652014652014650267*var_27 + 0.0006809856809856809850903*var_24 + -0.0004847004847004846819943*var_22 + -0.0002214452214452214450294*w[0][8]*w[1][8] + -0.0009690309690309690301285*var_33 + -0.0009207459207459207451221*w[0][7]*w[1][7] + 0.0001443001443001443000191*var_130 + var_50 + 0.0000899100899100899100119*var_65 + var_282 + 0.0001790801790801790709887*var_8 + 0.0000949050949050949050126*var_66 + -0.0001369001369001368909831*var_9 + 0.0004578754578754578750607*var_210 + 0.0001748251748251748250232*var_145 + -0.0000514300514300514345243*var_12 + -0.0028854478854478853369625*w[0][5]*w[1][5] + -0.0000917600917600917690472*var_20 + 0.0000416250416250416250055*var_26 + 0.0000297850297850297827452*var_19 + 0.0000299700299700299700040*var_29 + 0.0004811854811854811850638*var_25 + -0.0000989750989750989704956*var_16 + -0.0000057350057350057355654*var_15 + 0.0000697450697450697495268*var_14 + var_323 + -0.0001655751655751655569519*var_18; + const double var_452 = var_51 + var_43; + const double var_453 = var_144 + var_36; + const double var_454 = var_291 + 2.0000000000000000000000000*var_60; + const double var_455 = var_29 + var_33; + const double var_456 = var_76 + var_96; + const double var_457 = var_369 + var_98; + const double var_458 = var_14 + var_16; + const double var_459 = -1.0000000000000000000000000*var_458; + const double var_460 = 0.0727272727272727237401995*var_358 + 0.0060606060606060606008039*var_459 + 0.0666666666666666657414808*var_289; + const double var_461 = var_81 + var_91; + const double var_462 = var_45 + var_55; + const double var_463 = var_10 + var_11; + const double var_464 = var_34 + var_83; + const double var_465 = var_42 + var_53; + const double var_466 = var_41 + var_54; + const double var_467 = var_73 + var_107; + const double var_468 = var_122 + var_304; + const double var_469 = var_368 + var_59; + const double var_470 = 4.8571428571428567622092487*var_464 + 3.1005291005291004680088918*w[0][2]*w[1][2] + 6.7142857142857135244184974*var_461 + 6.5714285714285711748061658*var_462 + -9.1428571428571423496123316*var_466 + var_355 + -4.1428571428571423496123316*var_469 + 2.4285714285714283811046243*var_467 + var_465 + -0.8412698412698412786525637*var_463 + 0.0158730158730158721347436*var_468 + 0.6666666666666666296592325*var_357 + 0.6031746031746031411202580*var_372; + const double var_471 = 0.0093240093240093240012367*var_453 + 0.0002590002590002590181044*var_366 + 0.0023976023976023976003180*var_455 + 0.0001603334936668270060446*var_58 + 0.0004662004662004662000618*var_470 + 0.0011988011988011988001590*var_456 + 0.0004884004884004884000648*var_452 + 0.0017390017390017389279505*var_356 + 0.0013986013986013986001855*var_454 + 0.0012210012210012210001620*var_460 + 0.0005994005994005994000795*var_371 + 0.0007992007992007992001060*var_457 + 0.0001998001998001998000265*var_62 + 0.0013320013320013320001767*var_57; + const double var_472 = -1.0000000000000000000000000*var_217; + const double var_473 = var_224 + var_115 + var_472; + const double var_474 = 0.0001027543884686741789986*var_65; + const double var_475 = var_29 + var_31; + const double var_476 = var_115 + var_111; + const double var_477 = var_476 + var_475; + const double var_478 = var_8 + var_262; + const double var_479 = var_29 + var_96; + const double var_480 = var_122 + var_156; + const double var_481 = var_217 + var_384; + const double var_482 = -0.0003096903096903096900411*var_53 + -0.0003696303696303696300490*var_226 + -0.0004495504495504495500596*var_54 + 0.0000388500388500388500052*var_227 + 0.0002497502497502497500331*var_94 + 0.0013186813186813186801749*var_88 + 0.0004662004662004662000618*var_51 + var_435 + 0.0005994005994005994000795*var_92 + 0.0000366300366300366300049*var_220 + 0.0004273504273504273500567*var_480 + 0.0020979020979020979002783*var_380 + 0.0016183816183816183802147*var_383 + 0.0000699300699300699300093*var_224 + 0.0000111000111000111000015*var_237 + -0.0000799200799200799200106*var_223 + -0.0010489510489510489501391*var_222 + 0.0001098901098901098900146*var_481 + 0.0009712509712509712501288*var_221 + -0.0001931401931401931400256*var_90 + 0.0001156867823534490094745*var_219 + 0.0000640100640100640190435*var_216 + 0.0000023433356766690098121*var_52 + 0.0006193806193806193800822*var_101 + -0.0001298701298701298700172*var_218 + 0.0010789210789210789201431*var_300 + 0.0000259000259000259011328*var_436; + const double var_483 = -0.0001008515294229580020434*var_57 + -0.0006536320822035107279066*var_60 + -0.0002703469370136036740125*w[0][2]*w[1][2] + -0.0000738943596086453325473*var_58 + 0.0000285428856857428271232*var_62 + 0.0005965463108320250397790*var_59; + const double var_484 = -0.0002283430854859426169853*var_42 + 0.0002654488368774082980052*var_41 + 0.0012987012987012987001723*var_46 + -0.0002530802530802530800336*var_43 + -0.0008337341670675003880639*w[0][1]*w[1][1] + -0.0000369647988695607745057*var_40; + const double var_485 = -0.0000463029034457605905136*var_17; + const double var_486 = 0.0013986013986013986001855*var_35 + 0.0001198801198801198800159*var_274 + var_268 + -0.0001477887192172906650946*var_11 + 0.0002226345083487940590145*var_275 + -0.0000567686281971996315300*var_13 + -0.0004623947481090337919413*var_30 + -0.0019294990723562150877757*w[0][4]*w[1][4] + 0.0003938918224632510420823*var_32 + -0.0012321012321012321001634*var_23 + 0.0000976800976800976800130*var_10 + 0.0002711574140145568559759*var_27 + 0.0000713572142143570695020*var_24 + 0.0000488400488400488400065*var_22 + 0.0002568859711716854339440*var_33 + -0.0181818181818181809350499*var_411 + var_485 + var_483 + 0.0006964464107321250482124*var_28 + 0.0002854288568574282780078*var_84 + 0.0000754800754800754800100*var_38 + -0.0001366887081172795650932*var_8 + 0.0006022548879691736519598*var_66 + 0.0002886002886002886000383*var_9 + 0.0008391608391608391601113*var_210 + 0.0019980019980019980002650*var_145 + 0.0004528804528804528800601*var_12 + 0.0003824746681889538719307*var_26 + -0.0001563515849230135020508*var_20 + -0.0001195629767058338505234*var_19 + var_484 + var_415 + 0.0000802372230943659495031*var_16 + -0.0001411287125572839779887*var_64 + -0.0000091971520542949128818*var_15 + -0.0001509601509601509600200*var_14 + -0.0001712573141144569559627*var_36 + 0.0000574029145457716905151*var_18; + const double var_487 = 0.0002654488368774082980052*var_54 + 0.0012987012987012987001723*var_255 + -0.0000369647988695607745057*var_52 + -0.0002283430854859426169853*var_53 + -0.0008337341670675003880639*w[0][0]*w[1][0] + -0.0002530802530802530800336*var_51; + const double var_488 = -0.0000463029034457605905136*var_15; + const double var_489 = 0.0000028542885685742827970*var_28; + const double var_490 = 0.0299145299145299192744574*var_38 + 0.0348508634222919957967868*var_32; + const double var_491 = -1.0000000000000000000000000*var_142; + const double var_492 = -1.0000000000000000000000000*var_120; + const double var_493 = 0.0002854288568574282780078*var_35 + 0.0000976800976800976800130*var_11 + 0.0003938918224632510420823*var_31 + 0.0004528804528804528800601*var_13 + -0.0000091971520542949128818*var_17 + 0.0000754800754800754800100*var_21 + 0.0000488400488400488400065*var_23 + -0.0001477887192172906650946*var_10 + 0.0003824746681889538719307*var_27 + 0.0006022548879691736519598*var_24 + -0.0012321012321012321001634*var_22 + 0.0001198801198801198800159*var_492 + var_487 + var_483 + -0.0004623947481090337919413*var_65 + 0.0013986013986013986001855*var_84 + 0.0002886002886002886000383*var_8 + -0.0019294990723562150877757*w[0][6]*w[1][6] + 0.0000713572142143570695020*var_66 + -0.0001366887081172795650932*var_9 + var_488 + -0.0000567686281971996315300*var_12 + 0.0019980019980019980002650*var_37 + -0.0001411287125572839779887*var_20 + 0.0002711574140145568559759*var_26 + 0.0000574029145457716905151*var_19 + 0.0002568859711716854339440*var_29 + 0.0006964464107321250482124*var_25 + -0.0001509601509601509600200*var_16 + -0.0001563515849230135020508*var_64 + 0.0002226345083487940590145*var_491 + var_489 + 0.0008391608391608391601113*var_82 + -0.0001712573141144569559627*var_144 + 0.0000802372230943659495031*var_14 + var_106 + -0.0001195629767058338505234*var_18 + -0.0181818181818181809350499*var_490; + const double var_494 = var_244 + var_122; + const double var_495 = 0.0000666000666000666000088*var_100 + 0.0000727843584986442089946*var_54 + var_256 + 0.0000199800199800199800027*var_255 + -0.0000012333345666679000237*var_436 + -0.0000047395285490523587200*var_52 + 0.0000014271442842871413985*var_53; + const double var_496 = 0.0000727843584986442089946*var_61 + 0.0000256885971171685447497*var_57 + 0.0000085628657057228488146*var_60 + 0.0000037176227652418131736*w[0][2]*w[1][2] + -0.0000052504814409576312814*var_58 + 0.0001427144284287141390039*var_59; + const double var_497 = var_138 + var_210; + const double var_498 = var_122 + var_39; + const double var_499 = -4.5000000000000000000000000*w[0][4]*w[1][4]; + const double var_500 = 4.6000000000000005329070518*w[0][8]*w[1][8]; + const double var_501 = var_495 + -0.0000287014572728858452576*var_11 + 0.0000277500277500277500037*var_13 + 0.0000171257314114456976291*var_499 + 0.0000388500388500388500052*var_110 + 0.0000055500055500055500007*var_17 + 0.0002140716426430712220584*var_32 + 0.0001198801198801198800159*var_177 + -0.0000461443318586175757674*var_21 + -0.0000128442985585842723748*var_27 + 0.0000271157414014556876305*var_24 + 0.0001455687169972884179893*var_33 + 0.0000613672042243470795006*var_28 + 0.0001098901098901098900146*var_84 + 0.0001812473241044669459640*var_66 + 0.0003596403596403596400477*var_95 + 0.0000095142952285809423744*var_9 + var_444 + 0.0000309214594928880652579*var_12 + 0.0000042814328528614244073*var_26 + 0.0000204557347414490276296*var_20 + -0.0000534386248671963015296*var_19 + 0.0000856286570572284779813*var_76 + 0.0000513771942343370894993*var_96 + 0.0000093557236414379276281*var_16 + 0.0000288600288600288600038*var_64 + 0.0000071357214214357067808*var_107 + 0.0000166500166500166500022*var_498 + 0.0000057085771371485655940*var_497 + 0.0000256885971171685447497*var_146 + 0.0000112585826871541164418*var_15 + 0.0000020614306328592044070*var_137 + -0.0000134785849071563364421*var_14 + 0.0000499500499500499500066*var_36 + var_496 + -0.0000285428856857428271232*var_500 + -0.0005223348080490937319492*w[0][3]*w[1][3]; + A[13] = var_501*var_7; + A[195] = A[13]; + const double var_502 = 0.0000190285904571618847488*var_57 + 0.0003139717425431711220717*var_278 + 0.0013320013320013320001767*var_184 + -0.0000059904821809583709991*var_58 + 0.0004281432852861424441168*var_59; + const double var_503 = 0.0000694191170381646489775*var_58 + 0.0000818229389657961105184*var_57 + 0.0000337933671267004592516*w[0][2]*w[1][2] + 0.0001769658912516055410385*var_60; + const double var_504 = 0.0000188523998047807549942*w[0][0]*w[1][0] + 0.0001046572475143903695064*var_51 + 0.0000627943485086342189933*var_52 + 0.0000399600399600399600053*var_55; + const double var_505 = 0.0348508634222919957967868*var_29 + 0.0299145299145299192744574*var_23; + const double var_506 = 0.0000656486370772084979787*var_25 + 0.0012987012987012987001723*var_144 + var_70 + 0.0001366887081172795650932*var_19 + 0.0003539317825032110820770*w[0][7]*w[1][7] + var_504 + 0.0004681033252461824041221*w[0][4]*w[1][4] + var_503 + var_407 + 0.0000513771942343370894993*var_36 + 0.0002051916337630623420572*var_14 + 0.0002568859711716854339440*var_91 + 0.0006771006771006771000898*var_21 + 0.0028971028971028971003843*w[0][8]*w[1][8] + 0.0002220002220002220000294*var_8 + 0.0181818181818181809350499*var_505 + 0.0001509601509601509600200*var_11 + 0.0010446696160981874638984*var_31; + const double var_507 = 0.0006964464107321250482124*var_54 + 0.0002083630655059226369826*var_53; + const double var_508 = 0.0000028542885685742827970*var_27; + const double var_509 = -1.0000000000000000000000000*var_506 + 0.0000612086326372040715306*var_15 + 0.0001741116026830312620531*var_26 + 0.0000031714317428603144071*var_20 + var_508 + 0.0000260057402914545776303*var_22 + 0.0001056086770372484579840*var_24 + 0.0008020550877693734519863*var_28 + 0.0000948258091115234010276*var_38 + 0.0000707229278657850105169*var_64 + var_416 + var_155 + 0.0000003171431742860314513*var_13 + 0.0000041228612657184088140*var_17 + 0.0002553002553002553000339*var_12 + 0.0004452690166975881180290*var_32 + var_410 + 0.0002397602397602397600318*var_65 + 0.0000840429411857983305187*var_16 + 0.0005965463108320250397790*var_66 + var_507 + 0.0000269571698143126728842*var_18 + 0.0003085803085803085800409*var_9 + 0.0000231514517228802952568*var_10; + const double var_510 = 0.0000009514295228580943010*var_158; + const double var_511 = -0.0000413871842443270994980*var_61 + -0.0000260233593566926892505*w[0][2]*w[1][2] + var_510 + -0.0000056028627457198890965*var_58 + 0.0002426145283288140390172*var_241 + -0.0000228343085485942623762*var_59; + const double var_512 = 0.0000014271442842871413985*var_42 + 0.0000727843584986442089946*var_41 + -0.0000012333345666679000237*var_49 + 0.0000666000666000666000088*var_44 + 0.0000199800199800199800027*var_46 + -0.0000047395285490523587200*var_40; + const double var_513 = var_84 + var_122; + const double var_514 = var_157 + var_146; + const double var_515 = -4.5000000000000000000000000*w[0][5]*w[1][5]; + const double var_516 = 4.6000000000000005329070518*w[0][4]*w[1][4]; + const double var_517 = 0.0000095142952285809423744*var_11 + -0.0000285428856857428271232*var_516 + -0.0000287014572728858452576*var_13 + 0.0001455687169972884179893*var_31 + -0.0000534386248671963015296*var_17 + var_443 + var_512 + 0.0000309214594928880652579*var_10 + 0.0000856286570572284779813*var_109 + 0.0000613672042243470795006*var_27 + 0.0000166500166500166500022*var_514 + 0.0000513771942343370894993*var_77 + -0.0000128442985585842723748*var_24 + 0.0000288600288600288600038*var_22 + 0.0000071357214214357067808*var_67 + 0.0000271157414014556876305*var_28 + 0.0000204557347414490276296*var_38 + -0.0005223348080490937319492*w[0][6]*w[1][6] + 0.0000020614306328592044070*var_71 + 0.0000277500277500277500037*var_9 + 0.0001098901098901098900146*var_145 + 0.0001812473241044669459640*var_26 + 0.0000093557236414379276281*var_19 + 0.0002140716426430712220584*var_29 + 0.0000042814328528614244073*var_25 + 0.0003596403596403596400477*var_76 + 0.0001198801198801198800159*var_96 + 0.0000171257314114456976291*var_515 + 0.0000055500055500055500007*var_16 + -0.0000461443318586175757674*var_64 + 0.0000057085771371485655940*var_513 + 0.0000388500388500388500052*var_147 + -0.0000134785849071563364421*var_15 + 0.0000499500499500499500066*var_34 + var_511 + 0.0000112585826871541164418*var_18 + 0.0000256885971171685447497*var_263; + A[29] = var_517*var_7; + const double var_518 = var_73 + var_108; + const double var_519 = var_91 + var_36; + const double var_520 = var_81 + var_83; + const double var_521 = var_67 + var_73; + const double var_522 = var_521 + 2.0000000000000000000000000*var_45; + const double var_523 = var_107 + var_93; + const double var_524 = 0.0083116883116883116811024*var_98; + const double var_525 = var_57 + var_51; + const double var_526 = var_163 + var_525; + const double var_527 = var_195 + var_396; + const double var_528 = var_524 + 0.0140259740259740268292221*var_476 + 0.0561038961038961073168885*var_519 + 0.0222222222222222230703093*var_192 + 0.0045192667414889631932740*var_40 + 0.0014814814814814814079164*var_89 + 0.0170594837261503935732510*var_190 + 0.0114478114478114480906390*var_212 + 0.0299567099567099558166117*var_198 + 0.0036940836940836940804900*var_43 + -0.0024434824434824437694447*var_191 + 0.0093506493506493506412403*var_205 + 0.0155844155844155844020671*var_202 + 0.0055411255411255411207350*var_201 + 0.0030399230399230400649635*var_75 + -0.0062722462722462728190731*var_196 + 0.0062337662337662337608268*var_527 + -0.0126406926406926415490384*var_204 + 0.0008658008658008658001148*var_522 + 0.0018577307466196356193489*var_193 + 0.0342857142857142874192711*var_520 + 0.0063492063492063492008421*var_526 + -0.0050216450216450216406661*var_42 + 0.0173160173160173160022968*var_523 + -0.0043867243867243867205818*var_200 + -0.0529870129870129852323046*var_41 + -0.0015776815776815777524894*var_194 + 0.0029822029822029819112750*var_197; + const double var_529 = var_138 + var_156; + const double var_530 = var_288 + var_210 + 9.0000000000000000000000000*var_31; + const double var_531 = var_77 + var_95; + const double var_532 = 0.0008905380333951762360581*var_47; + const double var_533 = 0.0121212121212121212016077*var_57 + 0.0335097001763668411733477*w[0][2]*w[1][2]; + const double var_534 = var_58 + 15.5714285714285711748061658*var_61; + const double var_535 = var_115 + var_117; + const double var_536 = var_535 + var_389; + const double var_537 = var_79 + var_114; + const double var_538 = var_467 + var_537; + const double var_539 = 0.1333333333333333314829616*var_533 + 0.0002226345083487940590145*var_111 + -0.0006294234865663437964237*var_366 + -0.0001264344121486978770718*var_372 + 0.0005729250173694618334871*var_357 + 0.0035621521335807049442324*var_453 + 0.0060606060606060606008039*var_454 + 0.0001731601731601731600230*var_534 + -0.0024434824434824437694447*var_463 + 0.0002281316567030852910953*var_355 + 0.0009400123685837972163648*var_462 + 0.0013358070500927641914568*var_464 + 0.0008080808080808080801072*var_452 + 0.0052910052910052907115812*var_356 + 0.0072727272727272727209646*var_536 + 0.0002721088435374149580061*var_368 + 0.0181818181818181809350499*var_461 + 0.0012121212121212121201608*var_538 + 0.0222222222222222230703093*var_460 + 0.0029684601113172540479135*var_531 + -0.0007173778602350031844553*var_371 + -0.0001016972445543874140235*var_362 + var_532; + A[83] = 0.1538461538461538546940233*var_539*var_7; + const double var_540 = 0.0001480662194947909154896*var_42 + 0.0003746253746253746250497*var_41 + 0.0006324033109747394720487*var_45 + var_148 + 0.0000011892869035726177968*var_43 + 0.0002169127169127169215638*w[0][1]*w[1][1] + -0.0001134667801334468030267*var_40; + const double var_541 = -0.0001079277864992150782943*var_61 + 0.0000576804148232719612389*var_57 + -0.0000029291695958362626886*w[0][2]*w[1][2] + 0.0000178393035535892673755*var_60 + -0.0001495418162084828780315*var_58 + 0.0005619380619380619917846*var_59; + const double var_542 = 0.0001665001665001665000221*var_100 + -0.0002720493791922363232411*var_54 + 0.0006868131868131868668012*var_255 + 0.0000096794739651882502488*var_52 + -0.0002640216925931211720650*var_53 + -0.0023726273726273725168945*w[0][0]*w[1][0]; + const double var_543 = var_210 + var_96; + const double var_544 = 0.0000720509649081077632521*var_11 + 0.0006529185100613672191466*var_31 + 0.0005133755133755133750681*var_13 + 0.0010683760683760684835619*var_110 + 0.0000307232450089592985191*var_17 + -0.0000963322391893820445053*var_30 + 0.0003288378288378288375436*var_21 + -0.0000831509760081188632535*var_10 + 0.0003746253746253746250497*var_109 + 0.0001657073085644514059619*var_23 + 0.0000205151990866276556183*var_27 + 0.0002497502497502497500331*var_24 + 0.0009098044812330525988806*w[0][8]*w[1][8] + 0.0017898767898767899836576*var_39 + 0.0024350649350649354422937*var_84 + 0.0008741258741258741251159*var_8 + var_540 + -0.0003041601255886970363654*var_66 + -0.0003127824556395984809815*var_9 + -0.0000882054453483024930192*var_12 + 0.0000286419929277072138807*var_20 + -0.0000383545026402169229938*var_26 + 0.0001193251193251193250158*var_19 + 0.0006047523904666762036703*var_29 + 0.0004370629370629370625580*var_25 + 0.0001248751248751248750166*var_515 + -0.0001277492348920920503270*var_16 + -0.0000465804037232608680137*var_64 + 0.0002140716426430712220584*var_543 + 0.0000111000111000111000015*var_15 + var_542 + 0.0001855287569573283779946*var_81 + 0.0003282431853860424898935*var_73 + 0.0001273528059242345032969*var_14 + var_541 + -0.0000653116724545295992662*var_18 + 0.0009722420436706150905989*w[0][3]*w[1][3]; + A[10] = 0.2000000000000000111022302*var_544*var_7; + const double var_545 = 0.6000000000000000888178420*var_73 + var_27; + A[53] = 0.2857142857142856984253854*var_128*var_7; + A[123] = A[53]; + const double var_546 = -1.0000000000000000000000000*var_184; + const double var_547 = 0.0000697714983429269084867*var_163 + 0.0004909376337947766360051*var_117 + 0.0000685029256457827905166*var_43 + 0.0000181828753257324693805*var_40 + 0.0000513771942343370894993*var_79; + const double var_548 = var_156 + var_110; + const double var_549 = var_35 + var_304; + const double var_550 = -4.5000000000000000000000000*w[0][3]*w[1][3]; + const double var_551 = 4.6000000000000005329070518*w[0][6]*w[1][6]; + const double var_552 = var_495 + 0.0000309214594928880652579*var_11 + 0.0001455687169972884179893*var_32 + -0.0000134785849071563364421*var_17 + -0.0005223348080490937319492*w[0][4]*w[1][4] + 0.0000856286570572284779813*var_177 + 0.0000057085771371485655940*var_549 + 0.0000166500166500166500022*var_548 + 0.0000204557347414490276296*var_21 + 0.0000095142952285809423744*var_10 + 0.0000288600288600288600038*var_23 + 0.0001812473241044669459640*var_27 + 0.0002140716426430712220584*var_33 + 0.0000256885971171685447497*var_130 + 0.0000071357214214357067808*var_129 + -0.0000285428856857428271232*var_551 + 0.0000388500388500388500052*var_39 + 0.0000042814328528614244073*var_28 + 0.0000277500277500277500037*var_8 + -0.0000128442985585842723748*var_66 + 0.0000513771942343370894993*var_95 + var_259 + -0.0000287014572728858452576*var_12 + 0.0001098901098901098900146*var_37 + 0.0000613672042243470795006*var_26 + -0.0000461443318586175757674*var_20 + 0.0000112585826871541164418*var_19 + 0.0000271157414014556876305*var_25 + 0.0001198801198801198800159*var_76 + 0.0000499500499500499500066*var_83 + 0.0003596403596403596400477*var_96 + -0.0000534386248671963015296*var_15 + 0.0000055500055500055500007*var_14 + 0.0000171257314114456976291*var_550 + var_511 + 0.0000093557236414379276281*var_18 + 0.0000020614306328592044070*var_344; + A[14] = var_552*var_7; + const double var_553 = var_98 + var_396; + const double var_554 = var_46 + var_475; + const double var_555 = 2.0000000000000000000000000*var_554 + -4.0000000000000000000000000*var_202 + -16.0000000000000000000000000*var_553 + var_42 + var_206; + const double var_556 = 0.0000799200799200799200106*var_57 + 0.0000025371453942882516104*var_184 + 0.0000148704910609672526944*var_58 + 0.0000685029256457827905166*var_241 + 0.0001198801198801198800159*var_62 + -0.0003482232053660625241062*var_59; + const double var_557 = -2.0000000000000000000000000*var_31 + var_32; + const double var_558 = var_65 + -2.0000000000000000000000000*var_29; + const double var_559 = 0.0005137719423433708678881*var_558 + 0.0002220002220002220000294*var_146 + var_340 + 0.0003330003330003330000442*var_147 + 0.0006850292564578278238507*var_557 + 0.0000856286570572284779813*var_93; + const double var_560 = -1.0000000000000000000000000*var_89; + const double var_561 = 0.0060606060606060606008039*var_560 + 0.0666666666666666657414808*var_191 + 0.0727272727272727237401995*var_196; + const double var_562 = var_108 + var_129; + const double var_563 = 6.5714285714285711748061658*var_198 + -0.8412698412698412786525637*var_197 + var_190 + 6.7142857142857135244184974*var_195 + 0.6031746031746031411202580*var_192 + 4.8571428571428567622092487*var_519 + -9.1428571428571423496123316*var_203 + 0.0158730158730158721347436*var_529 + 2.4285714285714283811046243*var_562 + var_201 + -4.1428571428571423496123316*var_254 + 0.6666666666666666296592325*var_193 + 3.1005291005291004680088918*w[0][1]*w[1][1]; + const double var_564 = 0.0001603334936668270060446*var_40 + 0.0012210012210012210001620*var_561 + 0.0093240093240093240012367*var_520 + 0.0004884004884004884000648*var_525 + 0.0001998001998001998000265*var_79 + 0.0013986013986013986001855*var_522 + 0.0023976023976023976003180*var_202 + 0.0011988011988011988001590*var_205 + 0.0004662004662004662000618*var_563 + 0.0007992007992007992001060*var_553 + 0.0005994005994005994000795*var_212 + 0.0013320013320013320001767*var_43 + 0.0002590002590002590181044*var_75 + 0.0017390017390017389279505*var_194; + A[84] = 0.0571428571428571410728559*var_564*var_7; + A[140] = A[84]; + const double var_565 = var_26 + var_129; + const double var_566 = var_147 + var_304; + const double var_567 = var_244 + var_82; + const double var_568 = 4.6000000000000005329070518*w[0][7]*w[1][7]; + const double var_569 = 0.0001098901098901098900146*var_35 + 0.0000166500166500166500022*var_566 + 0.0000309214594928880652579*var_13 + 0.0002140716426430712220584*var_31 + 0.0000112585826871541164418*var_17 + 0.0000256885971171685447497*var_110 + var_512 + -0.0000287014572728858452576*var_10 + 0.0001198801198801198800159*var_109 + 0.0000042814328528614244073*var_27 + 0.0003596403596403596400477*var_77 + 0.0001812473241044669459640*var_24 + var_258 + -0.0000461443318586175757674*var_38 + 0.0000095142952285809423744*var_8 + 0.0000020614306328592044070*var_345 + 0.0000171257314114456976291*var_168 + 0.0000271157414014556876305*var_66 + 0.0000277500277500277500037*var_12 + -0.0000285428856857428271232*var_568 + -0.0005223348080490937319492*w[0][5]*w[1][5] + -0.0000128442985585842723748*var_26 + 0.0000288600288600288600038*var_20 + 0.0001455687169972884179893*var_29 + 0.0000613672042243470795006*var_25 + 0.0000513771942343370894993*var_76 + 0.0000856286570572284779813*var_96 + -0.0000134785849071563364421*var_16 + 0.0000057085771371485655940*var_567 + 0.0000204557347414490276296*var_64 + 0.0000388500388500388500052*var_146 + 0.0000055500055500055500007*var_15 + 0.0000499500499500499500066*var_144 + 0.0000071357214214357067808*var_73 + 0.0000093557236414379276281*var_14 + var_496 + -0.0000534386248671963015296*var_18; + A[27] = var_569*var_7; + const double var_570 = 0.0006371406371406371400845*var_163 + 0.0001798201798201798200239*var_42 + 0.0031968031968031968004240*var_41 + 0.0003596403596403596400477*var_45 + 0.0001998001998001998000265*var_43 + -0.0001593468260134926739978*var_40; + const double var_571 = 0.0013186813186813186801749*var_54 + 0.0004595404595404595400610*var_114 + 0.0000399600399600399600053*var_255 + -0.0001766135099468432679767*var_52 + -0.0004129204129204129200548*var_51 + -0.0008547008547008547001134*var_161; + const double var_572 = var_14 + var_8; + const double var_573 = 0.5000000000000000000000000*var_304 + var_21; + const double var_574 = var_34 + var_96; + const double var_575 = var_145 + var_557 + 9.0000000000000000000000000*var_33; + const double var_576 = 0.0007836607836607836601039*var_11 + 0.0002397602397602397600318*var_575 + 0.0005194805194805194800689*var_499 + -0.0000510600510600510600068*var_17 + 0.0010789210789210789201431*var_30 + 0.0004817404817404817400639*var_10 + 0.0002153402153402153400286*var_23 + 0.0013786213786213786201829*var_27 + 0.0004662004662004662000618*var_156 + 0.0004995004995004995000663*var_334 + -0.0002863802863802863800380*var_22 + 0.0000488400488400488400065*var_573 + var_160 + 0.0003774003774003774000501*var_157 + 0.0004595404595404595400610*var_129 + 0.0001198801198801198800159*var_84 + -0.0001909201909201909200253*var_38 + 0.0001887001887001887000250*var_572 + -0.0005794205794205794200769*w[0][6]*w[1][6] + var_571 + -0.0018093018093018093002400*var_20 + 0.0006593406593406593400875*var_26 + 0.0002686202686202686200356*var_19 + 0.0000022200022200022200003*var_16 + -0.0015473415473415473402052*var_64 + -0.0002908202908202908200386*var_15 + var_570 + 0.0000599400599400599400080*var_73 + 0.0010389610389610389601378*var_36 + 0.0003219003219003219000427*var_18 + 0.0003596403596403596400477*var_574; + A[52] = 0.1428571428571428492126927*var_576*var_7; + const double var_577 = -2.0000000000000000000000000*var_30 + var_33; + const double var_578 = 0.0001548451548451548450205*var_41 + -0.0011621711621711621701541*var_45 + -0.0001309801309801309800174*var_43 + -0.0003467725689947911906115*w[0][1]*w[1][1] + -0.0000257150257150257172622*var_40 + 0.0002680652680652680650356*var_79; + const double var_579 = -0.0005694305694305694300755*var_29 + -0.0003570503570503570319773*var_23 + 0.0000249750249750249750033*var_93; + const double var_580 = -0.0001369001369001368909831*var_11 + 0.0000799200799200799200106*var_13 + -0.0009690309690309690301285*var_31 + 0.0000297850297850297827452*var_17 + -0.0002214452214452214450294*w[0][4]*w[1][4] + 0.0000299700299700299700040*var_30 + 0.0004095904095904095900543*var_32 + 0.0001443001443001443000191*var_110 + var_579 + -0.0004847004847004846819943*var_21 + -0.0000514300514300514345243*var_10 + 0.0002014652014652014650267*var_24 + -0.0028854478854478853369625*w[0][8]*w[1][8] + 0.0000899100899100899100119*var_33 + 0.0006809856809856809850903*var_28 + 0.0002697302697302697300358*var_65 + 0.0004578754578754578750607*var_84 + -0.0000917600917600917690472*var_38 + -0.0001206201206201206290510*var_8 + var_56 + 0.0004811854811854811850638*var_66 + 0.0001824101824101824280942*var_9 + var_280 + 0.0001748251748251748250232*var_210 + 0.0001790801790801790709887*var_12 + -0.0002047952047952047950272*w[0][5]*w[1][5] + 0.0000949050949050949050126*var_26 + 0.0000828800828800828754935*var_20 + -0.0000989750989750989704956*var_19 + 0.0000416250416250416250055*var_25 + 0.0000475450475450475495238*var_16 + 0.0001061901061901061854966*var_64 + var_578 + 0.0000697450697450697495268*var_15 + -0.0001655751655751655569519*var_14 + -0.0000057350057350057355654*var_18 + -0.0009207459207459207451221*w[0][3]*w[1][3]; + const double var_581 = 0.1333333333333333314829616*var_51 + var_55; + const double var_582 = 15.5714285714285711748061658*var_53 + var_52; + const double var_583 = var_404 + 0.0005155338488671821518816*w[0][0]*w[1][0] + 0.0000199800199800199800027*var_582 + 0.0013986013986013986001855*var_581; + const double var_584 = 0.0001027543884686741789986*var_29; + const double var_585 = 0.0000656486370772084979787*var_26 + 0.0003539317825032110820770*w[0][6]*w[1][6] + 0.0002568859711716854339440*var_144 + 0.0006771006771006771000898*var_22 + 0.0028971028971028971003843*w[0][5]*w[1][5] + 0.0000513771942343370894993*var_81 + 0.0010446696160981874638984*var_33 + var_215 + 0.0181818181818181809350499*var_490 + var_584 + 0.0012987012987012987001723*var_83 + var_408 + var_583 + 0.0001366887081172795650932*var_16 + 0.0004681033252461824041221*w[0][8]*w[1][8] + 0.0002051916337630623420572*var_18 + 0.0001509601509601509600200*var_9 + 0.0002220002220002220000294*var_10; + const double var_586 = var_35 + var_95; + const double var_587 = 0.0003746253746253746250497*var_54 + -0.0001134667801334468030267*var_52 + 0.0000011892869035726177968*var_51 + 0.0002169127169127169215638*w[0][0]*w[1][0] + 0.0001480662194947909154896*var_53 + 0.0006324033109747394720487*var_55; + const double var_588 = var_369 + var_461; + const double var_589 = var_158 + var_462; + const double var_590 = 2.0000000000000000000000000*var_453 + var_589 + var_467 + var_99 + var_452 + var_390; + const double var_591 = var_9 + var_285; + const double var_592 = 0.0006993006993006993000928*var_46 + 0.0003496503496503496500464*var_206; + const double var_593 = var_201 + var_75; + const double var_594 = 0.0016183816183816183802147*var_519 + 0.0004273504273504273500567*var_392 + 0.0002497502497502497500331*var_562 + 0.0000023433356766690098121*var_40 + 0.0000366300366300366300049*var_212 + 0.0000640100640100640190435*var_190 + 0.0000699300699300699300093*var_89 + 0.0000259000259000259011328*var_49 + -0.0001298701298701298700172*var_191 + 0.0006193806193806193800822*var_198 + 0.0004662004662004662000618*var_43 + 0.0020979020979020979002783*var_205 + 0.0013186813186813186801749*var_202 + -0.0000799200799200799200106*var_196 + -0.0010489510489510489501391*var_195 + -0.0001931401931401931400256*var_525 + 0.0001156867823534490094745*var_193 + 0.0005994005994005994000795*var_520 + var_592 + -0.0003696303696303696300490*var_199 + -0.0003096903096903096900411*var_42 + 0.0000111000111000111000015*var_394 + 0.0010789210789210789201431*var_553 + 0.0000388500388500388500052*var_200 + -0.0004495504495504495500596*var_41 + 0.0001098901098901098900146*var_593 + 0.0009712509712509712501288*var_194; + A[28] = 0.1428571428571428492126927*var_594*var_7; + const double var_595 = 0.0000197950197950197961320*var_191 + 0.0000566100566100566100075*var_42 + 0.0000325864611578897302581*var_41 + 0.0001665001665001665000221*var_45 + var_290 + 0.0000555000555000555000074*var_43 + 0.0000832500832500832500110*var_521 + 0.0006857340190673524241843*w[0][1]*w[1][1] + 0.0000002496034242065987916*var_40; + const double var_596 = 0.0002497502497502497500331*var_111 + 0.0000116550116550116550015*var_61 + -0.0000068185782471496764412*var_57 + -0.0000007282546965086647396*w[0][2]*w[1][2] + 0.0000523756079311634846658*var_58 + 0.0000218828790257361705104*var_241; + const double var_597 = var_23 + 0.5000000000000000000000000*var_157; + const double var_598 = 0.0004995004995004995000663*var_34 + 0.0000349650349650349650046*var_24; + const double var_599 = 0.0000349650349650349650046*var_26 + 0.0004995004995004995000663*var_144; + const double var_600 = 0.0000197950197950197961320*var_11 + 0.0000072942930085787232211*var_13 + -0.0000599400599400599400080*var_32 + -0.0000118400118400118405663*var_17 + 0.0005698005698005697639355*var_21 + -0.0000058935773221487511588*var_10 + 0.0000102278673707245138148*var_27 + var_352 + -0.0000137957280814423676287*var_22 + 0.3333333333333333148296163*var_599 + var_595 + -0.0000670757813614956510239*var_33 + var_598 + -0.0000483643340786197957677*var_38 + 0.0000710400710400710400094*var_8 + 0.0002849002849002848819678*var_597 + -0.0000637457780314923210235*w[0][6]*w[1][6] + -0.0002571502571502571319641*var_9 + -0.0001279672708244136930620*w[0][5]*w[1][5] + 0.0000048100048100048102830*var_20 + 0.0000313971742543171094967*var_25 + 0.0000028542885685742827970*var_76 + 0.0000199800199800199800027*var_83 + -0.0000184207327064469914999*var_16 + -0.0000084307227164370031927*var_64 + -0.0000113642970785827912453*var_15 + 0.0000266400266400266400035*var_81 + -0.0000196100196100196122614*var_18 + var_596; + const double var_601 = 0.3333333333333333148296163*var_38 + var_110; + const double var_602 = var_25 + var_28; + const double var_603 = var_26 + var_27; + const double var_604 = -0.5000000000000000000000000*var_603 + var_60; + const double var_605 = 0.0001998001998001998000265*var_98; + const double var_606 = 0.0002873669540336207120848*var_357 + 0.0002766281337709909290967*var_464 + 0.0002497502497502497500331*var_389 + -0.0000591075591075591075078*var_465 + 0.0001456876456876456875193*var_462 + -0.0000926454497883069330198*var_59 + -0.0000341325341325341325045*var_368 + var_605 + 0.0026584526584526586671930*var_356 + 0.0000394050394050394050052*var_452 + 0.0001246901246901247080866*var_289 + -0.0000077832220689363545632*var_362 + 0.0000240500240500240488738*var_459 + 0.0001902726902726902544552*var_358 + 0.0000204983141491077987901*var_58 + 0.0002414252414252414250320*var_61 + 0.0022311022311022311002959*var_461 + 0.0000558759288918019060848*var_355 + -0.0012570762570762571835870*var_463 + 0.0000499500499500499500066*var_531 + -0.0000616975616975617020257*var_371 + 0.0002886002886002886000383*var_57 + 0.0011155511155511155501480*var_604 + -0.0009906759906759907835516*var_466 + 0.0001048951048951048950139*var_369 + -0.0001115551115551115550148*var_602 + 0.0000092632235489378356928*var_372 + 0.0079950913284246617751538*w[0][2]*w[1][2] + 0.0005827505827505827500773*var_453 + -0.0000498575498575498529891*var_366; + A[97] = var_493*var_7; + A[111] = A[97]; + const double var_607 = var_76 + var_82; + const double var_608 = 0.0024350649350649354422937*var_35 + -0.0000831509760081188632535*var_11 + -0.0000882054453483024930192*var_13 + 0.0003746253746253746250497*var_177 + 0.0006529185100613672191466*var_32 + 0.0000111000111000111000015*var_17 + 0.0000720509649081077632521*var_10 + -0.0000383545026402169229938*var_27 + 0.0001657073085644514059619*var_22 + -0.0003041601255886970363654*var_24 + 0.0006047523904666762036703*var_33 + 0.0009098044812330525988806*w[0][7]*w[1][7] + var_149 + 0.0001855287569573283779946*var_91 + 0.0004370629370629370625580*var_28 + -0.0000963322391893820445053*var_65 + 0.0003288378288378288375436*var_38 + -0.0003127824556395984809815*var_8 + var_587 + 0.0002497502497502497500331*var_66 + 0.0008741258741258741251159*var_9 + 0.0005133755133755133750681*var_12 + 0.0009722420436706150905989*w[0][5]*w[1][5] + -0.0000465804037232608680137*var_20 + 0.0000205151990866276556183*var_26 + -0.0000653116724545295992662*var_19 + 0.0002140716426430712220584*var_607 + 0.0001273528059242345032969*var_16 + 0.0000286419929277072138807*var_64 + 0.0003282431853860424898935*var_107 + 0.0017898767898767899836576*var_147 + 0.0010683760683760684835619*var_146 + 0.0000307232450089592985191*var_15 + -0.0001277492348920920503270*var_14 + 0.0001248751248751248750166*var_550 + var_541 + 0.0001193251193251193250158*var_18; + A[25] = 0.2000000000000000111022302*var_608*var_7; + A[151] = A[25]; + const double var_609 = var_109 + var_96; + const double var_610 = 0.0000394050394050394050052*var_525 + -0.0009906759906759907835516*var_203 + 0.0001902726902726902544552*var_196 + 0.0001456876456876456875193*var_198 + 0.0002886002886002886000383*var_43 + -0.0000616975616975617020257*var_212 + -0.0000498575498575498529891*var_75 + 0.0001246901246901247080866*var_191 + 0.0002497502497502497500331*var_475 + var_605 + 0.0002766281337709909290967*var_519 + -0.0012570762570762571835870*var_197 + 0.0005827505827505827500773*var_520 + 0.0002873669540336207120848*var_193 + 0.0001048951048951048950139*var_396 + -0.0000341325341325341325045*var_199 + -0.0000077832220689363545632*var_200 + 0.0079950913284246617751538*w[0][1]*w[1][1] + 0.0000240500240500240488738*var_560 + -0.0000591075591075591075078*var_201 + 0.0026584526584526586671930*var_194 + 0.0000558759288918019060848*var_190 + 0.0000499500499500499500066*var_609 + -0.0000926454497883069330198*var_41 + 0.0022311022311022311002959*var_195 + -0.0001115551115551115550148*var_204 + 0.0000092632235489378356928*var_192 + 0.0000204983141491077987901*var_40 + 0.0002414252414252414250320*var_42 + 0.0011155511155511155501480*var_207; + A[16] = 0.1250000000000000000000000*var_610*var_7; + const double var_611 = var_102 + var_92; + const double var_612 = var_117 + var_111; + const double var_613 = var_518 + var_612; + const double var_614 = var_225 + var_217; + const double var_615 = var_138 + var_304; + const double var_616 = 0.0000095142952285809423744*var_614 + -0.0009932924218638504963719*var_54 + 0.0000475714761429047152601*var_227 + 0.0001198801198801198800159*var_433 + 0.0001636458779315922210367*var_220 + 0.0001883830455259026569800*var_613 + -0.0006850292564578278238507*var_383 + -0.0001370058512915655810332*var_222 + 0.0000818229389657961105184*var_615 + 0.0000608914894629180352618*var_221 + 0.0000932400932400932400124*var_381 + 0.0003253888968174682380131*var_384 + 0.0000799200799200799200106*var_428 + 0.0001940916226630512420558*var_90 + 0.0000348857491714634542434*var_219 + 0.0000621600621600621600082*var_216 + 0.0000274857417714560587599*var_52 + 0.0000685029256457827905166*var_611 + -0.0000704057846914989810243*var_218 + 0.0000513771942343370894993*var_302 + 0.0002759145616288473119165*var_236; + A[72] = var_616*var_7; + const double var_617 = -0.0000882054453483024930192*var_11 + 0.0008741258741258741251159*var_13 + -0.0000963322391893820445053*var_31 + var_303 + 0.0017898767898767899836576*var_110 + 0.0001273528059242345032969*var_17 + 0.0006529185100613672191466*var_30 + 0.0009722420436706150905989*w[0][4]*w[1][4] + 0.0000286419929277072138807*var_21 + -0.0003127824556395984809815*var_10 + -0.0000465804037232608680137*var_23 + -0.0003041601255886970363654*var_27 + 0.0003746253746253746250497*var_77 + 0.0004370629370629370625580*var_24 + 0.0003282431853860424898935*var_108 + var_150 + 0.0010683760683760684835619*var_39 + -0.0000383545026402169229938*var_28 + 0.0006047523904666762036703*var_65 + 0.0005133755133755133750681*var_8 + 0.0009098044812330525988806*w[0][6]*w[1][6] + 0.0000205151990866276556183*var_66 + -0.0000831509760081188632535*var_9 + 0.0000720509649081077632521*var_12 + 0.0024350649350649354422937*var_37 + 0.0003288378288378288375436*var_20 + 0.0000111000111000111000015*var_19 + 0.0002497502497502497500331*var_25 + -0.0000653116724545295992662*var_16 + 0.0001657073085644514059619*var_64 + 0.0001193251193251193250158*var_15 + 0.0002140716426430712220584*var_586 + var_542 + 0.0001855287569573283779946*var_144 + 0.0000307232450089592985191*var_14 + 0.0001248751248751248750166*var_447 + -0.0001277492348920920503270*var_18; + A[7] = 0.2000000000000000111022302*var_617*var_7; + const double var_618 = 0.0000832500832500832500110*var_111 + -0.0000663622092193520745013*var_60 + -0.0000159276349752540227517*w[0][2]*w[1][2] + 0.0000321078098855876600749*var_58 + var_510; + const double var_619 = var_263 + 0.3333333333333333148296163*var_64; + const double var_620 = 0.0169544740973312409171303*w[0][9]*w[1][9]; + const double var_621 = -0.0028792635935493077550817*var_203 + 0.0041743970315398885861935*var_205 + -0.0007373578802150230560378*var_196 + 0.0070108462965605819125492*var_198 + 0.0017411160268303125121109*var_43 + 0.0016566766566766567836400*var_212 + 0.0004899862042719184797648*var_75 + -0.0001129822558393986945075*var_191 + 0.0287284144427001585098136*var_519 + 0.0006981114123971266047924*var_197 + 0.0072998430141287288727692*var_520 + var_620 + 0.0001793180364608935829437*var_193 + 0.0093763379477665182576418*var_396 + -0.0023333809048094759572289*var_199 + 0.0012713476999191284429885*var_89 + -0.0019528090956662383977788*var_200 + 0.0002529216814931100178535*w[0][1]*w[1][1] + -0.0013058370201227344382933*var_201 + 0.0046881689738832591288209*var_202 + -0.0006112934684363255941411*var_194 + 0.0029489029489029486112706*var_190 + 0.0027187098615670040810399*var_41 + 0.0019694591123162550477810*var_195 + -0.0046774653917511059553203*var_204 + 0.0014402264402264403336112*var_192 + 0.0008311794026079740100102*var_40 + -0.0010382474668188953429576*var_42 + 0.0000071357214214357067808*var_209 + 0.0010489510489510489501391*var_207; + A[112] = 0.2000000000000000111022302*var_621*var_7; + const double var_622 = var_44 + var_198; + const double var_623 = var_520 + var_622; + const double var_624 = var_156 + 3.0000000000000000000000000*var_129; + const double var_625 = -0.0005423148280291137119519*var_54 + 0.0000271333604666937992507*var_52 + -0.0000986667653334319985073*w[0][0]*w[1][0] + 0.0002093144950287807390128*var_51 + 0.0001427144284287141390039*var_359; + const double var_626 = 0.0002568859711716854339440*var_79; + const double var_627 = -0.0000077523887047696566868*var_40 + -0.0000007047626095245142539*w[0][1]*w[1][1] + 0.0003996003996003996000530*var_117 + var_626; + const double var_628 = var_108 + var_24; + const double var_629 = 0.3333333333333333148296163*var_21 + var_146; + const double var_630 = var_66 + var_344; + const double var_631 = var_137 + var_12; + const double var_632 = var_29 + var_35; + const double var_633 = var_625 + 0.0001998001998001998000265*var_25 + 0.0003583717869432155220775*var_20 + 0.0002759145616288473119165*var_15 + 0.0003996003996003996000530*var_144 + var_326 + 0.0005708577137148565560157*var_516 + var_502 + 0.0001712573141144569559627*var_632 + 0.0001427144284287141390039*var_631 + 0.0000983143840286697525506*var_304 + 0.0001966287680573395051011*var_64 + 0.0000475714761429047152601*var_345 + 0.0000761143618286475389951*var_629 + 0.0002949431520860091898890*var_13 + 0.0000095142952285809423744*var_14 + 0.0001046572475143903695064*var_17 + -0.0010275438846867417357761*var_83 + 0.0004566861709718852339705*var_91 + var_627 + 0.0000856286570572284779813*var_630 + var_442 + 0.0008562865705722848882336*var_126 + 0.0001744287458573172779931*var_138 + 0.0003710575139146567559892*var_628 + 0.0008848294562580276238772*var_93 + 0.0001554001554001554000206*var_244; + A[104] = 0.8000000000000000444089210*var_633*var_7; + const double var_634 = 0.0001141715427429713084926*var_100; + const double var_635 = 0.0000856286570572284779813*var_129 + 0.0002220002220002220000294*var_263 + 0.0003330003330003330000442*var_130 + 0.0006850292564578278238507*var_288 + 0.0005137719423433708678881*var_577 + var_634; + const double var_636 = 0.0013320013320013320001767*var_163 + 0.0004281432852861424441168*var_41 + 0.0003139717425431711220717*var_331 + 0.0000190285904571618847488*var_43 + -0.0000059904821809583709991*var_40; + const double var_637 = var_327 + 0.0003996003996003996000530*var_115 + -0.0000007047626095245142539*w[0][0]*w[1][0] + -0.0000077523887047696566868*var_52; + const double var_638 = 0.0000729429300857872305172*var_10 + 0.0002283430854859426169853*var_82; + const double var_639 = var_32 + var_37; + const double var_640 = var_285 + var_25; + const double var_641 = 0.0001998001998001998000265*var_26 + 0.0004566861709718852339705*var_144 + 0.0000856286570572284779813*var_640 + 0.0001046572475143903695064*var_19 + 0.0001554001554001554000206*var_304 + var_637 + 0.0000761143618286475389951*var_308 + 0.0002759145616288473119165*var_14 + var_426 + 0.0000475714761429047152601*var_344 + 0.0008562865705722848882336*var_127 + 0.0003996003996003996000530*var_83 + 0.0008848294562580276238772*var_73 + 0.0001712573141144569559627*var_639 + -0.0010275438846867417357761*var_91 + 0.0003583717869432155220775*var_23 + var_635 + 0.0001966287680573395051011*var_21 + 0.0003710575139146567559892*var_422 + var_636 + 0.0005708577137148565560157*var_500 + 0.0001744287458573172779931*var_157 + 0.0000983143840286697525506*var_156 + var_638 + 0.0000095142952285809423744*var_18 + 0.0001427144284287141390039*var_478 + 0.0002949431520860091898890*var_11; + A[88] = 0.8000000000000000444089210*var_641*var_7; + const double var_642 = 0.0006850292564578278238507*var_558 + 0.0003330003330003330000442*var_146 + 0.0000856286570572284779813*var_107 + 0.0002220002220002220000294*var_147 + 0.0005137719423433708678881*var_557 + var_634; + const double var_643 = var_626 + 0.0000285428856857428271232*var_41 + -0.0010275438846867417357761*var_45 + 0.0000570857713714856542463*var_43 + -0.0001480001480001479909846*w[0][1]*w[1][1] + -0.0000165619213238260851249*var_40; + const double var_644 = var_53 + 4.0000000000000000000000000*var_55; + const double var_645 = 0.0000444000444000444000059*var_161 + 0.0009704581133152561560687*var_54 + -0.0000387619435238482885160*var_52 + 0.0000856286570572284779813*var_644; + const double var_646 = var_142 + var_166; + const double var_647 = 0.0005708577137148565560157*var_35 + -0.0001363715649429935220481*var_11 + 0.0003425146282289139119254*var_30 + 0.0004281432852861424441168*var_646 + 0.0000475714761429047152601*var_156 + var_642 + var_643 + 0.0001141715427429713084926*var_91 + 0.0000570857713714856542463*var_84 + 0.0000761143618286475389951*var_38 + 0.0001554001554001554000206*var_345 + var_638 + 0.0005994005994005994000795*var_66 + 0.0001490572919144347830648*var_9 + 0.0029684601113172540479135*var_145 + 0.0001046572475143903695064*var_12 + -0.0001078286792572506915368*var_20 + 0.0001427144284287141390039*var_26 + 0.0000285428856857428271232*var_93 + 0.0000031714317428603144071*var_285 + 0.0000729429300857872305172*var_16 + -0.0000602572031143459762768*var_64 + 0.0000539143396286253457684*var_15 + var_330 + -0.0000983143840286697525506*var_14 + var_645 + 0.0009704581133152561560687*var_36 + 0.0001300287014572728779872*var_18 + 0.0000856286570572284779813*var_122; + A[57] = 0.8000000000000000444089210*var_647*var_7; + const double var_648 = var_458 + var_111 + var_367; + const double var_649 = 0.0000732600732600732600097*var_100 + 0.0010406260406260407335582*var_54 + 0.0000699300699300699300093*var_255 + 0.0000008633341966675299531*var_436 + -0.0000659217325883992535029*var_52 + 0.0000649350649350649350086*var_53 + var_48; + const double var_650 = var_450 + -0.0001206201206201206290510*var_11 + -0.0000514300514300514345243*var_13 + 0.0002697302697302697300358*var_32 + -0.0000057350057350057355654*var_17 + 0.0000899100899100899100119*var_30 + -0.0004847004847004846819943*var_23 + 0.0000799200799200799200106*var_10 + 0.0000416250416250416250055*var_27 + 0.0000949050949050949050126*var_24 + 0.0000828800828800828754935*var_22 + -0.0009207459207459207451221*w[0][8]*w[1][8] + -0.0002214452214452214450294*w[0][7]*w[1][7] + 0.0000299700299700299700040*var_33 + 0.0004811854811854811850638*var_28 + 0.0004095904095904095900543*var_65 + 0.0001061901061901061854966*var_38 + -0.0001369001369001368909831*var_8 + -0.0002047952047952047950272*w[0][6]*w[1][6] + var_430 + 0.0006809856809856809850903*var_66 + 0.0001790801790801790709887*var_9 + 0.0001824101824101824280942*var_12 + var_649 + 0.0001748251748251748250232*var_37 + 0.0002014652014652014650267*var_26 + -0.0001655751655751655569519*var_19 + -0.0009690309690309690301285*var_29 + 0.0000697450697450697495268*var_16 + -0.0000917600917600917690472*var_64 + var_578 + 0.0000475450475450475495238*var_15 + 0.0004578754578754578750607*var_82 + -0.0000989750989750989704956*var_14 + 0.0000297850297850297827452*var_18 + -0.0028854478854478853369625*w[0][3]*w[1][3] + 0.0001443001443001443000191*var_263; + A[3] = 0.1428571428571428492126927*var_650*var_7; + const double var_651 = var_226 + var_228; + const double var_652 = -0.0005180005180005180362088*var_216 + 0.0023976023976023976003180*var_51 + 0.0005328005328005328000707*var_221 + 0.0004662004662004662000618*var_480 + 0.0001332001332001332000177*var_161 + 0.0071928071928071928009540*var_651 + var_391 + -0.0012654012654012654001678*var_227 + 0.0001628001628001628090566*var_52 + 0.0019980019980019980002650*var_472 + -0.0002220002220002220000294*var_219 + 0.0053946053946053946007155*var_53 + 0.0008658008658008658001148*var_223 + var_87 + 0.0083916083916083916011130*var_360 + 0.0002664002664002664000353*var_350; + A[209] = 0.2285714285714285642914234*var_652*var_7; + A[223] = A[209]; + A[21] = 0.1428571428571428492126927*var_451*var_7; + A[91] = A[21]; + const double var_653 = 0.0005965463108320250397790*var_54 + 0.0000285428856857428271232*var_114 + -0.0000738943596086453325473*var_52 + -0.0001008515294229580020434*var_51 + -0.0002703469370136036740125*w[0][0]*w[1][0] + -0.0006536320822035107279066*var_55; + const double var_654 = var_325 + 0.0003330003330003330000442*var_263 + 0.0002220002220002220000294*var_130 + 0.0005137719423433708678881*var_288 + 0.0000856286570572284779813*var_67 + 0.0006850292564578278238507*var_577; + const double var_655 = 0.0004281432852861424441168*var_54 + -0.0000059904821809583709991*var_52 + 0.0003139717425431711220717*var_644 + 0.0000190285904571618847488*var_51 + 0.0013320013320013320001767*var_161; + const double var_656 = var_28 + var_262; + const double var_657 = var_145 + var_31; + const double var_658 = var_333 + 0.0000856286570572284779813*var_656 + 0.0003996003996003996000530*var_34 + 0.0003583717869432155220775*var_22 + 0.0001998001998001998000265*var_27 + 0.0000095142952285809423744*var_19 + -0.0010275438846867417357761*var_81 + 0.0001966287680573395051011*var_38 + 0.0001427144284287141390039*var_591 + var_655 + 0.0004566861709718852339705*var_36 + var_426 + 0.0000761143618286475389951*var_181 + 0.0008848294562580276238772*var_107 + var_627 + var_654 + 0.0002759145616288473119165*var_16 + 0.0003710575139146567559892*var_565 + 0.0005708577137148565560157*var_568 + 0.0001554001554001554000206*var_122 + 0.0000475714761429047152601*var_71 + 0.0008562865705722848882336*var_178 + 0.0000983143840286697525506*var_157 + 0.0001744287458573172779931*var_156 + 0.0001046572475143903695064*var_18 + 0.0001712573141144569559627*var_657 + 0.0002949431520860091898890*var_10; + A[196] = A[28]; + const double var_659 = 0.0008163265306122449282283*var_111 + 0.0037105751391465677767323*var_61 + 0.0024242424242424242403215*var_57 + 0.0181818181818181809350499*var_60 + 0.0089359200470311584557637*w[0][2]*w[1][2] + 0.0002886002886002886000383*var_58; + const double var_660 = 0.0000325864611578897302581*var_54 + 0.0000197950197950197961320*var_218 + 0.0000002496034242065987916*var_52 + var_290 + 0.0000555000555000555000074*var_51 + 0.0006857340190673524241843*w[0][0]*w[1][0] + 0.0000566100566100566100075*var_53 + 0.0001665001665001665000221*var_55 + 0.0000832500832500832500110*var_378; + const double var_661 = 0.0000349650349650349650046*var_27 + 0.0004995004995004995000663*var_36; + const double var_662 = 0.0000349650349650349650046*var_66 + 0.0004995004995004995000663*var_83; + const double var_663 = var_662 + -0.0000058935773221487511588*var_11 + -0.0000599400599400599400080*var_31 + -0.0000113642970785827912453*var_17 + -0.0000637457780314923210235*w[0][4]*w[1][4] + -0.0000483643340786197957677*var_21 + 0.0000197950197950197961320*var_10 + -0.0000137957280814423676287*var_23 + var_660 + 0.3333333333333333148296163*var_661 + 0.0000266400266400266400035*var_91 + 0.0000313971742543171094967*var_28 + 0.0005698005698005697639355*var_38 + -0.0002571502571502571319641*var_8 + 0.0000710400710400710400094*var_9 + var_295 + 0.0000072942930085787232211*var_12 + 0.0000102278673707245138148*var_26 + -0.0000084307227164370031927*var_20 + -0.0000196100196100196122614*var_19 + -0.0000670757813614956510239*var_29 + 0.0002849002849002848819678*var_248 + 0.0000028542885685742827970*var_96 + 0.0000048100048100048102830*var_64 + -0.0000118400118400118405663*var_15 + 0.0000199800199800199800027*var_34 + -0.0000184207327064469914999*var_14 + var_596 + -0.0001279672708244136930620*w[0][3]*w[1][3]; + A[9] = var_663*var_7; + const double var_664 = 0.0035714285714285713170535*var_592 + var_434 + 0.0000321107463964606792430*var_525 + -0.0000415655772798629902405*var_203 + 0.0000062437562437562437508*var_79 + 0.0000001233334566667899971*var_49 + -0.0000228739514453800177568*var_196 + 0.0000545882688739831567460*var_198 + -0.0000076114361828647544077*var_43 + 0.0000433693290836148007670*var_212 + 0.0000067987567987567987509*var_75 + -0.0000098512598512598512513*var_191 + 0.0000203368060510917648758*var_475 + -0.0000126659055230483799382*var_519 + 0.0000054707197564340426276*var_197 + 0.0000708220351077493972744*var_520 + 0.0000075035194082813135342*var_193 + -0.0000845582988440131335262*var_396 + -0.0000487012987012987012565*var_199 + -0.0000074726860441146156577*var_89 + 0.0000401384329955758507478*var_201 + 0.0000010703582132153561018*var_202 + 0.0000033300033300033300004*var_194 + 0.0000332691999358666055161*var_190 + -0.0001667974882260596467421*var_41 + 0.0000162337662337662337522*var_195 + -0.0000058869701726844580306*var_204 + 0.0000544296972868401487760*var_192 + 0.0000084505441648298791889*var_40 + 0.0000003964289678575393009*var_529; + A[22] = var_664*var_7; + const double var_665 = 0.0002568859711716854339440*var_62; + const double var_666 = 0.0000570857713714856542463*var_57 + -0.0010275438846867417357761*var_60 + -0.0001480001480001479909846*w[0][2]*w[1][2] + var_665 + -0.0000165619213238260851249*var_58 + 0.0000285428856857428271232*var_59; + const double var_667 = 0.0002283430854859426169853*var_145 + 0.0000729429300857872305172*var_9; + const double var_668 = var_178 + var_249; + const double var_669 = 0.0001046572475143903695064*var_11 + 0.0003425146282289139119254*var_31 + 0.0004281432852861424441168*var_668 + -0.0000983143840286697525506*var_17 + -0.0001078286792572506915368*var_21 + 0.0001490572919144347830648*var_10 + -0.0000602572031143459762768*var_23 + 0.0005994005994005994000795*var_27 + 0.0000856286570572284779813*var_156 + 0.0000761143618286475389951*var_22 + var_635 + 0.0000285428856857428271232*var_67 + var_667 + 0.0001427144284287141390039*var_28 + var_342 + 0.0000031714317428603144071*var_71 + 0.0005708577137148565560157*var_210 + -0.0001363715649429935220481*var_12 + 0.0000570857713714856542463*var_37 + 0.0000539143396286253457684*var_19 + var_666 + 0.0009704581133152561560687*var_83 + 0.0001300287014572728779872*var_16 + 0.0001554001554001554000206*var_262 + 0.0029684601113172540479135*var_82 + 0.0001141715427429713084926*var_34 + var_645 + 0.0000729429300857872305172*var_18 + 0.0000475714761429047152601*var_122; + A[87] = 0.8000000000000000444089210*var_669*var_7; + A[185] = A[87]; + const double var_670 = -0.0005423148280291137119519*var_41 + 0.0001427144284287141390039*var_80 + 0.0002093144950287807390128*var_43 + -0.0000986667653334319985073*w[0][1]*w[1][1] + 0.0000271333604666937992507*var_40; + const double var_671 = var_66 + var_93; + const double var_672 = var_84 + var_33; + const double var_673 = var_345 + var_13; + const double var_674 = 0.0001046572475143903695064*var_15 + 0.0001966287680573395051011*var_20 + var_667 + 0.0001712573141144569559627*var_672 + -0.0010275438846867417357761*var_34 + var_642 + 0.0008848294562580276238772*var_108 + 0.0003710575139146567559892*var_671 + 0.0001998001998001998000265*var_28 + var_502 + 0.0004566861709718852339705*var_81 + 0.0003583717869432155220775*var_64 + var_637 + 0.0003996003996003996000530*var_36 + 0.0002759145616288473119165*var_17 + 0.0002949431520860091898890*var_12 + var_670 + 0.0005708577137148565560157*var_551 + 0.0000095142952285809423744*var_16 + 0.0000983143840286697525506*var_122 + 0.0001554001554001554000206*var_138 + 0.0000856286570572284779813*var_72 + 0.0001427144284287141390039*var_673 + 0.0008562865705722848882336*var_120 + 0.0000475714761429047152601*var_137 + 0.0000761143618286475389951*var_601 + 0.0001744287458573172779931*var_244; + A[59] = 0.8000000000000000444089210*var_674*var_7; + A[213] = A[59]; + const double var_675 = 0.0001741116026830312620531*var_61 + 0.0001332001332001332000177*var_158 + -0.0000247371675943104528839*var_173 + -0.0001444058586915729900692*var_58 + 0.0000742115027829313484873*var_241 + 0.0015812758669901526720897*var_59 + var_104; + const double var_676 = -0.0000463029034457605905136*var_18; + const double var_677 = -1.0000000000000000000000000*var_178; + const double var_678 = -1.0000000000000000000000000*var_127; + const double var_679 = 0.0019980019980019980002650*var_35 + -0.0001366887081172795650932*var_11 + 0.0000976800976800976800130*var_13 + 0.0000574029145457716905151*var_17 + 0.0002568859711716854339440*var_30 + -0.0181818181818181809350499*var_505 + -0.0012321012321012321001634*var_21 + -0.0000567686281971996315300*var_10 + -0.0001563515849230135020508*var_22 + 0.0003824746681889538719307*var_24 + var_676 + var_508 + -0.0019294990723562150877757*w[0][7]*w[1][7] + -0.0004623947481090337919413*var_33 + -0.0001712573141144569559627*var_91 + var_675 + 0.0006022548879691736519598*var_28 + 0.0003938918224632510420823*var_65 + -0.0001411287125572839779887*var_38 + -0.0001477887192172906650946*var_8 + 0.0006964464107321250482124*var_66 + 0.0004528804528804528800601*var_9 + 0.0013986013986013986001855*var_145 + 0.0001198801198801198800159*var_677 + var_653 + 0.0002886002886002886000383*var_12 + 0.0008391608391608391601113*var_37 + 0.0000488400488400488400065*var_20 + 0.0000713572142143570695020*var_26 + -0.0001509601509601509600200*var_19 + 0.0002711574140145568559759*var_25 + var_484 + -0.0000091971520542949128818*var_16 + 0.0000754800754800754800100*var_64 + 0.0000802372230943659495031*var_15 + 0.0002226345083487940590145*var_678 + 0.0002854288568574282780078*var_82 + -0.0001195629767058338505234*var_14; + A[161] = var_679*var_7; + const double var_680 = 0.0001824101824101824280942*var_11 + -0.0001369001369001368909831*var_13 + 0.0000899100899100899100119*var_31 + 0.0000299700299700299700040*var_32 + -0.0028854478854478853369625*w[0][4]*w[1][4] + -0.0000989750989750989704956*var_17 + var_63 + 0.0001790801790801790709887*var_10 + -0.0000917600917600917690472*var_23 + 0.0006809856809856809850903*var_27 + 0.0001061901061901061854966*var_22 + -0.0002047952047952047950272*w[0][8]*w[1][8] + 0.0002697302697302697300358*var_33 + 0.0002014652014652014650267*var_28 + -0.0009690309690309690301285*var_65 + 0.0001748251748251748250232*var_84 + 0.0000828800828800828754935*var_38 + -0.0000514300514300514345243*var_8 + -0.0009207459207459207451221*w[0][6]*w[1][6] + 0.0000416250416250416250055*var_66 + 0.0000799200799200799200106*var_9 + 0.0004578754578754578750607*var_145 + -0.0001206201206201206290510*var_12 + var_649 + -0.0002214452214452214450294*w[0][5]*w[1][5] + 0.0004811854811854811850638*var_26 + 0.0000475450475450475495238*var_19 + 0.0004095904095904095900543*var_29 + 0.0000949050949050949050126*var_25 + 0.0000297850297850297827452*var_16 + -0.0004847004847004846819943*var_64 + 0.0001443001443001443000191*var_147 + -0.0001655751655751655569519*var_15 + -0.0000057350057350057355654*var_14 + var_281 + var_440 + 0.0000697450697450697495268*var_18; + A[5] = 0.1428571428571428492126927*var_680*var_7; + A[129] = 0.2857142857142856984253854*var_320*var_7; + A[143] = A[129]; + const double var_681 = var_77 + var_37; + const double var_682 = 0.0395604395604395586705238*var_681 + 0.3076923076923077093880465*var_34; + const double var_683 = var_62 + var_114; + const double var_684 = 0.0003296703296703296700437*var_255; + const double var_685 = 0.0000149850149850149850020*var_683 + var_684 + 0.0001298701298701298700172*var_525 + -0.0040459540459540461673771*var_203 + 0.0008991008991008991001193*var_196 + 0.0014585414585414585401935*var_43 + -0.0002147852147852147850285*var_212 + -0.0005211455211455211450691*var_75 + 0.0004578754578754578750607*var_191 + 0.0000899100899100899100119*var_475 + -0.0013936063936063937136051*var_197 + var_242 + 0.0001798201798201798200239*var_85 + 0.0003233803233803233981129*var_193 + 0.0003596403596403596400477*var_396 + 0.0000366300366300366300049*var_394 + 0.0007042957042957042950934*var_199 + 0.0002097902097902097900278*var_211 + -0.0001615051615051615050214*var_89 + -0.0001215451215451215450161*var_200 + 0.0025097125097125099271733*w[0][1]*w[1][1] + var_239 + 0.0033916083916083914970296*var_194 + -0.0000194250194250194250026*var_190 + 0.0017982017982017982002385*var_609 + 0.0004645354645354645350616*var_41 + 0.0038211788211788212839271*var_195 + 0.0001004551004551004550133*var_40 + 0.0019930069930069928968441*var_42 + 0.0003746253746253746250497*var_562 + 0.0044655344655344653137519*var_207; + const double var_686 = 0.0001798201798201798200239*var_61 + 0.0001998001998001998000265*var_57 + 0.0003596403596403596400477*var_60 + 0.0006371406371406371400845*var_184 + -0.0001593468260134926739978*var_58 + 0.0031968031968031968004240*var_59; + const double var_687 = var_91 + var_95; + const double var_688 = 9.0000000000000000000000000*var_32 + var_82 + var_577; + const double var_689 = 0.0004995004995004995000663*var_347 + 0.0001887001887001887000250*var_134 + 0.0010789210789210789201431*var_31 + -0.0018093018093018093002400*var_21 + -0.0015473415473415473402052*var_23 + -0.0001909201909201909200253*var_22 + 0.0003774003774003774000501*var_244 + -0.0005794205794205794200769*w[0][8]*w[1][8] + 0.0000599400599400599400080*var_108 + 0.0002397602397602397600318*var_688 + 0.0006593406593406593400875*var_28 + -0.0002863802863802863800380*var_38 + 0.0000488400488400488400065*var_296 + 0.0013786213786213786201829*var_66 + var_571 + 0.0004817404817404817400639*var_9 + 0.0003596403596403596400477*var_687 + 0.0007836607836607836601039*var_12 + 0.0001198801198801198800159*var_37 + -0.0002908202908202908200386*var_19 + 0.0010389610389610389601378*var_83 + 0.0003219003219003219000427*var_16 + 0.0002153402153402153400286*var_64 + var_245 + 0.0004595404595404595400610*var_107 + 0.0002686202686202686200356*var_15 + var_686 + -0.0000510600510600510600068*var_14 + 0.0005194805194805194800689*var_550 + 0.0000022200022200022200003*var_18 + 0.0004662004662004662000618*var_122; + const double var_690 = -1.0000000000000000000000000*var_220; + const double var_691 = 0.0001123876123876123875149*var_97 + var_208 + 0.0004120879120879120875547*var_380 + -0.0000800125800125800034756*var_217 + -0.0001736689236689236597380*var_224 + 0.0005661005661005661000751*var_226 + 0.0059003496503496500463770*var_238 + -0.0057217473884140545095645*var_216 + -0.0039238539238539236336800*var_236 + 0.0001685814185814185812724*var_222 + -0.0004671254671254670889219*var_225 + 0.0007950382950382950918156*var_234 + 0.0002411939911939912028170*var_218 + -0.0002578697023141467603753*var_219 + 0.0004023754023754023750534*var_51 + 0.0004495504495504495500596*var_88 + -0.0014131701631701631960425*var_101 + 0.0028490028490028491449382*var_690 + 0.0008470695970695970959674*var_433 + -0.0002643190143190143458901*var_384 + 0.0003733920400587067370962*w[0][0]*w[1][0] + 0.0007517945017945017486746*var_221 + 0.0015068265068265069336201*var_227 + -0.0008263598541376319678992*var_52 + 0.0014938764938764938390581*var_223 + 0.0005272505272505272500699*var_418 + 0.0000770063270063270062602*var_53 + 0.0003933566433566433834072*var_231 + 0.0001498501498501498500199*var_230 + 0.0035776723276723276963296*var_54; + A[17] = 0.0071428571428571426341070*var_691*var_7; + const double var_692 = 0.0007992007992007992001060*var_100 + 0.0000599400599400599400080*var_115 + var_159 + -0.0000717800717800717890445*var_52 + -0.0011388611388611388601511*var_53 + -0.0011637744971078303919676*w[0][0]*w[1][0] + -0.0020379620379620379602703*var_55; + const double var_693 = var_109 + var_144; + const double var_694 = 9.0000000000000000000000000*var_30 + var_35 + var_558; + const double var_695 = 0.0004817404817404817400639*var_13 + 0.0003219003219003219000427*var_17 + 0.0004995004995004995000663*var_545 + 0.0002153402153402153400286*var_21 + 0.0002397602397602397600318*var_694 + 0.0006593406593406593400875*var_24 + -0.0018093018093018093002400*var_22 + 0.0003774003774003774000501*var_304 + 0.0004595404595404595400610*var_108 + var_692 + 0.0010789210789210789201431*var_33 + var_246 + 0.0010389610389610389601378*var_91 + 0.0000599400599400599400080*var_67 + -0.0015473415473415473402052*var_38 + 0.0007836607836607836601039*var_8 + 0.0000488400488400488400065*var_597 + 0.0003596403596403596400477*var_693 + -0.0005794205794205794200769*w[0][5]*w[1][5] + -0.0002863802863802863800380*var_20 + 0.0013786213786213786201829*var_25 + 0.0004662004662004662000618*var_138 + -0.0002908202908202908200386*var_16 + -0.0001909201909201909200253*var_64 + 0.0001887001887001887000250*var_315 + 0.0000022200022200022200003*var_15 + var_570 + 0.0001198801198801198800159*var_82 + 0.0002686202686202686200356*var_14 + 0.0005194805194805194800689*var_447 + -0.0000510600510600510600068*var_18; + const double var_696 = 0.0000513771942343370894993*var_54 + 0.0000096552477504858455004*var_52 + 0.0001998001998001998000265*var_644 + 0.0000266400266400266400035*var_51 + 0.0008880008880008880001178*var_161; + const double var_697 = 0.0000025371453942882516104*var_163 + -0.0003482232053660625241062*var_41 + 0.0000685029256457827905166*var_46 + 0.0000799200799200799200106*var_43 + 0.0000148704910609672526944*var_40 + 0.0001198801198801198800159*var_79; + const double var_698 = 0.0004909376337947766360051*var_111 + 0.0000685029256457827905166*var_57 + 0.0000697714983429269084867*var_184 + 0.0000181828753257324693805*var_58 + 0.0000513771942343370894993*var_62; + const double var_699 = var_76 + var_142; + const double var_700 = 3.0000000000000000000000000*var_67 + var_157; + const double var_701 = var_244 + 3.0000000000000000000000000*var_93; + const double var_702 = var_145 + var_95; + const double var_703 = 0.0395604395604395586705238*var_702 + 0.3076923076923077093880465*var_83; + const double var_704 = var_82 + var_96; + const double var_705 = 0.0395604395604395586705238*var_704 + 0.3076923076923077093880465*var_36; + const double var_706 = var_485 + -0.0000120514406228691952554*var_15 + -0.0000405943263086120257666*var_20 + 0.0000513771942343370894993*var_26 + -0.0004509775938347366759998*var_25 + 0.0025974025974025974003445*var_705 + 0.0000114171542742971311881*var_146 + 0.0000913372341943770495046*var_34 + 0.0000856286570572284779813*var_28 + -0.0003482232053660625241062*var_24 + -0.0000234685948971663281375*var_19 + 0.0000171257314114456976291*var_701 + var_697 + 0.0001998001998001998000265*var_38 + 0.0004110175538746967159945*var_179 + var_696 + 0.0000057085771371485655940*var_700 + 0.0001484230055658626969747*var_91 + 0.0000868972297543726230565*var_247 + 0.0001211486925772640115386*var_16 + -0.0000526457669314812210220*var_21 + 0.0000666000666000666000088*var_286 + var_698 + 0.0000932400932400932400124*var_122 + 0.0000577200577200577200077*var_71 + 0.0003082631654060225641009*var_699 + 0.0001224172652744081430613*var_9 + 0.0051948051948051948006890*var_703; + const double var_707 = var_84 + var_35; + const double var_708 = 0.0003233803233803233981129*var_357 + var_684 + 0.0000899100899100899100119*var_389 + 0.0004645354645354645350616*var_59 + var_240 + 0.0007042957042957042950934*var_368 + 0.0033916083916083914970296*var_356 + 0.0001298701298701298700172*var_452 + 0.0004578754578754578750607*var_289 + -0.0001215451215451215450161*var_362 + 0.0000149850149850149850020*var_537 + 0.0002097902097902097900278*var_707 + 0.0001798201798201798200239*var_364 + 0.0008991008991008991001193*var_358 + 0.0001004551004551004550133*var_58 + 0.0003746253746253746250497*var_467 + 0.0019930069930069928968441*var_61 + 0.0038211788211788212839271*var_461 + -0.0000194250194250194250026*var_355 + -0.0013936063936063937136051*var_463 + 0.0017982017982017982002385*var_531 + -0.0002147852147852147850285*var_371 + 0.0014585414585414585401935*var_57 + -0.0001615051615051615050214*var_458 + 0.0044655344655344653137519*var_604 + -0.0040459540459540461673771*var_466 + 0.0003596403596403596400477*var_369 + 0.0000366300366300366300049*var_373 + 0.0025097125097125099271733*w[0][2]*w[1][2] + -0.0005211455211455211450691*var_366; + A[67] = 0.1428571428571428492126927*var_7*var_708; + const double var_709 = 0.0000513771942343370894993*var_114 + 0.0004909376337947766360051*var_115 + 0.0000181828753257324693805*var_52 + 0.0000685029256457827905166*var_51 + 0.0000697714983429269084867*var_161; + const double var_710 = -0.0003482232053660625241062*var_54 + 0.0001198801198801198800159*var_114 + 0.0000685029256457827905166*var_255 + 0.0000148704910609672526944*var_52 + 0.0000799200799200799200106*var_51 + 0.0000025371453942882516104*var_161; + const double var_711 = var_241 + var_389; + const double var_712 = var_177 + var_32; + const double var_713 = -0.0035107749393463675430249*var_42 + -0.0011988011988011988001590*var_105 + -0.0078778364492650201911239*var_45 + var_172 + -0.0010846296560582274239037*var_43 + 0.0016269444840873411358556*var_117 + -0.0001384858527715670519984*var_40; + const double var_714 = var_91 + var_82; + const double var_715 = 1.9428571428571428381104624*w[0][5]*w[1][5]; + const double var_716 = 0.0004566861709718852339705*var_619 + -0.0009038580467151895560599*var_11 + 0.0123305266162409016966750*var_32 + 0.0002949431520860091898890*var_17 + 0.0029970029970029970003975*var_715 + -0.0035298035298035298004682*var_21 + 0.0005423148280291137119519*var_10 + 0.0000285428856857428271232*var_156 + 0.0005137719423433708678881*var_22 + 0.0017125731411445697764673*var_714 + var_420 + 0.0016269444840873411358556*var_28 + 0.0006184291898577613322621*var_38 + -0.0020075162932305786953058*var_8 + 0.0062508919651776788384279*var_66 + 0.0008087150944293801119872*var_9 + 0.0035964035964035964004770*var_699 + 0.0013415156272299129120579*var_12 + var_713 + 0.0007706579135150563560422*var_93 + -0.0017030588459159886477456*var_19 + 0.0002568859711716854339440*var_565 + -0.0092478949621806767061871*var_29 + 0.0047952047952047952006360*var_83 + 0.0015413158270301127120844*var_96 + 0.0013224870367727510882955*var_16 + 0.0028257456828885401528551*var_107 + 0.0019980019980019980002650*var_146 + 0.0006374577803149231560245*var_15 + 0.0006850292564578278238507*var_34 + -0.0001617430188858760169764*var_14 + var_176 + 0.0004662004662004662000618*var_18 + -0.0160981875267589558120562*w[0][3]*w[1][3]; + A[163] = 0.2000000000000000111022302*var_7*var_716; + A[85] = 0.1428571428571428492126927*var_689*var_7; + A[155] = A[85]; + A[132] = 0.8000000000000000444089210*var_658*var_7; + A[188] = A[132]; + const double var_717 = var_612 + var_229; + const double var_718 = 0.0002721088435374149580061*var_226 + 0.0012121212121212121201608*var_377 + -0.0001016972445543874140235*var_227 + 0.0001731601731601731600230*var_582 + 0.0072727272727272727209646*var_717 + -0.0024434824434824437694447*var_225 + 0.0016161616161616161602144*var_51 + 0.0002226345083487940590145*var_115 + 0.0060606060606060606008039*var_379 + 0.0035621521335807049442324*var_92 + -0.0007173778602350031844553*var_220 + 0.0013358070500927641914568*var_383 + 0.0044679600235155792278818*w[0][0]*w[1][0] + 0.0181818181818181809350499*var_222 + 0.0052910052910052907115812*var_221 + 0.0222222222222222230703093*var_382 + 0.0008080808080808080801072*var_90 + 0.0029684601113172540479135*var_232 + 0.0005729250173694618334871*var_219 + 0.0002281316567030852910953*var_216 + 0.0009400123685837972163648*var_101 + -0.0001264344121486978770718*var_236 + -0.0006294234865663437964237*var_217 + var_532; + A[99] = 0.1538461538461538546940233*var_7*var_718; + const double var_719 = var_44 + var_100; + const double var_720 = -1.0000000000000000000000000*var_371; + const double var_721 = -0.0002578697023141467603753*var_357 + 0.0004120879120879120875547*var_456 + var_208 + 0.0001123876123876123875149*var_390 + 0.0028490028490028491449382*var_720 + 0.0005272505272505272500699*var_719 + -0.0002643190143190143458901*var_465 + -0.0014131701631701631960425*var_462 + 0.0035776723276723276963296*var_59 + 0.0005661005661005661000751*var_368 + 0.0007517945017945017486746*var_356 + 0.0002411939911939912028170*var_289 + 0.0015068265068265069336201*var_362 + 0.0059003496503496500463770*var_707 + 0.0003933566433566433834072*var_364 + 0.0014938764938764938390581*var_358 + -0.0008263598541376319678992*var_58 + 0.0000770063270063270062602*var_61 + 0.0001685814185814185812724*var_461 + -0.0057217473884140545095645*var_355 + -0.0004671254671254670889219*var_463 + 0.0004023754023754023750534*var_57 + 0.0004495504495504495500596*var_455 + -0.0001736689236689236597380*var_458 + 0.0007950382950382950918156*var_604 + 0.0001498501498501498500199*var_466 + 0.0008470695970695970959674*var_602 + -0.0039238539238539236336800*var_372 + 0.0003733920400587067370962*w[0][2]*w[1][2] + -0.0000800125800125800034756*var_366; + const double var_722 = -0.0000234685948971663281375*var_15 + 0.0000856286570572284779813*var_26 + -0.0000526457669314812210220*var_20 + -0.0003482232053660625241062*var_25 + 0.0051948051948051948006890*var_705 + 0.0001484230055658626969747*var_34 + 0.0001998001998001998000265*var_22 + 0.0000513771942343370894993*var_28 + -0.0004509775938347366759998*var_24 + -0.0000120514406228691952554*var_19 + 0.0000057085771371485655940*var_701 + 0.0000666000666000666000088*var_123 + var_696 + 0.0000114171542742971311881*var_130 + 0.0003082631654060225641009*var_179 + 0.0000171257314114456976291*var_700 + var_547 + var_556 + 0.0000913372341943770495046*var_91 + 0.0000577200577200577200077*var_285 + -0.0000405943263086120257666*var_21 + 0.0000868972297543726230565*var_119 + var_271 + 0.0000932400932400932400124*var_156 + 0.0001211486925772640115386*var_18 + 0.0004110175538746967159945*var_699 + 0.0001224172652744081430613*var_10 + 0.0025974025974025974003445*var_703; + A[102] = 4.0000000000000000000000000*var_7*var_722; + const double var_723 = 0.0000687407830264973160241*var_54 + -0.0000057643708437359238579*var_52 + 0.0000218828790257361705104*var_53 + 0.0000111000111000111000015*var_51 + 0.0018981018981018981002518*var_161 + 0.0000532800532800532800071*var_55; + const double var_724 = 0.0000135578707007278438152*var_61 + 0.0000118928690357261788150*var_158 + 0.0000156985871271585547483*var_546 + 0.0000062723872247681772512*var_58 + 0.0000057085771371485655940*var_241 + 0.0000423386137671851947519*var_59; + const double var_725 = -0.0000141392998535855662456*var_11 + 0.0000713572142143570695020*var_177 + 0.0000001057143914286771460*var_17 + 0.0000171257314114456976291*var_30 + -0.0000304457447314590176309*w[0][4]*w[1][4] + 0.0000485229056657628105139*var_32 + 0.1428571428571428492126927*var_579 + 0.0000096992954135811279391*var_10 + 0.0001017501017501017454960*var_22 + 0.0000481000481000480977476*var_156 + -0.0001703058845915988810376*w[0][8]*w[1][8] + -0.0000085628657057228488146*var_33 + 0.0001565101565101565100208*w[0][7]*w[1][7] + 0.0000123685837971552264420*var_129 + var_724 + 0.0000209314495028780752565*var_91 + 0.0000632700632700632700084*var_28 + 0.0000428143285286142389907*var_65 + 0.0001646501646501646409868*var_38 + 0.0000682650682650682650091*var_66 + var_723 + 0.0000577200577200577200077*var_9 + 0.0000254243111385968535059*var_12 + 0.0000092764378478664185609*var_26 + -0.0000066335780621494908765*var_20 + -0.0000195571624143052706245*var_19 + -0.0000409114694828980552592*var_25 + var_427 + 0.0000168350168350168338729*var_16 + 0.0000041757184614327470627*var_64 + 0.0001084629656058227505219*var_147 + 0.0000043871472442901017518*var_15 + -0.0000178921607493036056242*var_14 + 0.0000366300366300366300049*var_36 + 0.0000073207216064358923455*var_18 + 0.0000962000962000961954953*var_122 + -0.0001660244517387374490070*w[0][3]*w[1][3]; + A[1] = 0.0071428571428571426341070*var_7*var_721; + const double var_726 = var_67 + var_129; + const double var_727 = var_184 + var_452; + const double var_728 = var_524 + 0.0045192667414889631932740*var_58 + 0.0062337662337662337608268*var_588 + 0.0030399230399230400649635*var_366 + -0.0024434824434824437694447*var_289 + -0.0529870129870129852323046*var_59 + 0.0055411255411255411207350*var_465 + 0.0222222222222222230703093*var_372 + 0.0018577307466196356193489*var_357 + 0.0173160173160173160022968*var_726 + -0.0062722462722462728190731*var_358 + 0.0342857142857142874192711*var_453 + 0.0008658008658008658001148*var_454 + 0.0155844155844155844020671*var_455 + 0.0029822029822029819112750*var_463 + 0.0170594837261503935732510*var_355 + 0.0299567099567099558166117*var_462 + 0.0561038961038961073168885*var_464 + -0.0015776815776815777524894*var_356 + 0.0014814814814814814079164*var_458 + 0.0093506493506493506412403*var_456 + 0.0063492063492063492008421*var_727 + 0.0036940836940836940804900*var_57 + -0.0050216450216450216406661*var_61 + -0.0126406926406926415490384*var_602 + 0.0140259740259740268292221*var_535 + 0.0114478114478114480906390*var_371 + -0.0043867243867243867205818*var_362; + const double var_729 = var_476 + var_523; + const double var_730 = var_75 + var_197; + const double var_731 = -0.0006850292564578278238507*var_519 + 0.0000818229389657961105184*var_494 + 0.0002759145616288473119165*var_192 + 0.0000274857417714560587599*var_40 + 0.0001636458779315922210367*var_212 + 0.0000621600621600621600082*var_190 + -0.0000704057846914989810243*var_191 + 0.0001883830455259026569800*var_729 + 0.0003253888968174682380131*var_201 + 0.0001198801198801198800159*var_204 + -0.0001370058512915655810332*var_195 + 0.0001940916226630512420558*var_525 + 0.0000095142952285809423744*var_730 + 0.0000348857491714634542434*var_193 + 0.0000685029256457827905166*var_623 + 0.0000932400932400932400124*var_560 + 0.0000799200799200799200106*var_321 + 0.0000475714761429047152601*var_200 + -0.0009932924218638504963719*var_41 + 0.0000513771942343370894993*var_555 + 0.0000608914894629180352618*var_194; + A[118] = var_7*var_731; + A[71] = var_509*var_7; + A[169] = A[71]; + const double var_732 = 0.0002093144950287807390128*var_100 + 0.0001998001998001998000265*var_54 + -0.0000313619361238408862562*var_52 + -0.0004566861709718852339705*var_161 + 0.0000285428856857428271232*var_359; + const double var_733 = 0.0002283430854859426169853*var_84 + 0.0000729429300857872305172*var_13; + const double var_734 = var_66 + 0.6000000000000000888178420*var_108; + const double var_735 = var_734 + var_120; + const double var_736 = 0.0029684601113172540479135*var_35 + 0.0001300287014572728779872*var_17 + 0.0004281432852861424441168*var_735 + 0.0001427144284287141390039*var_24 + -0.0001078286792572506915368*var_22 + 0.0000856286570572284779813*var_244 + 0.0003425146282289139119254*var_33 + var_343 + var_643 + 0.0009704581133152561560687*var_91 + 0.0005994005994005994000795*var_28 + -0.0000602572031143459762768*var_38 + -0.0001363715649429935220481*var_8 + 0.0001554001554001554000206*var_71 + 0.0001046572475143903695064*var_9 + 0.0005708577137148565560157*var_145 + 0.0001490572919144347830648*var_12 + -0.0000983143840286697525506*var_19 + 0.0000475714761429047152601*var_138 + 0.0000539143396286253457684*var_16 + 0.0000761143618286475389951*var_64 + var_733 + 0.0000285428856857428271232*var_107 + 0.0000729429300857872305172*var_15 + 0.0000031714317428603144071*var_137 + 0.0000570857713714856542463*var_82 + var_559 + 0.0001141715427429713084926*var_36 + var_732; + A[179] = 0.8000000000000000444089210*var_7*var_736; + const double var_737 = -0.0000463029034457605905136*var_19; + const double var_738 = 0.0000028542885685742827970*var_26; + const double var_739 = 0.0299145299145299192744574*var_22 + 0.0348508634222919957967868*var_33; + const double var_740 = -0.0000567686281971996315300*var_11 + var_737 + 0.0002886002886002886000383*var_13 + 0.0003938918224632510420823*var_30 + 0.0000802372230943659495031*var_17 + -0.0001411287125572839779887*var_21 + -0.0001563515849230135020508*var_23 + -0.0001366887081172795650932*var_10 + 0.0000713572142143570695020*var_27 + 0.0006964464107321250482124*var_24 + -0.0019294990723562150877757*w[0][8]*w[1][8] + -0.0181818181818181809350499*var_739 + var_487 + var_675 + var_738 + 0.0002711574140145568559759*var_28 + 0.0002568859711716854339440*var_65 + 0.0019980019980019980002650*var_84 + -0.0012321012321012321001634*var_38 + 0.0004528804528804528800601*var_8 + 0.0003824746681889538719307*var_66 + -0.0001477887192172906650946*var_9 + 0.0002854288568574282780078*var_210 + 0.0008391608391608391601113*var_145 + 0.0002226345083487940590145*var_677 + 0.0000976800976800976800130*var_12 + 0.0013986013986013986001855*var_37 + 0.0000754800754800754800100*var_20 + -0.0004623947481090337919413*var_29 + 0.0006022548879691736519598*var_25 + -0.0001195629767058338505234*var_16 + 0.0000488400488400488400065*var_64 + var_269 + 0.0000574029145457716905151*var_15 + 0.0001198801198801198800159*var_678 + -0.0001712573141144569559627*var_81 + -0.0000091971520542949128818*var_14 + -0.0001509601509601509600200*var_18; + A[211] = A[29]; + A[15] = A[1]; + const double var_741 = 0.0000199800199800199800027*var_534 + var_404 + 0.0153846153846153854694023*var_533 + 0.0013986013986013986001855*var_60; + const double var_742 = 0.0218181818181818198976174*var_111 + 0.0012533498247783963607666*var_57 + 0.0009400123685837972163648*var_60 + 0.0002473716759431045220628*var_173 + 0.0014494147827481161042856*var_58 + 0.0012121212121212121201608*var_62; + const double var_743 = var_376 + 0.0025479282622139767452984*var_45 + 0.0011708925994640280963954*var_43 + 0.0060606060606060606008039*var_117 + 0.0010664467807324951205417*w[0][1]*w[1][1] + 0.0007076051520495965857852*var_40 + 0.0024242424242424242403215*var_79; + const double var_744 = 0.0012121212121212121201608*var_114 + 0.0218181818181818198976174*var_115 + 0.0014494147827481161042856*var_52 + 0.0002473716759431045220628*var_189 + 0.0012533498247783963607666*var_51 + 0.0009400123685837972163648*var_55; + const double var_745 = var_108 + var_126; + const double var_746 = var_109 + var_31; + const double var_747 = -0.0061183261183261183208115*var_11 + 0.0014814814814814814079164*var_13 + 0.0017316017316017316002297*var_715 + 0.0016161616161616161602144*var_17 + 0.0003655603655603655781185*var_21 + -0.0008493094207379922122927*var_23 + -0.0028475228475228478094983*var_10 + 0.0002721088435374149580061*var_24 + -0.0008520579949151378283331*var_22 + -0.0043042671614100178056894*var_33 + 0.0036363636363636363604823*var_120 + 0.0121212121212121212016077*var_91 + 0.0001236858379715522610314*var_67 + -0.0003243317529031815001431*var_38 + 0.0000962000962000961954953*var_8 + 0.0072727272727272727209646*var_745 + 0.0032653061224489797129134*var_95 + -0.0004507661650518793501098*var_9 + 0.0040404040404040404005359*var_12 + 0.0052910052910052907115812*var_20 + 0.0109090909090909099488087*var_93 + -0.0007668521954236240563418*var_19 + 0.0013358070500927641914568*var_746 + var_659 + 0.0011873840445269015757973*var_83 + 0.0158730158730158721347436*var_64 + 0.0012121212121212121201608*var_107 + 0.0028282828282828282803751*var_15 + 0.0727272727272727237401995*var_81 + 0.0024242424242424242403215*var_73 + var_744 + -0.0008987837559266130841792*var_18 + 0.0007421150278293135119784*var_500 + 0.0004040404040404040400536*var_344 + 0.0109833024118738391966543*w[0][3]*w[1][3] + var_743; + A[80] = 0.1538461538461538546940233*var_7*var_747; + A[141] = A[99]; + const double var_748 = var_589 + var_453; + const double var_749 = var_156 + var_157; + const double var_750 = var_726 + var_535; + const double var_751 = var_463 + var_366; + const double var_752 = var_61 + var_603 + -4.0000000000000000000000000*var_455 + 2.0000000000000000000000000*var_711 + -16.0000000000000000000000000*var_457; + const double var_753 = 0.0000818229389657961105184*var_749 + 0.0000274857417714560587599*var_58 + -0.0000704057846914989810243*var_289 + -0.0009932924218638504963719*var_59 + 0.0003253888968174682380131*var_465 + 0.0002759145616288473119165*var_372 + 0.0000348857491714634542434*var_357 + 0.0000799200799200799200106*var_546 + 0.0000513771942343370894993*var_752 + 0.0000621600621600621600082*var_355 + -0.0006850292564578278238507*var_464 + 0.0001940916226630512420558*var_452 + 0.0000608914894629180352618*var_356 + 0.0001883830455259026569800*var_750 + 0.0000095142952285809423744*var_751 + -0.0001370058512915655810332*var_461 + 0.0001198801198801198800159*var_602 + 0.0001636458779315922210367*var_371 + 0.0000932400932400932400124*var_459 + 0.0000685029256457827905166*var_748 + 0.0000475714761429047152601*var_362; + A[164] = var_7*var_753; + A[220] = A[164]; + const double var_754 = 0.0001027543884686741789986*var_31; + const double var_755 = 0.0348508634222919957967868*var_65 + 0.0299145299145299192744574*var_64; + const double var_756 = 0.0006771006771006771000898*var_20 + 0.0001366887081172795650932*var_15 + 0.0002568859711716854339440*var_34 + 0.0028971028971028971003843*w[0][6]*w[1][6] + 0.0000656486370772084979787*var_24 + 0.0003539317825032110820770*w[0][5]*w[1][5] + 0.0010446696160981874638984*var_30 + 0.0012987012987012987001723*var_81 + var_504 + var_215 + var_741 + 0.0002220002220002220000294*var_13 + 0.0002051916337630623420572*var_17 + 0.0001509601509601509600200*var_12 + 0.0181818181818181809350499*var_755 + 0.0000513771942343370894993*var_83 + var_754 + 0.0004681033252461824041221*w[0][3]*w[1][3]; + const double var_757 = var_562 + var_683; + const double var_758 = 0.0001731601731601731600230*var_406 + 0.0013358070500927641914568*var_519 + 0.0072727272727272727209646*var_477 + 0.0012121212121212121201608*var_757 + -0.0001264344121486978770718*var_192 + 0.0222222222222222230703093*var_561 + 0.0002281316567030852910953*var_190 + -0.0007173778602350031844553*var_212 + 0.0016161616161616161602144*var_43 + 0.0009400123685837972163648*var_198 + -0.0006294234865663437964237*var_75 + 0.0181818181818181809350499*var_195 + 0.0008080808080808080801072*var_525 + 0.0060606060606060606008039*var_522 + 0.0005729250173694618334871*var_193 + 0.0035621521335807049442324*var_520 + 0.0002226345083487940590145*var_117 + 0.0002721088435374149580061*var_199 + -0.0001016972445543874140235*var_200 + 0.0044679600235155792278818*w[0][1]*w[1][1] + 0.0029684601113172540479135*var_609 + 0.0052910052910052907115812*var_194 + var_532 + -0.0024434824434824437694447*var_197; + const double var_759 = -0.0000077523887047696566868*var_58 + var_665 + -0.0000007047626095245142539*w[0][2]*w[1][2] + 0.0003996003996003996000530*var_111; + const double var_760 = var_65 + var_210; + const double var_761 = var_137 + var_27; + const double var_762 = var_11 + var_344; + const double var_763 = var_625 + 0.0008562865705722848882336*var_135 + 0.0004566861709718852339705*var_34 + 0.0000475714761429047152601*var_262 + 0.0000856286570572284779813*var_761 + 0.0001998001998001998000265*var_24 + 0.0002759145616288473119165*var_19 + var_341 + 0.0000761143618286475389951*var_423 + var_733 + 0.0003996003996003996000530*var_81 + 0.0001744287458573172779931*var_304 + -0.0010275438846867417357761*var_36 + 0.0001046572475143903695064*var_14 + 0.0000095142952285809423744*var_17 + 0.0008848294562580276238772*var_67 + 0.0001966287680573395051011*var_23 + 0.0005708577137148565560157*var_448 + 0.0003583717869432155220775*var_21 + var_759 + 0.0003710575139146567559892*var_74 + var_636 + 0.0002949431520860091898890*var_8 + 0.0001427144284287141390039*var_762 + 0.0000983143840286697525506*var_138 + 0.0001554001554001554000206*var_157 + 0.0001712573141144569559627*var_760; + A[148] = 0.8000000000000000444089210*var_7*var_763; + A[204] = A[148]; + const double var_764 = var_304 + 2.0000000000000000000000000*var_21; + const double var_765 = var_344 + var_764; + const double var_766 = -0.0005224405224405224762094*var_11 + 0.0002338402338402338490660*var_13 + 0.0004662004662004662000618*var_715 + 0.0003196803196803196800424*var_177 + 0.0060339660339660339608003*w[0][4]*w[1][4] + 0.0002294002294002293819604*var_17 + -0.0003981203981203981561929*var_10 + 0.0004795204795204795200636*var_77 + -0.0000458800458800458845236*var_22 + 0.0005994005994005994000795*var_120 + 0.0000666000666000666000088*var_129 + 0.0000562400562400562422662*var_38 + 0.0010789210789210789201431*var_745 + var_113 + -0.0000547600547600547645248*var_572 + 0.0023043623043623043603056*w[0][6]*w[1][6] + 0.0000932400932400932400124*var_66 + 0.0000014800014800014800708*var_765 + 0.0000799200799200799200106*var_178 + 0.0003996003996003996000530*var_12 + 0.0008806008806008806723969*var_20 + 0.0015584415584415584402067*var_93 + -0.0001613201613201613380914*var_19 + -0.0009590409590409590401272*var_29 + 0.0006127206127206127200813*var_83 + 0.0011914011914011914724382*var_64 + 0.0003862803862803862800512*var_107 + 0.0001021201021201021200135*var_146 + 0.0003892403892403892761917*var_15 + var_313 + 0.0001332001332001332000177*var_34 + 0.0002264402264402264400300*var_73 + var_133 + -0.0001080401080401080445318*var_18 + 0.0006393606393606393600848*w[0][3]*w[1][3]; + const double var_767 = 0.0008880008880008880001178*var_163 + 0.0000513771942343370894993*var_41 + 0.0001998001998001998000265*var_331 + 0.0000266400266400266400035*var_43 + 0.0000096552477504858455004*var_40; + const double var_768 = var_138 + 3.0000000000000000000000000*var_108; + const double var_769 = -0.0000463029034457605905136*var_16; + const double var_770 = var_76 + var_210; + const double var_771 = 0.0395604395604395586705238*var_770 + 0.3076923076923077093880465*var_144; + const double var_772 = 0.0000513771942343370894993*var_25 + 0.0000577200577200577200077*var_262 + -0.0003482232053660625241062*var_28 + var_767 + 0.0000856286570572284779813*var_27 + 0.0051948051948051948006890*var_771 + 0.0000666000666000666000088*var_764 + 0.0000868972297543726230565*var_572 + 0.0001211486925772640115386*var_19 + 0.0000913372341943770495046*var_81 + -0.0000405943263086120257666*var_38 + var_769 + -0.0000526457669314812210220*var_64 + 0.0000171257314114456976291*var_624 + 0.0000114171542742971311881*var_263 + -0.0000234685948971663281375*var_17 + var_556 + 0.0001484230055658626969747*var_83 + var_709 + 0.0001998001998001998000265*var_23 + -0.0004509775938347366759998*var_66 + 0.0004110175538746967159945*var_421 + 0.0000932400932400932400124*var_157 + -0.0000120514406228691952554*var_18 + 0.0003082631654060225641009*var_307 + 0.0001224172652744081430613*var_11 + 0.0000057085771371485655940*var_768 + 0.0025974025974025974003445*var_682; + A[58] = 4.0000000000000000000000000*var_7*var_772; + A[198] = A[58]; + const double var_773 = var_222 + var_228; + const double var_774 = var_161 + var_90; + const double var_775 = var_524 + -0.0529870129870129852323046*var_54 + -0.0050216450216450216406661*var_53 + -0.0043867243867243867205818*var_227 + 0.0062337662337662337608268*var_773 + 0.0155844155844155844020671*var_88 + 0.0029822029822029819112750*var_225 + 0.0036940836940836940804900*var_51 + 0.0008658008658008658001148*var_379 + -0.0126406926406926415490384*var_433 + 0.0140259740259740268292221*var_612 + 0.0342857142857142874192711*var_92 + 0.0114478114478114480906390*var_220 + 0.0173160173160173160022968*var_518 + 0.0093506493506493506412403*var_380 + 0.0561038961038961073168885*var_383 + 0.0014814814814814814079164*var_224 + -0.0062722462722462728190731*var_223 + 0.0063492063492063492008421*var_774 + -0.0015776815776815777524894*var_221 + 0.0055411255411255411207350*var_384 + 0.0018577307466196356193489*var_219 + 0.0170594837261503935732510*var_216 + 0.0045192667414889631932740*var_52 + 0.0299567099567099558166117*var_101 + -0.0024434824434824437694447*var_218 + 0.0222222222222222230703093*var_236 + 0.0030399230399230400649635*var_217; + A[50] = 0.0219780219780219797376386*var_7*var_775; + A[78] = A[50]; + const double var_776 = var_545 + var_127; + const double var_777 = var_332 + 0.0001490572919144347830648*var_11 + -0.0001363715649429935220481*var_13 + 0.0003425146282289139119254*var_32 + 0.0001046572475143903695064*var_10 + 0.0000761143618286475389951*var_23 + -0.0000602572031143459762768*var_22 + var_442 + 0.0000475714761429047152601*var_304 + 0.0000856286570572284779813*var_157 + 0.0000285428856857428271232*var_129 + 0.0004281432852861424441168*var_776 + -0.0001078286792572506915368*var_38 + var_654 + 0.0029684601113172540479135*var_210 + 0.0000570857713714856542463*var_145 + 0.0005994005994005994000795*var_26 + 0.0000729429300857872305172*var_19 + 0.0001427144284287141390039*var_25 + var_666 + 0.0001141715427429713084926*var_83 + 0.0001554001554001554000206*var_285 + -0.0000983143840286697525506*var_15 + 0.0005708577137148565560157*var_82 + 0.0009704581133152561560687*var_34 + 0.0001300287014572728779872*var_14 + 0.0000539143396286253457684*var_18 + var_732 + 0.0000031714317428603144071*var_344; + A[133] = 0.8000000000000000444089210*var_7*var_777; + const double var_778 = var_339 + 0.0004681033252461824041221*w[0][6]*w[1][6] + 0.0000513771942343370894993*var_144 + 0.0000656486370772084979787*var_28 + 0.0006771006771006771000898*var_38 + 0.0002568859711716854339440*var_81 + 0.0028971028971028971003843*w[0][7]*w[1][7] + var_503 + 0.0012987012987012987001723*var_36 + 0.0010446696160981874638984*var_32 + var_583 + 0.0181818181818181809350499*var_739 + 0.0002051916337630623420572*var_16 + 0.0003539317825032110820770*w[0][8]*w[1][8] + 0.0001366887081172795650932*var_18 + var_474 + 0.0002220002220002220000294*var_9 + 0.0001509601509601509600200*var_10; + const double var_779 = 0.0006964464107321250482124*var_41 + 0.0002083630655059226369826*var_42; + const double var_780 = 0.0000256885971171685447497*var_54; + const double var_781 = 0.0000707229278657850105169*var_20 + 0.0000041228612657184088140*var_15 + 0.0008020550877693734519863*var_25 + -1.0000000000000000000000000*var_778 + 0.0001741116026830312620531*var_27 + 0.0005965463108320250397790*var_24 + 0.0000269571698143126728842*var_19 + 0.0002397602397602397600318*var_30 + var_779 + 0.0000031714317428603144071*var_64 + var_155 + var_584 + 0.0002553002553002553000339*var_13 + 0.0000840429411857983305187*var_14 + 0.0000612086326372040715306*var_17 + var_738 + 0.0000003171431742860314513*var_12 + 0.0000260057402914545776303*var_23 + 0.0000948258091115234010276*var_21 + 0.0001056086770372484579840*var_66 + 0.0003085803085803085800409*var_8 + 0.0000231514517228802952568*var_11 + 0.0004452690166975881180290*var_31 + var_780; + A[114] = var_7*var_781; + A[81] = 0.2857142857142856984253854*var_7*var_766; + const double var_782 = 0.0001027543884686741789986*var_32; + A[116] = 0.1428571428571428492126927*var_695*var_7; + A[172] = A[116]; + const double var_783 = var_339 + var_409 + 0.0002051916337630623420572*var_15 + 0.0000513771942343370894993*var_34 + 0.0004681033252461824041221*w[0][5]*w[1][5] + var_782 + 0.0028971028971028971003843*w[0][4]*w[1][4] + 0.0006771006771006771000898*var_64 + var_741 + 0.0001509601509601509600200*var_13 + 0.0001366887081172795650932*var_17 + 0.0002220002220002220000294*var_12 + 0.0002568859711716854339440*var_83 + 0.0012987012987012987001723*var_91 + 0.0010446696160981874638984*var_65 + 0.0000656486370772084979787*var_66 + 0.0181818181818181809350499*var_273 + 0.0003539317825032110820770*w[0][3]*w[1][3]; + const double var_784 = 0.0000256885971171685447497*var_59; + const double var_785 = -1.0000000000000000000000000*var_783 + 0.0005965463108320250397790*var_26 + 0.0001741116026830312620531*var_25 + 0.0000707229278657850105169*var_22 + 0.0008020550877693734519863*var_27 + 0.0001056086770372484579840*var_28 + 0.0000840429411857983305187*var_19 + var_784 + 0.0000031714317428603144071*var_38 + 0.0002397602397602397600318*var_33 + var_779 + 0.0004452690166975881180290*var_29 + 0.0000269571698143126728842*var_14 + 0.0000948258091115234010276*var_23 + var_272 + 0.0000041228612657184088140*var_16 + 0.0000260057402914545776303*var_21 + 0.0000231514517228802952568*var_8 + var_413 + 0.0000612086326372040715306*var_18 + 0.0000003171431742860314513*var_9 + 0.0003085803085803085800409*var_11 + var_754 + 0.0002553002553002553000339*var_10; + A[150] = A[10]; + const double var_786 = var_10 + var_71; + const double var_787 = var_26 + var_345; + const double var_788 = var_30 + var_82; + const double var_789 = 0.0000095142952285809423744*var_15 + 0.0003710575139146567559892*var_180 + 0.0001966287680573395051011*var_22 + -0.0010275438846867417357761*var_144 + 0.0003583717869432155220775*var_38 + var_655 + var_346 + 0.0001427144284287141390039*var_786 + 0.0000761143618286475389951*var_619 + 0.0005708577137148565560157*var_266 + var_670 + 0.0004566861709718852339705*var_83 + 0.0001712573141144569559627*var_788 + 0.0003996003996003996000530*var_91 + var_559 + 0.0000475714761429047152601*var_285 + 0.0001046572475143903695064*var_16 + var_759 + 0.0001998001998001998000265*var_66 + 0.0001744287458573172779931*var_122 + 0.0000856286570572284779813*var_787 + 0.0001554001554001554000206*var_156 + 0.0002759145616288473119165*var_18 + 0.0008562865705722848882336*var_142 + 0.0002949431520860091898890*var_9 + 0.0008848294562580276238772*var_129 + 0.0000983143840286697525506*var_244; + A[177] = 0.8000000000000000444089210*var_7*var_789; + A[12] = 0.1428571428571428492126927*var_482*var_7; + A[180] = A[12]; + const double var_790 = var_76 + var_33; + A[184] = A[72]; + const double var_791 = var_81 + var_77; + const double var_792 = 0.0001793180364608935829437*var_357 + 0.0041743970315398885861935*var_456 + 0.0287284144427001585098136*var_464 + 0.0000071357214214357067808*var_719 + -0.0013058370201227344382933*var_465 + 0.0070108462965605819125492*var_462 + 0.0027187098615670040810399*var_59 + -0.0023333809048094759572289*var_368 + -0.0006112934684363255941411*var_356 + -0.0001129822558393986945075*var_289 + var_620 + -0.0019528090956662383977788*var_362 + -0.0007373578802150230560378*var_358 + 0.0008311794026079740100102*var_58 + -0.0010382474668188953429576*var_61 + 0.0019694591123162550477810*var_461 + 0.0029489029489029486112706*var_355 + 0.0006981114123971266047924*var_463 + 0.0016566766566766567836400*var_371 + 0.0017411160268303125121109*var_57 + 0.0046881689738832591288209*var_455 + 0.0012713476999191284429885*var_458 + 0.0010489510489510489501391*var_604 + -0.0028792635935493077550817*var_466 + 0.0093763379477665182576418*var_369 + -0.0046774653917511059553203*var_602 + 0.0014402264402264403336112*var_372 + 0.0002529216814931100178535*w[0][2]*w[1][2] + 0.0072998430141287288727692*var_453 + 0.0004899862042719184797648*var_366; + A[160] = 0.2000000000000000111022302*var_7*var_792; + const double var_793 = var_78 + var_562 + var_622 + var_525 + 2.0000000000000000000000000*var_520 + var_99; + A[82] = var_7*var_785; + const double var_794 = 0.0024242424242424242403215*var_114 + var_376 + 0.0060606060606060606008039*var_115 + 0.0007076051520495965857852*var_52 + 0.0010664467807324951205417*w[0][0]*w[1][0] + 0.0011708925994640280963954*var_51 + 0.0025479282622139767452984*var_55; + const double var_795 = 0.0003496503496503496500464*var_603 + 0.0006993006993006993000928*var_241; + const double var_796 = 0.0000075035194082813135342*var_357 + var_434 + -0.0000126659055230483799382*var_464 + 0.0035714285714285713170535*var_795 + 0.0000203368060510917648758*var_389 + 0.0000401384329955758507478*var_465 + 0.0000545882688739831567460*var_462 + -0.0001667974882260596467421*var_59 + -0.0000487012987012987012565*var_368 + 0.0000033300033300033300004*var_356 + 0.0000321107463964606792430*var_452 + -0.0000098512598512598512513*var_289 + 0.0000062437562437562437508*var_62 + 0.0000001233334566667899971*var_260 + -0.0000228739514453800177568*var_358 + 0.0000084505441648298791889*var_58 + 0.0000003964289678575393009*var_468 + 0.0000162337662337662337522*var_461 + 0.0000332691999358666055161*var_355 + 0.0000054707197564340426276*var_463 + 0.0000433693290836148007670*var_371 + -0.0000076114361828647544077*var_57 + 0.0000010703582132153561018*var_455 + -0.0000074726860441146156577*var_458 + -0.0000415655772798629902405*var_466 + -0.0000845582988440131335262*var_369 + -0.0000058869701726844580306*var_602 + 0.0000544296972868401487760*var_372 + 0.0000708220351077493972744*var_453 + 0.0000067987567987567987509*var_366; + A[40] = var_7*var_796; + A[146] = 0.0219780219780219797376386*var_7*var_728; + A[174] = A[146]; + const double var_797 = 0.0000028542885685742827970*var_66; + const double var_798 = var_67 + var_127; + const double var_799 = 1.9428571428571428381104624*w[0][4]*w[1][4]; + const double var_800 = var_116 + 0.0005994005994005994000795*var_135 + 0.0002338402338402338490660*var_11 + -0.0009590409590409590401272*var_32 + 0.0011914011914011914724382*var_21 + 0.0008806008806008806723969*var_23 + 0.0003196803196803196800424*var_77 + 0.0060339660339660339608003*w[0][8]*w[1][8] + 0.0003862803862803862800512*var_108 + 0.0006393606393606393600848*w[0][7]*w[1][7] + 0.0000799200799200799200106*var_120 + 0.0002264402264402264400300*var_129 + 0.0006127206127206127200813*var_91 + 0.0001021201021201021200135*var_39 + var_131 + 0.0003996003996003996000530*var_8 + -0.0005224405224405224762094*var_9 + 0.0010789210789210789201431*var_798 + 0.0000014800014800014800708*var_287 + -0.0003981203981203981561929*var_12 + 0.0000562400562400562422662*var_20 + 0.0000666000666000666000088*var_93 + 0.0002294002294002293819604*var_19 + 0.0000932400932400932400124*var_25 + 0.0004795204795204795200636*var_96 + -0.0001613201613201613380914*var_16 + -0.0000458800458800458845236*var_64 + -0.0001080401080401080445318*var_15 + 0.0004662004662004662000618*var_799 + 0.0015584415584415584402067*var_73 + 0.0003892403892403892761917*var_14 + var_314 + 0.0001332001332001332000177*var_36 + -0.0000547600547600547645248*var_247 + 0.0023043623043623043603056*w[0][3]*w[1][3]; + A[86] = 0.2857142857142856984253854*var_7*var_800; + A[170] = A[86]; + const double var_801 = 0.0022263450834879407527755*var_158 + 0.0030826316540602254241688*var_60 + 0.0002812002812002811638972*w[0][2]*w[1][2] + -0.0003372289086574801141548*var_58 + 0.0007706579135150563560422*var_62 + 0.0041958041958041958005565*var_59; + const double var_802 = var_77 + var_120; + const double var_803 = var_84 + var_36; + const double var_804 = -0.0020075162932305786953058*var_11 + -0.0092478949621806767061871*var_31 + 0.0005423148280291137119519*var_13 + 0.0004662004662004662000618*var_17 + 0.0029970029970029970003975*var_319 + 0.0015413158270301127120844*var_109 + -0.0035298035298035298004682*var_23 + 0.0004566861709718852339705*var_601 + var_305 + -0.0160981875267589558120562*w[0][8]*w[1][8] + 0.0035964035964035964004770*var_802 + 0.0062508919651776788384279*var_28 + 0.0123305266162409016966750*var_65 + -0.0009038580467151895560599*var_8 + 0.0017125731411445697764673*var_803 + 0.0016269444840873411358556*var_66 + 0.0013415156272299129120579*var_9 + 0.0008087150944293801119872*var_12 + var_713 + 0.0002568859711716854339440*var_628 + 0.0005137719423433708678881*var_20 + 0.0028257456828885401528551*var_93 + -0.0001617430188858760169764*var_19 + 0.0000285428856857428271232*var_138 + 0.0006374577803149231560245*var_16 + 0.0006184291898577613322621*var_64 + 0.0007706579135150563560422*var_107 + 0.0019980019980019980002650*var_147 + 0.0013224870367727510882955*var_15 + 0.0047952047952047952006360*var_81 + 0.0006850292564578278238507*var_144 + -0.0017030588459159886477456*var_14 + 0.0002949431520860091898890*var_18 + var_801; + A[73] = 0.2000000000000000111022302*var_7*var_804; + const double var_805 = var_232 + var_379; + const double var_806 = 0.0935064935064935098818495*var_103 + 0.0701298701298701254724932*var_53 + 0.0043290043290043290005742*var_225 + 0.0025974025974025974003445*var_385 + 0.2337662337662337885824115*var_612 + 0.0415584415584415584055122*var_690 + 0.1246753246753246752165367*var_383 + 0.0255892255892255920945999*w[0][0]*w[1][0] + 0.0207792207792207792027561*var_237 + 0.0597402597402597393405621*var_223 + 0.7480519480519480790547959*var_222 + -0.0242424242424242424032155*var_221 + 0.0155844155844155844020671*var_473 + 0.8415584415584415056699186*var_229 + 0.2805194805194805018899729*var_805 + -0.0021164021164021165448410*var_219 + 0.0132756132756132756017609*var_216 + 0.1168831168831168942912058*var_235 + 0.0051948051948051948006890*var_52 + 0.0779220779220779341533998*var_218; + A[192] = 0.0175824175824175824023321*var_7*var_806; + A[11] = var_7*var_725; + A[165] = A[11]; + const double var_807 = 0.0002886002886002886000383*var_11 + -0.0001477887192172906650946*var_13 + 0.0002568859711716854339440*var_31 + -0.0001195629767058338505234*var_17 + -0.0004623947481090337919413*var_32 + 0.0000488400488400488400065*var_21 + 0.0004528804528804528800601*var_10 + 0.0000754800754800754800100*var_23 + 0.0006964464107321250482124*var_27 + 0.0002711574140145568559759*var_24 + -0.0001411287125572839779887*var_22 + 0.0002226345083487940590145*var_492 + -0.0181818181818181809350499*var_755 + 0.0000713572142143570695020*var_28 + var_270 + 0.0008391608391608391601113*var_84 + -0.0001563515849230135020508*var_38 + 0.0000976800976800976800130*var_8 + -0.0000567686281971996315300*var_9 + 0.0019980019980019980002650*var_210 + 0.0002854288568574282780078*var_145 + var_797 + var_653 + -0.0001366887081172795650932*var_12 + -0.0019294990723562150877757*w[0][5]*w[1][5] + -0.0012321012321012321001634*var_20 + 0.0006022548879691736519598*var_26 + 0.0000802372230943659495031*var_19 + 0.0003938918224632510420823*var_29 + 0.0003824746681889538719307*var_25 + var_769 + 0.0001198801198801198800159*var_491 + -0.0001509601509601509600200*var_15 + 0.0013986013986013986001855*var_82 + -0.0001712573141144569559627*var_34 + 0.0000574029145457716905151*var_14 + var_106 + -0.0000091971520542949128818*var_18; + A[105] = A[7]; + A[145] = var_7*var_740; + const double var_808 = 0.0060606060606060606008039*var_111 + 0.0011708925994640280963954*var_57 + var_376 + 0.0025479282622139767452984*var_60 + 0.0010664467807324951205417*w[0][2]*w[1][2] + 0.0007076051520495965857852*var_58 + 0.0024242424242424242403215*var_62; + A[49] = var_486*var_7; + A[63] = A[49]; + const double var_809 = 0.0037105751391465677767323*var_42 + 0.0181818181818181809350499*var_405 + 0.0008163265306122449282283*var_117 + 0.0089359200470311584557637*w[0][1]*w[1][1] + 0.0002886002886002886000383*var_40; + const double var_810 = 0.0036363636363636363604823*var_135 + 0.0013358070500927641914568*var_790 + 0.0014814814814814814079164*var_11 + -0.0004507661650518793501098*var_13 + 0.0158730158730158721347436*var_21 + 0.0052910052910052907115812*var_23 + 0.0032653061224489797129134*var_109 + 0.0000962000962000961954953*var_10 + 0.0002721088435374149580061*var_27 + 0.0003655603655603655781185*var_22 + 0.0012121212121212121201608*var_108 + 0.0109833024118738391966543*w[0][7]*w[1][7] + 0.0024242424242424242403215*var_129 + 0.0011873840445269015757973*var_91 + -0.0043042671614100178056894*var_65 + -0.0008493094207379922122927*var_38 + 0.0040404040404040404005359*var_8 + 0.0007421150278293135119784*var_266 + -0.0061183261183261183208115*var_9 + 0.0072727272727272727209646*var_798 + -0.0028475228475228478094983*var_12 + var_742 + var_794 + -0.0003243317529031815001431*var_20 + 0.0016161616161616161602144*var_19 + 0.0004040404040404040400536*var_285 + -0.0007668521954236240563418*var_16 + -0.0008520579949151378283331*var_64 + var_809 + 0.0001236858379715522610314*var_107 + -0.0008987837559266130841792*var_15 + 0.0017316017316017316002297*var_799 + 0.0121212121212121212016077*var_144 + 0.0727272727272727237401995*var_34 + 0.0109090909090909099488087*var_73 + 0.0028282828282828282803751*var_14; + const double var_811 = var_95 + var_126; + const double var_812 = 3.0000000000000000000000000*var_73 + var_304; + const double var_813 = var_177 + var_35; + const double var_814 = 0.0395604395604395586705238*var_813 + 0.3076923076923077093880465*var_81; + const double var_815 = -0.0003482232053660625241062*var_26 + 0.0001211486925772640115386*var_15 + 0.0000666000666000666000088*var_139 + 0.0000913372341943770495046*var_144 + -0.0000405943263086120257666*var_22 + 0.0000513771942343370894993*var_24 + 0.0004110175538746967159945*var_811 + -0.0004509775938347366759998*var_27 + 0.0000114171542742971311881*var_147 + 0.0003082631654060225641009*var_802 + var_697 + 0.0001998001998001998000265*var_64 + 0.0000577200577200577200077*var_345 + var_676 + 0.0001484230055658626969747*var_36 + -0.0000234685948971663281375*var_14 + 0.0000057085771371485655940*var_812 + 0.0001224172652744081430613*var_12 + var_709 + 0.0000171257314114456976291*var_432 + -0.0000526457669314812210220*var_23 + 0.0051948051948051948006890*var_814 + -0.0000120514406228691952554*var_16 + 0.0000856286570572284779813*var_66 + var_279 + 0.0025974025974025974003445*var_338 + 0.0000868972297543726230565*var_134 + 0.0000932400932400932400124*var_244; + A[89] = 4.0000000000000000000000000*var_7*var_815; + A[215] = A[89]; + A[92] = A[36]; + const double var_816 = var_145 + var_177; + const double var_817 = 0.0005133755133755133750681*var_11 + -0.0003127824556395984809815*var_13 + var_303 + 0.0001248751248751248750166*var_499 + 0.0006047523904666762036703*var_32 + -0.0001277492348920920503270*var_17 + 0.0002140716426430712220584*var_816 + -0.0000465804037232608680137*var_21 + 0.0008741258741258741251159*var_10 + 0.0000286419929277072138807*var_23 + var_277 + 0.0002497502497502497500331*var_27 + 0.0003288378288378288375436*var_22 + 0.0006529185100613672191466*var_33 + 0.0009722420436706150905989*w[0][7]*w[1][7] + 0.0010683760683760684835619*var_130 + 0.0003282431853860424898935*var_129 + 0.0000205151990866276556183*var_28 + 0.0001657073085644514059619*var_38 + -0.0000882054453483024930192*var_8 + var_587 + -0.0000383545026402169229938*var_66 + 0.0000720509649081077632521*var_9 + 0.0024350649350649354422937*var_210 + -0.0000831509760081188632535*var_12 + 0.0009098044812330525988806*w[0][5]*w[1][5] + 0.0004370629370629370625580*var_26 + 0.0000307232450089592985191*var_19 + -0.0000963322391893820445053*var_29 + -0.0003041601255886970363654*var_25 + 0.0003746253746253746250497*var_76 + 0.0001193251193251193250158*var_16 + -0.0000653116724545295992662*var_15 + 0.0001855287569573283779946*var_34 + 0.0000111000111000111000015*var_14 + 0.0001273528059242345032969*var_18 + 0.0017898767898767899836576*var_263; + A[37] = 0.2000000000000000111022302*var_7*var_817; + A[107] = A[37]; + const double var_818 = 0.0000254243111385968535059*var_11 + var_438 + 0.0000171257314114456976291*var_31 + -0.0000178921607493036056242*var_17 + -0.0001660244517387374490070*w[0][4]*w[1][4] + -0.0000085628657057228488146*var_32 + -0.0000066335780621494908765*var_21 + 0.0000041757184614327470627*var_23 + 0.0000577200577200577200077*var_10 + 0.0000682650682650682650091*var_27 + 0.0000962000962000961954953*var_156 + -0.0000409114694828980552592*var_24 + 0.0001646501646501646409868*var_22 + 0.0000485229056657628105139*var_33 + 0.1428571428571428492126927*var_68 + 0.0000092764378478664185609*var_28 + 0.0001017501017501017454960*var_38 + -0.0001703058845915988810376*w[0][6]*w[1][6] + var_723 + 0.0000096992954135811279391*var_9 + -0.0000141392998535855662456*var_12 + 0.0001565101565101565100208*w[0][5]*w[1][5] + 0.0000632700632700632700084*var_26 + 0.0000043871472442901017518*var_19 + 0.0000428143285286142389907*var_29 + 0.0000713572142143570695020*var_76 + 0.0000366300366300366300049*var_83 + 0.0000073207216064358923455*var_16 + var_322 + 0.0000123685837971552264420*var_107 + -0.0000195571624143052706245*var_15 + 0.0000209314495028780752565*var_34 + 0.0000001057143914286771460*var_14 + 0.0000168350168350168338729*var_18 + 0.0000481000481000480977476*var_122 + -0.0000304457447314590176309*w[0][3]*w[1][3] + 0.0001084629656058227505219*var_263; + A[8] = var_7*var_818; + const double var_819 = 0.3333333333333333148296163*var_662 + 0.0000072942930085787232211*var_11 + -0.0002571502571502571319641*var_13 + var_351 + -0.0000184207327064469914999*var_17 + -0.0001279672708244136930620*w[0][4]*w[1][4] + -0.0000599400599400599400080*var_30 + -0.0000084307227164370031927*var_21 + 0.0000710400710400710400094*var_10 + 0.0000048100048100048102830*var_23 + var_660 + 0.0005698005698005697639355*var_22 + var_661 + 0.0000199800199800199800027*var_91 + var_618 + 0.0000102278673707245138148*var_28 + -0.0000670757813614956510239*var_65 + 0.0000028542885685742827970*var_95 + 0.0000197950197950197961320*var_9 + -0.0000058935773221487511588*var_12 + 0.0000313971742543171094967*var_26 + -0.0000483643340786197957677*var_20 + -0.0000118400118400118405663*var_19 + -0.0000137957280814423676287*var_64 + -0.0000196100196100196122614*var_15 + 0.0000266400266400266400035*var_34 + -0.0000113642970785827912453*var_14 + 0.0002849002849002848819678*var_165 + -0.0000637457780314923210235*w[0][3]*w[1][3]; + const double var_820 = 0.0002473716759431045220628*var_105 + 0.0009400123685837972163648*var_45 + 0.0218181818181818198976174*var_117 + 0.0012533498247783963607666*var_43 + 0.0014494147827481161042856*var_40 + 0.0012121212121212121201608*var_79; + const double var_821 = -0.0028475228475228478094983*var_11 + 0.0040404040404040404005359*var_13 + 0.0028282828282828282803751*var_17 + -0.0003243317529031815001431*var_21 + -0.0061183261183261183208115*var_10 + -0.0008520579949151378283331*var_23 + -0.0008493094207379922122927*var_22 + 0.0032653061224489797129134*var_77 + 0.0036363636363636363604823*var_126 + 0.0109090909090909099488087*var_108 + 0.0001236858379715522610314*var_129 + 0.0727272727272727237401995*var_91 + 0.0003655603655603655781185*var_38 + -0.0004507661650518793501098*var_8 + 0.0013358070500927641914568*var_712 + 0.0002721088435374149580061*var_66 + 0.0004040404040404040400536*var_71 + 0.0000962000962000961954953*var_9 + 0.0007421150278293135119784*var_568 + 0.0014814814814814814079164*var_12 + 0.0109833024118738391966543*w[0][5]*w[1][5] + var_794 + 0.0158730158730158721347436*var_20 + -0.0008987837559266130841792*var_19 + -0.0043042671614100178056894*var_29 + var_659 + 0.0052910052910052907115812*var_64 + 0.0024242424242424242403215*var_107 + 0.0072727272727272727209646*var_121 + 0.0016161616161616161602144*var_15 + 0.0121212121212121212016077*var_81 + 0.0011873840445269015757973*var_34 + 0.0012121212121212121201608*var_73 + var_820 + 0.0017316017316017316002297*var_125 + -0.0007668521954236240563418*var_18; + A[128] = 0.1538461538461538546940233*var_7*var_821; + A[35] = var_299*var_7; + A[186] = A[102]; + const double var_822 = 0.0009818752675895532720102*var_41 + 0.0000713572142143570695020*var_42; + const double var_823 = 0.0008020550877693734519863*var_26 + 0.0001056086770372484579840*var_25 + 0.0000948258091115234010276*var_22 + var_822 + 0.0005965463108320250397790*var_27 + 0.0001741116026830312620531*var_28 + 0.0000612086326372040715306*var_19 + var_784 + 0.0000260057402914545776303*var_38 + var_782 + 0.0004452690166975881180290*var_33 + var_797 + 0.0002397602397602397600318*var_29 + 0.0000041228612657184088140*var_14 + 0.0000707229278657850105169*var_23 + -1.0000000000000000000000000*var_756 + 0.0000269571698143126728842*var_16 + 0.0000031714317428603144071*var_21 + var_507 + 0.0000003171431742860314513*var_8 + 0.0000840429411857983305187*var_18 + 0.0000231514517228802952568*var_9 + 0.0002553002553002553000339*var_11 + 0.0003085803085803085800409*var_10; + const double var_824 = 0.0007836607836607836601039*var_13 + 0.0002686202686202686200356*var_17 + 0.0010789210789210789201431*var_32 + -0.0002863802863802863800380*var_21 + -0.0001909201909201909200253*var_23 + 0.0001887001887001887000250*var_399 + 0.0013786213786213786201829*var_24 + -0.0015473415473415473402052*var_22 + 0.0000488400488400488400065*var_353 + 0.0004662004662004662000618*var_304 + var_692 + -0.0005794205794205794200769*w[0][7]*w[1][7] + var_164 + -0.0018093018093018093002400*var_38 + 0.0004817404817404817400639*var_8 + 0.0001198801198801198800159*var_145 + 0.0002153402153402153400286*var_20 + 0.0000599400599400599400080*var_93 + 0.0000022200022200022200003*var_19 + 0.0006593406593406593400875*var_25 + 0.0003774003774003774000501*var_138 + 0.0003596403596403596400477*var_791 + 0.0005194805194805194800689*var_515 + 0.0004995004995004995000663*var_734 + -0.0000510600510600510600068*var_16 + 0.0002397602397602397600318*var_530 + 0.0010389610389610389601378*var_34 + var_686 + 0.0004595404595404595400610*var_73 + 0.0003219003219003219000427*var_14 + -0.0002908202908202908200386*var_18; + A[130] = 0.1428571428571428492126927*var_7*var_824; + A[158] = A[130]; + A[159] = A[145]; + A[138] = A[54]; + A[201] = A[103]; + const double var_825 = var_609 + var_522; + A[75] = A[5]; + const double var_826 = var_109 + var_37; + const double var_827 = 0.0008741258741258741251159*var_11 + 0.0006047523904666762036703*var_31 + -0.0000831509760081188632535*var_13 + -0.0000653116724545295992662*var_17 + 0.0001657073085644514059619*var_21 + 0.0003288378288378288375436*var_23 + 0.0005133755133755133750681*var_10 + 0.0004370629370629370625580*var_27 + var_277 + -0.0000383545026402169229938*var_24 + 0.0000286419929277072138807*var_22 + 0.0002140716426430712220584*var_826 + 0.0009722420436706150905989*w[0][8]*w[1][8] + -0.0000963322391893820445053*var_33 + 0.0017898767898767899836576*var_130 + 0.0003282431853860424898935*var_67 + -0.0003041601255886970363654*var_28 + -0.0000465804037232608680137*var_38 + 0.0000720509649081077632521*var_8 + 0.0001248751248751248750166*var_168 + var_540 + var_151 + -0.0000882054453483024930192*var_9 + -0.0003127824556395984809815*var_12 + 0.0002497502497502497500331*var_26 + 0.0001273528059242345032969*var_19 + 0.0006529185100613672191466*var_29 + 0.0000205151990866276556183*var_25 + 0.0001855287569573283779946*var_83 + 0.0003746253746253746250497*var_96 + 0.0000111000111000111000015*var_16 + -0.0001277492348920920503270*var_15 + 0.0024350649350649354422937*var_82 + 0.0001193251193251193250158*var_14 + 0.0000307232450089592985191*var_18 + 0.0009098044812330525988806*w[0][3]*w[1][3] + 0.0010683760683760684835619*var_263; + A[152] = A[40]; + A[56] = 0.1538461538461538546940233*var_7*var_758; + A[168] = A[56]; + A[26] = var_600*var_7; + A[166] = A[26]; + A[69] = 0.1428571428571428492126927*var_253*var_7; + A[139] = A[69]; + A[98] = 0.0219780219780219797376386*var_528*var_7; + A[126] = A[98]; + const double var_828 = 0.0008163265306122449282283*var_115 + 0.0002886002886002886000383*var_52 + 0.0037105751391465677767323*var_53 + 0.0089359200470311584557637*w[0][0]*w[1][0] + 0.0181818181818181809350499*var_581; + const double var_829 = var_65 + var_95; + const double var_830 = var_808 + 0.0013358070500927641914568*var_829 + -0.0004507661650518793501098*var_11 + 0.0007421150278293135119784*var_516 + -0.0043042671614100178056894*var_31 + -0.0061183261183261183208115*var_13 + -0.0007668521954236240563418*var_17 + -0.0008520579949151378283331*var_21 + 0.0040404040404040404005359*var_10 + -0.0003243317529031815001431*var_23 + 0.0158730158730158721347436*var_22 + 0.0001236858379715522610314*var_108 + 0.0109090909090909099488087*var_129 + 0.0012121212121212121201608*var_67 + 0.0002721088435374149580061*var_28 + 0.0052910052910052907115812*var_38 + -0.0028475228475228478094983*var_8 + 0.0004040404040404040400536*var_345 + 0.0109833024118738391966543*w[0][6]*w[1][6] + 0.0014814814814814814079164*var_9 + 0.0036363636363636363604823*var_178 + 0.0000962000962000961954953*var_12 + -0.0008493094207379922122927*var_20 + 0.0024242424242424242403215*var_93 + 0.0032653061224489797129134*var_76 + 0.0121212121212121212016077*var_83 + 0.0016161616161616161602144*var_16 + 0.0003655603655603655781185*var_64 + var_828 + 0.0011873840445269015757973*var_144 + -0.0008987837559266130841792*var_14 + var_820 + 0.0727272727272727237401995*var_36 + 0.0072727272727272727209646*var_400 + 0.0017316017316017316002297*var_310 + 0.0028282828282828282803751*var_18; + A[181] = A[27]; + A[205] = A[163]; + A[125] = A[83]; + A[193] = 0.2285714285714285642914234*var_375*var_7; + A[207] = A[193]; + const double var_831 = var_393 + var_117 + var_89; + const double var_832 = 0.2337662337662337885824115*var_476 + 0.1246753246753246752165367*var_519 + 0.1168831168831168942912058*var_683 + 0.0155844155844155844020671*var_831 + 0.0051948051948051948006890*var_40 + 0.0132756132756132756017609*var_190 + 0.2805194805194805018899729*var_825 + 0.0779220779220779341533998*var_191 + 0.0935064935064935098818495*var_793 + 0.0597402597402597393405621*var_196 + 0.0025974025974025974003445*var_529 + 0.7480519480519480790547959*var_195 + -0.0021164021164021165448410*var_193 + 0.0415584415584415584055122*var_213 + 0.0701298701298701254724932*var_42 + 0.0207792207792207792027561*var_394 + 0.8415584415584415056699186*var_475 + 0.0255892255892255920945999*w[0][1]*w[1][1] + -0.0242424242424242424032155*var_194 + 0.0043290043290043290005742*var_197; + A[147] = 4.0000000000000000000000000*var_7*var_706; + A[61] = A[19]; + A[95] = A[81]; + A[79] = A[65]; + A[121] = A[23]; + A[45] = A[3]; + A[119] = 0.2000000000000000111022302*var_183*var_7; + A[217] = A[119]; + const double var_833 = var_454 + var_531; + A[77] = A[35]; + A[110] = A[82]; + A[208] = 0.0175824175824175824023321*var_7*var_832; + const double var_834 = var_144 + var_35; + A[202] = A[118]; + A[190] = A[162]; + A[216] = A[104]; + const double var_835 = 0.0415584415584415584055122*var_720 + 0.0025974025974025974003445*var_468 + 0.0051948051948051948006890*var_58 + 0.0779220779220779341533998*var_289 + 0.2805194805194805018899729*var_833 + 0.0935064935064935098818495*var_590 + -0.0021164021164021165448410*var_357 + 0.0597402597402597393405621*var_358 + 0.0043290043290043290005742*var_463 + 0.0132756132756132756017609*var_355 + 0.1246753246753246752165367*var_464 + 0.8415584415584415056699186*var_389 + 0.0155844155844155844020671*var_648 + -0.0242424242424242424032155*var_356 + 0.1168831168831168942912058*var_537 + 0.7480519480519480790547959*var_461 + 0.0255892255892255920945999*w[0][2]*w[1][2] + 0.0207792207792207792027561*var_373 + 0.0701298701298701254724932*var_61 + 0.2337662337662337885824115*var_535; + A[200] = A[88]; + A[41] = 0.1428571428571428492126927*var_580*var_7; + A[167] = A[41]; + const double var_836 = 0.0008087150944293801119872*var_13 + 0.0015413158270301127120844*var_177 + 0.0123305266162409016966750*var_30 + 0.0013224870367727510882955*var_17 + -0.0092478949621806767061871*var_32 + 0.0002568859711716854339440*var_671 + -0.0020075162932305786953058*var_10 + 0.0035964035964035964004770*var_811 + 0.0016269444840873411358556*var_24 + -0.0035298035298035298004682*var_22 + 0.0000285428856857428271232*var_244 + 0.0028257456828885401528551*var_108 + -0.0160981875267589558120562*w[0][7]*w[1][7] + 0.0004566861709718852339705*var_629 + 0.0047952047952047952006360*var_91 + var_175 + 0.0019980019980019980002650*var_39 + 0.0013415156272299129120579*var_8 + -0.0009038580467151895560599*var_9 + 0.0005423148280291137119519*var_12 + 0.0006184291898577613322621*var_20 + 0.0002949431520860091898890*var_19 + 0.0062508919651776788384279*var_25 + -0.0017030588459159886477456*var_16 + 0.0005137719423433708678881*var_64 + 0.0004662004662004662000618*var_15 + 0.0029970029970029970003975*var_799 + 0.0007706579135150563560422*var_73 + 0.0006374577803149231560245*var_14 + 0.0006850292564578278238507*var_36 + -0.0001617430188858760169764*var_18 + 0.0017125731411445697764673*var_834 + var_419 + var_801; + A[70] = 0.1428571428571428492126927*var_685*var_7; + A[154] = A[70]; + const double var_837 = var_366 + var_465; + const double var_838 = 0.0000023433356766690098121*var_58 + -0.0001298701298701298700172*var_289 + 0.0010789210789210789201431*var_457 + var_795 + -0.0004495504495504495500596*var_59 + 0.0002497502497502497500331*var_467 + 0.0001156867823534490094745*var_357 + -0.0000799200799200799200106*var_358 + 0.0000259000259000259011328*var_260 + 0.0005994005994005994000795*var_453 + 0.0013186813186813186801749*var_455 + 0.0000640100640100640190435*var_355 + 0.0006193806193806193800822*var_462 + 0.0016183816183816183802147*var_464 + -0.0001931401931401931400256*var_452 + 0.0004273504273504273500567*var_363 + 0.0009712509712509712501288*var_356 + 0.0000699300699300699300093*var_458 + 0.0020979020979020979002783*var_456 + -0.0003696303696303696300490*var_368 + -0.0010489510489510489501391*var_461 + 0.0000111000111000111000015*var_373 + 0.0004662004662004662000618*var_57 + -0.0003096903096903096900411*var_61 + 0.0000366300366300366300049*var_371 + 0.0000388500388500388500052*var_362 + 0.0001098901098901098900146*var_837; + A[44] = 0.1428571428571428492126927*var_7*var_838; + A[212] = A[44]; + A[108] = A[52]; + const double var_839 = 0.0000710400710400710400094*var_11 + -0.0000058935773221487511588*var_13 + -0.0000196100196100196122614*var_17 + -0.0000670757813614956510239*var_30 + var_293 + 0.0000072942930085787232211*var_10 + 0.0005698005698005697639355*var_23 + 0.0000313971742543171094967*var_27 + 0.0000028542885685742827970*var_77 + 0.0000048100048100048102830*var_22 + var_599 + var_595 + 0.0002849002849002848819678*var_573 + var_618 + -0.0000599400599400599400080*var_65 + 0.3333333333333333148296163*var_598 + -0.0000084307227164370031927*var_38 + 0.0000197950197950197961320*var_8 + -0.0001279672708244136930620*w[0][6]*w[1][6] + -0.0002571502571502571319641*var_12 + -0.0000637457780314923210235*w[0][5]*w[1][5] + -0.0000137957280814423676287*var_20 + 0.0000102278673707245138148*var_25 + 0.0000266400266400266400035*var_83 + -0.0000113642970785827912453*var_16 + -0.0000483643340786197957677*var_64 + -0.0000184207327064469914999*var_15 + 0.0000199800199800199800027*var_81 + -0.0000118400118400118405663*var_18; + A[18] = var_7*var_839; + const double var_840 = 0.0000269571698143126728842*var_15 + 0.0000948258091115234010276*var_20 + 0.0005965463108320250397790*var_25 + var_414 + 0.0001056086770372484579840*var_27 + 0.0008020550877693734519863*var_24 + var_822 + 0.0000041228612657184088140*var_19 + 0.0004452690166975881180290*var_30 + 0.0000260057402914545776303*var_64 + 0.0003085803085803085800409*var_13 + 0.0000612086326372040715306*var_14 + 0.0000840429411857983305187*var_17 + 0.0000231514517228802952568*var_12 + 0.0000031714317428603144071*var_23 + 0.0000707229278657850105169*var_21 + 0.0001741116026830312620531*var_66 + 0.0002553002553002553000339*var_8 + -1.0000000000000000000000000*var_585 + var_489 + var_474 + 0.0000003171431742860314513*var_11 + 0.0002397602397602397600318*var_31 + var_780; + A[199] = A[73]; + A[51] = 0.0571428571428571410728559*var_471*var_7; + A[93] = A[51]; + const double var_841 = 0.0000962000962000961954953*var_11 + -0.0028475228475228478094983*var_13 + 0.0032653061224489797129134*var_177 + -0.0043042671614100178056894*var_30 + -0.0008987837559266130841792*var_17 + 0.0017316017316017316002297*var_319 + -0.0008493094207379922122927*var_21 + 0.0014814814814814814079164*var_10 + 0.0003655603655603655781185*var_23 + 0.0052910052910052907115812*var_22 + 0.0109833024118738391966543*w[0][8]*w[1][8] + 0.0072727272727272727209646*var_316 + 0.0013358070500927641914568*var_479 + 0.0024242424242424242403215*var_67 + 0.0158730158730158721347436*var_38 + -0.0061183261183261183208115*var_8 + 0.0040404040404040404005359*var_9 + -0.0004507661650518793501098*var_12 + var_742 + 0.0002721088435374149580061*var_26 + -0.0008520579949151378283331*var_20 + 0.0012121212121212121201608*var_93 + 0.0727272727272727237401995*var_83 + 0.0028282828282828282803751*var_16 + -0.0003243317529031815001431*var_64 + 0.0004040404040404040400536*var_262 + 0.0109090909090909099488087*var_107 + var_828 + 0.0011873840445269015757973*var_81 + 0.0001236858379715522610314*var_73 + -0.0007668521954236240563418*var_14 + 0.0036363636363636363604823*var_142 + 0.0121212121212121212016077*var_36 + 0.0016161616161616161602144*var_18 + 0.0007421150278293135119784*var_448 + var_743; + A[6] = var_7*var_819; + A[90] = A[6]; + const double var_842 = 0.0001998001998001998000265*var_20 + -0.0004509775938347366759998*var_26 + 0.0001484230055658626969747*var_144 + -0.0000526457669314812210220*var_22 + -0.0003482232053660625241062*var_27 + 0.0003082631654060225641009*var_811 + 0.0000856286570572284779813*var_24 + 0.0004110175538746967159945*var_802 + 0.0000868972297543726230565*var_399 + 0.0000666000666000666000088*var_401 + var_547 + 0.0000913372341943770495046*var_36 + 0.0001224172652744081430613*var_13 + -0.0000120514406228691952554*var_14 + 0.0001211486925772640115386*var_17 + 0.0000171257314114456976291*var_812 + 0.0000057085771371485655940*var_432 + 0.0000114171542742971311881*var_39 + -0.0000405943263086120257666*var_23 + 0.0025974025974025974003445*var_814 + -0.0000234685948971663281375*var_16 + 0.0000513771942343370894993*var_66 + var_279 + 0.0051948051948051948006890*var_338 + var_737 + 0.0000932400932400932400124*var_138 + var_710 + 0.0000577200577200577200077*var_137; + A[134] = 4.0000000000000000000000000*var_7*var_842; + A[109] = A[67]; + const double var_843 = var_30 + var_77; + const double var_844 = var_808 + 0.0040404040404040404005359*var_11 + 0.0000962000962000961954953*var_13 + 0.0036363636363636363604823*var_127 + 0.0013358070500927641914568*var_843 + 0.0109833024118738391966543*w[0][4]*w[1][4] + -0.0043042671614100178056894*var_32 + 0.0052910052910052907115812*var_21 + 0.0158730158730158721347436*var_23 + -0.0004507661650518793501098*var_10 + -0.0003243317529031815001431*var_22 + 0.0024242424242424242403215*var_108 + 0.0012121212121212121201608*var_129 + 0.0007421150278293135119784*var_551 + 0.0109090909090909099488087*var_67 + -0.0008520579949151378283331*var_38 + 0.0014814814814814814079164*var_8 + -0.0028475228475228478094983*var_9 + -0.0061183261183261183208115*var_12 + 0.0003655603655603655781185*var_20 + 0.0001236858379715522610314*var_93 + 0.0028282828282828282803751*var_19 + 0.0002721088435374149580061*var_25 + 0.0032653061224489797129134*var_96 + -0.0008987837559266130841792*var_16 + -0.0008493094207379922122927*var_64 + var_809 + -0.0007668521954236240563418*var_15 + 0.0004040404040404040400536*var_137 + 0.0727272727272727237401995*var_144 + 0.0121212121212121212016077*var_34 + 0.0016161616161616161602144*var_14 + 0.0011873840445269015757973*var_36 + var_744 + 0.0072727272727272727209646*var_136 + 0.0017316017316017316002297*var_141; + A[48] = 0.1538461538461538546940233*var_7*var_844; + A[31] = A[17]; + A[203] = A[133]; + const double var_845 = 0.0093763379477665182576418*var_228 + 0.0041743970315398885861935*var_380 + 0.0004899862042719184797648*var_217 + 0.0012713476999191284429885*var_224 + 0.0016566766566766567836400*var_220 + var_620 + -0.0023333809048094759572289*var_226 + 0.0029489029489029486112706*var_216 + 0.0014402264402264403336112*var_236 + 0.0019694591123162550477810*var_222 + 0.0006981114123971266047924*var_225 + 0.0010489510489510489501391*var_234 + 0.0287284144427001585098136*var_383 + -0.0001129822558393986945075*var_218 + 0.0001793180364608935829437*var_219 + 0.0017411160268303125121109*var_51 + 0.0046881689738832591288209*var_88 + 0.0070108462965605819125492*var_101 + -0.0046774653917511059553203*var_433 + -0.0013058370201227344382933*var_384 + 0.0002529216814931100178535*w[0][0]*w[1][0] + 0.0072998430141287288727692*var_92 + -0.0006112934684363255941411*var_221 + -0.0019528090956662383977788*var_227 + 0.0008311794026079740100102*var_52 + -0.0007373578802150230560378*var_223 + -0.0010382474668188953429576*var_53 + 0.0000071357214214357067808*var_418 + -0.0028792635935493077550817*var_230 + 0.0027187098615670040810399*var_54; + A[64] = 0.2000000000000000111022302*var_7*var_845; + A[39] = 0.1428571428571428492126927*var_284*var_7; + A[137] = A[39]; + A[183] = A[57]; + A[218] = A[134]; + A[34] = 0.2000000000000000111022302*var_7*var_827; + A[62] = A[34]; + A[224] = 0.0175824175824175824023321*var_7*var_835; + const double var_846 = 0.0000856286570572284779813*var_25 + 0.0000666000666000666000088*var_317 + -0.0004509775938347366759998*var_28 + var_767 + 0.0000513771942343370894993*var_27 + 0.0025974025974025974003445*var_771 + 0.0001484230055658626969747*var_81 + -0.0000526457669314812210220*var_38 + 0.0000932400932400932400124*var_304 + 0.0000057085771371485655940*var_624 + -0.0000405943263086120257666*var_64 + 0.0001211486925772640115386*var_14 + -0.0000120514406228691952554*var_17 + 0.0000577200577200577200077*var_344 + 0.0000913372341943770495046*var_83 + var_488 + 0.0001998001998001998000265*var_21 + -0.0003482232053660625241062*var_66 + var_698 + 0.0001224172652744081430613*var_8 + 0.0003082631654060225641009*var_421 + var_710 + -0.0000234685948971663281375*var_18 + 0.0000868972297543726230565*var_315 + 0.0004110175538746967159945*var_307 + 0.0000114171542742971311881*var_110 + 0.0000171257314114456976291*var_768 + 0.0051948051948051948006890*var_682; + A[178] = 4.0000000000000000000000000*var_7*var_846; + A[206] = A[178]; + A[153] = A[55]; + A[176] = 0.1538461538461538546940233*var_7*var_810; + const double var_847 = 0.0000096992954135811279391*var_11 + 0.0000485229056657628105139*var_31 + 0.0000254243111385968535059*var_13 + 0.0000428143285286142389907*var_30 + 0.0000043871472442901017518*var_17 + 0.0001646501646501646409868*var_21 + -0.0000141392998535855662456*var_10 + 0.0001017501017501017454960*var_23 + 0.0000713572142143570695020*var_109 + 0.0000092764378478664185609*var_27 + 0.0000682650682650682650091*var_24 + 0.0000962000962000961954953*var_304 + 0.0001565101565101565100208*w[0][8]*w[1][8] + 0.0000481000481000480977476*var_157 + -0.0001703058845915988810376*w[0][7]*w[1][7] + 0.1428571428571428492126927*var_283 + var_724 + 0.0000123685837971552264420*var_67 + 0.0001084629656058227505219*var_39 + -0.0000409114694828980552592*var_28 + 0.0000171257314114456976291*var_65 + 0.0000577200577200577200077*var_8 + -0.0000304457447314590176309*w[0][6]*w[1][6] + -0.0001660244517387374490070*w[0][5]*w[1][5] + 0.0000041757184614327470627*var_20 + 0.0000073207216064358923455*var_19 + -0.0000085628657057228488146*var_29 + 0.0000632700632700632700084*var_25 + -0.0000178921607493036056242*var_16 + -0.0000066335780621494908765*var_64 + var_188 + 0.0000001057143914286771460*var_15 + 0.0000209314495028780752565*var_81 + 0.0000366300366300366300049*var_144 + 0.0000168350168350168338729*var_14 + var_439 + -0.0000195571624143052706245*var_18; + A[24] = var_7*var_847; + A[144] = 0.1538461538461538546940233*var_7*var_841; + A[135] = A[9]; + A[120] = A[8]; + A[32] = 0.1250000000000000000000000*var_606*var_7; + A[96] = 0.1538461538461538546940233*var_7*var_830; + A[113] = var_7*var_807; + A[2] = 0.0071428571428571426341070*var_214*var_7; + A[117] = 0.2000000000000000111022302*var_7*var_836; + A[127] = A[113]; + A[68] = var_7*var_823; + A[124] = A[68]; + A[101] = 0.2857142857142856984253854*var_403*var_7; + A[171] = A[101]; + A[30] = A[2]; + A[189] = A[147]; + A[210] = A[14]; + const double var_848 = 0.0000499500499500499500066*var_232 + 0.0000240500240500240488738*var_381 + 0.0001048951048951048950139*var_228 + 0.0000394050394050394050052*var_90 + -0.0000498575498575498529891*var_217 + var_605 + -0.0000616975616975617020257*var_220 + -0.0000341325341325341325045*var_226 + 0.0000558759288918019060848*var_216 + 0.0002497502497502497500331*var_229 + 0.0000092632235489378356928*var_236 + 0.0022311022311022311002959*var_222 + -0.0012570762570762571835870*var_225 + 0.0011155511155511155501480*var_234 + 0.0002766281337709909290967*var_383 + 0.0001246901246901247080866*var_218 + 0.0002873669540336207120848*var_219 + 0.0002886002886002886000383*var_51 + 0.0001456876456876456875193*var_101 + -0.0001115551115551115550148*var_433 + -0.0000591075591075591075078*var_384 + 0.0079950913284246617751538*w[0][0]*w[1][0] + 0.0005827505827505827500773*var_92 + 0.0026584526584526586671930*var_221 + -0.0000077832220689363545632*var_227 + 0.0000204983141491077987901*var_52 + 0.0001902726902726902544552*var_223 + 0.0002414252414252414250320*var_53 + -0.0009906759906759907835516*var_230 + -0.0000926454497883069330198*var_54; + A[100] = var_7*var_840; + A[156] = A[100]; + A[187] = A[117]; + A[46] = A[18]; + A[221] = A[179]; + A[60] = A[4]; + A[106] = A[22]; + A[175] = A[161]; + A[142] = A[114]; + A[191] = A[177]; + A[122] = A[38]; + A[173] = A[131]; + A[0] = 0.1250000000000000000000000*var_7*var_848; + A[136] = A[24]; + } + + 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/mass_matrix_2d/mass_matrix_f2_p3_q4_quadrature.h b/mass_matrix_2d/mass_matrix_f2_p3_q4_quadrature.h new file mode 100644 index 0000000..f724d92 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p3_q4_quadrature.h @@ -0,0 +1,8500 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P3_Q4_QUADRATURE_H +#define __MASS_MATRIX_F2_P3_Q4_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p3_q4_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p3_q4_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p3_q4_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p3_q4_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p3_q4_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p3_q4_quadrature_finite_element_1() + { + // 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.0224478343233824, 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.0412393049421162, -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.0388807895679869, 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.0439885919382571, 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.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 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.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.00927360943924092, 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.0535412090610519}; + + // 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.0622092633087791, -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.251415744421884, 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.0224478343233824, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0412393049421162, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0388807895679869, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0439885919382571, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.00927360943924092, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0622092633087791, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.251415744421884, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p3_q4_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p3_q4_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p3_q4_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_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.0*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 mass_matrix_f2_p3_q4_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p3_q4_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p3_q4_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_p3_q4_quadrature_dofmap_1() + { + // 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.0*m.num_entities[1] + 3.0*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 mass_matrix_f2_p3_q4_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 mass_matrix_f2_p3_q4_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p3_q4_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Array of quadrature weights. + static const double W64[64] = {0.00225490635804067, 0.00461192269546131, 0.00569439870231093, 0.00536750948658183, 0.00400862976569763, 0.00229987790174679, 0.000903105459518999, 0.000166783703247789, 0.00495362697982869, 0.0101315713673239, 0.0125095780341758, 0.011791460746211, 0.00880624443170159, 0.00505242143815854, 0.00198396157514547, 0.000366394040824771, 0.00698794170371612, 0.0142923216403241, 0.0176469084969194, 0.016633880716434, 0.0124227203558096, 0.00712730825639973, 0.00279871857246886, 0.000516861727436939, 0.00807892713920297, 0.016523696115099, 0.020402014502064, 0.0192308287687631, 0.0143622051929694, 0.00824005215605507, 0.00323566572086397, 0.000597556249615681, 0.00807892713920296, 0.0165236961150989, 0.020402014502064, 0.0192308287687631, 0.0143622051929694, 0.00824005215605507, 0.00323566572086397, 0.000597556249615681, 0.00698794170371612, 0.0142923216403241, 0.0176469084969194, 0.016633880716434, 0.0124227203558096, 0.00712730825639973, 0.00279871857246886, 0.000516861727436939, 0.00495362697982869, 0.0101315713673239, 0.0125095780341758, 0.011791460746211, 0.00880624443170159, 0.00505242143815854, 0.00198396157514547, 0.000366394040824771, 0.00225490635804067, 0.00461192269546132, 0.00569439870231094, 0.00536750948658184, 0.00400862976569764, 0.00229987790174679, 0.000903105459519001, 0.000166783703247789}; + // Quadrature points on the UFC reference element: (0.0195020502602501, 0.0177799151473634), (0.0180418349638001, 0.0913236078997939), (0.0155999615159342, 0.214308479395631), (0.01247033193684, 0.371932164583272), (0.00903035100664362, 0.545186684803427), (0.00569492613313233, 0.71317524285557), (0.00286640239202857, 0.855633742957854), (0.000886210384823616, 0.95536604471003), (0.0998591349040865, 0.0177799151473634), (0.0923821858484057, 0.0913236078997939), (0.0798787122753652, 0.214308479395631), (0.0638536226992409, 0.371932164583272), (0.0462393967490529, 0.545186684803427), (0.0291605441175791, 0.71317524285557), (0.0146772497934947, 0.855633742957854), (0.00453778967803614, 0.95536604471003), (0.233015798295905, 0.0177799151473634), (0.215568748962855, 0.0913236078997939), (0.186392581165165, 0.214308479395631), (0.148998916139621, 0.371932164583272), (0.107897088799642, 0.545186684803427), (0.0680445256493261, 0.71317524285557), (0.0342485550340933, 0.855633742957854), (0.0105886826011672, 0.95536604471003), (0.401023447367823, 0.0177799151473634), (0.370996831485534, 0.0913236078997939), (0.320784238705222, 0.214308479395631), (0.256429218282022, 0.371932164583272), (0.185692398660614, 0.545186684803427), (0.11710558017937, 0.71317524285557), (0.0589422421465923, 0.855633742957854), (0.0182232708290937, 0.95536604471003), (0.581196637484813, 0.0177799151473634), (0.537679560614672, 0.0913236078997939), (0.464907281899148, 0.214308479395631), (0.371638617134706, 0.371932164583272), (0.269120916535959, 0.545186684803427), (0.16971917696506, 0.71317524285557), (0.0854240148955533, 0.855633742957854), (0.0264106844608761, 0.95536604471003), (0.749204286556732, 0.0177799151473634), (0.693107643137351, 0.0913236078997939), (0.599298939439204, 0.214308479395631), (0.479068919277106, 0.371932164583272), (0.346916226396932, 0.545186684803427), (0.218780231495104, 0.71317524285557), (0.110117702008052, 0.855633742957854), (0.0340452726888027, 0.95536604471003), (0.88236094994855, 0.0177799151473634), (0.8162942062518, 0.0913236078997939), (0.705812808329004, 0.214308479395631), (0.564214212717487, 0.371932164583272), (0.408573918447521, 0.545186684803427), (0.257664213026851, 0.71317524285557), (0.129689007248651, 0.855633742957854), (0.0400961656119337, 0.95536604471003), (0.962718034592386, 0.0177799151473634), (0.890634557136406, 0.0913236078997939), (0.770091559088435, 0.214308479395631), (0.615597503479888, 0.371932164583272), (0.44578296418993, 0.545186684803427), (0.281129831011298, 0.71317524285557), (0.141499854650117, 0.855633742957854), (0.0437477449051463, 0.95536604471003) + + // Value of basis functions at quadrature points. + static const double FE0[64][10] = \ + {{0.807225505302963, 0.0178239428840214, 0.0163826439966072, -0.00146906142904908, -0.00147712283785834, 0.145438284135968, -0.0729181176510951, 0.159525211648987, -0.0795443577738006, 0.00901307172325663}, + {0.500250823188824, 0.0166034772356766, 0.0572209773438471, -0.00701309618780693, -0.00538307404933874, 0.611936513747061, -0.265735263712635, 0.120893795626887, -0.0683953028250487, 0.0396211496325331}, + {0.15653845670491, 0.0145219306646567, 0.0519244590621585, -0.0143403411079553, -0.00537197901507225, 0.973097999074361, -0.265187557730946, 0.0708338343849126, -0.0515302785630722, 0.069513476526047}, + {-0.039932257114608, 0.0117792672629172, -0.019040633081034, -0.0200907042934335, 0.00241684987468035, 0.872469210295006, 0.119307710225706, 0.0292525941370027, -0.0332528040968106, 0.0770907667905736}, + {-0.0498261910535888, 0.00866670223065465, -0.0631390163152936, -0.0215543327434722, 0.0140805292558371, 0.368944049909013, 0.695084838276183, 0.0061111071956796, -0.0176243378815928, 0.0592566511265803}, + {0.0254615574022666, 0.00554981245166036, 0.056694991855783, -0.0179644087649839, 0.0208267259844173, -0.14129819024666, 1.02811060576433, -0.00112830999710279, -0.00708147296321746, 0.0308286885135042}, + {0.0641490431525104, 0.00282953519001736, 0.380020414290623, -0.0109417512274318, 0.0172933525657739, -0.313546579737132, 0.853685749521881, -0.00105039179855638, -0.00180948474863445, 0.00937011279094874}, + {0.0355121243622528, 0.000882679357024949, 0.772042818658422, -0.00379981964675363, 0.00710973852518115, -0.163394030616098, 0.350971995666499, -0.000151566499094355, -0.000173999841748748, 0.00100006003431413}, + {0.47020973746355, 0.0594668341845099, 0.0163826439966072, -0.00559616028351829, -0.00756352315613956, 0.116279705326824, -0.0668317173328138, 0.653073464333186, -0.277719733919075, 0.0422987493868698}, + {0.265449988133646, 0.0575250264178156, 0.0572209773438471, -0.0274431564798025, -0.0275637233274521, 0.486043893400969, -0.243554614434521, 0.491677873041549, -0.245300094366671, 0.185943830270621}, + {0.0463119810525849, 0.0534595098590293, 0.0519244590621585, -0.058573933810599, -0.0275069118379525, 0.760615208731617, -0.243052624908065, 0.283502377422861, -0.192909925143069, 0.326229859571435}, + {-0.0600574472839972, 0.0466774120250636, -0.019040633081034, -0.0863990804381065, 0.0123753417952441, 0.654077930981418, 0.109349218305142, 0.112292642040204, -0.131065806592769, 0.361790422248835}, + {-0.0357035269576087, 0.0370629148556119, -0.0631390163152936, -0.0977046399747995, 0.0720985461382729, 0.226256889805529, 0.637066821393747, 0.0191897241560415, -0.0732218315628921, 0.278094118461392}, + {0.0358848566633488, 0.0254456094649719, 0.0566949918557829, -0.0853976678869873, 0.106642061318412, -0.187716658943997, 0.942295270430337, -0.00767542054996665, -0.0308534586847473, 0.144680416332845}, + {0.0638181501493886, 0.0137220804056573, 0.380020414290623, -0.0540242282227647, 0.0885496244632998, -0.305068349063997, 0.782429477624355, -0.00523303855201277, -0.00818849020769617, 0.0439743591131469}, + {0.0331515865514707, 0.00444554825005743, 0.772042818658422, -0.0192430476716599, 0.0364050101935159, -0.151644069101048, 0.321676723998165, -0.000720277735756419, -0.000807619687337058, 0.00469332654417076}, + {0.115723962596159, 0.0456157640261118, 0.0163826439966073, -0.00561081141250939, -0.0176490652342445, 0.0747863424539101, -0.0567461752547091, 0.980117123399934, -0.236426547960034, 0.0838067633887748}, + {0.0296702250286437, 0.0515328119766076, 0.0572209773438471, -0.0312980539051096, -0.0643184321727071, 0.307431005789668, -0.206799905589266, 0.725688776807737, -0.237539020586649, 0.368411615307229}, + {-0.0483207200592166, 0.0591932994851923, 0.0519244590621585, -0.0792399156192371, -0.0641858656870188, 0.461149891737979, -0.206373671058999, 0.401080343939162, -0.221588980173731, 0.64636115837371}, + {-0.0589391326283225, 0.0639813152458781, -0.019040633081034, -0.137907233247907, 0.0288771793424126, 0.350558993625728, 0.0928473807579736, 0.140436657721587, -0.177632040150641, 0.716817512414326}, + {-0.00678016964142761, 0.0611615854552766, -0.0631390163152936, -0.179024503117915, 0.168237991451859, 0.0346813427943663, 0.540927376080161, 0.00686373315321105, -0.113917868475907, 0.550989528615669}, + {0.0505120918391691, 0.0486269923200345, 0.0566949918557829, -0.173796948096037, 0.248843383971813, -0.241293130595103, 0.800093947776937, -0.0230219385463298, -0.053315558719267, 0.286656168193001}, + {0.0615598618813391, 0.0291509945612395, 0.380020414290623, -0.118320020229917, 0.206625677790385, -0.283924856835237, 0.66435342429727, -0.0113646944909555, -0.0152274601562861, 0.0871266588915391}, + {0.0290069854895284, 0.0100894841280526, 0.772042818658422, -0.0440762414470225, 0.0849490887374542, -0.131416464538955, 0.273132645454226, -0.00145653829678759, -0.00157069394235881, 0.00929891575743996}, + {-0.055406624637136, -0.0324493693177595, 0.0163826439966072, 0.00651566075631112, -0.0303742880732422, 0.0345779132432746, -0.0440209524157112, 0.779899895847354, 0.212986400169712, 0.111888720430589}, + {-0.0637747792964597, -0.0185913269258039, 0.0572209773438471, 0.0172269218752282, -0.110692921200296, 0.135458724130567, -0.160425416561678, 0.550293167399344, 0.101425732049258, 0.491858921185992}, + {-0.0555370126851502, 0.00626565428530698, 0.0519244590621585, -0.0116465833510272, -0.110464772424612, 0.176973964593192, -0.160094764321406, 0.264900664046378, -0.0252653624551276, 0.862943753250288}, + {-0.0188997187595525, 0.0364053242476599, -0.019040633081034, -0.0990181011248814, 0.0496980294677158, 0.0714787626404375, 0.0720265306326704, 0.0492811457922452, -0.0989399510918513, 0.957008611276591}, + {0.0309147755718756, 0.0593383230002561, -0.0631390163152936, -0.201780837875702, 0.289539935934244, -0.127187806685882, 0.419625431597776, -0.0433205901064875, -0.0996052279744915, 0.735615012853705}, + {0.0620975991120015, 0.0626206415759849, 0.0566949918557829, -0.243791776902441, 0.428262943649539, -0.267351005358985, 0.620674388099211, -0.0438998617909714, -0.0580167920034083, 0.382708871763287}, + {0.0553914609549912, 0.0442298904674371, 0.380020414290623, -0.186817833236612, 0.355605680937512, -0.244621430931155, 0.515373421150143, -0.0168512938332078, -0.0186513557938836, 0.116321045994153}, + {0.0233547247376187, 0.0167561093806047, 0.772042818658422, -0.0740614433569781, 0.146198569648003, -0.104547141852547, 0.211883164543677, -0.0019941999100094, -0.00204739682977932, 0.0124147949809879}, + {-0.0324493693177595, -0.055406624637136, 0.0163826439966073, 0.0345779132432747, -0.0440209524157113, 0.00651566075631127, -0.0303742880732423, 0.212986400169712, 0.779899895847354, 0.11188872043059}, + {-0.0185913269258039, -0.0637747792964597, 0.0572209773438471, 0.135458724130567, -0.160425416561678, 0.0172269218752281, -0.110692921200296, 0.101425732049258, 0.550293167399345, 0.491858921185992}, + {0.00626565428530702, -0.0555370126851502, 0.0519244590621585, 0.176973964593192, -0.160094764321406, -0.0116465833510272, -0.110464772424612, -0.0252653624551277, 0.264900664046378, 0.862943753250288}, + {0.0364053242476599, -0.0188997187595525, -0.019040633081034, 0.0714787626404375, 0.0720265306326704, -0.0990181011248815, 0.0496980294677158, -0.0989399510918514, 0.0492811457922453, 0.957008611276591}, + {0.0593383230002561, 0.0309147755718756, -0.0631390163152936, -0.127187806685882, 0.419625431597776, -0.201780837875702, 0.289539935934244, -0.0996052279744917, -0.0433205901064873, 0.735615012853705}, + {0.0626206415759849, 0.0620975991120015, 0.0566949918557829, -0.267351005358985, 0.620674388099211, -0.243791776902441, 0.428262943649538, -0.0580167920034085, -0.0438998617909712, 0.382708871763286}, + {0.0442298904674371, 0.0553914609549912, 0.380020414290623, -0.244621430931155, 0.515373421150143, -0.186817833236612, 0.355605680937512, -0.0186513557938838, -0.0168512938332075, 0.116321045994153}, + {0.0167561093806048, 0.0233547247376186, 0.772042818658422, -0.104547141852547, 0.211883164543676, -0.0740614433569786, 0.146198569648004, -0.00204739682977956, -0.0019941999100092, 0.012414794980988}, + {0.0456157640261118, 0.115723962596159, 0.0163826439966072, 0.0747863424539099, -0.0567461752547089, -0.00561081141250942, -0.0176490652342444, -0.236426547960034, 0.980117123399934, 0.0838067633887746}, + {0.0515328119766076, 0.0296702250286437, 0.0572209773438471, 0.307431005789668, -0.206799905589266, -0.0312980539051096, -0.0643184321727071, -0.237539020586649, 0.725688776807737, 0.368411615307229}, + {0.0591932994851924, -0.0483207200592166, 0.0519244590621585, 0.461149891737979, -0.206373671058999, -0.0792399156192371, -0.0641858656870188, -0.221588980173731, 0.401080343939162, 0.64636115837371}, + {0.0639813152458782, -0.0589391326283225, -0.019040633081034, 0.350558993625728, 0.0928473807579736, -0.137907233247907, 0.0288771793424127, -0.177632040150641, 0.140436657721587, 0.716817512414326}, + {0.0611615854552767, -0.00678016964142762, -0.0631390163152936, 0.0346813427943663, 0.540927376080161, -0.179024503117915, 0.168237991451859, -0.113917868475908, 0.00686373315321122, 0.550989528615669}, + {0.0486269923200345, 0.0505120918391691, 0.0566949918557829, -0.241293130595103, 0.800093947776937, -0.173796948096037, 0.248843383971813, -0.0533155587192672, -0.0230219385463296, 0.286656168193}, + {0.0291509945612394, 0.0615598618813391, 0.380020414290623, -0.283924856835237, 0.66435342429727, -0.118320020229917, 0.206625677790385, -0.0152274601562863, -0.0113646944909553, 0.0871266588915391}, + {0.0100894841280527, 0.0290069854895284, 0.772042818658422, -0.131416464538955, 0.273132645454226, -0.0440762414470229, 0.0849490887374547, -0.00157069394235899, -0.00145653829678739, 0.00929891575744002}, + {0.05946683418451, 0.47020973746355, 0.0163826439966072, 0.116279705326824, -0.0668317173328137, -0.00559616028351832, -0.00756352315613959, -0.277719733919075, 0.653073464333186, 0.0422987493868697}, + {0.0575250264178156, 0.265449988133646, 0.0572209773438471, 0.486043893400969, -0.243554614434521, -0.0274431564798025, -0.0275637233274521, -0.245300094366671, 0.491677873041549, 0.18594383027062}, + {0.0534595098590293, 0.0463119810525849, 0.0519244590621585, 0.760615208731617, -0.243052624908065, -0.058573933810599, -0.0275069118379525, -0.192909925143069, 0.283502377422862, 0.326229859571435}, + {0.0466774120250636, -0.0600574472839972, -0.019040633081034, 0.654077930981418, 0.109349218305142, -0.0863990804381065, 0.0123753417952442, -0.131065806592769, 0.112292642040204, 0.361790422248835}, + {0.0370629148556119, -0.0357035269576087, -0.0631390163152936, 0.226256889805529, 0.637066821393747, -0.0977046399747994, 0.0720985461382728, -0.0732218315628921, 0.0191897241560417, 0.278094118461391}, + {0.0254456094649719, 0.0358848566633488, 0.0566949918557829, -0.187716658943997, 0.942295270430337, -0.0853976678869872, 0.106642061318412, -0.0308534586847474, -0.00767542054996641, 0.144680416332845}, + {0.0137220804056572, 0.0638181501493887, 0.380020414290623, -0.305068349063997, 0.782429477624355, -0.0540242282227645, 0.0885496244632994, -0.0081884902076963, -0.00523303855201251, 0.0439743591131468}, + {0.00444554825005747, 0.0331515865514706, 0.772042818658422, -0.151644069101048, 0.321676723998164, -0.0192430476716602, 0.0364050101935163, -0.000807619687337252, -0.000720277735756183, 0.00469332654417076}, + {0.0178239428840215, 0.807225505302963, 0.0163826439966072, 0.145438284135968, -0.0729181176510951, -0.00146906142904918, -0.00147712283785831, -0.0795443577738011, 0.159525211648988, 0.00901307172325663}, + {0.0166034772356767, 0.500250823188824, 0.0572209773438471, 0.611936513747061, -0.265735263712635, -0.00701309618780697, -0.00538307404933874, -0.0683953028250491, 0.120893795626888, 0.0396211496325332}, + {0.0145219306646567, 0.15653845670491, 0.0519244590621585, 0.973097999074361, -0.265187557730946, -0.0143403411079553, -0.00537197901507222, -0.0515302785630723, 0.0708338343849127, 0.069513476526047}, + {0.0117792672629172, -0.039932257114608, -0.019040633081034, 0.872469210295006, 0.119307710225706, -0.0200907042934334, 0.00241684987468039, -0.0332528040968106, 0.0292525941370028, 0.0770907667905735}, + {0.00866670223065463, -0.0498261910535888, -0.0631390163152936, 0.368944049909013, 0.695084838276183, -0.021554332743472, 0.0140805292558371, -0.0176243378815928, 0.0061111071956797, 0.0592566511265796}, + {0.00554981245166034, 0.0254615574022665, 0.0566949918557829, -0.14129819024666, 1.02811060576433, -0.0179644087649838, 0.0208267259844171, -0.0070814729632175, -0.00112830999710254, 0.0308286885135037}, + {0.00282953519001743, 0.0641490431525105, 0.380020414290623, -0.313546579737132, 0.853685749521881, -0.010941751227432, 0.0172933525657741, -0.00180948474863467, -0.00105039179855613, 0.00937011279094882}, + {0.000882679357025046, 0.0355121243622528, 0.772042818658422, -0.163394030616098, 0.350971995666499, -0.00379981964675408, 0.00710973852518171, -0.000173999841748956, -0.000151566499094147, 0.00100006003431419}}; + + static const double FE1[64][15] = \ + {{0.720387747630081, -0.0168300963375383, -0.015550527284872, 0.00163854086057334, 0.00118783679893825, 0.00165669951402109, 0.240852789949979, -0.181311893435648, 0.081782914040552, 0.264181419089758, -0.197398645310535, 0.0887210554052762, 0.0304534696971366, -0.00984886306639675, -0.00992244755132476}, + {0.334350007538137, -0.0157476116392644, -0.041607895510836, 0.00785907599312747, 0.00388119731430558, 0.00455873502072224, 0.868465037653299, -0.529157865026806, 0.225041796160404, 0.171573410660296, -0.152820018526424, 0.0766457307985556, 0.120332694035309, -0.043569536784057, -0.0298047576867686}, + {0.0231833153588187, -0.0138754408101468, -0.0124866302613435, 0.0161962116837833, 0.00179005174576421, 0.00145450091366685, 0.989147938202103, -0.196067923056882, 0.0718013871481121, 0.0720021429531595, -0.0937310210810572, 0.0581991246546323, 0.171393765376422, -0.0772454474565525, -0.0117619753704807}, + {-0.0372979176398618, -0.0113607013577723, 0.0234218149212636, 0.0229165574221674, -0.00859721664442312, -0.00309021587419028, 0.412858260863228, 0.653223900573648, -0.152548399433187, 0.0138425230353485, -0.0426654097549133, 0.0379299691739386, 0.133613946690294, -0.0868093356871081, 0.0445622237115678}, + {0.0153548787387587, -0.00844404938870885, -0.0158869085152141, 0.0248516699640842, -0.0224124304330252, 0.00280185612278432, -0.110069778477085, 0.89891855540164, 0.138313530307914, -0.00182317133300847, -0.0121547300476419, 0.020320472620592, 0.0549994325595515, -0.0676932950399705, 0.0829239675193287}, + {0.00957969305354466, -0.00546003408216049, -0.0276596689577737, 0.0209266940090266, -0.0294131916469231, 0.0171102034388012, -0.0582847907315524, 0.18501428650562, 0.844644599222123, -0.000465422182312679, -0.000779263349280848, 0.00824918981599346, 0.00454965031691995, -0.0357053867828633, 0.0676934413708371}, + {-0.0357244095644531, -0.00280652589685835, 0.207650183826703, 0.0128563794508787, -0.0234934550144674, 0.0225385929518186, 0.200933462410377, -0.509171697014143, 1.11261685922732, 0.000673133992239074, 0.000696041664133325, 0.00212611510310175, -0.00481971484331965, -0.0109779896131299, 0.0269030233197961}, + {-0.0310132994081584, -0.00088046214273825, 0.672205957376832, 0.00449151328668965, -0.00952135873936943, 0.0116030067386997, 0.167810030907446, -0.389151493856983, 0.572782025160269, 0.000155662840323034, 0.000127487896077555, 0.000205673603947132, -0.000977847169457868, -0.00118105479106664, 0.0033441582974893}, + {0.301212821143164, -0.0416040690416377, -0.015550527284872, 0.0045511171935714, 0.00396183286832819, 0.00848303527364849, 0.161846478234107, -0.147441846167928, 0.0749565782809246, 0.908994737588923, -0.535399560105175, 0.225857550891767, 0.12680570000079, -0.0301073579871757, -0.0465664908884351}, + {0.103391388541423, -0.0416340810050223, -0.041607895510836, 0.0231269555486489, 0.0135042007708598, 0.0233427423963804, 0.569707379345283, -0.42871056307971, 0.206257788784746, 0.576311144601667, -0.43078675369888, 0.206719820392112, 0.499194850467653, -0.138941914463906, -0.139875063090418}, + {-0.0312085494098578, -0.0408081157499809, -0.0124866302613435, 0.0522026408865433, 0.00665233476823637, 0.00744768888489726, 0.605447553034706, -0.157492704094436, 0.0658081991768817, 0.225667089902693, -0.27979873733087, 0.171926433663422, 0.704946955624449, -0.263104681739943, -0.0551994773553985}, + {-0.0225601623417477, -0.037941797179199, 0.0234218149212636, 0.0822668469579536, -0.0344986519838966, -0.0158232739504572, 0.180656446025266, 0.514555047338839, -0.13981534135692, 0.0310152485886992, -0.134862110463046, 0.124797284852033, 0.538925950557131, -0.319269814251769, 0.20913251228585}, + {0.021572373044133, -0.032093186406357, -0.0158869085152141, 0.0994473280876234, -0.0970407971089643, 0.0143467443070456, -0.137786433769746, 0.667304994998036, 0.126768642123653, -0.0116862017274203, -0.0390674215703635, 0.0745278372499994, 0.209059432588477, -0.268632297899773, 0.389165894598872}, + {0.0025132133211552, -0.0233137650114745, -0.0276596689577737, 0.0922635401725182, -0.136142544211903, 0.0876118198153854, -0.0145621063354509, 0.0417487273917892, 0.774142982845539, -0.000595420197901868, -0.000813905413033122, 0.0333340405570383, 0.00525682503864158, -0.151472092064178, 0.317688353049649}, + {-0.0382307908207458, -0.0131475847004944, 0.207650183826703, 0.0611949901181771, -0.114547744464186, 0.115407578387356, 0.21093648204494, -0.517471477951854, 1.01974787379179, 0.00361833256696031, 0.00344903062892843, 0.00927536762351407, -0.0250813572764778, -0.0490579774818332, 0.126257093707226}, + {-0.0293101803798725, -0.00438827560495148, 0.672205957376832, 0.0224956245923683, -0.048038930350579, 0.0594125335413836, 0.157778841261754, -0.362984048658182, 0.524972498357585, 0.000749416625443686, 0.000599973671381315, 0.000944128477450075, -0.00467032764518738, -0.00546149597532369, 0.0156942847098986}, + {-0.000791078327532018, -0.00582669203954899, -0.015550527284872, 0.000801557105315896, 0.00104577906383194, 0.0197946961803756, 0.0707053809756933, -0.0988298182782798, 0.0636449173741977, 0.926633825601262, -0.094730327579658, 0.0337757528225179, 0.198336926938653, -0.00674792757836945, -0.0922624649735873}, + {-0.0359908448726913, -0.0120347337036228, -0.041607895510836, 0.00822598079580996, 0.00688357353176852, 0.0544690053557198, 0.23109000831666, -0.2848297056581, 0.175131525825407, 0.545486376811778, -0.145891002076937, 0.0624317226727732, 0.773906975114481, -0.0601356933292724, -0.277135293272937}, + {-0.0334141500459977, -0.0223526052072552, -0.0124866302613435, 0.0339977982717186, 0.00580391140949369, 0.0173787723340557, 0.190069948015166, -0.102476705755877, 0.0558771157277232, 0.165311369444572, -0.158839000302599, 0.0950725071866869, 1.07033252558048, -0.194907804061609, -0.109367052335214}, + {0.00663809354630194, -0.0338626997514491, 0.0234218149212636, 0.0838243228201285, -0.0436788442948979, -0.0369227393644254, -0.036450901015783, 0.31851226322517, -0.118715875942952, -0.0146025142777031, -0.105694717009156, 0.107970300948746, 0.778432535171098, -0.343226527686862, 0.41435548871052}, + {0.0221296379144453, -0.0411761873776797, -0.0158869085152141, 0.139844929513345, -0.157919107269212, 0.0334773386617496, -0.119724828639292, 0.346292501382224, 0.107638047768948, -0.0236945633987251, -0.0329923906302845, 0.0889869040822356, 0.253154730181475, -0.371186802048947, 0.771056698374932}, + {-0.0108839504063844, -0.0389029059491852, -0.0276596689577737, 0.162735488996636, -0.261745900143559, 0.204437362230779, 0.0584478548013947, -0.144397384397703, 0.657317440430145, 0.00557654881464668, 0.00541222754468843, 0.0499222432520186, -0.0424264970025999, -0.2472706799839, 0.629437820770797}, + {-0.040990407386457, -0.0262749037685394, 0.207650183826703, 0.125639672349686, -0.245060834007854, 0.269297235882888, 0.219245169353835, -0.51085522435261, 0.865858216296254, 0.00877575283861117, 0.00728443442551398, 0.0161694791890338, -0.0577776699833318, -0.0891150343153835, 0.25015392965165}, + {-0.0261623974581368, -0.00978532900005473, 0.672205957376832, 0.0505730482776807, -0.109332916192516, 0.138635878883036, 0.139643836272053, -0.317090957616473, 0.445749153015932, 0.00154772536420102, 0.00119285076434308, 0.00180221311909855, -0.00952009394577891, -0.010554148370344, 0.0310951795101257}, + {-0.028142124080269, 0.0223136923296902, -0.015550527284872, -0.00454741790821049, -0.0160038172338055, 0.0340669489361074, 0.0118567443386973, -0.0508649297870856, 0.0493726646184657, 0.267427175543548, 0.746110465066622, -0.14864772838255, 0.175678425974943, 0.0801081850358625, -0.123177757167144}, + {-0.01319954290128, 0.0234107938090704, -0.041607895510836, -0.0225640135181179, -0.0416312594983321, 0.0937419199135526, 0.0227096342464765, -0.143452422322423, 0.135858611267574, 0.0922565647962882, 0.444382252950585, -0.132848549823364, 0.670804187644173, 0.282137462525146, -0.369997743578514}, + {0.0106622616521446, 0.0186307429382647, -0.0124866302613435, -0.0372095020654963, -0.0111156270524488, 0.0299091102122326, -0.0320599290898916, -0.0489104726683462, 0.0433467778495464, -0.0479883949298086, 0.145193455464034, -0.0807199440492284, 0.879184101655078, 0.289577797306066, -0.146013746960803}, + {0.0234186698704818, 0.00211411708289207, 0.0234218149212636, -0.00637240429901968, 0.00478506316089386, -0.0635445507749753, -0.0920829341581127, 0.13120618404595, -0.0920940645324021, -0.0634867243862504, 0.00476977576875405, -0.00636737487913779, 0.551865856292455, 0.0291689114532588, 0.553197660433949}, + {0.00609404082734274, -0.0225920658504383, -0.0158869085152141, 0.0873062383326183, -0.122992439315374, 0.0576149679850738, -0.0276359694564604, 0.0530002766997203, 0.0835004184456243, -0.00941290314075061, -0.00393271586282033, 0.043097044616658, 0.0666815206559956, -0.224263760525573, 1.0294222551036}, + {-0.0278543503198826, -0.0402275295776552, -0.0276596689577737, 0.181321100503017, -0.329007581775416, 0.351839559257954, 0.136933927611599, -0.288047628350919, 0.50991524340297, 0.0224849743451396, 0.0135708497672736, 0.0431502190409087, -0.145655387059816, -0.24111347424327, 0.840349746355869}, + {-0.0413165406002055, -0.0366125404747618, 0.207650183826703, 0.1813273908851, -0.373481651168546, 0.463464308815837, 0.212778234978009, -0.466255946436086, 0.671691143363305, 0.0146577041319606, 0.0101325264391238, 0.0181032058020456, -0.0907550849558157, -0.105358403502487, 0.333975468895817}, + {-0.0215850703270563, -0.0158836129776581, 0.672205957376832, 0.0829469640192732, -0.182163131970903, 0.238594286246385, 0.113996394475687, -0.254680109677888, 0.345790745652583, 0.0021744410758299, 0.00159627178167121, 0.00229303323666444, -0.013159421688214, -0.0136412945731352, 0.0415145473499274}, + {0.0223136923296901, -0.028142124080269, -0.015550527284872, 0.0118567443386973, -0.0508649297870857, 0.0493726646184658, -0.00454741790821032, -0.0160038172338055, 0.0340669489361075, -0.14864772838255, 0.746110465066622, 0.267427175543548, 0.0801081850358624, 0.175678425974943, -0.123177757167144}, + {0.0234107938090704, -0.0131995429012799, -0.041607895510836, 0.0227096342464765, -0.143452422322423, 0.135858611267574, -0.0225640135181178, -0.0416312594983319, 0.0937419199135526, -0.132848549823364, 0.444382252950585, 0.0922565647962883, 0.282137462525146, 0.670804187644173, -0.369997743578514}, + {0.0186307429382647, 0.0106622616521446, -0.0124866302613435, -0.0320599290898917, -0.0489104726683462, 0.0433467778495464, -0.0372095020654962, -0.0111156270524487, 0.0299091102122326, -0.0807199440492285, 0.145193455464034, -0.0479883949298086, 0.289577797306066, 0.879184101655078, -0.146013746960803}, + {0.00211411708289209, 0.0234186698704818, 0.0234218149212636, -0.0920829341581127, 0.13120618404595, -0.092094064532402, -0.00637240429901968, 0.00478506316089407, -0.0635445507749753, -0.00636737487913791, 0.00476977576875408, -0.0634867243862504, 0.0291689114532588, 0.551865856292455, 0.553197660433949}, + {-0.0225920658504383, 0.00609404082734276, -0.0158869085152141, -0.0276359694564603, 0.0530002766997201, 0.0835004184456244, 0.0873062383326183, -0.122992439315374, 0.0576149679850737, 0.043097044616658, -0.00393271586282032, -0.00941290314075057, -0.224263760525573, 0.0666815206559958, 1.0294222551036}, + {-0.0402275295776552, -0.0278543503198826, -0.0276596689577737, 0.136933927611599, -0.288047628350919, 0.50991524340297, 0.181321100503017, -0.329007581775415, 0.351839559257954, 0.0431502190409087, 0.0135708497672736, 0.0224849743451396, -0.24111347424327, -0.145655387059815, 0.840349746355869}, + {-0.0366125404747618, -0.0413165406002055, 0.207650183826703, 0.212778234978009, -0.466255946436086, 0.671691143363305, 0.1813273908851, -0.373481651168546, 0.463464308815837, 0.0181032058020455, 0.0101325264391238, 0.0146577041319607, -0.105358403502488, -0.0907550849558154, 0.333975468895817}, + {-0.0158836129776582, -0.0215850703270562, 0.672205957376832, 0.113996394475687, -0.254680109677887, 0.345790745652582, 0.0829469640192736, -0.182163131970904, 0.238594286246387, 0.00229303323666434, 0.00159627178167124, 0.00217444107582999, -0.0136412945731355, -0.0131594216882138, 0.0415145473499275}, + {-0.00582669203954894, -0.000791078327532056, -0.015550527284872, 0.070705380975693, -0.0988298182782797, 0.0636449173741976, 0.000801557105315896, 0.00104577906383212, 0.0197946961803756, 0.0337757528225177, -0.0947303275796572, 0.926633825601262, -0.0067479275783695, 0.198336926938653, -0.0922624649735873}, + {-0.0120347337036227, -0.0359908448726912, -0.041607895510836, 0.23109000831666, -0.2848297056581, 0.175131525825407, 0.00822598079581002, 0.00688357353176863, 0.0544690053557199, 0.0624317226727732, -0.145891002076937, 0.545486376811778, -0.0601356933292724, 0.773906975114481, -0.277135293272937}, + {-0.0223526052072551, -0.0334141500459977, -0.0124866302613435, 0.190069948015166, -0.102476705755877, 0.0558771157277233, 0.0339977982717186, 0.00580391140949392, 0.0173787723340557, 0.0950725071866868, -0.158839000302599, 0.165311369444572, -0.19490780406161, 1.07033252558048, -0.109367052335214}, + {-0.0338626997514491, 0.00663809354630199, 0.0234218149212636, -0.0364509010157831, 0.31851226322517, -0.118715875942952, 0.0838243228201285, -0.0436788442948977, -0.0369227393644254, 0.107970300948746, -0.105694717009156, -0.0146025142777032, -0.343226527686862, 0.778432535171098, 0.41435548871052}, + {-0.0411761873776797, 0.0221296379144453, -0.0158869085152141, -0.119724828639292, 0.346292501382224, 0.107638047768949, 0.139844929513345, -0.157919107269212, 0.0334773386617496, 0.0889869040822355, -0.0329923906302844, -0.0236945633987251, -0.371186802048947, 0.253154730181475, 0.771056698374932}, + {-0.0389029059491852, -0.0108839504063844, -0.0276596689577737, 0.0584478548013946, -0.144397384397703, 0.657317440430146, 0.162735488996636, -0.261745900143559, 0.204437362230779, 0.0499222432520185, 0.0054122275446885, 0.00557654881464667, -0.2472706799839, -0.0424264970025996, 0.629437820770797}, + {-0.0262749037685394, -0.040990407386457, 0.207650183826703, 0.219245169353835, -0.51085522435261, 0.865858216296254, 0.125639672349686, -0.245060834007854, 0.269297235882889, 0.0161694791890337, 0.00728443442551409, 0.00877575283861122, -0.0891150343153837, -0.0577776699833316, 0.25015392965165}, + {-0.00978532900005478, -0.0261623974581368, 0.672205957376832, 0.139643836272053, -0.317090957616473, 0.445749153015931, 0.0505730482776808, -0.109332916192516, 0.138635878883037, 0.00180221311909846, 0.00119285076434313, 0.00154772536420111, -0.0105541483703442, -0.00952009394577874, 0.0310951795101259}, + {-0.0416040690416377, 0.301212821143164, -0.015550527284872, 0.161846478234107, -0.147441846167928, 0.0749565782809247, 0.00455111719357149, 0.00396183286832821, 0.00848303527364846, 0.225857550891767, -0.535399560105175, 0.908994737588923, -0.0301073579871758, 0.12680570000079, -0.0465664908884351}, + {-0.0416340810050223, 0.103391388541424, -0.041607895510836, 0.569707379345283, -0.42871056307971, 0.206257788784746, 0.0231269555486489, 0.0135042007708601, 0.0233427423963804, 0.206719820392112, -0.43078675369888, 0.576311144601667, -0.138941914463906, 0.499194850467653, -0.139875063090418}, + {-0.0408081157499809, -0.0312085494098577, -0.0124866302613435, 0.605447553034706, -0.157492704094436, 0.0658081991768818, 0.0522026408865433, 0.00665233476823669, 0.00744768888489729, 0.171926433663422, -0.27979873733087, 0.225667089902693, -0.263104681739943, 0.704946955624449, -0.0551994773553983}, + {-0.037941797179199, -0.0225601623417476, 0.0234218149212636, 0.180656446025266, 0.514555047338839, -0.13981534135692, 0.0822668469579536, -0.0344986519838963, -0.0158232739504572, 0.124797284852033, -0.134862110463046, 0.0310152485886991, -0.319269814251769, 0.538925950557131, 0.20913251228585}, + {-0.032093186406357, 0.021572373044133, -0.0158869085152141, -0.137786433769746, 0.667304994998037, 0.126768642123653, 0.0994473280876233, -0.0970407971089639, 0.0143467443070456, 0.0745278372499993, -0.0390674215703635, -0.0116862017274203, -0.268632297899774, 0.209059432588477, 0.389165894598872}, + {-0.0233137650114745, 0.00251321332115522, -0.0276596689577737, -0.014562106335451, 0.0417487273917892, 0.774142982845539, 0.0922635401725181, -0.136142544211903, 0.0876118198153852, 0.0333340405570382, -0.000813905413033007, -0.000595420197901859, -0.151472092064178, 0.00525682503864178, 0.317688353049648}, + {-0.0131475847004944, -0.0382307908207458, 0.207650183826703, 0.21093648204494, -0.517471477951854, 1.01974787379179, 0.0611949901181769, -0.114547744464185, 0.115407578387356, 0.00927536762351387, 0.0034490306289286, 0.00361833256696033, -0.0490579774818333, -0.0250813572764775, 0.126257093707225}, + {-0.00438827560495154, -0.0293101803798724, 0.672205957376832, 0.157778841261754, -0.362984048658182, 0.524972498357584, 0.0224956245923686, -0.0480389303505794, 0.0594125335413844, 0.000944128477449964, 0.000599973671381385, 0.000749416625443734, -0.00546149597532394, -0.00467032764518721, 0.0156942847098986}, + {-0.0168300963375383, 0.72038774763008, -0.015550527284872, 0.240852789949979, -0.181311893435649, 0.0817829140405521, 0.00163854086057324, 0.00118783679893848, 0.00165669951402107, 0.0887210554052764, -0.197398645310535, 0.264181419089759, -0.00984886306639687, 0.0304534696971369, -0.00992244755132479}, + {-0.0157476116392645, 0.334350007538137, -0.041607895510836, 0.868465037653298, -0.529157865026806, 0.225041796160404, 0.00785907599312748, 0.003881197314306, 0.00455873502072222, 0.076645730798556, -0.152820018526425, 0.171573410660297, -0.0435695367840574, 0.12033269403531, -0.0298047576867687}, + {-0.0138754408101468, 0.0231833153588188, -0.0124866302613435, 0.989147938202103, -0.196067923056882, 0.0718013871481122, 0.0161962116837832, 0.00179005174576466, 0.00145450091366683, 0.0581991246546323, -0.0937310210810572, 0.0720021429531596, -0.0772454474565528, 0.171393765376422, -0.0117619753704805}, + {-0.0113607013577723, -0.0372979176398618, 0.0234218149212636, 0.412858260863228, 0.653223900573648, -0.152548399433187, 0.0229165574221675, -0.0085972166444228, -0.00309021587419031, 0.0379299691739386, -0.0426654097549133, 0.0138425230353484, -0.0868093356871082, 0.133613946690294, 0.044562223711568}, + {-0.00844404938870877, 0.0153548787387587, -0.0158869085152141, -0.110069778477085, 0.898918555401641, 0.138313530307914, 0.0248516699640842, -0.0224124304330248, 0.00280185612278437, 0.0203204726205919, -0.0121547300476418, -0.00182317133300843, -0.0676932950399702, 0.0549994325595512, 0.0829239675193281}, + {-0.00546003408216042, 0.00957969305354466, -0.0276596689577737, -0.0582847907315525, 0.185014286505621, 0.844644599222124, 0.0209266940090264, -0.0294131916469225, 0.0171102034388011, 0.00824918981599329, -0.000779263349280709, -0.000465422182312696, -0.0357053867828632, 0.00454965031692008, 0.0676934413708362}, + {-0.0028065258968584, -0.0357244095644531, 0.207650183826703, 0.200933462410377, -0.509171697014143, 1.11261685922732, 0.0128563794508789, -0.0234934550144674, 0.0225385929518193, 0.00212611510310159, 0.000696041664133532, 0.000673133992239113, -0.0109779896131303, -0.00481971484331942, 0.0269030233197963}, + {-0.000880462142738327, -0.0310132994081584, 0.672205957376832, 0.167810030907446, -0.389151493856983, 0.572782025160268, 0.00449151328668998, -0.00952135873936982, 0.0116030067387005, 0.000205673603947069, 0.000127487896077673, 0.000155662840323118, -0.00118105479106689, -0.000977847169457674, 0.00334415829748941}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 225; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 45952 + for (unsigned int ip = 0; ip < 64; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + + // Total number of operations to compute function values = 40 + for (unsigned int r = 0; r < 10; r++) + { + F0 += FE0[ip][r]*w[0][r]; + F1 += FE0[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 3 + double I[1]; + // Number of operations: 3 + I[0] = F0*F1*W64[ip]*det; + + + // Number of operations for primary indices: 675 + for (unsigned int j = 0; j < 15; j++) + { + for (unsigned int k = 0; k < 15; k++) + { + // Number of operations to compute entry: 3 + A[j*15 + k] += FE1[ip][j]*FE1[ip][k]*I[0]; + }// 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 mass_matrix_f2_p3_q4_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p3_q4_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p3_q4_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1))), 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 mass_matrix_f2_p3_q4_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p3_q4_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p3_q4_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p3_q4_quadrature_finite_element_0(); + 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 mass_matrix_f2_p3_q4_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p3_q4_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p3_q4_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p3_q4_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f2_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/mass_matrix_2d/mass_matrix_f2_p3_q4_tensor.h b/mass_matrix_2d/mass_matrix_f2_p3_q4_tensor.h new file mode 100644 index 0000000..93a3109 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f2_p3_q4_tensor.h @@ -0,0 +1,8650 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F2_P3_Q4_TENSOR_H +#define __MASS_MATRIX_F2_P3_Q4_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p3_q4_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p3_q4_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p3_q4_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f2_p3_q4_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f2_p3_q4_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p3_q4_tensor_finite_element_1() + { + // 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.0224478343233824, 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.0412393049421162, -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.0388807895679869, 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.0439885919382571, 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.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 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.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.00927360943924092, 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.0535412090610519}; + + // 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.0622092633087791, -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.251415744421884, 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.0224478343233824, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0412393049421162, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0388807895679869, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0439885919382571, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.00927360943924092, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0622092633087791, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.251415744421884, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f2_p3_q4_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p3_q4_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p3_q4_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_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.0*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 mass_matrix_f2_p3_q4_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f2_p3_q4_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f2_p3_q4_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f2_p3_q4_tensor_dofmap_1() + { + // 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.0*m.num_entities[1] + 3.0*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 mass_matrix_f2_p3_q4_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 mass_matrix_f2_p3_q4_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f2_p3_q4_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 150 + // Number of operations (multiply-add pairs) for tensor contraction: 10628 + // Total number of operations (multiply-add pairs): 10787 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0 = det*w[0][0]*w[1][0]*(1.0); + const double G0_0_1 = det*w[0][0]*w[1][1]*(1.0); + const double G0_0_2 = det*w[0][0]*w[1][2]*(1.0); + const double G0_0_3 = det*w[0][0]*w[1][3]*(1.0); + const double G0_0_4 = det*w[0][0]*w[1][4]*(1.0); + const double G0_0_5 = det*w[0][0]*w[1][5]*(1.0); + const double G0_0_6 = det*w[0][0]*w[1][6]*(1.0); + const double G0_0_7 = det*w[0][0]*w[1][7]*(1.0); + const double G0_0_8 = det*w[0][0]*w[1][8]*(1.0); + const double G0_0_9 = det*w[0][0]*w[1][9]*(1.0); + const double G0_1_0 = det*w[0][1]*w[1][0]*(1.0); + const double G0_1_1 = det*w[0][1]*w[1][1]*(1.0); + const double G0_1_2 = det*w[0][1]*w[1][2]*(1.0); + const double G0_1_3 = det*w[0][1]*w[1][3]*(1.0); + const double G0_1_4 = det*w[0][1]*w[1][4]*(1.0); + const double G0_1_5 = det*w[0][1]*w[1][5]*(1.0); + const double G0_1_6 = det*w[0][1]*w[1][6]*(1.0); + const double G0_1_7 = det*w[0][1]*w[1][7]*(1.0); + const double G0_1_8 = det*w[0][1]*w[1][8]*(1.0); + const double G0_1_9 = det*w[0][1]*w[1][9]*(1.0); + const double G0_2_0 = det*w[0][2]*w[1][0]*(1.0); + const double G0_2_1 = det*w[0][2]*w[1][1]*(1.0); + const double G0_2_2 = det*w[0][2]*w[1][2]*(1.0); + const double G0_2_3 = det*w[0][2]*w[1][3]*(1.0); + const double G0_2_4 = det*w[0][2]*w[1][4]*(1.0); + const double G0_2_5 = det*w[0][2]*w[1][5]*(1.0); + const double G0_2_6 = det*w[0][2]*w[1][6]*(1.0); + const double G0_2_7 = det*w[0][2]*w[1][7]*(1.0); + const double G0_2_8 = det*w[0][2]*w[1][8]*(1.0); + const double G0_2_9 = det*w[0][2]*w[1][9]*(1.0); + const double G0_3_0 = det*w[0][3]*w[1][0]*(1.0); + const double G0_3_1 = det*w[0][3]*w[1][1]*(1.0); + const double G0_3_2 = det*w[0][3]*w[1][2]*(1.0); + const double G0_3_3 = det*w[0][3]*w[1][3]*(1.0); + const double G0_3_4 = det*w[0][3]*w[1][4]*(1.0); + const double G0_3_5 = det*w[0][3]*w[1][5]*(1.0); + const double G0_3_6 = det*w[0][3]*w[1][6]*(1.0); + const double G0_3_7 = det*w[0][3]*w[1][7]*(1.0); + const double G0_3_8 = det*w[0][3]*w[1][8]*(1.0); + const double G0_3_9 = det*w[0][3]*w[1][9]*(1.0); + const double G0_4_0 = det*w[0][4]*w[1][0]*(1.0); + const double G0_4_1 = det*w[0][4]*w[1][1]*(1.0); + const double G0_4_2 = det*w[0][4]*w[1][2]*(1.0); + const double G0_4_3 = det*w[0][4]*w[1][3]*(1.0); + const double G0_4_4 = det*w[0][4]*w[1][4]*(1.0); + const double G0_4_5 = det*w[0][4]*w[1][5]*(1.0); + const double G0_4_6 = det*w[0][4]*w[1][6]*(1.0); + const double G0_4_7 = det*w[0][4]*w[1][7]*(1.0); + const double G0_4_8 = det*w[0][4]*w[1][8]*(1.0); + const double G0_4_9 = det*w[0][4]*w[1][9]*(1.0); + const double G0_5_0 = det*w[0][5]*w[1][0]*(1.0); + const double G0_5_1 = det*w[0][5]*w[1][1]*(1.0); + const double G0_5_2 = det*w[0][5]*w[1][2]*(1.0); + const double G0_5_3 = det*w[0][5]*w[1][3]*(1.0); + const double G0_5_4 = det*w[0][5]*w[1][4]*(1.0); + const double G0_5_5 = det*w[0][5]*w[1][5]*(1.0); + const double G0_5_6 = det*w[0][5]*w[1][6]*(1.0); + const double G0_5_7 = det*w[0][5]*w[1][7]*(1.0); + const double G0_5_8 = det*w[0][5]*w[1][8]*(1.0); + const double G0_5_9 = det*w[0][5]*w[1][9]*(1.0); + const double G0_6_0 = det*w[0][6]*w[1][0]*(1.0); + const double G0_6_1 = det*w[0][6]*w[1][1]*(1.0); + const double G0_6_2 = det*w[0][6]*w[1][2]*(1.0); + const double G0_6_3 = det*w[0][6]*w[1][3]*(1.0); + const double G0_6_4 = det*w[0][6]*w[1][4]*(1.0); + const double G0_6_5 = det*w[0][6]*w[1][5]*(1.0); + const double G0_6_6 = det*w[0][6]*w[1][6]*(1.0); + const double G0_6_7 = det*w[0][6]*w[1][7]*(1.0); + const double G0_6_8 = det*w[0][6]*w[1][8]*(1.0); + const double G0_6_9 = det*w[0][6]*w[1][9]*(1.0); + const double G0_7_0 = det*w[0][7]*w[1][0]*(1.0); + const double G0_7_1 = det*w[0][7]*w[1][1]*(1.0); + const double G0_7_2 = det*w[0][7]*w[1][2]*(1.0); + const double G0_7_3 = det*w[0][7]*w[1][3]*(1.0); + const double G0_7_4 = det*w[0][7]*w[1][4]*(1.0); + const double G0_7_5 = det*w[0][7]*w[1][5]*(1.0); + const double G0_7_6 = det*w[0][7]*w[1][6]*(1.0); + const double G0_7_7 = det*w[0][7]*w[1][7]*(1.0); + const double G0_7_8 = det*w[0][7]*w[1][8]*(1.0); + const double G0_7_9 = det*w[0][7]*w[1][9]*(1.0); + const double G0_8_0 = det*w[0][8]*w[1][0]*(1.0); + const double G0_8_1 = det*w[0][8]*w[1][1]*(1.0); + const double G0_8_2 = det*w[0][8]*w[1][2]*(1.0); + const double G0_8_3 = det*w[0][8]*w[1][3]*(1.0); + const double G0_8_4 = det*w[0][8]*w[1][4]*(1.0); + const double G0_8_5 = det*w[0][8]*w[1][5]*(1.0); + const double G0_8_6 = det*w[0][8]*w[1][6]*(1.0); + const double G0_8_7 = det*w[0][8]*w[1][7]*(1.0); + const double G0_8_8 = det*w[0][8]*w[1][8]*(1.0); + const double G0_8_9 = det*w[0][8]*w[1][9]*(1.0); + const double G0_9_0 = det*w[0][9]*w[1][0]*(1.0); + const double G0_9_1 = det*w[0][9]*w[1][1]*(1.0); + const double G0_9_2 = det*w[0][9]*w[1][2]*(1.0); + const double G0_9_3 = det*w[0][9]*w[1][3]*(1.0); + const double G0_9_4 = det*w[0][9]*w[1][4]*(1.0); + const double G0_9_5 = det*w[0][9]*w[1][5]*(1.0); + const double G0_9_6 = det*w[0][9]*w[1][6]*(1.0); + const double G0_9_7 = det*w[0][9]*w[1][7]*(1.0); + const double G0_9_8 = det*w[0][9]*w[1][8]*(1.0); + const double G0_9_9 = det*w[0][9]*w[1][9]*(1.0); + + // Compute element tensor + A[108] = -1.35666802333532e-05*G0_0_0 - 1.02542959685864e-05*G0_0_1 - 2.27638322876525e-05*G0_0_2 + 3.8374324088628e-05*G0_0_3 - 4.15457558314897e-05*G0_0_4 - 4.09114694829171e-05*G0_0_5 - 6.66000666000979e-05*G0_0_6 - 2.72743129886115e-05*G0_0_7 + 2.69571698143254e-05*G0_0_8 - 5.89886304172295e-05*G0_0_9 - 1.02542959685865e-05*G0_1_0 + 1.01133434466821e-05*G0_1_1 - 2.52305014209894e-05*G0_1_2 + 3.07628879057603e-05*G0_1_3 - 5.3914339628651e-05*G0_1_4 + 4.59857602714962e-05*G0_1_5 - 7.29429300858212e-06*G0_1_6 - 3.48857491714812e-06*G0_1_7 + 6.97714983429626e-06*G0_1_8 + 2.85428856857564e-05*G0_1_9 - 2.27638322876525e-05*G0_2_0 - 2.52305014209894e-05*G0_2_1 - 0.000166253499586911*G0_2_2 + 0.000111951540523022*G0_2_3 - 0.000221048792477468*G0_2_4 + 6.88200688201013e-05*G0_2_5 - 0.000258471687043237*G0_2_6 + 2.69571698143254e-05*G0_2_8 - 0.000114171542743025*G0_2_9 + 3.8374324088628e-05*G0_3_0 + 3.07628879057603e-05*G0_3_1 + 0.000111951540523022*G0_3_2 - 3.42514628229032e-05*G0_3_3 + 0.00018838304552599*G0_3_4 - 0.000162694448408811*G0_3_5 + 9.41915227629953e-05*G0_3_6 - 4.28143285286352e-05*G0_3_7 + 5.13771942343626e-05*G0_3_8 - 4.15457558314897e-05*G0_4_0 - 5.3914339628651e-05*G0_4_1 - 0.000221048792477468*G0_4_2 + 0.00018838304552599*G0_4_3 - 0.000333951762523347*G0_4_4 + 0.000196945911231718*G0_4_5 - 0.000291137433994713*G0_4_6 + 2.5688597117181e-05*G0_4_7 - 8.56286570572749e-06*G0_4_8 - 5.13771942343618e-05*G0_4_9 - 4.09114694829171e-05*G0_5_0 + 4.59857602714962e-05*G0_5_1 + 6.88200688201013e-05*G0_5_2 - 0.000162694448408811*G0_5_3 + 0.000196945911231718*G0_5_4 + 0.000148423005565932*G0_5_5 + 0.000456686170972099*G0_5_6 - 5.70857713715104e-06*G0_5_7 - 6.56486370772395e-05*G0_5_8 + 0.000308263165406167*G0_5_9 - 6.66000666000979e-05*G0_6_0 - 7.29429300858213e-06*G0_6_1 - 0.000258471687043237*G0_6_2 + 9.41915227629953e-05*G0_6_3 - 0.000291137433994713*G0_6_4 + 0.000456686170972099*G0_6_5 - 8.27743684886927e-05*G0_6_6 + 7.13572142143905e-05*G0_6_7 - 6.56486370772395e-05*G0_6_8 + 0.000154131582703084*G0_6_9 - 2.72743129886115e-05*G0_7_0 - 3.48857491714812e-06*G0_7_1 - 4.28143285286352e-05*G0_7_3 + 2.5688597117181e-05*G0_7_4 - 5.70857713715105e-06*G0_7_5 + 7.13572142143905e-05*G0_7_6 - 1.71257314114531e-05*G0_7_7 - 8.56286570572747e-06*G0_7_8 + 3.42514628229074e-05*G0_7_9 + 2.69571698143254e-05*G0_8_0 + 6.97714983429626e-06*G0_8_1 + 2.69571698143254e-05*G0_8_2 + 5.13771942343626e-05*G0_8_3 - 8.56286570572749e-06*G0_8_4 - 6.56486370772395e-05*G0_8_5 - 6.56486370772394e-05*G0_8_6 - 8.56286570572747e-06*G0_8_7 + 5.13771942343624e-05*G0_8_8 - 6.85029256458144e-05*G0_8_9 - 5.89886304172295e-05*G0_9_0 + 2.85428856857564e-05*G0_9_1 - 0.000114171542743025*G0_9_2 - 5.13771942343618e-05*G0_9_4 + 0.000308263165406167*G0_9_5 + 0.000154131582703084*G0_9_6 + 3.42514628229074e-05*G0_9_7 - 6.85029256458144e-05*G0_9_8 + 0.000513771942343613*G0_9_9; + A[52] = A[108]; + A[60] = 5.30333863667449e-06*G0_0_0 + 7.50351940828485e-06*G0_0_1 + 7.50351940828484e-06*G0_0_2 - 7.47268604411815e-06*G0_0_3 - 7.47268604411813e-06*G0_0_4 + 3.33000333000481e-06*G0_0_5 + 5.47071975643666e-06*G0_0_6 + 3.33000333000494e-06*G0_0_7 + 5.4707197564366e-06*G0_0_8 - 7.61143618286835e-06*G0_0_9 + 7.50351940828485e-06*G0_1_0 + 3.32691999358823e-05*G0_1_1 + 8.45054416483386e-06*G0_1_2 + 5.44296972868657e-05*G0_1_3 - 9.8512598512645e-06*G0_1_5 + 6.79875679876001e-06*G0_1_6 - 2.28739514453908e-05*G0_1_7 + 4.33693290836352e-05*G0_1_8 + 3.21107463964758e-05*G0_1_9 + 7.50351940828484e-06*G0_2_0 + 8.45054416483386e-06*G0_2_1 + 3.32691999358823e-05*G0_2_2 + 5.44296972868658e-05*G0_2_4 - 2.28739514453908e-05*G0_2_5 + 4.33693290836353e-05*G0_2_6 - 9.85125985126452e-06*G0_2_7 + 6.79875679876003e-06*G0_2_8 + 3.21107463964758e-05*G0_2_9 - 7.47268604411815e-06*G0_3_0 + 5.44296972868657e-05*G0_3_1 - 1.26659055230543e-05*G0_3_3 - 0.000166797488226138*G0_3_4 + 4.01384329955948e-05*G0_3_5 - 4.87012987013217e-05*G0_3_6 - 5.88697017268721e-06*G0_3_7 + 5.45882688740089e-05*G0_3_8 - 8.45582988440529e-05*G0_3_9 - 7.47268604411813e-06*G0_4_0 + 5.44296972868658e-05*G0_4_2 - 0.000166797488226138*G0_4_3 - 1.26659055230541e-05*G0_4_4 - 5.88697017268727e-06*G0_4_5 + 5.45882688740089e-05*G0_4_6 + 4.01384329955947e-05*G0_4_7 - 4.87012987013217e-05*G0_4_8 - 8.45582988440529e-05*G0_4_9 + 3.33000333000481e-06*G0_5_0 - 9.85125985126451e-06*G0_5_1 - 2.28739514453908e-05*G0_5_2 + 4.01384329955948e-05*G0_5_3 - 5.88697017268726e-06*G0_5_4 + 1.62337662337738e-05*G0_5_5 - 4.15655772798826e-05*G0_5_6 - 2.4975024975037e-06*G0_5_7 + 1.24875124875185e-06*G0_5_8 + 2.03368060511013e-05*G0_5_9 + 5.47071975643666e-06*G0_6_0 + 6.79875679876001e-06*G0_6_1 + 4.33693290836353e-05*G0_6_2 - 4.87012987013217e-05*G0_6_3 + 5.45882688740089e-05*G0_6_4 - 4.15655772798826e-05*G0_6_5 + 7.08220351077827e-05*G0_6_6 + 1.24875124875184e-06*G0_6_7 - 6.24375624375922e-06*G0_6_8 + 1.07035821321589e-06*G0_6_9 + 3.33000333000494e-06*G0_7_0 - 2.28739514453908e-05*G0_7_1 - 9.85125985126451e-06*G0_7_2 - 5.88697017268721e-06*G0_7_3 + 4.01384329955947e-05*G0_7_4 - 2.4975024975037e-06*G0_7_5 + 1.24875124875184e-06*G0_7_6 + 1.62337662337739e-05*G0_7_7 - 4.15655772798826e-05*G0_7_8 + 2.03368060511013e-05*G0_7_9 + 5.4707197564366e-06*G0_8_0 + 4.33693290836352e-05*G0_8_1 + 6.79875679876003e-06*G0_8_2 + 5.45882688740089e-05*G0_8_3 - 4.87012987013217e-05*G0_8_4 + 1.24875124875185e-06*G0_8_5 - 6.24375624375922e-06*G0_8_6 - 4.15655772798826e-05*G0_8_7 + 7.08220351077829e-05*G0_8_8 + 1.07035821321595e-06*G0_8_9 - 7.61143618286835e-06*G0_9_0 + 3.21107463964758e-05*G0_9_1 + 3.21107463964758e-05*G0_9_2 - 8.45582988440529e-05*G0_9_3 - 8.45582988440529e-05*G0_9_4 + 2.03368060511013e-05*G0_9_5 + 1.0703582132159e-06*G0_9_6 + 2.03368060511013e-05*G0_9_7 + 1.07035821321595e-06*G0_9_8 - 0.000173398030540969*G0_9_9; + A[202] = -A[108] + 4.8593381926738e-05*G0_0_0 + 2.46314532028934e-05*G0_0_1 + 4.72190948381646e-06*G0_0_2 - 3.20314606029037e-05*G0_0_3 - 3.20314606029045e-05*G0_0_4 + 0.000235003092146059*G0_0_5 - 1.90285904571708e-05*G0_0_6 + 0.000136371564943057*G0_0_7 - 5.48657691515088e-05*G0_0_8 + 0.000135102992245913*G0_0_9 + 2.46314532028934e-05*G0_1_0 + 1.23333456666917e-06*G0_1_1 + 9.65524775049042e-06*G0_1_2 + 9.16543773687071e-05*G0_1_3 - 4.44000444000657e-05*G0_1_4 - 4.72543329686409e-05*G0_1_5 - 0.000100534386248719*G0_1_6 + 6.7868639297243e-05*G0_1_8 - 3.99600399600592e-05*G0_1_9 + 4.72190948381646e-06*G0_2_0 + 9.65524775049043e-06*G0_2_1 - 0.00010409343742682*G0_2_2 + 3.01286015571878e-05*G0_2_3 - 5.7402914545799e-05*G0_2_4 + 0.000116391544963028*G0_2_5 + 1.74428745857395e-05*G0_2_6 - 4.34486148772062e-05*G0_2_8 + 7.99200799201181e-05*G0_2_9 - 3.20314606029037e-05*G0_3_0 + 9.16543773687071e-05*G0_3_1 + 3.01286015571878e-05*G0_3_2 - 0.000171257314114529*G0_3_3 + 0.00016269444840881*G0_3_5 + 0.000214071642643172*G0_3_6 + 8.5628657057246e-06*G0_3_7 - 5.13771942343571e-05*G0_3_8 + 0.000102754388468728*G0_3_9 - 3.20314606029045e-05*G0_4_0 - 4.44000444000657e-05*G0_4_1 - 5.7402914545799e-05*G0_4_2 - 0.000265448836877532*G0_4_4 + 8.56286570572734e-06*G0_4_5 - 0.000222634508348899*G0_4_6 + 7.70657913515426e-05*G0_4_7 + 4.28143285286324e-05*G0_4_8 - 0.000256885971171809*G0_4_9 + 0.000235003092146059*G0_5_0 - 4.72543329686409e-05*G0_5_1 + 0.000116391544963028*G0_5_2 + 0.00016269444840881*G0_5_3 + 8.56286570572731e-06*G0_5_4 - 0.000536606250892218*G0_5_5 - 0.000536606250892216*G0_5_6 + 6.27943485086639e-05*G0_5_7 + 5.42314828029365e-05*G0_5_8 - 0.000513771942343613*G0_5_9 - 1.90285904571708e-05*G0_6_0 - 0.000100534386248719*G0_6_1 + 1.74428745857395e-05*G0_6_2 + 0.000214071642643172*G0_6_3 - 0.000222634508348899*G0_6_4 - 0.000536606250892216*G0_6_5 - 0.000767803624946844*G0_6_6 - 0.0001170258313116*G0_6_7 + 0.000259740259740381*G0_6_8 - 0.000667903525046698*G0_6_9 + 0.000136371564943057*G0_7_0 + 8.56286570572461e-06*G0_7_3 + 7.70657913515426e-05*G0_7_4 + 6.27943485086639e-05*G0_7_5 - 0.0001170258313116*G0_7_6 + 5.13771942343629e-05*G0_7_7 - 0.00019694591123172*G0_7_8 - 0.000171257314114539*G0_7_9 - 5.48657691515088e-05*G0_8_0 + 6.7868639297243e-05*G0_8_1 - 4.34486148772062e-05*G0_8_2 - 5.13771942343571e-05*G0_8_3 + 4.28143285286325e-05*G0_8_4 + 5.42314828029365e-05*G0_8_5 + 0.000259740259740381*G0_8_6 - 0.00019694591123172*G0_8_7 - 8.5628657057264e-05*G0_8_8 + 3.42514628229123e-05*G0_8_9 + 0.000135102992245913*G0_9_0 - 3.99600399600592e-05*G0_9_1 + 7.99200799201181e-05*G0_9_2 + 0.000102754388468728*G0_9_3 - 0.000256885971171809*G0_9_4 - 0.000513771942343613*G0_9_5 - 0.000667903525046698*G0_9_6 - 0.000171257314114539*G0_9_7 + 3.42514628229123e-05*G0_9_8 - 0.00195233338090572*G0_9_9; + A[4] = A[60]; + A[16] = 6.98449111147853e-06*G0_0_0 + 3.59208692542195e-05*G0_0_1 + 2.56228926863968e-06*G0_0_2 + 1.55862655862729e-05*G0_0_3 - 6.23219373219666e-06*G0_0_4 + 1.15790294361777e-06*G0_0_5 - 7.71219521219885e-06*G0_0_7 + 2.37840862840975e-05*G0_0_8 + 4.92562992563224e-06*G0_0_9 + 3.59208692542195e-05*G0_1_0 + 0.000999386416053554*G0_1_1 + 3.59208692542195e-05*G0_1_2 + 0.000332306582306739*G0_1_3 - 0.000157134532134606*G0_1_4 - 3.00625300625446e-06*G0_1_5 - 3.00625300625441e-06*G0_1_6 - 0.000157134532134607*G0_1_7 + 0.000332306582306739*G0_1_8 + 3.6075036075053e-05*G0_1_9 + 2.56228926863968e-06*G0_2_0 + 3.59208692542195e-05*G0_2_1 + 6.98449111147853e-06*G0_2_2 + 2.37840862840975e-05*G0_2_3 - 7.71219521219884e-06*G0_2_4 + 1.15790294361778e-06*G0_2_6 - 6.23219373219668e-06*G0_2_7 + 1.55862655862729e-05*G0_2_8 + 4.92562992563224e-06*G0_2_9 + 1.55862655862729e-05*G0_3_0 + 0.000332306582306739*G0_3_1 + 2.37840862840975e-05*G0_3_2 + 0.00027888777888791*G0_3_3 - 0.000123834498834557*G0_3_4 - 7.3884448884484e-06*G0_3_5 - 1.39443889443955e-05*G0_3_6 - 6.97219447219777e-05*G0_3_7 + 0.000139443889443955*G0_3_8 + 3.12187812187959e-05*G0_3_9 - 6.23219373219666e-06*G0_4_0 - 0.000157134532134606*G0_4_1 - 7.71219521219884e-06*G0_4_2 - 0.000123834498834557*G0_4_3 + 7.28438228438571e-05*G0_4_4 - 4.26656676656877e-06*G0_4_5 + 1.82109557109643e-05*G0_4_6 + 3.01781551781695e-05*G0_4_7 - 6.97219447219776e-05*G0_4_8 - 6.24375624375916e-06*G0_4_9 + 1.15790294361777e-06*G0_5_0 - 3.00625300625446e-06*G0_5_1 - 7.3884448884484e-06*G0_5_3 - 4.26656676656877e-06*G0_5_4 + 3.45785167213902e-05*G0_5_5 - 1.15806812235438e-05*G0_5_6 + 1.82109557109643e-05*G0_5_7 - 1.39443889443956e-05*G0_5_8 + 1.31118881118943e-05*G0_5_9 - 3.00625300625441e-06*G0_6_1 + 1.15790294361778e-06*G0_6_2 - 1.39443889443955e-05*G0_6_3 + 1.82109557109643e-05*G0_6_4 - 1.15806812235438e-05*G0_6_5 + 3.45785167213902e-05*G0_6_6 - 4.2665667665688e-06*G0_6_7 - 7.38844488844834e-06*G0_6_8 + 1.31118881118943e-05*G0_6_9 - 7.71219521219885e-06*G0_7_0 - 0.000157134532134607*G0_7_1 - 6.23219373219668e-06*G0_7_2 - 6.97219447219777e-05*G0_7_3 + 3.01781551781695e-05*G0_7_4 + 1.82109557109643e-05*G0_7_5 - 4.2665667665688e-06*G0_7_6 + 7.28438228438573e-05*G0_7_7 - 0.000123834498834557*G0_7_8 - 6.24375624375915e-06*G0_7_9 + 2.37840862840975e-05*G0_8_0 + 0.000332306582306739*G0_8_1 + 1.55862655862729e-05*G0_8_2 + 0.000139443889443955*G0_8_3 - 6.97219447219776e-05*G0_8_4 - 1.39443889443956e-05*G0_8_5 - 7.38844488844834e-06*G0_8_6 - 0.000123834498834557*G0_8_7 + 0.00027888777888791*G0_8_8 + 3.12187812187958e-05*G0_8_9 + 4.92562992563224e-06*G0_9_0 + 3.6075036075053e-05*G0_9_1 + 4.92562992563224e-06*G0_9_2 + 3.12187812187959e-05*G0_9_3 - 6.24375624375916e-06*G0_9_4 + 1.31118881118943e-05*G0_9_5 + 1.31118881118943e-05*G0_9_6 - 6.24375624375915e-06*G0_9_7 + 3.12187812187958e-05*G0_9_8 + 7.49250749251103e-05*G0_9_9; + A[1] = -4.08696242029768e-05*G0_0_0 - 5.90257038670015e-06*G0_0_1 - 1.84192644510191e-06*G0_0_2 + 1.72281422281503e-06*G0_0_4 - 2.03500203500299e-05*G0_0_5 + 1.06705463848371e-05*G0_0_6 - 2.80275280275412e-05*G0_0_7 + 1.07630464773373e-05*G0_0_8 - 3.76607519464839e-06*G0_0_9 - 5.90257038670015e-06*G0_1_0 - 4.08696242029769e-05*G0_1_1 - 1.84192644510192e-06*G0_1_2 - 2.035002035003e-05*G0_1_3 + 1.06705463848371e-05*G0_1_4 + 1.72281422281503e-06*G0_1_6 + 1.07630464773373e-05*G0_1_7 - 2.80275280275413e-05*G0_1_8 - 3.76607519464839e-06*G0_1_9 - 1.84192644510191e-06*G0_2_0 - 1.84192644510192e-06*G0_2_1 + 2.6670860004206e-06*G0_2_2 - 3.3366104794692e-06*G0_2_3 + 5.36996072710612e-06*G0_2_4 - 3.33661047946919e-06*G0_2_5 + 5.36996072710612e-06*G0_2_6 - 1.24049231192146e-06*G0_2_7 - 1.24049231192147e-06*G0_2_8 + 2.87411001696852e-06*G0_2_9 - 2.03500203500299e-05*G0_3_1 - 3.3366104794692e-06*G0_3_2 - 2.80969030969166e-06*G0_3_3 + 1.07035821321586e-06*G0_3_4 - 2.83942248228097e-06*G0_3_6 + 4.04357547214882e-06*G0_3_7 - 1.00940725940774e-05*G0_3_8 + 3.21107463964757e-06*G0_3_9 + 1.72281422281503e-06*G0_4_0 + 1.06705463848371e-05*G0_4_1 + 5.36996072710612e-06*G0_4_2 + 1.07035821321586e-06*G0_4_3 + 1.20415298986785e-06*G0_4_4 - 2.83942248228097e-06*G0_4_5 + 5.67884496456193e-06*G0_4_6 - 1.88799295942243e-06*G0_4_7 + 6.05049712192855e-06*G0_4_8 - 2.94348508634362e-06*G0_4_9 - 2.03500203500299e-05*G0_5_0 - 3.33661047946919e-06*G0_5_2 - 2.83942248228097e-06*G0_5_4 - 2.80969030969155e-06*G0_5_5 + 1.07035821321582e-06*G0_5_6 - 1.00940725940773e-05*G0_5_7 + 4.04357547214879e-06*G0_5_8 + 3.21107463964761e-06*G0_5_9 + 1.06705463848371e-05*G0_6_0 + 1.72281422281503e-06*G0_6_1 + 5.36996072710612e-06*G0_6_2 - 2.83942248228097e-06*G0_6_3 + 5.67884496456193e-06*G0_6_4 + 1.07035821321582e-06*G0_6_5 + 1.20415298986786e-06*G0_6_6 + 6.05049712192852e-06*G0_6_7 - 1.88799295942241e-06*G0_6_8 - 2.94348508634363e-06*G0_6_9 - 2.80275280275412e-05*G0_7_0 + 1.07630464773373e-05*G0_7_1 - 1.24049231192146e-06*G0_7_2 + 4.04357547214882e-06*G0_7_3 - 1.88799295942243e-06*G0_7_4 - 1.00940725940773e-05*G0_7_5 + 6.05049712192852e-06*G0_7_6 - 4.21453546453744e-05*G0_7_7 + 2.55548023405286e-05*G0_7_8 + 1.07630464773373e-05*G0_8_0 - 2.80275280275413e-05*G0_8_1 - 1.24049231192147e-06*G0_8_2 - 1.00940725940774e-05*G0_8_3 + 6.05049712192855e-06*G0_8_4 + 4.04357547214879e-06*G0_8_5 - 1.88799295942241e-06*G0_8_6 + 2.55548023405287e-05*G0_8_7 - 4.21453546453745e-05*G0_8_8 - 3.76607519464839e-06*G0_9_0 - 3.76607519464839e-06*G0_9_1 + 2.87411001696852e-06*G0_9_2 + 3.21107463964757e-06*G0_9_3 - 2.94348508634362e-06*G0_9_4 + 3.21107463964762e-06*G0_9_5 - 2.94348508634363e-06*G0_9_6 + 1.01684030255507e-05*G0_9_9; + A[125] = -A[1] - 5.77244624863951e-06*G0_0_0 + 2.0737456253339e-05*G0_0_1 + 8.63003839194722e-05*G0_0_2 - 9.74059009773754e-05*G0_0_3 + 0.00022964304214315*G0_0_4 - 0.000130715845001621*G0_0_5 + 0.000259310795025203*G0_0_6 - 4.7478976050427e-05*G0_0_7 - 4.88268345411429e-06*G0_0_8 + 0.000120554049125534*G0_0_9 + 2.0737456253339e-05*G0_1_0 - 5.77244624863959e-06*G0_1_1 + 8.63003839194722e-05*G0_1_2 - 0.000130715845001621*G0_1_3 + 0.000259310795025203*G0_1_4 - 9.74059009773755e-05*G0_1_5 + 0.00022964304214315*G0_1_6 - 4.88268345411435e-06*G0_1_7 - 4.7478976050427e-05*G0_1_8 + 0.000120554049125534*G0_1_9 + 8.63003839194722e-05*G0_2_0 + 8.63003839194722e-05*G0_2_1 + 0.000690045551156988*G0_2_2 - 0.000379256986400022*G0_2_3 + 0.000819370774728303*G0_2_4 - 0.000379256986400022*G0_2_5 + 0.000819370774728303*G0_2_6 - 2.19605130319522e-05*G0_2_7 - 2.19605130319518e-05*G0_2_8 + 0.000251514358657334*G0_2_9 - 9.74059009773754e-05*G0_3_0 - 0.000130715845001621*G0_3_1 - 0.000379256986400022*G0_3_2 + 0.000545213714856829*G0_3_3 - 0.00111781076066843*G0_3_4 + 0.000415373317159227*G0_3_5 - 0.000935240354883652*G0_3_6 + 4.5906474477925e-05*G0_3_7 + 0.000134523214880421*G0_3_8 - 0.000453475096332453*G0_3_9 + 0.00022964304214315*G0_4_0 + 0.000259310795025203*G0_4_1 + 0.000819370774728303*G0_4_2 - 0.00111781076066843*G0_4_3 + 0.00279840695019398*G0_4_4 - 0.000935240354883652*G0_4_5 + 0.0018704807097673*G0_4_6 - 0.000188368179439697*G0_4_7 - 0.000180429689358345*G0_4_8 + 0.0011159376337953*G0_4_9 - 0.000130715845001621*G0_5_0 - 9.74059009773755e-05*G0_5_1 - 0.000379256986400022*G0_5_2 + 0.000415373317159227*G0_5_3 - 0.000935240354883652*G0_5_4 + 0.000545213714856829*G0_5_5 - 0.00111781076066843*G0_5_6 + 0.000134523214880421*G0_5_7 + 4.59064744779245e-05*G0_5_8 - 0.000453475096332453*G0_5_9 + 0.000259310795025203*G0_6_0 + 0.00022964304214315*G0_6_1 + 0.000819370774728303*G0_6_2 - 0.000935240354883652*G0_6_3 + 0.0018704807097673*G0_6_4 - 0.00111781076066843*G0_6_5 + 0.00279840695019398*G0_6_6 - 0.000180429689358346*G0_6_7 - 0.000188368179439696*G0_6_8 + 0.0011159376337953*G0_6_9 - 4.7478976050427e-05*G0_7_0 - 4.88268345411436e-06*G0_7_1 - 2.19605130319522e-05*G0_7_2 + 4.5906474477925e-05*G0_7_3 - 0.000188368179439697*G0_7_4 + 0.000134523214880421*G0_7_5 - 0.000180429689358346*G0_7_6 + 0.00016336342229207*G0_7_7 - 8.69666048237875e-06*G0_7_8 - 4.88268345411429e-06*G0_8_0 - 4.7478976050427e-05*G0_8_1 - 2.19605130319518e-05*G0_8_2 + 0.000134523214880421*G0_8_3 - 0.000180429689358345*G0_8_4 + 4.59064744779246e-05*G0_8_5 - 0.000188368179439696*G0_8_6 - 8.69666048237873e-06*G0_8_7 + 0.00016336342229207*G0_8_8 + 0.000120554049125534*G0_9_0 + 0.000120554049125534*G0_9_1 + 0.000251514358657334*G0_9_2 - 0.000453475096332453*G0_9_3 + 0.0011159376337953*G0_9_4 - 0.000453475096332453*G0_9_5 + 0.0011159376337953*G0_9_6 + 0.00124322106465022*G0_9_9; + A[83] = A[125]; + A[80] = A[125] + 2.96000296000439e-06*G0_0_0 + 1.77600177600261e-05*G0_0_1 + 2.07200207200305e-05*G0_0_2 - 2.11428782857455e-05*G0_0_3 + 0.000207200207200305*G0_0_4 - 2.07200207200305e-05*G0_0_5 - 2.07200207200303e-05*G0_0_6 - 3.04457447314733e-05*G0_0_7 + 3.04457447314733e-05*G0_0_8 + 6.8502925645815e-05*G0_0_9 + 1.77600177600261e-05*G0_1_0 + 0.000128971557543047*G0_1_1 + 0.000134844579289087*G0_1_2 - 2.02971631543161e-05*G0_1_3 + 0.00037296037296055*G0_1_4 - 4.1440041440061e-05*G0_1_5 + 2.07200207200306e-05*G0_1_6 - 5.37029108457933e-05*G0_1_7 + 7.56915042629684e-05*G0_1_8 + 5.58171986743679e-05*G0_1_9 + 2.07200207200305e-05*G0_2_0 + 0.000134844579289087*G0_2_1 + 0.000687378465156567*G0_2_2 - 0.000565360565360832*G0_2_3 + 0.0016280016280024*G0_2_4 - 6.21600621600915e-05*G0_2_5 - 4.1440041440061e-05*G0_2_7 + 2.07200207200306e-05*G0_2_8 + 0.000124320124320183*G0_2_9 - 2.11428782857455e-05*G0_3_0 - 2.02971631543161e-05*G0_3_1 - 0.000565360565360832*G0_3_2 + 0.00114171542743025*G0_3_3 - 0.00223776223776329*G0_3_4 + 0.000156034441748801*G0_3_5 - 0.000186480186480275*G0_3_6 - 6.08914894629464e-05*G0_3_7 + 0.00024737167594322*G0_3_8 - 4.56686170972107e-05*G0_3_9 + 0.000207200207200305*G0_4_0 + 0.00037296037296055*G0_4_1 + 0.0016280016280024*G0_4_2 - 0.00223776223776329*G0_4_3 + 0.00839160839161235*G0_4_4 - 0.000745920745921098*G0_4_5 + 0.000932400932401373*G0_4_6 - 0.000186480186480275*G0_4_7 - 0.000186480186480273*G0_4_8 + 0.00111888111888165*G0_4_9 - 2.07200207200305e-05*G0_5_0 - 4.1440041440061e-05*G0_5_1 - 6.21600621600915e-05*G0_5_2 + 0.000156034441748801*G0_5_3 - 0.000745920745921098*G0_5_4 - 3.0445744731473e-05*G0_5_5 + 0.000186480186480274*G0_5_6 - 0.000205508776937445*G0_5_9 - 2.07200207200303e-05*G0_6_0 + 2.07200207200306e-05*G0_6_1 - 0.000186480186480275*G0_6_3 + 0.000932400932401373*G0_6_4 + 0.000186480186480274*G0_6_5 - 0.000932400932401372*G0_6_6 - 3.04457447314733e-05*G0_7_0 - 5.37029108457933e-05*G0_7_1 - 4.1440041440061e-05*G0_7_2 - 6.08914894629464e-05*G0_7_3 - 0.000186480186480275*G0_7_4 - 2.28343085486047e-05*G0_7_7 - 9.133723419442e-05*G0_7_8 - 0.000205508776937445*G0_7_9 + 3.04457447314733e-05*G0_8_0 + 7.56915042629684e-05*G0_8_1 + 2.07200207200306e-05*G0_8_2 + 0.00024737167594322*G0_8_3 - 0.000186480186480273*G0_8_4 - 9.133723419442e-05*G0_8_7 + 0.00031968031968047*G0_8_8 + 0.000205508776937445*G0_8_9 + 6.8502925645815e-05*G0_9_0 + 5.58171986743679e-05*G0_9_1 + 0.000124320124320183*G0_9_2 - 4.56686170972107e-05*G0_9_3 + 0.00111888111888165*G0_9_4 - 0.000205508776937445*G0_9_5 - 0.000205508776937445*G0_9_7 + 0.000205508776937445*G0_9_8 + 0.00041101755387489*G0_9_9; + A[41] = -A[16] - 1.06698122571188e-05*G0_0_0 + 2.65034788844437e-05*G0_0_1 + 1.44696573268071e-06*G0_0_3 - 1.94564033849839e-05*G0_0_5 + 1.0444251515685e-05*G0_0_6 - 2.08207797493609e-05*G0_0_7 + 6.55264048121499e-06*G0_0_8 - 1.85429649715451e-05*G0_0_9 + 2.65034788844437e-05*G0_1_0 + 0.000949847477625703*G0_1_1 + 3.01036412147665e-05*G0_1_2 + 0.000281299388442378*G0_1_3 - 0.000131551649408854*G0_1_4 - 0.000131075934647425*G0_1_7 + 0.000263063655920923*G0_1_8 + 1.73635887921683e-05*G0_1_9 + 3.01036412147665e-05*G0_2_1 + 4.22692386978298e-06*G0_2_3 + 7.4578199578235e-06*G0_2_4 + 1.29979147836352e-05*G0_2_6 - 8.06732949590468e-06*G0_2_8 - 5.5400948258117e-06*G0_2_9 + 1.44696573268071e-06*G0_3_0 + 0.000281299388442378*G0_3_1 + 4.22692386978298e-06*G0_3_2 + 0.000147352647352716*G0_3_3 - 5.55694305694567e-05*G0_3_4 - 3.86518243661309e-07*G0_3_6 - 9.81161695448029e-07*G0_3_7 - 2.65805622948603e-05*G0_3_8 - 5.01284429856094e-05*G0_3_9 - 0.000131551649408854*G0_4_1 + 7.4578199578235e-06*G0_4_2 - 5.55694305694567e-05*G0_4_3 + 4.12087912088106e-05*G0_4_4 + 8.22094572094962e-06*G0_4_6 - 8.11688311688686e-06*G0_4_7 + 2.75617239903083e-05*G0_4_8 + 3.22891394320117e-05*G0_4_9 - 1.94564033849839e-05*G0_5_0 + 5.32205889349011e-06*G0_5_5 + 1.05400551829172e-05*G0_5_6 - 1.65162218733724e-05*G0_5_7 + 1.48363541220754e-05*G0_5_8 + 2.59561866704847e-05*G0_5_9 + 1.0444251515685e-05*G0_6_0 + 1.29979147836352e-05*G0_6_2 - 3.86518243661306e-07*G0_6_3 + 8.22094572094961e-06*G0_6_4 + 1.05400551829172e-05*G0_6_5 + 9.6034917463535e-06*G0_6_6 + 8.54799961943221e-06*G0_6_8 + 1.73933209647577e-05*G0_6_9 - 2.08207797493609e-05*G0_7_0 - 0.000131075934647425*G0_7_1 - 9.81161695448056e-07*G0_7_3 - 8.11688311688686e-06*G0_7_4 - 1.65162218733725e-05*G0_7_5 + 7.43304314733244e-06*G0_7_7 + 2.48263641120899e-05*G0_7_8 + 5.22691594120412e-05*G0_7_9 + 6.55264048121499e-06*G0_8_0 + 0.000263063655920923*G0_8_1 - 8.06732949590468e-06*G0_8_2 - 2.65805622948603e-05*G0_8_3 + 2.75617239903083e-05*G0_8_4 + 1.48363541220754e-05*G0_8_5 + 8.54799961943221e-06*G0_8_6 + 2.48263641120899e-05*G0_8_7 - 0.000133319061890553*G0_8_8 - 0.000107214214357122*G0_8_9 - 1.85429649715451e-05*G0_9_0 + 1.73635887921683e-05*G0_9_1 - 5.5400948258117e-06*G0_9_2 - 5.01284429856094e-05*G0_9_3 + 3.22891394320117e-05*G0_9_4 + 2.59561866704847e-05*G0_9_5 + 1.73933209647577e-05*G0_9_6 + 5.22691594120411e-05*G0_9_7 - 0.000107214214357122*G0_9_8 - 2.14071642643156e-06*G0_9_9; + A[165] = A[41] + 0.000228554514268907*G0_0_0 - 5.41786256072229e-06*G0_0_3 + 0.000122364408078751*G0_0_5 - 5.95172023743731e-05*G0_0_6 + 0.000177758749187404*G0_0_7 - 7.89686503972589e-05*G0_0_8 + 3.45686059971936e-05*G0_0_9 - 1.800668467336e-05*G0_1_1 - 1.58571587143062e-07*G0_1_4 + 3.16614602329037e-05*G0_1_7 - 3.92200392200578e-05*G0_1_8 + 3.17143174286165e-07*G0_1_9 + 5.41786256072225e-06*G0_2_3 - 1.09942967085876e-05*G0_2_4 - 1.84735899021701e-05*G0_2_6 + 1.0042867185729e-05*G0_2_7 + 5.76143433286556e-06*G0_2_8 - 1.42714428428787e-06*G0_2_9 - 5.41786256072229e-06*G0_3_0 + 5.41786256072225e-06*G0_3_2 - 3.44893202036224e-05*G0_3_3 + 4.75714761429376e-07*G0_3_4 + 4.28143285286347e-06*G0_3_5 - 4.28143285286341e-06*G0_3_6 - 4.75714761429132e-07*G0_3_7 + 3.44893202036218e-05*G0_3_8 - 1.58571587143069e-07*G0_4_1 - 1.09942967085876e-05*G0_4_2 + 4.7571476142939e-07*G0_4_3 + 1.18928690357308e-06*G0_4_4 + 1.66500166500242e-06*G0_4_7 - 3.40136054421927e-05*G0_4_8 + 4.28143285286357e-06*G0_4_9 + 0.000122364408078751*G0_5_0 + 4.28143285286346e-06*G0_5_3 + 6.58864944579534e-05*G0_5_5 - 5.11393368536463e-05*G0_5_6 + 8.80072308644148e-05*G0_5_7 - 4.11493268636318e-05*G0_5_8 - 2.14071642643173e-05*G0_5_9 - 5.95172023743731e-05*G0_6_0 - 1.84735899021701e-05*G0_6_2 - 4.28143285286341e-06*G0_6_3 - 5.11393368536463e-05*G0_6_5 + 4.59064744779245e-05*G0_6_6 - 4.68579040007831e-05*G0_6_7 + 5.94643451786589e-06*G0_6_8 + 1.28442985585904e-05*G0_6_9 + 0.000177758749187404*G0_7_0 + 3.16614602329037e-05*G0_7_1 + 1.0042867185729e-05*G0_7_2 - 4.75714761429119e-07*G0_7_3 + 1.66500166500242e-06*G0_7_4 + 8.80072308644148e-05*G0_7_5 - 4.68579040007831e-05*G0_7_6 + 0.000221920936206754*G0_7_7 - 0.000106322249179442*G0_7_8 - 9.99000999001463e-06*G0_7_9 - 7.89686503972589e-05*G0_8_0 - 3.92200392200578e-05*G0_8_1 + 5.76143433286556e-06*G0_8_2 + 3.44893202036218e-05*G0_8_3 - 3.40136054421927e-05*G0_8_4 - 4.11493268636318e-05*G0_8_5 + 5.94643451786589e-06*G0_8_6 - 0.000106322249179442*G0_8_7 + 0.000241900956186783*G0_8_8 + 6.70757813615268e-05*G0_8_9 + 3.45686059971936e-05*G0_9_0 + 3.17143174286165e-07*G0_9_1 - 1.42714428428787e-06*G0_9_2 + 4.28143285286356e-06*G0_9_4 - 2.14071642643173e-05*G0_9_5 + 1.28442985585904e-05*G0_9_6 - 9.99000999001462e-06*G0_9_7 + 6.70757813615268e-05*G0_9_8 - 8.5628657057273e-06*G0_9_9; + A[10] = -A[165] - 0.000263625263625387*G0_0_0 - 2.36359760169395e-05*G0_0_1 - 1.37957280814488e-05*G0_0_2 + 4.30786145072062e-06*G0_0_3 - 0.000111925111925165*G0_0_5 + 5.45750545750802e-05*G0_0_6 - 0.000193325193325284*G0_0_7 + 7.86250786251154e-05*G0_0_8 - 2.22000222000326e-05*G0_0_9 - 2.36359760169395e-05*G0_1_0 - 2.41630797186467e-05*G0_1_1 - 1.78657321514549e-05*G0_1_3 + 7.78322206894002e-06*G0_1_4 - 5.74161288447267e-06*G0_1_5 - 4.83643340786411e-06*G0_1_7 - 4.26953998382771e-05*G0_1_8 - 1.81564467278838e-05*G0_1_9 - 1.37957280814488e-05*G0_2_0 + 2.70893128036108e-07*G0_2_3 - 6.93089978804589e-06*G0_2_5 - 8.71483014340565e-06*G0_2_7 + 7.57840043554679e-06*G0_2_8 - 3.56786071071971e-07*G0_2_9 + 4.30786145072062e-06*G0_3_0 - 1.78657321514549e-05*G0_3_1 + 2.70893128036108e-07*G0_3_2 + 2.84239569953989e-05*G0_3_3 + 1.43309071880569e-05*G0_3_4 - 8.02768659911897e-06*G0_3_5 + 7.43304314733242e-06*G0_3_7 - 5.05446934018615e-06*G0_3_8 + 3.96032538889867e-05*G0_3_9 + 7.78322206894002e-06*G0_4_1 + 1.43309071880569e-05*G0_4_3 + 6.66000666000966e-06*G0_4_4 - 7.01679273108179e-06*G0_4_7 - 2.37857380714626e-06*G0_4_8 - 0.000111925111925165*G0_5_0 - 5.74161288447267e-06*G0_5_1 - 6.93089978804589e-06*G0_5_2 - 8.02768659911897e-06*G0_5_3 - 7.57575757576112e-05*G0_5_5 + 4.59064744779246e-05*G0_5_6 - 8.40825840826234e-05*G0_5_7 + 3.75814661529123e-05*G0_5_8 + 5.45750545750802e-05*G0_6_0 + 4.59064744779246e-05*G0_6_5 - 2.18828790257465e-05*G0_6_6 + 4.65011179297111e-05*G0_6_7 - 3.09214594929025e-05*G0_6_8 - 2.14071642643173e-06*G0_6_9 - 0.000193325193325284*G0_7_0 - 4.83643340786412e-06*G0_7_1 - 8.71483014340565e-06*G0_7_2 + 7.43304314733242e-06*G0_7_3 - 7.01679273108178e-06*G0_7_4 - 8.40825840826234e-05*G0_7_5 + 4.65011179297111e-05*G0_7_6 - 0.000330502830502985*G0_7_7 + 0.00015472622615487*G0_7_8 - 2.64021692593245e-05*G0_7_9 + 7.86250786251154e-05*G0_8_0 - 4.26953998382771e-05*G0_8_1 + 7.57840043554679e-06*G0_8_2 - 5.05446934018618e-06*G0_8_3 - 2.37857380714626e-06*G0_8_4 + 3.75814661529123e-05*G0_8_5 - 3.09214594929025e-05*G0_8_6 + 0.00015472622615487*G0_8_7 + 1.16550116550166e-05*G0_8_8 + 5.9226487797944e-05*G0_8_9 - 2.22000222000326e-05*G0_9_0 - 1.81564467278838e-05*G0_9_1 - 3.56786071071971e-07*G0_9_2 + 3.96032538889867e-05*G0_9_3 - 2.14071642643174e-06*G0_9_6 - 2.64021692593245e-05*G0_9_7 + 5.9226487797944e-05*G0_9_8 + 0.000132724418438767*G0_9_9; + A[158] = A[10] + 0.000308271974938786*G0_0_0 + 7.14453095405811e-06*G0_0_1 - 2.53714539428945e-06*G0_0_2 - 2.35478806907489e-05*G0_0_3 + 2.47371675943221e-05*G0_0_4 - 7.37357880215345e-06*G0_0_5 + 9.27643784787076e-06*G0_0_6 + 9.95036709322889e-05*G0_0_7 - 0.000106005106005156*G0_0_8 - 8.08715094429761e-05*G0_0_9 + 7.1445309540581e-06*G0_1_0 - 5.69492236159171e-05*G0_1_1 - 1.21901907616251e-05*G0_1_2 - 6.04157747015174e-05*G0_1_3 + 4.45982588839942e-05*G0_1_4 - 2.84834213405776e-05*G0_1_5 + 3.22296750868332e-05*G0_1_6 - 4.0435754721489e-06*G0_1_7 - 0.000106679035250514*G0_1_8 - 5.92264877979442e-05*G0_1_9 - 2.53714539428944e-06*G0_2_0 - 1.21901907616251e-05*G0_2_1 + 1.06991773658491e-05*G0_2_2 - 1.78987678987764e-05*G0_2_3 - 3.72841444270191e-05*G0_2_5 + 2.50344893202155e-05*G0_2_6 + 1.82555539698482e-05*G0_2_7 + 2.05151990866373e-05*G0_2_8 + 1.70068027210964e-05*G0_2_9 - 2.35478806907489e-05*G0_3_0 - 6.04157747015174e-05*G0_3_1 - 1.78987678987764e-05*G0_3_2 - 0.000211574140145668*G0_3_3 + 4.58470101327458e-05*G0_3_4 + 4.72741544170339e-05*G0_3_5 - 3.51434280005876e-05*G0_3_6 + 0.000132189239332159*G0_3_7 - 0.000132189239332159*G0_3_8 - 8.6699015270485e-05*G0_3_9 + 2.47371675943221e-05*G0_4_0 + 4.45982588839942e-05*G0_4_1 + 4.58470101327458e-05*G0_4_3 + 1.42714428428787e-05*G0_4_4 + 4.7809333523642e-05*G0_4_6 - 9.52618809762115e-05*G0_4_7 - 2.56885971171802e-05*G0_4_9 - 7.37357880215345e-06*G0_5_0 - 2.84834213405776e-05*G0_5_1 - 3.72841444270191e-05*G0_5_2 + 4.72741544170339e-05*G0_5_3 - 0.000221564150135682*G0_5_5 + 0.000113457970600881*G0_5_6 - 0.000153774796632012*G0_5_7 + 0.000146995861281644*G0_5_8 - 5.13771942343613e-05*G0_5_9 + 9.27643784787076e-06*G0_6_0 + 3.22296750868332e-05*G0_6_1 + 2.50344893202155e-05*G0_6_2 - 3.51434280005876e-05*G0_6_3 + 4.7809333523642e-05*G0_6_4 + 0.000113457970600881*G0_6_5 + 8.56286570572709e-06*G0_6_6 + 6.77893535036725e-06*G0_6_7 - 0.000109890109890162*G0_6_8 + 1.92664478378859e-05*G0_6_9 + 9.95036709322889e-05*G0_7_0 - 4.04357547214889e-06*G0_7_1 + 1.82555539698482e-05*G0_7_2 + 0.000132189239332159*G0_7_3 - 9.52618809762115e-05*G0_7_4 - 0.000153774796632012*G0_7_5 + 6.77893535036724e-06*G0_7_6 + 0.000404238618524521*G0_7_7 + 0.000344298558584435*G0_7_8 + 0.000229056657628194*G0_7_9 - 0.000106005106005156*G0_8_0 - 0.000106679035250514*G0_8_1 + 2.05151990866373e-05*G0_8_2 - 0.000132189239332159*G0_8_3 + 0.000146995861281644*G0_8_5 - 0.000109890109890162*G0_8_6 + 0.000344298558584435*G0_8_7 - 3.35378906807637e-05*G0_8_8 + 0.000177679463393832*G0_8_9 - 8.08715094429761e-05*G0_9_0 - 5.92264877979442e-05*G0_9_1 + 1.70068027210964e-05*G0_9_2 - 8.6699015270485e-05*G0_9_3 - 2.56885971171802e-05*G0_9_4 - 5.13771942343612e-05*G0_9_5 + 1.92664478378859e-05*G0_9_6 + 0.000229056657628194*G0_9_7 + 0.000177679463393832*G0_9_8 + 0.000295418866847577*G0_9_9; + A[135] = -A[10] + 0.000211208544541977*G0_0_0 + 2.24672446894774e-05*G0_0_1 + 9.41445385890273e-06*G0_0_2 + 4.25500425500627e-06*G0_0_3 - 9.62000962001414e-06*G0_0_4 + 7.12250712251045e-05*G0_0_5 - 3.97750397750584e-05*G0_0_6 + 0.000211825211825311*G0_0_7 - 8.2325082325121e-05*G0_0_8 + 2.22000222000327e-05*G0_0_9 + 2.24672446894774e-05*G0_1_0 + 2.74549084073023e-05*G0_1_1 + 1.9345733631457e-05*G0_1_3 - 1.03467960610867e-05*G0_1_4 + 6.73268530411705e-06*G0_1_5 - 5.21964807679339e-06*G0_1_6 + 8.48357991215532e-06*G0_1_7 + 1.74032316889542e-05*G0_1_8 + 9.41445385890273e-06*G0_2_0 + 8.51661565947682e-06*G0_2_3 + 3.16482459339749e-06*G0_2_5 - 5.75482718340134e-06*G0_2_7 + 7.04982847840322e-06*G0_2_8 + 4.71750471750694e-06*G0_2_9 + 4.25500425500627e-06*G0_3_0 + 1.9345733631457e-05*G0_3_1 + 8.51661565947682e-06*G0_3_2 + 6.64811379097406e-05*G0_3_3 - 2.18234146805678e-05*G0_3_4 - 9.93054564483606e-06*G0_3_5 + 2.55696684268235e-06*G0_3_6 - 2.58669901527166e-05*G0_3_7 + 6.01184529756241e-05*G0_3_8 + 5.3874696731865e-05*G0_3_9 - 9.62000962001414e-06*G0_4_0 - 1.03467960610867e-05*G0_4_1 - 2.18234146805678e-05*G0_4_3 - 2.66400266400392e-05*G0_4_4 + 1.57580514723446e-05*G0_4_5 - 1.8315018315027e-05*G0_4_6 + 2.96132438989722e-05*G0_4_7 - 3.42514628229075e-05*G0_4_8 - 4.566861709721e-05*G0_4_9 + 7.12250712251045e-05*G0_5_0 + 6.73268530411705e-06*G0_5_1 + 3.16482459339749e-06*G0_5_2 - 9.93054564483606e-06*G0_5_3 + 1.57580514723446e-05*G0_5_4 + 5.41125541125793e-05*G0_5_5 - 8.32500832501221e-06*G0_5_6 + 2.91375291375427e-05*G0_5_7 - 3.33000333000489e-05*G0_5_8 - 3.97750397750584e-05*G0_6_0 - 5.21964807679339e-06*G0_6_1 + 2.55696684268235e-06*G0_6_3 - 1.8315018315027e-05*G0_6_4 - 8.32500832501221e-06*G0_6_5 - 1.61743018885952e-05*G0_6_6 + 4.16250416250611e-06*G0_6_7 + 3.80571809143421e-06*G0_6_8 - 1.92664478378855e-05*G0_6_9 + 0.000211825211825311*G0_7_0 + 8.4835799121553e-06*G0_7_1 - 5.75482718340134e-06*G0_7_2 - 2.58669901527166e-05*G0_7_3 + 2.96132438989722e-05*G0_7_4 + 2.91375291375428e-05*G0_7_5 + 4.16250416250617e-06*G0_7_6 + 1.24875124875186e-05*G0_7_7 - 0.000137362637362702*G0_7_8 - 7.49250749251102e-05*G0_7_9 - 8.2325082325121e-05*G0_8_0 + 1.74032316889542e-05*G0_8_1 + 7.04982847840322e-06*G0_8_2 + 6.01184529756241e-05*G0_8_3 - 3.42514628229075e-05*G0_8_4 - 3.33000333000489e-05*G0_8_5 + 3.80571809143421e-06*G0_8_6 - 0.000137362637362702*G0_8_7 + 0.000201940916226725*G0_8_8 + 7.06436420722467e-05*G0_8_9 + 2.22000222000327e-05*G0_9_0 + 4.71750471750694e-06*G0_9_2 + 5.3874696731865e-05*G0_9_3 - 4.566861709721e-05*G0_9_4 - 1.92664478378855e-05*G0_9_6 - 7.49250749251102e-05*G0_9_7 + 7.06436420722467e-05*G0_9_8 - 2.14071642643171e-05*G0_9_9; + A[47] = A[165] - 0.000212644498358884*G0_0_0 + 1.66500166500247e-06*G0_0_3 + 1.24478695907326e-05*G0_0_4 - 0.000108383679812302*G0_0_5 + 5.77993435136563e-05*G0_0_6 - 0.000160474446188807*G0_0_7 + 8.20607963465492e-05*G0_0_8 - 2.2992880135748e-05*G0_0_9 - 5.7455771741513e-05*G0_1_3 + 3.2295746581476e-05*G0_1_4 - 3.22957465814761e-05*G0_1_7 + 5.74557717415132e-05*G0_1_8 + 0.000212644498358884*G0_2_2 - 8.20607963465493e-05*G0_2_3 + 0.000160474446188808*G0_2_4 - 5.77993435136565e-05*G0_2_5 + 0.000108383679812302*G0_2_6 - 1.24478695907326e-05*G0_2_7 - 1.66500166500239e-06*G0_2_8 + 2.29928801357482e-05*G0_2_9 + 1.66500166500247e-06*G0_3_0 - 5.7455771741513e-05*G0_3_1 - 8.20607963465493e-05*G0_3_2 - 4.28143285286319e-06*G0_3_3 - 2.64021692593247e-05*G0_3_4 + 8.32500832501223e-06*G0_3_5 - 2.16450216450319e-05*G0_3_6 - 4.99500499500743e-06*G0_3_7 + 9.99000999001492e-06*G0_3_9 + 1.24478695907326e-05*G0_4_0 + 3.2295746581476e-05*G0_4_1 + 0.000160474446188808*G0_4_2 - 2.64021692593247e-05*G0_4_3 + 0.000186955901241704*G0_4_4 - 3.73436087721978e-05*G0_4_5 + 5.89886304172297e-05*G0_4_6 + 4.9950049950072e-06*G0_4_8 + 5.70857713715115e-06*G0_4_9 - 0.000108383679812302*G0_5_0 - 5.77993435136565e-05*G0_5_2 + 8.32500832501223e-06*G0_5_3 - 3.73436087721978e-05*G0_5_4 - 1.56985871271654e-05*G0_5_5 - 5.89886304172293e-05*G0_5_7 + 2.16450216450316e-05*G0_5_8 + 2.56885971171808e-05*G0_5_9 + 5.77993435136563e-05*G0_6_0 + 0.000108383679812302*G0_6_2 - 2.16450216450319e-05*G0_6_3 + 5.89886304172297e-05*G0_6_4 + 1.56985871271661e-05*G0_6_6 + 3.73436087721976e-05*G0_6_7 - 8.32500832501221e-06*G0_6_8 - 2.56885971171807e-05*G0_6_9 - 0.000160474446188807*G0_7_0 - 3.22957465814761e-05*G0_7_1 - 1.24478695907326e-05*G0_7_2 - 4.99500499500743e-06*G0_7_3 - 5.89886304172292e-05*G0_7_5 + 3.73436087721976e-05*G0_7_6 - 0.000186955901241703*G0_7_7 + 2.64021692593241e-05*G0_7_8 - 5.70857713715123e-06*G0_7_9 + 8.20607963465492e-05*G0_8_0 + 5.74557717415132e-05*G0_8_1 - 1.66500166500239e-06*G0_8_2 + 4.9950049950072e-06*G0_8_4 + 2.16450216450316e-05*G0_8_5 - 8.32500832501221e-06*G0_8_6 + 2.64021692593241e-05*G0_8_7 + 4.28143285286433e-06*G0_8_8 - 9.99000999001439e-06*G0_8_9 - 2.2992880135748e-05*G0_9_0 + 2.29928801357482e-05*G0_9_2 + 9.99000999001492e-06*G0_9_3 + 5.70857713715116e-06*G0_9_4 + 2.56885971171807e-05*G0_9_5 - 2.56885971171807e-05*G0_9_6 - 5.70857713715123e-06*G0_9_7 - 9.99000999001439e-06*G0_9_8; + A[149] = A[158] + 4.78533811867367e-05*G0_0_0 - 8.24572253144075e-06*G0_0_1 + 1.4095252190492e-07*G0_0_2 + 7.70657913515418e-05*G0_0_4 + 4.34486148772063e-05*G0_0_5 + 7.29429300858231e-06*G0_0_6 - 7.92857935715468e-06*G0_0_7 + 1.49057291914507e-05*G0_0_8 + 0.000159840159840235*G0_0_9 - 8.24572253144075e-06*G0_1_0 - 2.70276460752778e-05*G0_1_1 - 2.99524109048062e-06*G0_1_2 - 5.89886304172295e-05*G0_1_3 + 3.13971742543318e-05*G0_1_4 - 3.71057513914831e-05*G0_1_5 + 1.99800199800294e-05*G0_1_6 - 4.24971853543481e-05*G0_1_7 - 7.29429300858215e-06*G0_1_8 - 0.000108462965605874*G0_1_9 + 1.4095252190491e-07*G0_2_0 - 2.99524109048062e-06*G0_2_1 - 6.16667283334247e-06*G0_2_2 - 3.45686059971935e-05*G0_2_3 - 1.45885860171643e-05*G0_2_5 + 3.0128601557187e-05*G0_2_6 - 0.0001170258313116*G0_2_7 - 2.85428856857555e-06*G0_2_8 - 0.000119880119880176*G0_2_9 - 5.89886304172295e-05*G0_3_1 - 3.45686059971935e-05*G0_3_2 + 0.000108462965605874*G0_3_3 + 3.13971742543319e-05*G0_3_4 + 4.28143285286343e-05*G0_3_5 - 2.56885971171806e-05*G0_3_6 + 4.28143285286345e-05*G0_3_7 - 8.56286570572686e-05*G0_3_8 + 0.000239760239760353*G0_3_9 + 7.70657913515419e-05*G0_4_0 + 3.13971742543318e-05*G0_4_1 + 3.13971742543319e-05*G0_4_3 + 0.000724989296418207*G0_4_4 - 0.000196945911231718*G0_4_5 + 0.000222634508348898*G0_4_6 + 4.28143285286342e-05*G0_4_7 + 4.28143285286344e-05*G0_4_8 + 0.000753532182103964*G0_4_9 + 4.34486148772062e-05*G0_5_0 - 3.71057513914831e-05*G0_5_1 - 1.45885860171643e-05*G0_5_2 + 4.28143285286343e-05*G0_5_3 - 0.000196945911231718*G0_5_4 - 0.000122734408448753*G0_5_5 - 2.85428856857557e-05*G0_5_6 - 0.000530897673755066*G0_5_7 + 0.000145568716997357*G0_5_8 - 0.000770657913515418*G0_5_9 + 7.29429300858231e-06*G0_6_0 + 1.99800199800294e-05*G0_6_1 + 3.0128601557187e-05*G0_6_2 - 2.56885971171806e-05*G0_6_3 + 0.000222634508348898*G0_6_4 - 2.85428856857556e-05*G0_6_5 - 1.14171542743025e-05*G0_6_6 + 0.000385328956757709*G0_6_7 - 4.28143285286346e-05*G0_6_8 + 0.00041101755387489*G0_6_9 - 7.92857935715468e-06*G0_7_0 - 4.24971853543481e-05*G0_7_1 - 0.0001170258313116*G0_7_2 + 4.28143285286345e-05*G0_7_3 + 4.28143285286342e-05*G0_7_4 - 0.000530897673755066*G0_7_5 + 0.000385328956757709*G0_7_6 - 0.00229199372056622*G0_7_7 + 0.00031968031968047*G0_7_8 - 0.00125017839303612*G0_7_9 + 1.49057291914507e-05*G0_8_0 - 7.29429300858217e-06*G0_8_1 - 2.85428856857554e-06*G0_8_2 - 8.56286570572686e-05*G0_8_3 + 4.28143285286344e-05*G0_8_4 + 0.000145568716997357*G0_8_5 - 4.28143285286346e-05*G0_8_6 + 0.00031968031968047*G0_8_7 - 0.000331097473954772*G0_8_8 + 0.000239760239760353*G0_8_9 + 0.000159840159840235*G0_9_0 - 0.000108462965605874*G0_9_1 - 0.000119880119880176*G0_9_2 + 0.000239760239760353*G0_9_3 + 0.000753532182103964*G0_9_4 - 0.000770657913515418*G0_9_5 + 0.00041101755387489*G0_9_6 - 0.00125017839303612*G0_9_7 + 0.000239760239760353*G0_9_8 - 0.000513771942343611*G0_9_9; + A[90] = A[135] - 2.02677980455853e-05*G0_0_1 + 2.02677980455854e-05*G0_0_2 + 7.77000777001145e-06*G0_0_3 - 7.7700077700115e-06*G0_0_4 + 0.000284900284900419*G0_0_5 - 0.000114700114700169*G0_0_6 - 0.000284900284900419*G0_0_7 + 0.000114700114700168*G0_0_8 - 2.02677980455853e-05*G0_1_0 + 1.51993802787525e-05*G0_1_1 + 1.86057328914559e-05*G0_1_3 - 7.0564356278675e-06*G0_1_6 - 5.12450512450753e-05*G0_1_7 + 3.99336113622016e-05*G0_1_8 + 2.02677980455854e-05*G0_2_0 - 1.51993802787526e-05*G0_2_2 - 1.8605732891456e-05*G0_2_4 + 5.12450512450753e-05*G0_2_5 - 3.99336113622016e-05*G0_2_6 + 7.05643562786753e-06*G0_2_8 + 7.77000777001145e-06*G0_3_0 + 1.86057328914559e-05*G0_3_1 + 6.42214927929517e-05*G0_3_3 - 1.16550116550172e-05*G0_3_5 + 2.11693068836026e-05*G0_3_6 - 2.33100233100343e-05*G0_3_7 + 4.44793301936369e-05*G0_3_8 + 6.42214927929517e-05*G0_3_9 - 7.7700077700115e-06*G0_4_0 - 1.8605732891456e-05*G0_4_2 - 6.42214927929516e-05*G0_4_4 + 2.33100233100343e-05*G0_4_5 - 4.44793301936369e-05*G0_4_6 + 1.16550116550171e-05*G0_4_7 - 2.11693068836026e-05*G0_4_8 - 6.42214927929516e-05*G0_4_9 + 0.000284900284900419*G0_5_0 + 5.12450512450754e-05*G0_5_2 - 1.16550116550172e-05*G0_5_3 + 2.33100233100343e-05*G0_5_4 + 0.00033300033300049*G0_5_5 - 0.000166500166500245*G0_5_6 - 0.000114700114700169*G0_6_0 - 7.0564356278675e-06*G0_6_1 - 3.99336113622016e-05*G0_6_2 + 2.11693068836026e-05*G0_6_3 - 4.44793301936369e-05*G0_6_4 - 0.000166500166500245*G0_6_5 - 6.66000666000994e-06*G0_6_6 - 5.99400599400881e-05*G0_6_9 - 0.000284900284900419*G0_7_0 - 5.12450512450753e-05*G0_7_1 - 2.33100233100343e-05*G0_7_3 + 1.16550116550171e-05*G0_7_4 - 0.00033300033300049*G0_7_7 + 0.000166500166500245*G0_7_8 + 0.000114700114700168*G0_8_0 + 3.99336113622016e-05*G0_8_1 + 7.05643562786752e-06*G0_8_2 + 4.44793301936369e-05*G0_8_3 - 2.11693068836026e-05*G0_8_4 + 0.000166500166500245*G0_8_7 + 6.66000666000996e-06*G0_8_8 + 5.99400599400882e-05*G0_8_9 + 6.42214927929517e-05*G0_9_3 - 6.42214927929516e-05*G0_9_4 - 5.99400599400881e-05*G0_9_6 + 5.99400599400882e-05*G0_9_8; + A[164] = A[202] - 7.40000740001091e-06*G0_0_1 + 7.40000740001094e-06*G0_0_2 + 7.99200799201169e-05*G0_0_3 - 7.99200799201172e-05*G0_0_4 - 0.000112268683697307*G0_0_5 - 0.000129394415108762*G0_0_6 + 0.000112268683697309*G0_0_7 + 0.000129394415108761*G0_0_8 - 7.4000074000109e-06*G0_1_0 + 7.10400710401041e-05*G0_1_1 + 0.000102754388468722*G0_1_3 - 9.13372341944197e-05*G0_1_4 + 0.000102754388468722*G0_1_5 + 2.28343085486051e-05*G0_1_6 + 3.8057180914342e-05*G0_1_7 + 0.00021502307216603*G0_1_8 + 0.000262594548308958*G0_1_9 + 7.40000740001094e-06*G0_2_0 - 7.10400710401043e-05*G0_2_2 + 9.13372341944195e-05*G0_2_3 - 0.000102754388468722*G0_2_4 - 3.80571809143415e-05*G0_2_5 - 0.00021502307216603*G0_2_6 - 0.000102754388468722*G0_2_7 - 2.28343085486055e-05*G0_2_8 - 0.000262594548308958*G0_2_9 + 7.99200799201169e-05*G0_3_0 + 0.000102754388468722*G0_3_1 + 9.13372341944196e-05*G0_3_2 + 0.00020550877693744*G0_3_3 - 0.000274011702583259*G0_3_5 - 6.85029256458157e-05*G0_3_6 - 0.000239760239760351*G0_3_7 + 0.000171257314114535*G0_3_8 - 0.000308263165406173*G0_3_9 - 7.99200799201172e-05*G0_4_0 - 9.13372341944197e-05*G0_4_1 - 0.000102754388468722*G0_4_2 - 0.000205508776937444*G0_4_4 + 0.000239760239760352*G0_4_5 - 0.000171257314114536*G0_4_6 + 0.000274011702583259*G0_4_7 + 6.85029256458163e-05*G0_4_8 + 0.000308263165406171*G0_4_9 - 0.000112268683697307*G0_5_0 + 0.000102754388468722*G0_5_1 - 3.80571809143414e-05*G0_5_2 - 0.000274011702583259*G0_5_3 + 0.000239760239760352*G0_5_4 + 0.000753532182103965*G0_5_5 + 0.000804909376338324*G0_5_6 - 0.000308263165406167*G0_5_8 + 0.000616526330812336*G0_5_9 - 0.000129394415108762*G0_6_0 + 2.28343085486051e-05*G0_6_1 - 0.00021502307216603*G0_6_2 - 6.85029256458157e-05*G0_6_3 - 0.000171257314114536*G0_6_4 + 0.000804909376338324*G0_6_5 + 0.000548023405166522*G0_6_6 + 0.000308263165406167*G0_6_7 + 0.000924789496218505*G0_6_9 + 0.000112268683697309*G0_7_0 + 3.8057180914342e-05*G0_7_1 - 0.000102754388468722*G0_7_2 - 0.000239760239760351*G0_7_3 + 0.000274011702583259*G0_7_4 + 0.000308263165406167*G0_7_6 - 0.000753532182103965*G0_7_7 - 0.000804909376338326*G0_7_8 - 0.000616526330812334*G0_7_9 + 0.000129394415108761*G0_8_0 + 0.00021502307216603*G0_8_1 - 2.28343085486055e-05*G0_8_2 + 0.000171257314114535*G0_8_3 + 6.85029256458163e-05*G0_8_4 - 0.000308263165406167*G0_8_5 - 0.000804909376338325*G0_8_7 - 0.000548023405166524*G0_8_8 - 0.000924789496218508*G0_8_9 + 0.000262594548308958*G0_9_1 - 0.000262594548308958*G0_9_2 - 0.000308263165406173*G0_9_3 + 0.000308263165406171*G0_9_4 + 0.000616526330812336*G0_9_5 + 0.000924789496218505*G0_9_6 - 0.000616526330812334*G0_9_7 - 0.000924789496218508*G0_9_8; + A[195] = A[41] - 3.53790829981475e-05*G0_0_0 - 3.92993250136293e-05*G0_0_3 + 1.29500129500192e-06*G0_0_4 - 1.82357325214552e-05*G0_0_5 + 1.63328734757383e-05*G0_0_6 - 3.5414321128623e-06*G0_0_7 + 5.8142915285789e-07*G0_0_8 - 4.31314717029207e-05*G0_0_9 + 2.35155790711456e-05*G0_1_1 + 2.53185967471801e-05*G0_1_3 + 5.33857676715072e-06*G0_1_4 - 1.65443022585957e-05*G0_1_7 + 2.30985945271768e-05*G0_1_8 + 1.77600177600262e-05*G0_1_9 - 9.14429485858492e-06*G0_2_3 + 1.36900136900201e-05*G0_2_4 + 8.6157229014412e-06*G0_2_6 + 1.01750101750149e-05*G0_2_8 + 3.61543218686245e-05*G0_2_9 - 3.92993250136293e-05*G0_3_0 + 2.53185967471801e-05*G0_3_1 - 9.14429485858492e-06*G0_3_2 - 0.000390799676514147*G0_3_3 + 4.51929023357829e-06*G0_3_4 + 6.35079206508078e-05*G0_3_5 - 9.27643784787074e-06*G0_3_6 + 0.000112506541078023*G0_3_7 - 7.65900765901132e-05*G0_3_8 - 0.000278293135436124*G0_3_9 + 1.29500129500192e-06*G0_4_0 + 5.33857676715071e-06*G0_4_1 + 1.36900136900201e-05*G0_4_2 + 4.51929023357829e-06*G0_4_3 - 4.54307597164955e-05*G0_4_4 - 9.27643784787079e-06*G0_4_5 - 3.09214594929034e-06*G0_4_7 - 3.59164644879097e-05*G0_4_8 - 8.9910089910132e-05*G0_4_9 - 1.82357325214552e-05*G0_5_0 + 6.35079206508078e-05*G0_5_3 - 9.27643784787079e-06*G0_5_4 + 7.92065077779739e-05*G0_5_5 - 4.49550449550663e-05*G0_5_6 + 1.47471576043075e-05*G0_5_7 - 1.66500166500249e-06*G0_5_8 + 0.000132724418438767*G0_5_9 + 1.63328734757383e-05*G0_6_0 + 8.61572290144119e-06*G0_6_2 - 9.27643784787074e-06*G0_6_3 - 4.49550449550663e-05*G0_6_5 + 1.92664478378855e-05*G0_6_6 - 1.45093002235926e-05*G0_6_8 - 8.99100899101322e-05*G0_6_9 - 3.54143211286229e-06*G0_7_0 - 1.65443022585957e-05*G0_7_1 + 0.000112506541078023*G0_7_3 - 3.09214594929034e-06*G0_7_4 + 1.47471576043075e-05*G0_7_5 - 4.44793301936369e-05*G0_7_7 - 5.94643451786578e-06*G0_7_8 + 0.000155558726987372*G0_7_9 + 5.8142915285789e-07*G0_8_0 + 2.30985945271768e-05*G0_8_1 + 1.01750101750149e-05*G0_8_2 - 7.65900765901133e-05*G0_8_3 - 3.59164644879097e-05*G0_8_4 - 1.66500166500249e-06*G0_8_5 - 1.45093002235926e-05*G0_8_6 - 5.94643451786581e-06*G0_8_7 + 0.000280909566623983*G0_8_8 + 1.85528756957406e-05*G0_8_9 - 4.31314717029207e-05*G0_9_0 + 1.77600177600262e-05*G0_9_1 + 3.61543218686245e-05*G0_9_2 - 0.000278293135436124*G0_9_3 - 8.9910089910132e-05*G0_9_4 + 0.000132724418438767*G0_9_5 - 8.99100899101322e-05*G0_9_6 + 0.000155558726987372*G0_9_7 + 1.85528756957406e-05*G0_9_8 - 7.70657913515427e-05*G0_9_9; + A[31] = 2.66708600042059e-06*G0_0_0 - 1.84192644510192e-06*G0_0_1 - 1.84192644510192e-06*G0_0_2 - 1.24049231192147e-06*G0_0_3 - 1.24049231192147e-06*G0_0_4 + 5.36996072710611e-06*G0_0_5 - 3.33661047946919e-06*G0_0_6 + 5.36996072710611e-06*G0_0_7 - 3.33661047946919e-06*G0_0_8 + 2.87411001696851e-06*G0_0_9 - 1.84192644510192e-06*G0_1_0 - 4.08696242029768e-05*G0_1_1 - 5.90257038670015e-06*G0_1_2 - 2.80275280275412e-05*G0_1_3 + 1.07630464773373e-05*G0_1_4 + 1.72281422281504e-06*G0_1_5 + 1.06705463848371e-05*G0_1_7 - 2.03500203500299e-05*G0_1_8 - 3.7660751946484e-06*G0_1_9 - 1.84192644510192e-06*G0_2_0 - 5.90257038670015e-06*G0_2_1 - 4.08696242029768e-05*G0_2_2 + 1.07630464773373e-05*G0_2_3 - 2.80275280275412e-05*G0_2_4 + 1.06705463848371e-05*G0_2_5 - 2.035002035003e-05*G0_2_6 + 1.72281422281505e-06*G0_2_7 - 3.7660751946484e-06*G0_2_9 - 1.24049231192147e-06*G0_3_0 - 2.80275280275412e-05*G0_3_1 + 1.07630464773373e-05*G0_3_2 - 4.21453546453745e-05*G0_3_3 + 2.55548023405287e-05*G0_3_4 - 1.88799295942242e-06*G0_3_5 + 4.04357547214881e-06*G0_3_6 + 6.05049712192855e-06*G0_3_7 - 1.00940725940774e-05*G0_3_8 - 1.24049231192147e-06*G0_4_0 + 1.07630464773372e-05*G0_4_1 - 2.80275280275412e-05*G0_4_2 + 2.55548023405287e-05*G0_4_3 - 4.21453546453745e-05*G0_4_4 + 6.05049712192854e-06*G0_4_5 - 1.00940725940773e-05*G0_4_6 - 1.88799295942243e-06*G0_4_7 + 4.04357547214882e-06*G0_4_8 + 5.36996072710611e-06*G0_5_0 + 1.72281422281504e-06*G0_5_1 + 1.06705463848371e-05*G0_5_2 - 1.88799295942242e-06*G0_5_3 + 6.05049712192854e-06*G0_5_4 + 1.20415298986784e-06*G0_5_5 + 1.07035821321586e-06*G0_5_6 + 5.67884496456194e-06*G0_5_7 - 2.83942248228096e-06*G0_5_8 - 2.94348508634361e-06*G0_5_9 - 3.33661047946919e-06*G0_6_0 - 2.035002035003e-05*G0_6_2 + 4.04357547214881e-06*G0_6_3 - 1.00940725940773e-05*G0_6_4 + 1.07035821321586e-06*G0_6_5 - 2.80969030969163e-06*G0_6_6 - 2.83942248228098e-06*G0_6_7 + 3.21107463964757e-06*G0_6_9 + 5.36996072710611e-06*G0_7_0 + 1.06705463848371e-05*G0_7_1 + 1.72281422281505e-06*G0_7_2 + 6.05049712192855e-06*G0_7_3 - 1.88799295942243e-06*G0_7_4 + 5.67884496456194e-06*G0_7_5 - 2.83942248228098e-06*G0_7_6 + 1.20415298986788e-06*G0_7_7 + 1.07035821321586e-06*G0_7_8 - 2.94348508634359e-06*G0_7_9 - 3.33661047946919e-06*G0_8_0 - 2.03500203500299e-05*G0_8_1 - 1.00940725940774e-05*G0_8_3 + 4.04357547214881e-06*G0_8_4 - 2.83942248228096e-06*G0_8_5 + 1.07035821321586e-06*G0_8_7 - 2.80969030969166e-06*G0_8_8 + 3.21107463964756e-06*G0_8_9 + 2.87411001696851e-06*G0_9_0 - 3.7660751946484e-06*G0_9_1 - 3.7660751946484e-06*G0_9_2 - 2.94348508634361e-06*G0_9_5 + 3.21107463964757e-06*G0_9_6 - 2.94348508634359e-06*G0_9_7 + 3.21107463964755e-06*G0_9_8 + 1.01684030255507e-05*G0_9_9; + A[99] = -A[31] + 0.000690045551156986*G0_0_0 + 8.63003839194719e-05*G0_0_1 + 8.63003839194719e-05*G0_0_2 - 2.1960513031952e-05*G0_0_3 - 2.19605130319519e-05*G0_0_4 + 0.000819370774728301*G0_0_5 - 0.000379256986400021*G0_0_6 + 0.000819370774728302*G0_0_7 - 0.000379256986400022*G0_0_8 + 0.000251514358657334*G0_0_9 + 8.63003839194719e-05*G0_1_0 - 5.77244624863951e-06*G0_1_1 + 2.0737456253339e-05*G0_1_2 - 4.7478976050427e-05*G0_1_3 - 4.8826834541143e-06*G0_1_4 + 0.00022964304214315*G0_1_5 - 9.74059009773753e-05*G0_1_6 + 0.000259310795025203*G0_1_7 - 0.000130715845001621*G0_1_8 + 0.000120554049125534*G0_1_9 + 8.63003839194719e-05*G0_2_0 + 2.0737456253339e-05*G0_2_1 - 5.77244624863954e-06*G0_2_2 - 4.88268345411433e-06*G0_2_3 - 4.7478976050427e-05*G0_2_4 + 0.000259310795025203*G0_2_5 - 0.000130715845001621*G0_2_6 + 0.00022964304214315*G0_2_7 - 9.74059009773754e-05*G0_2_8 + 0.000120554049125534*G0_2_9 - 2.1960513031952e-05*G0_3_0 - 4.7478976050427e-05*G0_3_1 - 4.88268345411434e-06*G0_3_2 + 0.00016336342229207*G0_3_3 - 8.6966604823787e-06*G0_3_4 - 0.000188368179439697*G0_3_5 + 4.59064744779249e-05*G0_3_6 - 0.000180429689358346*G0_3_7 + 0.000134523214880421*G0_3_8 - 2.19605130319519e-05*G0_4_0 - 4.88268345411431e-06*G0_4_1 - 4.7478976050427e-05*G0_4_2 - 8.6966604823787e-06*G0_4_3 + 0.00016336342229207*G0_4_4 - 0.000180429689358346*G0_4_5 + 0.000134523214880421*G0_4_6 - 0.000188368179439697*G0_4_7 + 4.59064744779248e-05*G0_4_8 + 0.000819370774728301*G0_5_0 + 0.00022964304214315*G0_5_1 + 0.000259310795025203*G0_5_2 - 0.000188368179439697*G0_5_3 - 0.000180429689358346*G0_5_4 + 0.00279840695019398*G0_5_5 - 0.00111781076066843*G0_5_6 + 0.0018704807097673*G0_5_7 - 0.000935240354883652*G0_5_8 + 0.0011159376337953*G0_5_9 - 0.000379256986400021*G0_6_0 - 9.74059009773753e-05*G0_6_1 - 0.000130715845001621*G0_6_2 + 4.59064744779249e-05*G0_6_3 + 0.000134523214880421*G0_6_4 - 0.00111781076066843*G0_6_5 + 0.000545213714856828*G0_6_6 - 0.000935240354883652*G0_6_7 + 0.000415373317159227*G0_6_8 - 0.000453475096332453*G0_6_9 + 0.000819370774728302*G0_7_0 + 0.000259310795025203*G0_7_1 + 0.00022964304214315*G0_7_2 - 0.000180429689358346*G0_7_3 - 0.000188368179439697*G0_7_4 + 0.0018704807097673*G0_7_5 - 0.000935240354883652*G0_7_6 + 0.00279840695019398*G0_7_7 - 0.00111781076066843*G0_7_8 + 0.0011159376337953*G0_7_9 - 0.000379256986400022*G0_8_0 - 0.000130715845001621*G0_8_1 - 9.74059009773754e-05*G0_8_2 + 0.000134523214880421*G0_8_3 + 4.59064744779248e-05*G0_8_4 - 0.000935240354883652*G0_8_5 + 0.000415373317159227*G0_8_6 - 0.00111781076066843*G0_8_7 + 0.000545213714856829*G0_8_8 - 0.000453475096332453*G0_8_9 + 0.000251514358657334*G0_9_0 + 0.000120554049125534*G0_9_1 + 0.000120554049125534*G0_9_2 + 0.0011159376337953*G0_9_5 - 0.000453475096332453*G0_9_6 + 0.0011159376337953*G0_9_7 - 0.000453475096332453*G0_9_8 + 0.00124322106465022*G0_9_9; + A[144] = A[99] + 0.000687378465156565*G0_0_0 + 0.000134844579289087*G0_0_1 + 2.07200207200306e-05*G0_0_2 + 2.07200207200304e-05*G0_0_3 - 4.14400414400609e-05*G0_0_4 - 6.21600621600921e-05*G0_0_6 + 0.0016280016280024*G0_0_7 - 0.000565360565360832*G0_0_8 + 0.000124320124320183*G0_0_9 + 0.000134844579289087*G0_1_0 + 0.000128971557543047*G0_1_1 + 1.77600177600261e-05*G0_1_2 + 7.56915042629684e-05*G0_1_3 - 5.37029108457932e-05*G0_1_4 + 2.07200207200305e-05*G0_1_5 - 4.14400414400611e-05*G0_1_6 + 0.000372960372960548*G0_1_7 - 2.02971631543153e-05*G0_1_8 + 5.58171986743677e-05*G0_1_9 + 2.07200207200306e-05*G0_2_0 + 1.77600177600261e-05*G0_2_1 + 2.96000296000439e-06*G0_2_2 + 3.04457447314733e-05*G0_2_3 - 3.04457447314733e-05*G0_2_4 - 2.07200207200305e-05*G0_2_5 - 2.07200207200306e-05*G0_2_6 + 0.000207200207200305*G0_2_7 - 2.11428782857455e-05*G0_2_8 + 6.8502925645815e-05*G0_2_9 + 2.07200207200304e-05*G0_3_0 + 7.56915042629684e-05*G0_3_1 + 3.04457447314733e-05*G0_3_2 + 0.00031968031968047*G0_3_3 - 9.13372341944201e-05*G0_3_4 - 0.000186480186480275*G0_3_7 + 0.000247371675943221*G0_3_8 + 0.000205508776937445*G0_3_9 - 4.14400414400609e-05*G0_4_0 - 5.37029108457932e-05*G0_4_1 - 3.04457447314733e-05*G0_4_2 - 9.13372341944201e-05*G0_4_3 - 2.28343085486049e-05*G0_4_4 - 0.000186480186480274*G0_4_7 - 6.08914894629467e-05*G0_4_8 - 0.000205508776937445*G0_4_9 + 2.07200207200304e-05*G0_5_1 - 2.07200207200305e-05*G0_5_2 - 0.000932400932401369*G0_5_5 + 0.000186480186480274*G0_5_6 + 0.000932400932401373*G0_5_7 - 0.000186480186480274*G0_5_8 - 6.21600621600921e-05*G0_6_0 - 4.1440041440061e-05*G0_6_1 - 2.07200207200307e-05*G0_6_2 + 0.000186480186480274*G0_6_5 - 3.04457447314728e-05*G0_6_6 - 0.000745920745921099*G0_6_7 + 0.000156034441748802*G0_6_8 - 0.000205508776937445*G0_6_9 + 0.0016280016280024*G0_7_0 + 0.000372960372960548*G0_7_1 + 0.000207200207200305*G0_7_2 - 0.000186480186480275*G0_7_3 - 0.000186480186480274*G0_7_4 + 0.000932400932401373*G0_7_5 - 0.000745920745921099*G0_7_6 + 0.00839160839161233*G0_7_7 - 0.00223776223776329*G0_7_8 + 0.00111888111888164*G0_7_9 - 0.000565360565360832*G0_8_0 - 2.02971631543153e-05*G0_8_1 - 2.11428782857455e-05*G0_8_2 + 0.000247371675943221*G0_8_3 - 6.08914894629467e-05*G0_8_4 - 0.000186480186480274*G0_8_5 + 0.000156034441748802*G0_8_6 - 0.00223776223776329*G0_8_7 + 0.00114171542743025*G0_8_8 - 4.56686170972105e-05*G0_8_9 + 0.000124320124320183*G0_9_0 + 5.58171986743677e-05*G0_9_1 + 6.8502925645815e-05*G0_9_2 + 0.000205508776937445*G0_9_3 - 0.000205508776937445*G0_9_4 - 0.000205508776937445*G0_9_6 + 0.00111888111888165*G0_9_7 - 4.56686170972105e-05*G0_9_8 + 0.00041101755387489*G0_9_9; + A[176] = A[144] - 0.00121068819481575*G0_0_0 - 6.44622866845392e-05*G0_0_2 + 0.000248640248640366*G0_0_3 - 7.61143618286832e-05*G0_0_4 - 0.000757760757761113*G0_0_5 + 0.000368731797303399*G0_0_6 - 0.0025726654298095*G0_0_7 + 0.0015628815628823*G0_0_8 - 0.000192823049965998*G0_0_9 + 0.00121068819481575*G0_1_1 + 6.44622866845393e-05*G0_1_2 + 0.000757760757761114*G0_1_3 - 0.000368731797303399*G0_1_4 - 0.000248640248640366*G0_1_5 + 7.61143618286835e-05*G0_1_6 - 0.0015628815628823*G0_1_7 + 0.0025726654298095*G0_1_8 + 0.000192823049965998*G0_1_9 - 6.44622866845392e-05*G0_2_0 + 6.44622866845393e-05*G0_2_1 + 0.000213120213120313*G0_2_3 - 8.11886526172621e-05*G0_2_4 - 0.000213120213120313*G0_2_5 + 8.11886526172624e-05*G0_2_6 - 0.000553097695955099*G0_2_7 + 0.000553097695955099*G0_2_8 + 0.000248640248640366*G0_3_0 + 0.000757760757761114*G0_3_1 + 0.000213120213120313*G0_3_2 + 0.00133961276818483*G0_3_3 - 0.000806812235384042*G0_3_4 - 0.00022834308548605*G0_3_6 - 0.000745920745921096*G0_3_7 + 0.00240521383378639*G0_3_8 + 0.000913372341944199*G0_3_9 - 7.61143618286832e-05*G0_4_0 - 0.000368731797303399*G0_4_1 - 8.11886526172621e-05*G0_4_2 - 0.000806812235384043*G0_4_3 + 0.000334903192046207*G0_4_4 + 0.00022834308548605*G0_4_5 + 0.000943818086675673*G0_4_7 - 0.0016592930878653*G0_4_8 - 0.000456686170972099*G0_4_9 - 0.000757760757761113*G0_5_0 - 0.000248640248640366*G0_5_1 - 0.000213120213120313*G0_5_2 + 0.00022834308548605*G0_5_4 - 0.00133961276818483*G0_5_5 + 0.000806812235384043*G0_5_6 - 0.00240521383378639*G0_5_7 + 0.000745920745921096*G0_5_8 - 0.0009133723419442*G0_5_9 + 0.000368731797303399*G0_6_0 + 7.61143618286835e-05*G0_6_1 + 8.11886526172624e-05*G0_6_2 - 0.00022834308548605*G0_6_3 + 0.000806812235384043*G0_6_5 - 0.000334903192046207*G0_6_6 + 0.0016592930878653*G0_6_7 - 0.000943818086675674*G0_6_8 + 0.000456686170972101*G0_6_9 - 0.0025726654298095*G0_7_0 - 0.0015628815628823*G0_7_1 - 0.000553097695955099*G0_7_2 - 0.000745920745921096*G0_7_3 + 0.000943818086675673*G0_7_4 - 0.00240521383378639*G0_7_5 + 0.0016592930878653*G0_7_6 - 0.00949907235621967*G0_7_7 - 0.0027401170258326*G0_7_9 + 0.0015628815628823*G0_8_0 + 0.0025726654298095*G0_8_1 + 0.000553097695955099*G0_8_2 + 0.00240521383378639*G0_8_3 - 0.0016592930878653*G0_8_4 + 0.000745920745921096*G0_8_5 - 0.000943818086675674*G0_8_6 + 0.00949907235621968*G0_8_8 + 0.0027401170258326*G0_8_9 - 0.000192823049965998*G0_9_0 + 0.000192823049965998*G0_9_1 + 0.000913372341944199*G0_9_3 - 0.000456686170972099*G0_9_4 - 0.0009133723419442*G0_9_5 + 0.000456686170972101*G0_9_6 - 0.0027401170258326*G0_9_7 + 0.0027401170258326*G0_9_8; + A[56] = A[176] - 0.000128971557543047*G0_0_0 - 0.000134844579289087*G0_0_1 - 1.77600177600261e-05*G0_0_2 - 2.07200207200303e-05*G0_0_3 + 4.14400414400608e-05*G0_0_4 - 7.56915042629682e-05*G0_0_5 + 5.37029108457932e-05*G0_0_6 + 2.02971631543158e-05*G0_0_7 - 0.000372960372960548*G0_0_8 - 5.58171986743677e-05*G0_0_9 - 0.000134844579289087*G0_1_0 - 0.000687378465156567*G0_1_1 - 2.07200207200305e-05*G0_1_2 + 6.21600621600913e-05*G0_1_4 - 2.07200207200303e-05*G0_1_5 + 4.14400414400609e-05*G0_1_6 + 0.000565360565360832*G0_1_7 - 0.00162800162800239*G0_1_8 - 0.000124320124320183*G0_1_9 - 1.77600177600261e-05*G0_2_0 - 2.07200207200305e-05*G0_2_1 - 2.96000296000432e-06*G0_2_2 + 2.07200207200304e-05*G0_2_3 + 2.07200207200305e-05*G0_2_4 - 3.04457447314733e-05*G0_2_5 + 3.04457447314733e-05*G0_2_6 + 2.11428782857454e-05*G0_2_7 - 0.000207200207200305*G0_2_8 - 6.85029256458148e-05*G0_2_9 - 2.07200207200303e-05*G0_3_0 + 2.07200207200304e-05*G0_3_2 + 0.000932400932401371*G0_3_3 - 0.000186480186480274*G0_3_4 + 0.000186480186480274*G0_3_7 - 0.000932400932401368*G0_3_8 + 4.14400414400608e-05*G0_4_0 + 6.21600621600913e-05*G0_4_1 + 2.07200207200305e-05*G0_4_2 - 0.000186480186480274*G0_4_3 + 3.04457447314731e-05*G0_4_4 - 0.000156034441748801*G0_4_7 + 0.000745920745921097*G0_4_8 + 0.000205508776937445*G0_4_9 - 7.56915042629682e-05*G0_5_0 - 2.07200207200303e-05*G0_5_1 - 3.04457447314733e-05*G0_5_2 - 0.00031968031968047*G0_5_5 + 9.13372341944199e-05*G0_5_6 - 0.000247371675943221*G0_5_7 + 0.000186480186480275*G0_5_8 - 0.000205508776937445*G0_5_9 + 5.37029108457932e-05*G0_6_0 + 4.14400414400609e-05*G0_6_1 + 3.04457447314733e-05*G0_6_2 + 9.13372341944199e-05*G0_6_5 + 2.28343085486049e-05*G0_6_6 + 6.08914894629467e-05*G0_6_7 + 0.000186480186480274*G0_6_8 + 0.000205508776937445*G0_6_9 + 2.02971631543157e-05*G0_7_0 + 0.000565360565360832*G0_7_1 + 2.11428782857454e-05*G0_7_2 + 0.000186480186480274*G0_7_3 - 0.000156034441748801*G0_7_4 - 0.000247371675943221*G0_7_5 + 6.08914894629467e-05*G0_7_6 - 0.00114171542743025*G0_7_7 + 0.00223776223776329*G0_7_8 + 4.56686170972094e-05*G0_7_9 - 0.000372960372960548*G0_8_0 - 0.00162800162800239*G0_8_1 - 0.000207200207200305*G0_8_2 - 0.000932400932401368*G0_8_3 + 0.000745920745921097*G0_8_4 + 0.000186480186480275*G0_8_5 + 0.000186480186480274*G0_8_6 + 0.00223776223776329*G0_8_7 - 0.00839160839161234*G0_8_8 - 0.00111888111888164*G0_8_9 - 5.58171986743676e-05*G0_9_0 - 0.000124320124320183*G0_9_1 - 6.85029256458148e-05*G0_9_2 + 0.000205508776937445*G0_9_4 - 0.000205508776937445*G0_9_5 + 0.000205508776937445*G0_9_6 + 4.56686170972094e-05*G0_9_7 - 0.00111888111888164*G0_9_8 - 0.00041101755387489*G0_9_9; + A[117] = -A[56] - 0.000204663061806015*G0_0_0 + 2.06965286330463e-05*G0_0_1 + 8.45715131429817e-06*G0_0_2 + 0.000286908858337565*G0_0_3 - 3.59428930857671e-06*G0_0_4 - 0.000725412153983923*G0_0_5 + 0.0001460972889545*G0_0_6 - 0.000509966224252178*G0_0_7 + 0.000516943374086474*G0_0_8 - 9.26058068915656e-05*G0_0_9 + 2.06965286330463e-05*G0_1_0 + 0.00069710418916801*G0_1_1 + 6.04451398102476e-05*G0_1_2 + 0.000722663579806777*G0_1_3 - 0.000267457410314679*G0_1_4 - 5.30686244972204e-05*G0_1_5 + 0.000243777386634644*G0_1_6 - 0.000556691985263675*G0_1_7 + 0.00084444655873267*G0_1_8 + 0.000454149025577811*G0_1_9 + 8.45715131429818e-06*G0_2_0 + 6.04451398102477e-05*G0_2_1 + 9.13372341944201e-05*G0_2_2 + 0.000242931671503214*G0_2_3 - 7.6114361828682e-06*G0_2_4 - 0.000417148988577756*G0_2_5 + 0.000104234389948725*G0_2_6 - 0.000437446151732071*G0_2_7 + 0.000355411783983379*G0_2_8 - 0.000320948892377614*G0_2_9 + 0.000286908858337565*G0_3_0 + 0.000722663579806777*G0_3_1 + 0.000242931671503214*G0_3_2 + 0.00313971742543318*G0_3_3 - 0.00144427001569927*G0_3_4 - 0.000340611769183358*G0_3_5 - 0.000751629323058248*G0_3_6 - 0.000881023738167009*G0_3_7 + 0.00196755625327146*G0_3_8 + 0.000399600399600586*G0_3_9 - 3.59428930857671e-06*G0_4_0 - 0.000267457410314679*G0_4_1 - 7.6114361828682e-06*G0_4_2 - 0.00144427001569927*G0_4_3 + 0.00171257314114537*G0_4_4 - 9.51429522858561e-06*G0_4_5 + 0.000761143618286833*G0_4_6 + 0.000671709243138129*G0_4_7 - 0.00108653251510445*G0_4_8 + 0.000981875267590013*G0_4_9 - 0.000725412153983923*G0_5_0 - 5.30686244972204e-05*G0_5_1 - 0.000417148988577756*G0_5_2 - 0.000340611769183358*G0_5_3 - 9.51429522858556e-06*G0_5_4 + 0.00034251462822908*G0_5_5 + 0.00143856143856211*G0_5_6 - 0.00143095000237924*G0_5_7 + 0.000138908710337345*G0_5_8 + 0.0001460972889545*G0_6_0 + 0.000243777386634644*G0_6_1 + 0.000104234389948725*G0_6_2 - 0.000751629323058248*G0_6_3 + 0.000761143618286833*G0_6_4 + 0.00143856143856211*G0_6_5 + 0.00116454973597886*G0_6_6 + 0.0012920412920419*G0_6_7 - 0.000888635174349877*G0_6_8 + 0.00246610532324934*G0_6_9 - 0.000509966224252178*G0_7_0 - 0.000556691985263675*G0_7_1 - 0.000437446151732071*G0_7_2 - 0.000881023738167009*G0_7_3 + 0.000671709243138129*G0_7_4 - 0.00143095000237924*G0_7_5 + 0.0012920412920419*G0_7_6 - 0.00267161410018678*G0_7_7 - 0.000279720279720412*G0_7_8 - 0.0023062651634091*G0_7_9 + 0.000516943374086474*G0_8_0 + 0.00084444655873267*G0_8_1 + 0.000355411783983379*G0_8_2 + 0.00196755625327146*G0_8_3 - 0.00108653251510445*G0_8_4 + 0.000138908710337345*G0_8_5 - 0.000888635174349877*G0_8_6 - 0.000279720279720412*G0_8_7 + 0.00245468816897504*G0_8_8 + 0.000810617953475476*G0_8_9 - 9.26058068915656e-05*G0_9_0 + 0.000454149025577811*G0_9_1 - 0.000320948892377614*G0_9_2 + 0.000399600399600586*G0_9_3 + 0.000981875267590013*G0_9_4 + 0.00246610532324934*G0_9_6 - 0.0023062651634091*G0_9_7 + 0.000810617953475476*G0_9_8 + 0.00369915798487402*G0_9_9; + A[199] = A[117] + 0.000249485963771795*G0_0_0 - 9.51429522858545e-06*G0_0_2 - 9.13372341944195e-05*G0_0_3 + 0.000171257314114537*G0_0_4 + 0.000614623471766617*G0_0_5 - 5.32800532800781e-05*G0_0_6 + 0.00043004614433206*G0_0_7 - 0.000449074734789231*G0_0_8 + 0.000422434708149194*G0_0_9 - 0.000249485963771795*G0_1_1 + 9.51429522858535e-06*G0_1_2 - 0.000614623471766618*G0_1_3 + 5.32800532800783e-05*G0_1_4 + 9.13372341944195e-05*G0_1_5 - 0.000171257314114537*G0_1_6 + 0.000449074734789231*G0_1_7 - 0.000430046144332061*G0_1_8 - 0.000422434708149194*G0_1_9 - 9.51429522858545e-06*G0_2_0 + 9.51429522858535e-06*G0_2_1 - 0.000395794681509153*G0_2_3 + 2.09314495028875e-05*G0_2_4 + 0.000395794681509153*G0_2_5 - 2.0931449502888e-05*G0_2_6 + 0.000468103325246402*G0_2_7 - 0.000468103325246402*G0_2_8 - 9.13372341944194e-05*G0_3_0 - 0.000614623471766618*G0_3_1 - 0.000395794681509153*G0_3_2 - 0.000205508776937439*G0_3_3 + 0.00179820179820264*G0_3_4 + 0.000513771942343613*G0_3_6 + 0.000274011702583258*G0_3_7 - 0.00167832167832246*G0_3_8 + 0.000719280719281063*G0_3_9 + 0.000171257314114537*G0_4_0 + 5.32800532800783e-05*G0_4_1 + 2.09314495028875e-05*G0_4_2 + 0.00179820179820264*G0_4_3 - 0.000205508776937443*G0_4_4 - 0.000513771942343613*G0_4_5 - 0.000959040959041409*G0_4_7 + 0.00140430997573921*G0_4_8 + 0.00102754388468723*G0_4_9 + 0.000614623471766617*G0_5_0 + 9.13372341944195e-05*G0_5_1 + 0.000395794681509153*G0_5_2 - 0.000513771942343613*G0_5_4 + 0.000205508776937441*G0_5_5 - 0.00179820179820264*G0_5_6 + 0.00167832167832246*G0_5_7 - 0.000274011702583259*G0_5_8 - 0.000719280719281063*G0_5_9 - 5.32800532800781e-05*G0_6_0 - 0.000171257314114537*G0_6_1 - 2.09314495028881e-05*G0_6_2 + 0.000513771942343613*G0_6_3 - 0.00179820179820264*G0_6_5 + 0.000205508776937444*G0_6_6 - 0.00140430997573921*G0_6_7 + 0.000959040959041409*G0_6_8 - 0.00102754388468722*G0_6_9 + 0.00043004614433206*G0_7_0 + 0.000449074734789231*G0_7_1 + 0.000468103325246402*G0_7_2 + 0.000274011702583258*G0_7_3 - 0.000959040959041409*G0_7_4 + 0.00167832167832246*G0_7_5 - 0.00140430997573921*G0_7_6 + 0.00287712287712423*G0_7_7 + 0.00154131582703083*G0_7_9 - 0.000449074734789231*G0_8_0 - 0.000430046144332061*G0_8_1 - 0.000468103325246402*G0_8_2 - 0.00167832167832246*G0_8_3 + 0.00140430997573921*G0_8_4 - 0.000274011702583259*G0_8_5 + 0.00095904095904141*G0_8_6 - 0.00287712287712423*G0_8_8 - 0.00154131582703083*G0_8_9 + 0.000422434708149194*G0_9_0 - 0.000422434708149193*G0_9_1 + 0.000719280719281063*G0_9_3 + 0.00102754388468723*G0_9_4 - 0.000719280719281063*G0_9_5 - 0.00102754388468722*G0_9_6 + 0.00154131582703083*G0_9_7 - 0.00154131582703083*G0_9_8; + A[214] = A[199] + 3.97486111772013e-05*G0_0_1 - 3.97486111772013e-05*G0_0_2 + 0.000296846011131864*G0_0_3 - 0.000296846011131865*G0_0_4 + 0.000121782978925894*G0_0_5 - 0.000289234574948997*G0_0_6 - 0.000121782978925893*G0_0_7 + 0.000289234574948996*G0_0_8 + 3.97486111772013e-05*G0_1_0 + 0.000296000296000435*G0_1_1 + 0.000829646543932648*G0_1_3 - 0.000563246277532256*G0_1_4 + 6.8502925645815e-05*G0_1_5 - 0.000433851862423495*G0_1_6 - 0.00027401170258326*G0_1_7 + 0.00050235478806931*G0_1_8 - 0.000228343085486049*G0_1_9 - 3.97486111772013e-05*G0_2_0 - 0.000296000296000435*G0_2_2 + 0.000563246277532256*G0_2_3 - 0.000829646543932647*G0_2_4 + 0.00027401170258326*G0_2_5 - 0.00050235478806931*G0_2_6 - 6.85029256458149e-05*G0_2_7 + 0.000433851862423494*G0_2_8 + 0.000228343085486049*G0_2_9 + 0.000296846011131864*G0_3_0 + 0.000829646543932648*G0_3_1 + 0.000563246277532256*G0_3_2 + 0.000822035107749773*G0_3_3 - 0.00054802340516652*G0_3_5 + 0.00130155558727049*G0_3_6 - 0.000890538033395594*G0_3_7 + 0.00219209362066608*G0_3_8 + 0.00246610532324933*G0_3_9 - 0.000296846011131865*G0_4_0 - 0.000563246277532256*G0_4_1 - 0.000829646543932647*G0_4_2 - 0.000822035107749782*G0_4_4 + 0.000890538033395596*G0_4_5 - 0.00219209362066608*G0_4_6 + 0.00054802340516652*G0_4_7 - 0.00130155558727048*G0_4_8 - 0.00246610532324934*G0_4_9 + 0.000121782978925894*G0_5_0 + 6.8502925645815e-05*G0_5_1 + 0.00027401170258326*G0_5_2 - 0.00054802340516652*G0_5_3 + 0.000890538033395596*G0_5_4 - 0.000685029256458151*G0_5_5 + 0.00116454973597886*G0_5_6 - 0.000205508776937445*G0_5_8 + 0.000411017553874891*G0_5_9 - 0.000289234574948997*G0_6_0 - 0.000433851862423495*G0_6_1 - 0.00050235478806931*G0_6_2 + 0.00130155558727049*G0_6_3 - 0.00219209362066608*G0_6_4 + 0.00116454973597886*G0_6_5 - 0.00438418724133216*G0_6_6 + 0.000205508776937446*G0_6_7 - 0.00328814043099912*G0_6_9 - 0.000121782978925893*G0_7_0 - 0.00027401170258326*G0_7_1 - 6.85029256458149e-05*G0_7_2 - 0.000890538033395594*G0_7_3 + 0.00054802340516652*G0_7_4 + 0.000205508776937446*G0_7_6 + 0.000685029256458149*G0_7_7 - 0.00116454973597885*G0_7_8 - 0.000411017553874888*G0_7_9 + 0.000289234574948996*G0_8_0 + 0.00050235478806931*G0_8_1 + 0.000433851862423494*G0_8_2 + 0.00219209362066608*G0_8_3 - 0.00130155558727048*G0_8_4 - 0.000205508776937445*G0_8_5 - 0.00116454973597885*G0_8_7 + 0.00438418724133216*G0_8_8 + 0.00328814043099911*G0_8_9 - 0.000228343085486049*G0_9_1 + 0.000228343085486049*G0_9_2 + 0.00246610532324933*G0_9_3 - 0.00246610532324934*G0_9_4 + 0.000411017553874891*G0_9_5 - 0.00328814043099912*G0_9_6 - 0.000411017553874888*G0_9_7 + 0.00328814043099911*G0_9_8; + A[163] = A[199] + 4.65143322286396e-05*G0_0_0 + 4.92629064057868e-05*G0_0_1 - 0.000308263165406168*G0_0_3 - 0.00013700585129163*G0_0_4 + 0.000194091622663142*G0_0_5 - 0.000114171542743025*G0_0_6 + 9.32400932401372e-05*G0_0_7 - 0.000220731649303182*G0_0_8 - 0.000650777793635244*G0_0_9 + 4.92629064057868e-05*G0_1_0 - 4.92629064057867e-05*G0_1_2 + 0.000306360306360451*G0_1_3 + 0.000106560106560157*G0_1_4 + 3.42514628229075e-05*G0_1_5 - 3.42514628229074e-05*G0_1_6 - 0.000106560106560157*G0_1_7 - 0.00030636030636045*G0_1_8 - 4.92629064057867e-05*G0_2_1 - 4.65143322286397e-05*G0_2_2 + 0.000220731649303181*G0_2_3 - 9.32400932401367e-05*G0_2_4 + 0.000114171542743025*G0_2_5 - 0.000194091622663142*G0_2_6 + 0.00013700585129163*G0_2_7 + 0.000308263165406167*G0_2_8 + 0.000650777793635242*G0_2_9 - 0.000308263165406168*G0_3_0 + 0.000306360306360451*G0_3_1 + 0.000220731649303181*G0_3_2 - 0.00335664335664494*G0_3_3 - 0.000633652062223787*G0_3_4 + 0.00041101755387489*G0_3_5 + 0.000102754388468723*G0_3_6 + 0.000924789496218505*G0_3_7 - 0.00184957899243701*G0_3_9 - 0.00013700585129163*G0_4_0 + 0.000106560106560157*G0_4_1 - 9.32400932401367e-05*G0_4_2 - 0.000633652062223787*G0_4_3 - 0.00130155558727049*G0_4_4 + 0.00041101755387489*G0_4_5 - 0.000513771942343613*G0_4_6 - 0.000924789496218501*G0_4_8 - 0.00277436848865551*G0_4_9 + 0.000194091622663142*G0_5_0 + 3.42514628229075e-05*G0_5_1 + 0.000114171542743025*G0_5_2 + 0.00041101755387489*G0_5_3 + 0.00041101755387489*G0_5_4 + 0.000822035107749779*G0_5_5 + 0.000513771942343612*G0_5_7 - 0.000102754388468722*G0_5_8 + 0.00215784215784317*G0_5_9 - 0.000114171542743025*G0_6_0 - 3.42514628229074e-05*G0_6_1 - 0.000194091622663142*G0_6_2 + 0.000102754388468723*G0_6_3 - 0.000513771942343613*G0_6_4 - 0.000822035107749779*G0_6_6 - 0.00041101755387489*G0_6_7 - 0.00041101755387489*G0_6_8 - 0.00215784215784317*G0_6_9 + 9.32400932401372e-05*G0_7_0 - 0.000106560106560157*G0_7_1 + 0.00013700585129163*G0_7_2 + 0.000924789496218505*G0_7_3 + 0.000513771942343612*G0_7_5 - 0.00041101755387489*G0_7_6 + 0.00130155558727048*G0_7_7 + 0.000633652062223791*G0_7_8 + 0.00277436848865551*G0_7_9 - 0.000220731649303182*G0_8_0 - 0.00030636030636045*G0_8_1 + 0.000308263165406167*G0_8_2 - 0.000924789496218501*G0_8_4 - 0.000102754388468722*G0_8_5 - 0.00041101755387489*G0_8_6 + 0.00063365206222379*G0_8_7 + 0.00335664335664493*G0_8_8 + 0.001849578992437*G0_8_9 - 0.000650777793635244*G0_9_0 + 0.000650777793635242*G0_9_2 - 0.00184957899243701*G0_9_3 - 0.00277436848865551*G0_9_4 + 0.00215784215784317*G0_9_5 - 0.00215784215784317*G0_9_6 + 0.00277436848865551*G0_9_7 + 0.001849578992437*G0_9_8; + A[205] = A[163]; + A[72] = A[202] - 7.10400710401043e-05*G0_0_0 + 7.40000740001094e-06*G0_0_2 - 2.28343085486056e-05*G0_0_3 - 0.000102754388468722*G0_0_4 - 0.00021502307216603*G0_0_5 - 3.80571809143416e-05*G0_0_6 - 0.000102754388468722*G0_0_7 + 9.13372341944195e-05*G0_0_8 - 0.000262594548308958*G0_0_9 + 7.10400710401044e-05*G0_1_1 - 7.40000740001084e-06*G0_1_2 + 0.00021502307216603*G0_1_3 + 3.8057180914342e-05*G0_1_4 + 2.28343085486049e-05*G0_1_5 + 0.000102754388468723*G0_1_6 - 9.13372341944199e-05*G0_1_7 + 0.000102754388468722*G0_1_8 + 0.000262594548308958*G0_1_9 + 7.40000740001094e-06*G0_2_0 - 7.40000740001085e-06*G0_2_1 + 0.000129394415108761*G0_2_3 + 0.000112268683697309*G0_2_4 - 0.000129394415108762*G0_2_5 - 0.000112268683697307*G0_2_6 - 7.99200799201173e-05*G0_2_7 + 7.99200799201171e-05*G0_2_8 - 2.28343085486056e-05*G0_3_0 + 0.00021502307216603*G0_3_1 + 0.000129394415108761*G0_3_2 - 0.000548023405166524*G0_3_3 - 0.000804909376338325*G0_3_4 - 0.000308263165406168*G0_3_6 + 6.85029256458168e-05*G0_3_7 + 0.000171257314114534*G0_3_8 - 0.000924789496218507*G0_3_9 - 0.000102754388468722*G0_4_0 + 3.8057180914342e-05*G0_4_1 + 0.000112268683697309*G0_4_2 - 0.000804909376338325*G0_4_3 - 0.000753532182103966*G0_4_4 + 0.000308263165406167*G0_4_5 + 0.00027401170258326*G0_4_7 - 0.000239760239760351*G0_4_8 - 0.000616526330812333*G0_4_9 - 0.00021502307216603*G0_5_0 + 2.28343085486049e-05*G0_5_1 - 0.000129394415108762*G0_5_2 + 0.000308263165406167*G0_5_4 + 0.00054802340516652*G0_5_5 + 0.000804909376338324*G0_5_6 - 0.000171257314114537*G0_5_7 - 6.85029256458147e-05*G0_5_8 + 0.000924789496218504*G0_5_9 - 3.80571809143416e-05*G0_6_0 + 0.000102754388468723*G0_6_1 - 0.000112268683697307*G0_6_2 - 0.000308263165406168*G0_6_3 + 0.000804909376338324*G0_6_5 + 0.000753532182103967*G0_6_6 + 0.000239760239760352*G0_6_7 - 0.00027401170258326*G0_6_8 + 0.000616526330812337*G0_6_9 - 0.000102754388468722*G0_7_0 - 9.13372341944199e-05*G0_7_1 - 7.99200799201173e-05*G0_7_2 + 6.85029256458168e-05*G0_7_3 + 0.00027401170258326*G0_7_4 - 0.000171257314114537*G0_7_5 + 0.000239760239760352*G0_7_6 - 0.000205508776937445*G0_7_7 + 0.00030826316540617*G0_7_9 + 9.13372341944195e-05*G0_8_0 + 0.000102754388468722*G0_8_1 + 7.99200799201171e-05*G0_8_2 + 0.000171257314114534*G0_8_3 - 0.000239760239760351*G0_8_4 - 6.85029256458147e-05*G0_8_5 - 0.00027401170258326*G0_8_6 + 0.000205508776937442*G0_8_8 - 0.000308263165406172*G0_8_9 - 0.000262594548308958*G0_9_0 + 0.000262594548308958*G0_9_1 - 0.000924789496218507*G0_9_3 - 0.000616526330812333*G0_9_4 + 0.000924789496218504*G0_9_5 + 0.000616526330812336*G0_9_6 + 0.00030826316540617*G0_9_7 - 0.000308263165406172*G0_9_8; + A[107] = 4.33825433825637e-05*G0_0_0 + 1.93589479303855e-06*G0_0_1 - 2.99083632417107e-05*G0_0_2 + 6.14464900179474e-06*G0_0_3 - 1.30623344909121e-05*G0_0_4 + 6.57675657675966e-05*G0_0_5 - 6.25564911279491e-05*G0_0_6 + 3.31414617129059e-05*G0_0_7 - 1.76410890696688e-05*G0_0_8 + 1.93589479303855e-06*G0_1_0 - 2.26933560267e-05*G0_1_2 + 5.7283985855441e-06*G0_1_3 - 1.66301952016316e-05*G0_1_4 + 2.54705611848589e-05*G0_1_5 - 2.55498469784304e-05*G0_1_6 + 1.44101929816283e-05*G0_1_7 - 9.31608074465657e-06*G0_1_8 + 1.15360829646598e-05*G0_1_9 - 2.99083632417107e-05*G0_2_0 - 2.26933560267e-05*G0_2_1 - 0.000474525474525699*G0_2_2 + 0.000102675102675151*G0_2_3 - 0.000213675213675314*G0_2_4 + 0.000174825174825257*G0_2_5 - 0.000357975357975527*G0_2_6 + 2.38650238650352e-05*G0_2_7 + 2.22000222000319e-06*G0_2_8 - 3.3300033300049e-05*G0_2_9 + 6.14464900179474e-06*G0_3_0 + 5.7283985855441e-06*G0_3_1 + 0.000102675102675151*G0_3_2 - 4.28143285286344e-05*G0_3_3 + 7.49250749251102e-05*G0_3_4 - 5.28043385186491e-05*G0_3_5 + 8.74125874126286e-05*G0_3_6 - 7.67090052804701e-06*G0_3_7 + 3.56786071071947e-06*G0_3_8 - 1.92664478378855e-05*G0_3_9 - 1.30623344909121e-05*G0_4_0 - 1.66301952016316e-05*G0_4_1 - 0.000213675213675314*G0_4_2 + 7.49250749251102e-05*G0_4_3 - 0.000112387612387665*G0_4_4 + 4.99500499500735e-05*G0_4_5 - 0.000137362637362702*G0_4_6 - 2.15855572998531e-05*G0_4_7 + 4.10303981732748e-06*G0_4_8 + 6.57675657675966e-05*G0_5_0 + 2.54705611848589e-05*G0_5_1 + 0.000174825174825257*G0_5_2 - 5.28043385186491e-05*G0_5_3 + 4.99500499500735e-05*G0_5_4 + 0.000181960896246696*G0_5_5 + 0.000112387612387665*G0_5_6 + 0.000126480662195007*G0_5_7 - 6.56486370772392e-05*G0_5_8 + 0.000130583702012335*G0_5_9 - 6.25564911279491e-05*G0_6_0 - 2.55498469784304e-05*G0_6_1 - 0.000357975357975527*G0_6_2 + 8.74125874126286e-05*G0_6_3 - 0.000137362637362702*G0_6_4 + 0.000112387612387665*G0_6_5 - 0.000487012987013216*G0_6_6 - 6.08320251177678e-05*G0_6_7 + 2.96132438989721e-05*G0_6_8 - 7.49250749251102e-05*G0_6_9 + 3.31414617129059e-05*G0_7_0 + 1.44101929816283e-05*G0_7_1 + 2.38650238650352e-05*G0_7_2 - 7.67090052804701e-06*G0_7_3 - 2.15855572998531e-05*G0_7_4 + 0.000126480662195007*G0_7_5 - 6.08320251177678e-05*G0_7_6 + 0.000194448408734214*G0_7_7 - 5.44098758384728e-05*G0_7_8 + 0.000120950478093392*G0_7_9 - 1.76410890696688e-05*G0_8_0 - 9.31608074465657e-06*G0_8_1 + 2.22000222000319e-06*G0_8_2 + 3.56786071071947e-06*G0_8_3 + 4.10303981732748e-06*G0_8_4 - 6.56486370772392e-05*G0_8_5 + 2.96132438989721e-05*G0_8_6 - 5.44098758384728e-05*G0_8_7 + 3.71057513914829e-05*G0_8_8 - 4.28143285286345e-05*G0_8_9 + 1.15360829646598e-05*G0_9_1 - 3.3300033300049e-05*G0_9_2 - 1.92664478378855e-05*G0_9_3 + 0.000130583702012335*G0_9_5 - 7.49250749251102e-05*G0_9_6 + 0.000120950478093392*G0_9_7 - 4.28143285286345e-05*G0_9_8 + 0.000218353075496035*G0_9_9; + A[36] = -A[107] - 2.41630797186467e-05*G0_0_0 - 2.36359760169395e-05*G0_0_2 - 5.74161288447273e-06*G0_0_4 - 4.26953998382771e-05*G0_0_5 - 4.83643340786421e-06*G0_0_6 - 1.78657321514548e-05*G0_0_7 + 7.78322206893999e-06*G0_0_8 - 1.81564467278838e-05*G0_0_9 - 1.37957280814489e-05*G0_1_2 - 6.93089978804589e-06*G0_1_4 + 7.57840043554686e-06*G0_1_5 - 8.71483014340567e-06*G0_1_6 + 2.70893128036128e-07*G0_1_7 - 3.56786071071976e-07*G0_1_9 - 2.36359760169395e-05*G0_2_0 - 1.37957280814489e-05*G0_2_1 - 0.000263625263625388*G0_2_2 + 5.45750545750802e-05*G0_2_3 - 0.000111925111925164*G0_2_4 + 7.86250786251156e-05*G0_2_5 - 0.000193325193325284*G0_2_6 + 4.30786145072066e-06*G0_2_7 - 2.22000222000327e-05*G0_2_9 + 5.45750545750802e-05*G0_3_2 - 2.18828790257465e-05*G0_3_3 + 4.59064744779246e-05*G0_3_4 - 3.09214594929026e-05*G0_3_5 + 4.65011179297112e-05*G0_3_6 - 2.14071642643172e-06*G0_3_9 - 5.74161288447273e-06*G0_4_0 - 6.93089978804589e-06*G0_4_1 - 0.000111925111925164*G0_4_2 + 4.59064744779246e-05*G0_4_3 - 7.57575757576114e-05*G0_4_4 + 3.75814661529125e-05*G0_4_5 - 8.40825840826237e-05*G0_4_6 - 8.02768659911888e-06*G0_4_7 - 4.26953998382771e-05*G0_5_0 + 7.57840043554686e-06*G0_5_1 + 7.86250786251156e-05*G0_5_2 - 3.09214594929026e-05*G0_5_3 + 3.75814661529125e-05*G0_5_4 + 1.16550116550171e-05*G0_5_5 + 0.00015472622615487*G0_5_6 - 5.05446934018599e-06*G0_5_7 - 2.37857380714629e-06*G0_5_8 + 5.92264877979442e-05*G0_5_9 - 4.83643340786418e-06*G0_6_0 - 8.71483014340567e-06*G0_6_1 - 0.000193325193325284*G0_6_2 + 4.65011179297112e-05*G0_6_3 - 8.40825840826237e-05*G0_6_4 + 0.00015472622615487*G0_6_5 - 0.000330502830502986*G0_6_6 + 7.4330431473325e-06*G0_6_7 - 7.01679273108179e-06*G0_6_8 - 2.64021692593246e-05*G0_6_9 - 1.78657321514548e-05*G0_7_0 + 2.70893128036132e-07*G0_7_1 + 4.30786145072066e-06*G0_7_2 - 8.02768659911888e-06*G0_7_4 - 5.05446934018596e-06*G0_7_5 + 7.4330431473325e-06*G0_7_6 + 2.84239569953988e-05*G0_7_7 + 1.43309071880569e-05*G0_7_8 + 3.96032538889865e-05*G0_7_9 + 7.78322206893999e-06*G0_8_0 - 2.3785738071463e-06*G0_8_5 - 7.01679273108179e-06*G0_8_6 + 1.43309071880569e-05*G0_8_7 + 6.66000666000961e-06*G0_8_8 - 1.81564467278838e-05*G0_9_0 - 3.56786071071975e-07*G0_9_1 - 2.22000222000327e-05*G0_9_2 - 2.14071642643172e-06*G0_9_3 + 5.92264877979442e-05*G0_9_5 - 2.64021692593245e-05*G0_9_6 + 3.96032538889865e-05*G0_9_7 + 0.000132724418438766*G0_9_9; + A[21] = A[36] + 1.80066846733598e-05*G0_0_0 + 3.92200392200577e-05*G0_0_5 - 3.16614602329037e-05*G0_0_6 + 1.5857158714311e-07*G0_0_8 - 3.17143174286192e-07*G0_0_9 + 1.847358990217e-05*G0_1_3 - 5.76143433286565e-06*G0_1_5 - 1.0042867185729e-05*G0_1_6 - 5.41786256072229e-06*G0_1_7 + 1.09942967085876e-05*G0_1_8 + 1.42714428428776e-06*G0_1_9 - 0.000228554514268908*G0_2_2 + 5.95172023743733e-05*G0_2_3 - 0.000122364408078752*G0_2_4 + 7.89686503972592e-05*G0_2_5 - 0.000177758749187404*G0_2_6 + 5.41786256072228e-06*G0_2_7 - 3.45686059971938e-05*G0_2_9 + 1.847358990217e-05*G0_3_1 + 5.95172023743733e-05*G0_3_2 - 4.59064744779247e-05*G0_3_3 + 5.11393368536467e-05*G0_3_4 - 5.94643451786585e-06*G0_3_5 + 4.68579040007832e-05*G0_3_6 + 4.28143285286344e-06*G0_3_7 - 1.28442985585902e-05*G0_3_9 - 0.000122364408078752*G0_4_2 + 5.11393368536467e-05*G0_4_3 - 6.58864944579541e-05*G0_4_4 + 4.1149326863632e-05*G0_4_5 - 8.80072308644152e-05*G0_4_6 - 4.28143285286339e-06*G0_4_7 + 2.14071642643172e-05*G0_4_9 + 3.92200392200576e-05*G0_5_0 - 5.76143433286566e-06*G0_5_1 + 7.89686503972592e-05*G0_5_2 - 5.94643451786585e-06*G0_5_3 + 4.1149326863632e-05*G0_5_4 - 0.000241900956186785*G0_5_5 + 0.000106322249179442*G0_5_6 - 3.44893202036223e-05*G0_5_7 + 3.40136054421931e-05*G0_5_8 - 6.70757813615276e-05*G0_5_9 - 3.16614602329037e-05*G0_6_0 - 1.0042867185729e-05*G0_6_1 - 0.000177758749187404*G0_6_2 + 4.68579040007832e-05*G0_6_3 - 8.80072308644152e-05*G0_6_4 + 0.000106322249179442*G0_6_5 - 0.000221920936206755*G0_6_6 + 4.7571476142943e-07*G0_6_7 - 1.66500166500252e-06*G0_6_8 + 9.99000999001477e-06*G0_6_9 - 5.41786256072228e-06*G0_7_1 + 5.41786256072228e-06*G0_7_2 + 4.28143285286344e-06*G0_7_3 - 4.28143285286339e-06*G0_7_4 - 3.44893202036224e-05*G0_7_5 + 4.75714761429417e-07*G0_7_6 + 3.44893202036218e-05*G0_7_7 - 4.757147614292e-07*G0_7_8 + 1.58571587143116e-07*G0_8_0 + 1.09942967085876e-05*G0_8_1 + 3.40136054421931e-05*G0_8_5 - 1.66500166500252e-06*G0_8_6 - 4.757147614292e-07*G0_8_7 - 1.18928690357329e-06*G0_8_8 - 4.28143285286335e-06*G0_8_9 - 3.17143174286192e-07*G0_9_0 + 1.42714428428776e-06*G0_9_1 - 3.45686059971938e-05*G0_9_2 - 1.28442985585902e-05*G0_9_3 + 2.14071642643172e-05*G0_9_4 - 6.70757813615276e-05*G0_9_5 + 9.99000999001475e-06*G0_9_6 - 4.28143285286334e-06*G0_9_8 + 8.56286570572652e-06*G0_9_9; + A[42] = A[21] + 2.35155790711457e-05*G0_0_0 + 2.30985945271768e-05*G0_0_5 - 1.65443022585957e-05*G0_0_6 + 2.531859674718e-05*G0_0_7 + 5.33857676715073e-06*G0_0_8 + 1.77600177600261e-05*G0_0_9 + 8.61572290144124e-06*G0_1_3 + 1.0175010175015e-05*G0_1_5 - 9.14429485858481e-06*G0_1_7 + 1.36900136900201e-05*G0_1_8 + 3.61543218686247e-05*G0_1_9 - 3.53790829981474e-05*G0_2_2 + 1.63328734757384e-05*G0_2_3 - 1.82357325214555e-05*G0_2_4 + 5.8142915285809e-07*G0_2_5 - 3.54143211286243e-06*G0_2_6 - 3.92993250136291e-05*G0_2_7 + 1.2950012950019e-06*G0_2_8 - 4.31314717029205e-05*G0_2_9 + 8.61572290144124e-06*G0_3_1 + 1.63328734757384e-05*G0_3_2 + 1.92664478378855e-05*G0_3_3 - 4.49550449550661e-05*G0_3_4 - 1.45093002235928e-05*G0_3_5 - 9.27643784787076e-06*G0_3_7 - 8.99100899101323e-05*G0_3_9 - 1.82357325214555e-05*G0_4_2 - 4.49550449550661e-05*G0_4_3 + 7.92065077779736e-05*G0_4_4 - 1.66500166500252e-06*G0_4_5 + 1.47471576043075e-05*G0_4_6 + 6.35079206508076e-05*G0_4_7 - 9.2764378478708e-06*G0_4_8 + 0.000132724418438766*G0_4_9 + 2.30985945271768e-05*G0_5_0 + 1.0175010175015e-05*G0_5_1 + 5.8142915285809e-07*G0_5_2 - 1.45093002235928e-05*G0_5_3 - 1.66500166500252e-06*G0_5_4 + 0.000280909566623985*G0_5_5 - 5.94643451786613e-06*G0_5_6 - 7.65900765901123e-05*G0_5_7 - 3.59164644879101e-05*G0_5_8 + 1.85528756957421e-05*G0_5_9 - 1.65443022585957e-05*G0_6_0 - 3.54143211286243e-06*G0_6_2 + 1.47471576043075e-05*G0_6_4 - 5.94643451786613e-06*G0_6_5 - 4.44793301936367e-05*G0_6_6 + 0.000112506541078022*G0_6_7 - 3.09214594929023e-06*G0_6_8 + 0.000155558726987371*G0_6_9 + 2.531859674718e-05*G0_7_0 - 9.14429485858482e-06*G0_7_1 - 3.92993250136291e-05*G0_7_2 - 9.27643784787076e-06*G0_7_3 + 6.35079206508075e-05*G0_7_4 - 7.65900765901124e-05*G0_7_5 + 0.000112506541078022*G0_7_6 - 0.000390799676514145*G0_7_7 + 4.51929023357798e-06*G0_7_8 - 0.000278293135436123*G0_7_9 + 5.33857676715072e-06*G0_8_0 + 1.36900136900201e-05*G0_8_1 + 1.2950012950019e-06*G0_8_2 - 9.2764378478708e-06*G0_8_4 - 3.59164644879101e-05*G0_8_5 - 3.09214594929022e-06*G0_8_6 + 4.51929023357798e-06*G0_8_7 - 4.54307597164952e-05*G0_8_8 - 8.99100899101323e-05*G0_8_9 + 1.77600177600261e-05*G0_9_0 + 3.61543218686247e-05*G0_9_1 - 4.31314717029205e-05*G0_9_2 - 8.99100899101323e-05*G0_9_3 + 0.000132724418438766*G0_9_4 + 1.85528756957421e-05*G0_9_5 + 0.000155558726987371*G0_9_6 - 0.000278293135436123*G0_9_7 - 8.99100899101323e-05*G0_9_8 - 7.70657913515407e-05*G0_9_9; + A[182] = A[42]; + A[11] = A[165]; + A[51] = -A[21] - 2.28989117878115e-05*G0_0_0 + 8.34262739025035e-06*G0_0_2 + 1.9055019055028e-05*G0_0_3 - 3.49914635629087e-05*G0_0_5 + 3.11328882757601e-05*G0_0_6 - 3.49386063671943e-05*G0_0_7 + 2.5160025160037e-05*G0_0_8 + 9.19715205429919e-06*G0_0_9 + 3.19433652767136e-05*G0_1_1 + 1.40864426578778e-05*G0_1_2 + 4.60914746629246e-05*G0_1_3 - 8.85358028215595e-06*G0_1_5 - 1.99800199800294e-05*G0_1_7 + 3.12386026671887e-05*G0_1_8 + 1.74428745857399e-05*G0_1_9 + 8.34262739025035e-06*G0_2_0 + 1.40864426578778e-05*G0_2_1 + 6.49438744677146e-05*G0_2_2 - 1.09942967085877e-05*G0_2_3 + 7.87572216144016e-05*G0_2_4 - 3.96428967857727e-05*G0_2_5 + 8.62629434058412e-05*G0_2_6 - 1.45621574193072e-05*G0_2_7 + 5.26457669315059e-05*G0_2_9 + 1.9055019055028e-05*G0_3_0 + 4.60914746629246e-05*G0_3_1 - 1.09942967085877e-05*G0_3_2 + 0.000507825507825745*G0_3_3 - 0.000221445221445325*G0_3_4 + 4.51929023357821e-06*G0_3_5 - 7.39736454022517e-05*G0_3_6 - 9.68079539508564e-05*G0_3_7 + 0.000165073022215957*G0_3_8 + 0.000141287284144493*G0_3_9 + 7.87572216144016e-05*G0_4_2 - 0.000221445221445325*G0_4_3 + 0.000149612292469506*G0_4_4 - 5.11393368536466e-05*G0_4_5 + 0.000125112982255898*G0_4_6 + 3.59164644879099e-05*G0_4_7 - 6.82650682651002e-05*G0_4_8 - 5.56586270872244e-05*G0_4_9 - 3.49914635629087e-05*G0_5_0 - 8.85358028215595e-06*G0_5_1 - 3.96428967857727e-05*G0_5_2 + 4.51929023357822e-06*G0_5_3 - 5.11393368536466e-05*G0_5_4 + 0.000120593692022319*G0_5_5 - 9.49050949051392e-05*G0_5_6 + 9.03858046715574e-06*G0_5_7 - 1.30821559393046e-05*G0_5_8 - 1.42714428428826e-06*G0_5_9 + 3.11328882757601e-05*G0_6_0 + 8.62629434058412e-05*G0_6_2 - 7.39736454022517e-05*G0_6_3 + 0.000125112982255898*G0_6_4 - 9.49050949051392e-05*G0_6_5 + 0.000113457970600881*G0_6_6 + 4.04357547214899e-06*G0_6_7 - 1.16550116550172e-05*G0_6_8 - 9.99000999001435e-06*G0_6_9 - 3.49386063671943e-05*G0_7_0 - 1.99800199800294e-05*G0_7_1 - 1.45621574193072e-05*G0_7_2 - 9.68079539508564e-05*G0_7_3 + 3.59164644879099e-05*G0_7_4 + 9.03858046715574e-06*G0_7_5 + 4.04357547214898e-06*G0_7_6 - 2.14071642643234e-06*G0_7_7 - 4.21007563864902e-05*G0_7_8 - 3.56786071071956e-05*G0_7_9 + 2.5160025160037e-05*G0_8_0 + 3.12386026671887e-05*G0_8_1 + 0.000165073022215957*G0_8_3 - 6.82650682651002e-05*G0_8_4 - 1.30821559393046e-05*G0_8_5 - 1.16550116550172e-05*G0_8_6 - 4.21007563864902e-05*G0_8_7 + 9.77593834737148e-05*G0_8_8 + 8.42015127729809e-05*G0_8_9 + 9.19715205429919e-06*G0_9_0 + 1.74428745857399e-05*G0_9_1 + 5.26457669315059e-05*G0_9_2 + 0.000141287284144493*G0_9_3 - 5.56586270872244e-05*G0_9_4 - 1.42714428428826e-06*G0_9_5 - 9.99000999001438e-06*G0_9_6 - 3.56786071071956e-05*G0_9_7 + 8.42015127729809e-05*G0_9_8 + 5.99400599400884e-05*G0_9_9; + A[32] = 6.98449111147852e-06*G0_0_0 + 2.56228926863968e-06*G0_0_1 + 3.59208692542196e-05*G0_0_2 - 6.23219373219668e-06*G0_0_3 + 1.55862655862729e-05*G0_0_4 - 7.71219521219887e-06*G0_0_5 + 2.37840862840975e-05*G0_0_6 + 1.15790294361776e-06*G0_0_7 + 4.92562992563225e-06*G0_0_9 + 2.56228926863968e-06*G0_1_0 + 6.98449111147853e-06*G0_1_1 + 3.59208692542195e-05*G0_1_2 - 7.71219521219886e-06*G0_1_3 + 2.37840862840975e-05*G0_1_4 - 6.23219373219668e-06*G0_1_5 + 1.55862655862729e-05*G0_1_6 + 1.15790294361778e-06*G0_1_8 + 4.92562992563225e-06*G0_1_9 + 3.59208692542196e-05*G0_2_0 + 3.59208692542195e-05*G0_2_1 + 0.000999386416053553*G0_2_2 - 0.000157134532134606*G0_2_3 + 0.000332306582306739*G0_2_4 - 0.000157134532134607*G0_2_5 + 0.000332306582306739*G0_2_6 - 3.00625300625463e-06*G0_2_7 - 3.00625300625433e-06*G0_2_8 + 3.60750360750532e-05*G0_2_9 - 6.23219373219668e-06*G0_3_0 - 7.71219521219886e-06*G0_3_1 - 0.000157134532134606*G0_3_2 + 7.28438228438572e-05*G0_3_3 - 0.000123834498834557*G0_3_4 + 3.01781551781694e-05*G0_3_5 - 6.97219447219776e-05*G0_3_6 - 4.26656676656874e-06*G0_3_7 + 1.82109557109642e-05*G0_3_8 - 6.24375624375923e-06*G0_3_9 + 1.55862655862729e-05*G0_4_0 + 2.37840862840975e-05*G0_4_1 + 0.000332306582306739*G0_4_2 - 0.000123834498834557*G0_4_3 + 0.00027888777888791*G0_4_4 - 6.97219447219777e-05*G0_4_5 + 0.000139443889443955*G0_4_6 - 7.38844488844844e-06*G0_4_7 - 1.39443889443955e-05*G0_4_8 + 3.1218781218796e-05*G0_4_9 - 7.71219521219887e-06*G0_5_0 - 6.23219373219668e-06*G0_5_1 - 0.000157134532134607*G0_5_2 + 3.01781551781694e-05*G0_5_3 - 6.97219447219777e-05*G0_5_4 + 7.28438228438573e-05*G0_5_5 - 0.000123834498834557*G0_5_6 + 1.82109557109643e-05*G0_5_7 - 4.26656676656879e-06*G0_5_8 - 6.24375624375923e-06*G0_5_9 + 2.37840862840975e-05*G0_6_0 + 1.55862655862729e-05*G0_6_1 + 0.000332306582306739*G0_6_2 - 6.97219447219776e-05*G0_6_3 + 0.000139443889443955*G0_6_4 - 0.000123834498834557*G0_6_5 + 0.000278887778887911*G0_6_6 - 1.39443889443956e-05*G0_6_7 - 7.38844488844832e-06*G0_6_8 + 3.1218781218796e-05*G0_6_9 + 1.15790294361776e-06*G0_7_0 - 3.00625300625463e-06*G0_7_2 - 4.26656676656874e-06*G0_7_3 - 7.38844488844843e-06*G0_7_4 + 1.82109557109643e-05*G0_7_5 - 1.39443889443956e-05*G0_7_6 + 3.45785167213901e-05*G0_7_7 - 1.15806812235438e-05*G0_7_8 + 1.31118881118942e-05*G0_7_9 + 1.15790294361778e-06*G0_8_1 - 3.00625300625433e-06*G0_8_2 + 1.82109557109642e-05*G0_8_3 - 1.39443889443955e-05*G0_8_4 - 4.26656676656879e-06*G0_8_5 - 7.38844488844832e-06*G0_8_6 - 1.15806812235438e-05*G0_8_7 + 3.45785167213901e-05*G0_8_8 + 1.31118881118943e-05*G0_8_9 + 4.92562992563225e-06*G0_9_0 + 4.92562992563225e-06*G0_9_1 + 3.60750360750532e-05*G0_9_2 - 6.24375624375923e-06*G0_9_3 + 3.1218781218796e-05*G0_9_4 - 6.24375624375923e-06*G0_9_5 + 3.1218781218796e-05*G0_9_6 + 1.31118881118942e-05*G0_9_7 + 1.31118881118943e-05*G0_9_8 + 7.49250749251102e-05*G0_9_9; + A[142] = A[149] - 0.000397133730467249*G0_0_0 - 3.8409562219104e-05*G0_0_1 - 3.77047996095791e-05*G0_0_2 + 2.94943152086148e-05*G0_0_3 - 9.99000999001468e-05*G0_0_4 - 0.000366300366300537*G0_0_5 + 0.000136054421768771*G0_0_6 - 0.000410700410700603*G0_0_7 + 0.000224854510568902*G0_0_8 - 0.000232148803577484*G0_0_9 - 3.8409562219104e-05*G0_1_0 + 2.17419265038416e-05*G0_1_1 - 6.73048292096223e-06*G0_1_2 + 0.000112268683697308*G0_1_3 - 5.8037200894371e-05*G0_1_4 - 5.80372008943709e-05*G0_1_5 + 2.85428856857559e-06*G0_1_6 - 0.00011290297004588*G0_1_7 + 0.000143031571603067*G0_1_8 + 6.27943485086638e-05*G0_1_9 - 3.77047996095791e-05*G0_2_0 - 6.73048292096223e-06*G0_2_1 - 3.77400377400554e-05*G0_2_2 + 6.12086326372328e-05*G0_2_3 - 8.24572253144068e-05*G0_2_5 + 9.8314384028717e-06*G0_2_6 - 8.0871509442976e-05*G0_2_7 + 4.09114694829173e-05*G0_2_8 + 9.5142952285854e-06*G0_2_9 + 2.94943152086148e-05*G0_3_0 + 0.000112268683697308*G0_3_1 + 6.12086326372328e-05*G0_3_2 - 0.000142714428428781*G0_3_3 + 2.8542885685755e-06*G0_3_4 + 2.85428856857562e-06*G0_3_5 + 7.13572142143906e-05*G0_3_6 - 8.56286570572704e-06*G0_3_7 + 5.13771942343614e-05*G0_3_8 - 0.000171257314114537*G0_3_9 - 9.99000999001468e-05*G0_4_0 - 5.8037200894371e-05*G0_4_1 + 2.85428856857548e-06*G0_4_3 - 0.00103325246182437*G0_4_4 + 0.000379620379620558*G0_4_5 - 0.000450977593834948*G0_4_6 + 0.000231197374054626*G0_4_7 - 4.28143285286345e-05*G0_4_8 - 0.000787783644926872*G0_4_9 - 0.000366300366300537*G0_5_0 - 5.80372008943708e-05*G0_5_1 - 8.24572253144068e-05*G0_5_2 + 2.85428856857559e-06*G0_5_3 + 0.000379620379620558*G0_5_4 - 0.000842015127729806*G0_5_5 + 0.000536606250892217*G0_5_6 - 0.000576566290852275*G0_5_7 + 0.00025403168260323*G0_5_8 + 0.000188383045525991*G0_5_9 + 0.000136054421768771*G0_6_0 + 2.85428856857559e-06*G0_6_1 + 9.8314384028717e-06*G0_6_2 + 7.13572142143905e-05*G0_6_3 - 0.000450977593834948*G0_6_4 + 0.000536606250892217*G0_6_5 - 0.000422434708149192*G0_6_6 + 0.000322534608249045*G0_6_7 - 0.000105608677037298*G0_6_8 - 0.000171257314114537*G0_6_9 - 0.000410700410700603*G0_7_0 - 0.00011290297004588*G0_7_1 - 8.0871509442976e-05*G0_7_2 - 8.56286570572705e-06*G0_7_3 + 0.000231197374054626*G0_7_4 - 0.000576566290852275*G0_7_5 + 0.000322534608249045*G0_7_6 - 0.000522334808049338*G0_7_7 + 0.000205508776937445*G0_7_8 + 5.13771942343613e-05*G0_7_9 + 0.000224854510568902*G0_8_0 + 0.000143031571603067*G0_8_1 + 4.09114694829173e-05*G0_8_2 + 5.13771942343615e-05*G0_8_3 - 4.28143285286345e-05*G0_8_4 + 0.00025403168260323*G0_8_5 - 0.000105608677037298*G0_8_6 + 0.000205508776937444*G0_8_7 - 0.000171257314114537*G0_8_8 - 0.000102754388468723*G0_8_9 - 0.000232148803577484*G0_9_0 + 6.27943485086638e-05*G0_9_1 + 9.5142952285854e-06*G0_9_2 - 0.000171257314114537*G0_9_3 - 0.000787783644926872*G0_9_4 + 0.000188383045525991*G0_9_5 - 0.000171257314114537*G0_9_6 + 5.13771942343613e-05*G0_9_7 - 0.000102754388468723*G0_9_8 - 0.000924789496218502*G0_9_9; + A[94] = A[108] + 2.36800236800346e-05*G0_0_0 - 2.46666913333705e-06*G0_0_2 + 7.61143618286823e-06*G0_0_3 + 3.42514628229076e-05*G0_0_4 + 7.16743573886763e-05*G0_0_5 + 1.26857269714474e-05*G0_0_6 + 3.42514628229074e-05*G0_0_7 - 3.04457447314733e-05*G0_0_8 + 8.75315161029857e-05*G0_0_9 - 2.36800236800353e-05*G0_1_1 + 2.46666913333688e-06*G0_1_2 - 7.16743573886774e-05*G0_1_3 - 1.2685726971447e-05*G0_1_4 - 7.61143618286839e-06*G0_1_5 - 3.42514628229075e-05*G0_1_6 + 3.04457447314734e-05*G0_1_7 - 3.42514628229077e-05*G0_1_8 - 8.7531516102986e-05*G0_1_9 - 2.46666913333705e-06*G0_2_0 + 2.46666913333687e-06*G0_2_1 - 4.31314717029207e-05*G0_2_3 - 3.74228945657695e-05*G0_2_4 + 4.31314717029204e-05*G0_2_5 + 3.74228945657692e-05*G0_2_6 + 2.66400266400392e-05*G0_2_7 - 2.66400266400392e-05*G0_2_8 + 7.61143618286823e-06*G0_3_0 - 7.16743573886774e-05*G0_3_1 - 4.31314717029207e-05*G0_3_2 + 0.000182674468388836*G0_3_3 + 0.00026830312544611*G0_3_4 + 0.000102754388468723*G0_3_6 - 2.28343085486043e-05*G0_3_7 - 5.70857713715136e-05*G0_3_8 + 0.000308263165406167*G0_3_9 + 3.42514628229076e-05*G0_4_0 - 1.2685726971447e-05*G0_4_1 - 3.74228945657695e-05*G0_4_2 + 0.00026830312544611*G0_4_3 + 0.000251177394034654*G0_4_4 - 0.000102754388468722*G0_4_5 - 9.13372341944202e-05*G0_4_7 + 7.99200799201179e-05*G0_4_8 + 0.000205508776937445*G0_4_9 + 7.16743573886763e-05*G0_5_0 - 7.61143618286839e-06*G0_5_1 + 4.31314717029204e-05*G0_5_2 - 0.000102754388468722*G0_5_4 - 0.000182674468388842*G0_5_5 - 0.000268303125446108*G0_5_6 + 5.70857713715121e-05*G0_5_7 + 2.28343085486053e-05*G0_5_8 - 0.000308263165406168*G0_5_9 + 1.26857269714474e-05*G0_6_0 - 3.42514628229075e-05*G0_6_1 + 3.74228945657691e-05*G0_6_2 + 0.000102754388468723*G0_6_3 - 0.000268303125446108*G0_6_5 - 0.000251177394034655*G0_6_6 - 7.99200799201173e-05*G0_6_7 + 9.133723419442e-05*G0_6_8 - 0.000205508776937445*G0_6_9 + 3.42514628229074e-05*G0_7_0 + 3.04457447314734e-05*G0_7_1 + 2.66400266400392e-05*G0_7_2 - 2.28343085486044e-05*G0_7_3 - 9.13372341944202e-05*G0_7_4 + 5.7085771371512e-05*G0_7_5 - 7.99200799201172e-05*G0_7_6 + 6.85029256458145e-05*G0_7_7 - 0.000102754388468722*G0_7_9 - 3.04457447314733e-05*G0_8_0 - 3.42514628229077e-05*G0_8_1 - 2.66400266400392e-05*G0_8_2 - 5.70857713715136e-05*G0_8_3 + 7.99200799201179e-05*G0_8_4 + 2.28343085486053e-05*G0_8_5 + 9.133723419442e-05*G0_8_6 - 6.85029256458159e-05*G0_8_8 + 0.000102754388468722*G0_8_9 + 8.75315161029857e-05*G0_9_0 - 8.7531516102986e-05*G0_9_1 + 0.000308263165406167*G0_9_3 + 0.000205508776937445*G0_9_4 - 0.000308263165406168*G0_9_5 - 0.000205508776937445*G0_9_6 - 0.000102754388468722*G0_9_7 + 0.000102754388468722*G0_9_8; + A[106] = 3.32691999358822e-05*G0_0_0 + 7.50351940828486e-06*G0_0_1 + 8.45054416483385e-06*G0_0_2 - 9.85125985126449e-06*G0_0_3 + 6.79875679875999e-06*G0_0_4 + 5.44296972868657e-05*G0_0_5 + 4.33693290836351e-05*G0_0_7 - 2.28739514453908e-05*G0_0_8 + 3.21107463964758e-05*G0_0_9 + 7.50351940828486e-06*G0_1_0 + 5.30333863667493e-06*G0_1_1 + 7.50351940828487e-06*G0_1_2 + 3.33000333000512e-06*G0_1_3 + 5.4707197564365e-06*G0_1_4 - 7.47268604411815e-06*G0_1_5 - 7.47268604411817e-06*G0_1_6 + 5.47071975643653e-06*G0_1_7 + 3.3300033300051e-06*G0_1_8 - 7.61143618286834e-06*G0_1_9 + 8.45054416483385e-06*G0_2_0 + 7.50351940828487e-06*G0_2_1 + 3.32691999358823e-05*G0_2_2 - 2.28739514453908e-05*G0_2_3 + 4.33693290836352e-05*G0_2_4 + 5.44296972868657e-05*G0_2_6 + 6.79875679876e-06*G0_2_7 - 9.85125985126448e-06*G0_2_8 + 3.21107463964758e-05*G0_2_9 - 9.85125985126449e-06*G0_3_0 + 3.33000333000512e-06*G0_3_1 - 2.28739514453908e-05*G0_3_2 + 1.62337662337739e-05*G0_3_3 - 4.15655772798825e-05*G0_3_4 + 4.01384329955947e-05*G0_3_5 - 5.88697017268713e-06*G0_3_6 + 1.24875124875182e-06*G0_3_7 - 2.49750249750366e-06*G0_3_8 + 2.03368060511014e-05*G0_3_9 + 6.79875679875999e-06*G0_4_0 + 5.4707197564365e-06*G0_4_1 + 4.33693290836352e-05*G0_4_2 - 4.15655772798825e-05*G0_4_3 + 7.08220351077826e-05*G0_4_4 - 4.87012987013216e-05*G0_4_5 + 5.45882688740088e-05*G0_4_6 - 6.24375624375921e-06*G0_4_7 + 1.24875124875184e-06*G0_4_8 + 1.07035821321579e-06*G0_4_9 + 5.44296972868657e-05*G0_5_0 - 7.47268604411815e-06*G0_5_1 + 4.01384329955947e-05*G0_5_3 - 4.87012987013216e-05*G0_5_4 - 1.26659055230545e-05*G0_5_5 - 0.000166797488226138*G0_5_6 + 5.45882688740089e-05*G0_5_7 - 5.88697017268721e-06*G0_5_8 - 8.4558298844053e-05*G0_5_9 - 7.47268604411817e-06*G0_6_1 + 5.44296972868657e-05*G0_6_2 - 5.88697017268713e-06*G0_6_3 + 5.45882688740088e-05*G0_6_4 - 0.000166797488226138*G0_6_5 - 1.26659055230546e-05*G0_6_6 - 4.87012987013217e-05*G0_6_7 + 4.01384329955948e-05*G0_6_8 - 8.45582988440532e-05*G0_6_9 + 4.33693290836351e-05*G0_7_0 + 5.47071975643653e-06*G0_7_1 + 6.79875679876e-06*G0_7_2 + 1.24875124875182e-06*G0_7_3 - 6.24375624375922e-06*G0_7_4 + 5.45882688740089e-05*G0_7_5 - 4.87012987013217e-05*G0_7_6 + 7.0822035107783e-05*G0_7_7 - 4.15655772798826e-05*G0_7_8 + 1.07035821321603e-06*G0_7_9 - 2.28739514453908e-05*G0_8_0 + 3.3300033300051e-06*G0_8_1 - 9.85125985126448e-06*G0_8_2 - 2.49750249750366e-06*G0_8_3 + 1.24875124875185e-06*G0_8_4 - 5.88697017268721e-06*G0_8_5 + 4.01384329955948e-05*G0_8_6 - 4.15655772798826e-05*G0_8_7 + 1.62337662337739e-05*G0_8_8 + 2.03368060511013e-05*G0_8_9 + 3.21107463964758e-05*G0_9_0 - 7.61143618286834e-06*G0_9_1 + 3.21107463964758e-05*G0_9_2 + 2.03368060511014e-05*G0_9_3 + 1.07035821321579e-06*G0_9_4 - 8.4558298844053e-05*G0_9_5 - 8.45582988440531e-05*G0_9_6 + 1.07035821321603e-06*G0_9_7 + 2.03368060511013e-05*G0_9_8 - 0.000173398030540969*G0_9_9; + A[101] = -A[158] + 8.04134137467848e-05*G0_0_0 + 1.0031121142237e-05*G0_0_1 + 1.19809643619223e-05*G0_0_2 + 1.13114398828738e-05*G0_0_4 + 0.000119351547923032*G0_0_5 - 3.73171801743404e-05*G0_0_6 - 6.87143544286718e-06*G0_0_7 - 4.49286163572089e-05*G0_0_8 - 2.28343085486051e-05*G0_0_9 + 1.0031121142237e-05*G0_1_0 + 1.37311248422424e-05*G0_1_1 + 3.98190874381539e-06*G0_1_2 - 1.12057254914452e-05*G0_1_3 + 1.13114398828738e-05*G0_1_4 + 6.9665783951531e-05*G0_1_5 - 7.71715057429698e-06*G0_1_6 + 2.11428782857434e-07*G0_1_7 - 5.40200540200795e-05*G0_1_8 - 6.34286348572303e-07*G0_1_9 + 1.19809643619223e-05*G0_2_0 + 3.98190874381539e-06*G0_2_1 + 2.74505036409928e-05*G0_2_2 + 6.02572031143742e-05*G0_2_5 + 1.58571587143104e-06*G0_2_6 + 5.82486296772284e-05*G0_2_7 + 1.51171579743079e-05*G0_2_8 + 0.00010212010212015*G0_2_9 - 1.12057254914452e-05*G0_3_1 + 0.000157937300794518*G0_3_3 - 7.32600732601077e-05*G0_3_4 - 8.46772275344102e-05*G0_3_5 - 1.61743018885953e-05*G0_3_6 - 3.90086104372003e-05*G0_3_7 + 0.00012368583797161*G0_3_8 + 7.99200799201169e-05*G0_3_9 + 1.13114398828738e-05*G0_4_0 + 1.13114398828738e-05*G0_4_1 - 7.32600732601077e-05*G0_4_3 + 8.94343751487035e-05*G0_4_4 - 7.32600732601079e-05*G0_4_5 + 8.94343751487033e-05*G0_4_6 - 8.46772275344103e-05*G0_4_7 - 8.46772275344101e-05*G0_4_8 - 0.000159840159840235*G0_4_9 + 0.000119351547923032*G0_5_0 + 6.9665783951531e-05*G0_5_1 + 6.02572031143742e-05*G0_5_2 - 8.46772275344102e-05*G0_5_3 - 7.32600732601079e-05*G0_5_4 + 0.00139003853289633*G0_5_5 - 0.000382474668189134*G0_5_6 + 0.000462394748109251*G0_5_7 - 0.00024832310546608*G0_5_8 + 0.000565149136577974*G0_5_9 - 3.73171801743404e-05*G0_6_0 - 7.717150574297e-06*G0_6_1 + 1.58571587143104e-06*G0_6_2 - 1.61743018885953e-05*G0_6_3 + 8.94343751487033e-05*G0_6_4 - 0.000382474668189134*G0_6_5 + 0.000148423005565933*G0_6_6 - 0.000214071642643172*G0_6_7 + 8.5628657057269e-06*G0_6_8 - 0.00027401170258326*G0_6_9 - 6.87143544286718e-06*G0_7_0 + 2.11428782857434e-07*G0_7_1 + 5.82486296772284e-05*G0_7_2 - 3.90086104372003e-05*G0_7_3 - 8.46772275344103e-05*G0_7_4 + 0.000462394748109251*G0_7_5 - 0.000214071642643172*G0_7_6 + 0.000575614861329418*G0_7_7 + 7.61143618286834e-05*G0_7_8 + 0.000496646210932159*G0_7_9 - 4.49286163572089e-05*G0_8_0 - 5.40200540200795e-05*G0_8_1 + 1.51171579743079e-05*G0_8_2 + 0.00012368583797161*G0_8_3 - 8.46772275344101e-05*G0_8_4 - 0.00024832310546608*G0_8_5 + 8.5628657057269e-06*G0_8_6 + 7.61143618286834e-05*G0_8_7 + 0.000407211835783456*G0_8_8 + 0.000171257314114537*G0_8_9 - 2.28343085486051e-05*G0_9_0 - 6.34286348572289e-07*G0_9_1 + 0.00010212010212015*G0_9_2 + 7.99200799201169e-05*G0_9_3 - 0.000159840159840234*G0_9_4 + 0.000565149136577974*G0_9_5 - 0.00027401170258326*G0_9_6 + 0.000496646210932159*G0_9_7 + 0.000171257314114537*G0_9_8 + 0.000924789496218503*G0_9_9; + A[157] = A[101] + 0.000111863445196831*G0_0_0 + 1.34022356244641e-05*G0_0_1 + 8.98572327144172e-06*G0_0_2 - 2.26493083636048e-05*G0_0_3 - 7.42643599786807e-06*G0_0_4 + 0.000144115144115212*G0_0_5 - 4.98179069607875e-05*G0_0_6 + 0.000232915232915342*G0_0_7 - 8.53379424808397e-05*G0_0_8 + 0.0001170258313116*G0_0_9 + 1.34022356244641e-05*G0_1_0 - 3.00728078506e-05*G0_1_1 + 1.14523924047753e-07*G0_1_2 - 2.13014498728886e-05*G0_1_3 - 1.71785886071677e-06*G0_1_4 - 4.58007600864961e-05*G0_1_5 - 2.8357885500756e-05*G0_1_6 + 6.16314902029478e-05*G0_1_7 - 1.75750175750261e-05*G0_1_8 - 3.98014683729158e-05*G0_1_9 + 8.98572327144174e-06*G0_2_0 + 1.14523924047749e-07*G0_2_1 - 2.01121629693154e-05*G0_2_2 - 1.69407312264535e-05*G0_2_3 + 1.42714428428781e-05*G0_2_5 - 1.50643007785945e-06*G0_2_6 - 1.32142989285741e-07*G0_2_7 - 4.35807578664926e-05*G0_2_8 - 5.50243407386523e-05*G0_2_9 - 2.26493083636048e-05*G0_3_0 - 2.13014498728886e-05*G0_3_1 - 1.69407312264534e-05*G0_3_2 - 0.000205033062176017*G0_3_3 + 0.000131059416773764*G0_3_4 + 0.000108225108225159*G0_3_5 + 7.39736454022517e-05*G0_3_6 + 5.68479139907983e-05*G0_3_7 - 0.00017649017649026*G0_3_8 + 5.70857713715116e-06*G0_3_9 - 7.42643599786807e-06*G0_4_0 - 1.71785886071677e-06*G0_4_1 + 0.000131059416773764*G0_4_3 - 6.80272108843865e-05*G0_4_4 + 1.1179296893588e-05*G0_4_5 - 8.51529422958398e-05*G0_4_6 + 1.68878740307389e-05*G0_4_7 + 0.000119642262499462*G0_4_8 + 0.000142714428428781*G0_4_9 + 0.000144115144115212*G0_5_0 - 4.5800760086496e-05*G0_5_1 + 1.42714428428781e-05*G0_5_2 + 0.000108225108225159*G0_5_3 + 1.1179296893588e-05*G0_5_4 - 0.00117810760667959*G0_5_5 - 7.13572142143867e-06*G0_5_6 - 0.000115598687027313*G0_5_7 + 0.000126302269159472*G0_5_8 - 0.000603682032253745*G0_5_9 - 4.98179069607875e-05*G0_6_0 - 2.8357885500756e-05*G0_6_1 - 1.50643007785944e-06*G0_6_2 + 7.39736454022517e-05*G0_6_3 - 8.51529422958398e-05*G0_6_4 - 7.13572142143856e-06*G0_6_5 - 0.000208363065506021*G0_6_6 - 1.07035821321588e-05*G0_6_7 + 0.000113457970600881*G0_6_8 + 1.71257314114531e-05*G0_6_9 + 0.000232915232915342*G0_7_0 + 6.16314902029478e-05*G0_7_1 - 1.32142989285741e-07*G0_7_2 + 5.68479139907983e-05*G0_7_3 + 1.68878740307389e-05*G0_7_4 - 0.000115598687027313*G0_7_5 - 1.07035821321589e-05*G0_7_6 - 0.000112506541078021*G0_7_7 - 0.000197421625993147*G0_7_8 - 0.000329670329670484*G0_7_9 - 8.53379424808397e-05*G0_8_0 - 1.75750175750261e-05*G0_8_1 - 4.35807578664926e-05*G0_8_2 - 0.00017649017649026*G0_8_3 + 0.000119642262499462*G0_8_4 + 0.000126302269159472*G0_8_5 + 0.000113457970600881*G0_8_6 - 0.000197421625993147*G0_8_7 - 0.000284477427334704*G0_8_8 - 0.000119880119880176*G0_8_9 + 0.0001170258313116*G0_9_0 - 3.98014683729159e-05*G0_9_1 - 5.50243407386523e-05*G0_9_2 + 5.70857713715117e-06*G0_9_3 + 0.000142714428428781*G0_9_4 - 0.000603682032253745*G0_9_5 + 1.71257314114531e-05*G0_9_6 - 0.000329670329670484*G0_9_7 - 0.000119880119880176*G0_9_8 - 0.000950478093335684*G0_9_9; + A[187] = A[117]; + A[174] = A[101] + 0.000128266794933522*G0_0_0 + 6.65295903391455e-05*G0_0_1 + 3.61778139556093e-06*G0_0_2 + 6.72343529486703e-05*G0_0_3 - 3.80571809143417e-05*G0_0_4 - 8.88000888001297e-05*G0_0_5 + 1.14171542743022e-05*G0_0_6 + 0.000236800236800348*G0_0_7 + 1.73371601943112e-05*G0_0_8 + 4.82057624914996e-05*G0_0_9 + 6.65295903391454e-05*G0_1_0 + 0.000347635903191622*G0_1_1 + 2.65930424660709e-05*G0_1_2 + 0.000235531664103203*G0_1_3 - 0.000122205836491608*G0_1_4 - 4.44000444000653e-05*G0_1_5 - 7.61143618286835e-06*G0_1_6 - 0.000163223020365954*G0_1_7 + 0.00050150907293788*G0_1_8 + 8.11886526172622e-05*G0_1_9 + 3.61778139556093e-06*G0_2_0 + 2.65930424660709e-05*G0_2_1 - 1.83238278476463e-06*G0_2_2 + 6.59657802515256e-05*G0_2_3 - 3.55200355200523e-05*G0_2_4 - 4.86286200572142e-05*G0_2_5 - 5.49714835429392e-06*G0_2_6 - 3.29828901257626e-05*G0_2_7 + 6.34286348572361e-05*G0_2_8 + 7.61143618286838e-06*G0_2_9 + 6.72343529486703e-05*G0_3_0 + 0.000235531664103203*G0_3_1 + 6.59657802515256e-05*G0_3_2 + 0.000578469149897993*G0_3_3 - 0.000243565957851787*G0_3_4 - 4.566861709721e-05*G0_3_6 - 0.000270205984491826*G0_3_7 + 0.00052899481470935*G0_3_8 + 0.000296846011131865*G0_3_9 - 3.80571809143417e-05*G0_4_0 - 0.000122205836491608*G0_4_1 - 3.55200355200523e-05*G0_4_2 - 0.000243565957851787*G0_4_3 + 9.89486703772883e-05*G0_4_4 + 4.566861709721e-05*G0_4_5 + 0.000140811569383064*G0_4_7 - 0.000258788830217523*G0_4_8 - 0.000114171542743025*G0_4_9 - 8.88000888001297e-05*G0_5_0 - 4.44000444000653e-05*G0_5_1 - 4.86286200572142e-05*G0_5_2 + 4.566861709721e-05*G0_5_4 - 0.000970458113315711*G0_5_5 + 0.000262594548308957*G0_5_6 - 9.51429522858531e-05*G0_5_7 + 6.46972075543804e-05*G0_5_8 - 0.00027401170258326*G0_5_9 + 1.14171542743023e-05*G0_6_0 - 7.61143618286834e-06*G0_6_1 - 5.49714835429391e-06*G0_6_2 - 4.566861709721e-05*G0_6_3 + 0.000262594548308958*G0_6_5 - 4.56686170972097e-05*G0_6_6 + 3.04457447314728e-05*G0_6_7 - 4.9474335188644e-05*G0_6_8 + 6.85029256458147e-05*G0_6_9 + 0.000236800236800348*G0_7_0 - 0.000163223020365954*G0_7_1 - 3.29828901257627e-05*G0_7_2 - 0.000270205984491826*G0_7_3 + 0.000140811569383064*G0_7_4 - 9.51429522858532e-05*G0_7_5 + 3.04457447314728e-05*G0_7_6 + 0.000574663431806561*G0_7_7 - 0.00078397792683544*G0_7_8 - 0.000205508776937445*G0_7_9 + 1.73371601943112e-05*G0_8_0 + 0.00050150907293788*G0_8_1 + 6.34286348572361e-05*G0_8_2 + 0.00052899481470935*G0_8_3 - 0.000258788830217523*G0_8_4 + 6.46972075543804e-05*G0_8_5 - 4.9474335188644e-05*G0_8_6 - 0.00078397792683544*G0_8_7 + 0.000974263831407148*G0_8_8 + 0.00027401170258326*G0_8_9 + 4.82057624914996e-05*G0_9_0 + 8.11886526172622e-05*G0_9_1 + 7.61143618286838e-06*G0_9_2 + 0.000296846011131865*G0_9_3 - 0.000114171542743025*G0_9_4 - 0.00027401170258326*G0_9_5 + 6.85029256458147e-05*G0_9_6 - 0.000205508776937445*G0_9_7 + 0.00027401170258326*G0_9_8 + 0.00013700585129163*G0_9_9; + A[175] = -A[174] + 0.000104586771253487*G0_0_0 - 4.50813149226059e-05*G0_0_1 + 3.86444830889459e-06*G0_0_2 - 8.41486555772666e-05*G0_0_3 + 2.65343122486104e-05*G0_0_4 + 9.5248666677283e-05*G0_0_5 - 4.01714687429162e-05*G0_0_6 + 0.000347271775843368*G0_0_7 - 0.000244200244200359*G0_0_8 + 3.86914672629141e-05*G0_0_9 - 4.50813149226059e-05*G0_1_0 - 0.000458800458800675*G0_1_1 - 3.30651124302073e-05*G0_1_2 - 0.00029230029230043*G0_1_3 + 0.000150748722177364*G0_1_4 + 2.05085919371731e-05*G0_1_5 + 3.70000370000537e-06*G0_1_6 + 0.000356468927897667*G0_1_7 - 0.000743700743701093*G0_1_8 - 0.000113537256394452*G0_1_9 + 3.86444830889459e-06*G0_2_0 - 3.30651124302073e-05*G0_2_1 - 9.23239018477546e-06*G0_2_2 - 7.11457854315332e-05*G0_2_3 + 4.08057550914885e-05*G0_2_4 + 8.77429448858433e-06*G0_2_5 + 1.41657284514494e-05*G0_2_6 + 2.33628805057487e-05*G0_2_7 - 8.70029441458422e-05*G0_2_8 - 5.20114805829337e-05*G0_2_9 - 8.41486555772666e-05*G0_3_0 - 0.000292300292300429*G0_3_1 - 7.11457854315332e-05*G0_3_2 - 0.000645069216498091*G0_3_3 + 0.000288283145426138*G0_3_4 + 6.37457780315224e-05*G0_3_5 + 5.23286237572197e-05*G0_3_6 + 0.000315874601589036*G0_3_7 - 0.000640312068883798*G0_3_8 - 0.000291137433994714*G0_3_9 + 2.65343122486104e-05*G0_4_0 + 0.000150748722177364*G0_4_1 + 4.08057550914886e-05*G0_4_2 + 0.000288283145426138*G0_4_3 - 0.000148423005565932*G0_4_4 - 1.61743018885953e-05*G0_4_5 - 3.61543218686246e-05*G0_4_6 - 0.000106560106560157*G0_4_7 + 0.000324437467294763*G0_4_8 + 0.000188383045525991*G0_4_9 + 9.5248666677283e-05*G0_5_0 + 2.05085919371731e-05*G0_5_1 + 8.77429448858433e-06*G0_5_2 + 6.37457780315224e-05*G0_5_3 - 1.61743018885953e-05*G0_5_4 - 8.56286570572682e-05*G0_5_5 - 4.28143285286344e-05*G0_5_6 + 4.75714761429306e-06*G0_5_7 + 1.90285904571707e-06*G0_5_8 - 0.000119880119880176*G0_5_9 - 4.01714687429162e-05*G0_6_0 + 3.70000370000537e-06*G0_6_1 + 1.41657284514494e-05*G0_6_2 + 5.23286237572198e-05*G0_6_3 - 3.61543218686246e-05*G0_6_4 - 4.28143285286345e-05*G0_6_5 - 3.42514628229074e-05*G0_6_6 - 6.66000666000997e-06*G0_6_7 + 9.32400932401372e-05*G0_6_8 + 5.13771942343614e-05*G0_6_9 + 0.000347271775843368*G0_7_0 + 0.000356468927897667*G0_7_1 + 2.33628805057487e-05*G0_7_2 + 0.000315874601589036*G0_7_3 - 0.000106560106560157*G0_7_4 + 4.75714761429295e-06*G0_7_5 - 6.66000666000997e-06*G0_7_6 - 0.000696446410732453*G0_7_7 + 0.00041672613101204*G0_7_8 - 0.000102754388468722*G0_7_9 - 0.000244200244200359*G0_8_0 - 0.000743700743701093*G0_8_1 - 8.70029441458422e-05*G0_8_2 - 0.000640312068883799*G0_8_3 + 0.000324437467294763*G0_8_4 + 1.90285904571707e-06*G0_8_5 + 9.32400932401372e-05*G0_8_6 + 0.00041672613101204*G0_8_7 - 0.000764949336378269*G0_8_8 - 0.000308263165406168*G0_8_9 + 3.86914672629141e-05*G0_9_0 - 0.000113537256394452*G0_9_1 - 5.20114805829337e-05*G0_9_2 - 0.000291137433994714*G0_9_3 + 0.000188383045525992*G0_9_4 - 0.000119880119880176*G0_9_5 + 5.13771942343614e-05*G0_9_6 - 0.000102754388468722*G0_9_7 - 0.000308263165406168*G0_9_8 - 0.000685029256458151*G0_9_9; + A[159] = -A[174] - 0.000458800458800674*G0_0_0 - 4.50813149226059e-05*G0_0_1 - 3.30651124302073e-05*G0_0_2 + 2.0508591937173e-05*G0_0_3 + 3.70000370000538e-06*G0_0_4 - 0.000292300292300429*G0_0_5 + 0.000150748722177365*G0_0_6 - 0.000743700743701093*G0_0_7 + 0.000356468927897667*G0_0_8 - 0.000113537256394453*G0_0_9 - 4.50813149226059e-05*G0_1_0 + 0.000104586771253487*G0_1_1 + 3.86444830889459e-06*G0_1_2 + 9.52486666772829e-05*G0_1_3 - 4.01714687429163e-05*G0_1_4 - 8.41486555772667e-05*G0_1_5 + 2.65343122486105e-05*G0_1_6 - 0.000244200244200359*G0_1_7 + 0.000347271775843368*G0_1_8 + 3.8691467262914e-05*G0_1_9 - 3.30651124302073e-05*G0_2_0 + 3.86444830889459e-06*G0_2_1 - 9.23239018477548e-06*G0_2_2 + 8.77429448858434e-06*G0_2_3 + 1.41657284514494e-05*G0_2_4 - 7.11457854315332e-05*G0_2_5 + 4.08057550914886e-05*G0_2_6 - 8.70029441458424e-05*G0_2_7 + 2.33628805057486e-05*G0_2_8 - 5.20114805829337e-05*G0_2_9 + 2.0508591937173e-05*G0_3_0 + 9.52486666772829e-05*G0_3_1 + 8.77429448858434e-06*G0_3_2 - 8.56286570572685e-05*G0_3_3 - 4.28143285286344e-05*G0_3_4 + 6.37457780315224e-05*G0_3_5 - 1.61743018885953e-05*G0_3_6 + 1.90285904571713e-06*G0_3_7 + 4.75714761429295e-06*G0_3_8 - 0.000119880119880176*G0_3_9 + 3.70000370000539e-06*G0_4_0 - 4.01714687429163e-05*G0_4_1 + 1.41657284514494e-05*G0_4_2 - 4.28143285286343e-05*G0_4_3 - 3.42514628229074e-05*G0_4_4 + 5.23286237572198e-05*G0_4_5 - 3.61543218686246e-05*G0_4_6 + 9.32400932401372e-05*G0_4_7 - 6.6600066600097e-06*G0_4_8 + 5.13771942343615e-05*G0_4_9 - 0.000292300292300429*G0_5_0 - 8.41486555772667e-05*G0_5_1 - 7.11457854315332e-05*G0_5_2 + 6.37457780315224e-05*G0_5_3 + 5.23286237572198e-05*G0_5_4 - 0.000645069216498091*G0_5_5 + 0.000288283145426138*G0_5_6 - 0.000640312068883798*G0_5_7 + 0.000315874601589035*G0_5_8 - 0.000291137433994714*G0_5_9 + 0.000150748722177364*G0_6_0 + 2.65343122486105e-05*G0_6_1 + 4.08057550914886e-05*G0_6_2 - 1.61743018885953e-05*G0_6_3 - 3.61543218686246e-05*G0_6_4 + 0.000288283145426138*G0_6_5 - 0.000148423005565933*G0_6_6 + 0.000324437467294763*G0_6_7 - 0.000106560106560157*G0_6_8 + 0.000188383045525992*G0_6_9 - 0.000743700743701093*G0_7_0 - 0.000244200244200359*G0_7_1 - 8.70029441458424e-05*G0_7_2 + 1.90285904571718e-06*G0_7_3 + 9.32400932401372e-05*G0_7_4 - 0.000640312068883798*G0_7_5 + 0.000324437467294763*G0_7_6 - 0.000764949336378272*G0_7_7 + 0.000416726131012042*G0_7_8 - 0.000308263165406169*G0_7_9 + 0.000356468927897667*G0_8_0 + 0.000347271775843368*G0_8_1 + 2.33628805057486e-05*G0_8_2 + 4.75714761429284e-06*G0_8_3 - 6.6600066600097e-06*G0_8_4 + 0.000315874601589035*G0_8_5 - 0.000106560106560157*G0_8_6 + 0.000416726131012042*G0_8_7 - 0.000696446410732453*G0_8_8 - 0.000102754388468723*G0_8_9 - 0.000113537256394453*G0_9_0 + 3.8691467262914e-05*G0_9_1 - 5.20114805829337e-05*G0_9_2 - 0.000119880119880176*G0_9_3 + 5.13771942343615e-05*G0_9_4 - 0.000291137433994714*G0_9_5 + 0.000188383045525992*G0_9_6 - 0.000308263165406169*G0_9_7 - 0.000102754388468722*G0_9_8 - 0.000685029256458152*G0_9_9; + A[5] = -A[32] + 3.01036412147666e-05*G0_0_2 - 8.06732949590472e-06*G0_0_4 + 7.45781995782345e-06*G0_0_5 + 4.22692386978303e-06*G0_0_6 + 1.29979147836351e-05*G0_0_7 - 5.54009482581172e-06*G0_0_9 - 1.06698122571189e-05*G0_1_1 + 2.65034788844438e-05*G0_1_2 - 2.0820779749361e-05*G0_1_3 + 6.55264048121497e-06*G0_1_4 + 1.4469657326807e-06*G0_1_6 + 1.0444251515685e-05*G0_1_7 - 1.9456403384984e-05*G0_1_8 - 1.85429649715451e-05*G0_1_9 + 3.01036412147666e-05*G0_2_0 + 2.65034788844438e-05*G0_2_1 + 0.000949847477625703*G0_2_2 - 0.000131075934647425*G0_2_3 + 0.000263063655920923*G0_2_4 - 0.000131551649408855*G0_2_5 + 0.000281299388442379*G0_2_6 + 1.73635887921685e-05*G0_2_9 - 2.0820779749361e-05*G0_3_1 - 0.000131075934647425*G0_3_2 + 7.43304314733235e-06*G0_3_3 + 2.48263641120901e-05*G0_3_4 - 8.11688311688695e-06*G0_3_5 - 9.8116169544784e-07*G0_3_6 - 1.65162218733726e-05*G0_3_8 + 5.22691594120412e-05*G0_3_9 - 8.06732949590472e-06*G0_4_0 + 6.55264048121497e-06*G0_4_1 + 0.000263063655920923*G0_4_2 + 2.48263641120901e-05*G0_4_3 - 0.000133319061890553*G0_4_4 + 2.75617239903083e-05*G0_4_5 - 2.65805622948605e-05*G0_4_6 + 8.5479996194322e-06*G0_4_7 + 1.48363541220755e-05*G0_4_8 - 0.000107214214357122*G0_4_9 + 7.45781995782345e-06*G0_5_0 - 0.000131551649408855*G0_5_2 - 8.11688311688694e-06*G0_5_3 + 2.75617239903083e-05*G0_5_4 + 4.12087912088106e-05*G0_5_5 - 5.55694305694568e-05*G0_5_6 + 8.22094572094959e-06*G0_5_7 + 3.22891394320118e-05*G0_5_9 + 4.22692386978303e-06*G0_6_0 + 1.4469657326807e-06*G0_6_1 + 0.000281299388442379*G0_6_2 - 9.8116169544784e-07*G0_6_3 - 2.65805622948606e-05*G0_6_4 - 5.55694305694568e-05*G0_6_5 + 0.000147352647352717*G0_6_6 - 3.86518243661324e-07*G0_6_7 - 5.01284429856094e-05*G0_6_9 + 1.29979147836351e-05*G0_7_0 + 1.0444251515685e-05*G0_7_1 + 8.5479996194322e-06*G0_7_4 + 8.22094572094959e-06*G0_7_5 - 3.86518243661326e-07*G0_7_6 + 9.60349174635333e-06*G0_7_7 + 1.05400551829173e-05*G0_7_8 + 1.73933209647577e-05*G0_7_9 - 1.9456403384984e-05*G0_8_1 - 1.65162218733726e-05*G0_8_3 + 1.48363541220755e-05*G0_8_4 + 1.05400551829173e-05*G0_8_7 + 5.32205889348978e-06*G0_8_8 + 2.59561866704845e-05*G0_8_9 - 5.54009482581172e-06*G0_9_0 - 1.85429649715451e-05*G0_9_1 + 1.73635887921685e-05*G0_9_2 + 5.22691594120412e-05*G0_9_3 - 0.000107214214357122*G0_9_4 + 3.22891394320118e-05*G0_9_5 - 5.01284429856094e-05*G0_9_6 + 1.73933209647577e-05*G0_9_7 + 2.59561866704845e-05*G0_9_8 - 2.14071642643179e-06*G0_9_9; + A[211] = A[5] + 1.0175010175015e-05*G0_0_4 + 1.36900136900201e-05*G0_0_5 - 9.14429485858487e-06*G0_0_6 + 8.61572290144126e-06*G0_0_7 + 3.61543218686246e-05*G0_0_9 - 3.53790829981471e-05*G0_1_1 - 3.54143211286233e-06*G0_1_3 + 5.81429152858016e-07*G0_1_4 + 1.29500129500191e-06*G0_1_5 - 3.92993250136292e-05*G0_1_6 + 1.63328734757383e-05*G0_1_7 - 1.82357325214553e-05*G0_1_8 - 4.31314717029205e-05*G0_1_9 + 2.35155790711458e-05*G0_2_2 - 1.65443022585958e-05*G0_2_3 + 2.3098594527177e-05*G0_2_4 + 5.33857676715069e-06*G0_2_5 + 2.53185967471801e-05*G0_2_6 + 1.77600177600261e-05*G0_2_9 - 3.54143211286234e-06*G0_3_1 - 1.65443022585958e-05*G0_3_2 - 4.44793301936367e-05*G0_3_3 - 5.94643451786602e-06*G0_3_4 - 3.09214594929025e-06*G0_3_5 + 0.000112506541078022*G0_3_6 + 1.47471576043074e-05*G0_3_8 + 0.000155558726987371*G0_3_9 + 1.0175010175015e-05*G0_4_0 + 5.81429152858016e-07*G0_4_1 + 2.3098594527177e-05*G0_4_2 - 5.946434517866e-06*G0_4_3 + 0.000280909566623985*G0_4_4 - 3.591646448791e-05*G0_4_5 - 7.65900765901123e-05*G0_4_6 - 1.45093002235928e-05*G0_4_7 - 1.66500166500243e-06*G0_4_8 + 1.85528756957416e-05*G0_4_9 + 1.36900136900201e-05*G0_5_0 + 1.29500129500191e-06*G0_5_1 + 5.3385767671507e-06*G0_5_2 - 3.09214594929026e-06*G0_5_3 - 3.591646448791e-05*G0_5_4 - 4.54307597164952e-05*G0_5_5 + 4.51929023357802e-06*G0_5_6 - 9.27643784787083e-06*G0_5_8 - 8.99100899101322e-05*G0_5_9 - 9.14429485858487e-06*G0_6_0 - 3.92993250136292e-05*G0_6_1 + 2.53185967471801e-05*G0_6_2 + 0.000112506541078022*G0_6_3 - 7.65900765901123e-05*G0_6_4 + 4.51929023357802e-06*G0_6_5 - 0.000390799676514146*G0_6_6 - 9.27643784787081e-06*G0_6_7 + 6.35079206508076e-05*G0_6_8 - 0.000278293135436123*G0_6_9 + 8.61572290144126e-06*G0_7_0 + 1.63328734757383e-05*G0_7_1 - 1.45093002235928e-05*G0_7_4 - 9.27643784787081e-06*G0_7_6 + 1.92664478378858e-05*G0_7_7 - 4.49550449550662e-05*G0_7_8 - 8.9910089910132e-05*G0_7_9 - 1.82357325214553e-05*G0_8_1 + 1.47471576043074e-05*G0_8_3 - 1.66500166500243e-06*G0_8_4 - 9.27643784787083e-06*G0_8_5 + 6.35079206508076e-05*G0_8_6 - 4.49550449550662e-05*G0_8_7 + 7.92065077779737e-05*G0_8_8 + 0.000132724418438766*G0_8_9 + 3.61543218686246e-05*G0_9_0 - 4.31314717029205e-05*G0_9_1 + 1.77600177600261e-05*G0_9_2 + 0.000155558726987371*G0_9_3 + 1.85528756957416e-05*G0_9_4 - 8.99100899101322e-05*G0_9_5 - 0.000278293135436123*G0_9_6 - 8.9910089910132e-05*G0_9_7 + 0.000132724418438766*G0_9_8 - 7.70657913515415e-05*G0_9_9; + A[76] = A[5] + 1.00428671857291e-05*G0_0_3 + 5.76143433286563e-06*G0_0_4 - 1.09942967085876e-05*G0_0_5 + 5.41786256072226e-06*G0_0_6 - 1.847358990217e-05*G0_0_7 - 1.4271442842878e-06*G0_0_9 + 0.000228554514268907*G0_1_1 + 0.000177758749187404*G0_1_3 - 7.89686503972589e-05*G0_1_4 - 5.41786256072224e-06*G0_1_6 - 5.95172023743733e-05*G0_1_7 + 0.000122364408078751*G0_1_8 + 3.45686059971937e-05*G0_1_9 - 1.80066846733598e-05*G0_2_2 + 3.16614602329037e-05*G0_2_3 - 3.92200392200575e-05*G0_2_4 - 1.5857158714311e-07*G0_2_5 + 3.17143174286206e-07*G0_2_9 + 1.00428671857291e-05*G0_3_0 + 0.000177758749187404*G0_3_1 + 3.16614602329037e-05*G0_3_2 + 0.000221920936206755*G0_3_3 - 0.000106322249179442*G0_3_4 + 1.66500166500248e-06*G0_3_5 - 4.7571476142939e-07*G0_3_6 - 4.68579040007832e-05*G0_3_7 + 8.80072308644152e-05*G0_3_8 - 9.99000999001471e-06*G0_3_9 + 5.76143433286563e-06*G0_4_0 - 7.89686503972589e-05*G0_4_1 - 3.92200392200576e-05*G0_4_2 - 0.000106322249179442*G0_4_3 + 0.000241900956186785*G0_4_4 - 3.40136054421929e-05*G0_4_5 + 3.44893202036223e-05*G0_4_6 + 5.94643451786591e-06*G0_4_7 - 4.1149326863632e-05*G0_4_8 + 6.70757813615272e-05*G0_4_9 - 1.09942967085876e-05*G0_5_0 - 1.5857158714311e-07*G0_5_2 + 1.66500166500248e-06*G0_5_3 - 3.40136054421929e-05*G0_5_4 + 1.18928690357324e-06*G0_5_5 + 4.75714761429187e-07*G0_5_6 + 4.28143285286342e-06*G0_5_9 + 5.41786256072226e-06*G0_6_0 - 5.41786256072224e-06*G0_6_1 - 4.7571476142939e-07*G0_6_3 + 3.44893202036223e-05*G0_6_4 + 4.75714761429173e-07*G0_6_5 - 3.44893202036219e-05*G0_6_6 - 4.28143285286343e-06*G0_6_7 + 4.28143285286339e-06*G0_6_8 - 1.847358990217e-05*G0_7_0 - 5.95172023743733e-05*G0_7_1 - 4.68579040007832e-05*G0_7_3 + 5.9464345178659e-06*G0_7_4 - 4.28143285286343e-06*G0_7_6 + 4.59064744779247e-05*G0_7_7 - 5.11393368536467e-05*G0_7_8 + 1.28442985585902e-05*G0_7_9 + 0.000122364408078751*G0_8_1 + 8.80072308644152e-05*G0_8_3 - 4.1149326863632e-05*G0_8_4 + 4.28143285286339e-06*G0_8_6 - 5.11393368536467e-05*G0_8_7 + 6.58864944579543e-05*G0_8_8 - 2.1407164264317e-05*G0_8_9 - 1.4271442842878e-06*G0_9_0 + 3.45686059971937e-05*G0_9_1 + 3.17143174286206e-07*G0_9_2 - 9.9900099900147e-06*G0_9_3 + 6.70757813615272e-05*G0_9_4 + 4.28143285286342e-06*G0_9_5 + 1.28442985585902e-05*G0_9_7 - 2.1407164264317e-05*G0_9_8 - 8.56286570572674e-06*G0_9_9; + A[212] = A[76] + 2.22910540370963e-05*G0_0_2 - 1.13642970785883e-06*G0_0_3 - 6.60714946429536e-07*G0_0_4 + 2.72214557928971e-06*G0_0_6 - 1.56985871271659e-05*G0_0_9 - 0.000201755916041725*G0_1_1 + 1.02542959685865e-05*G0_1_2 - 0.00015941730227452*G0_1_3 + 8.47829419258389e-05*G0_1_4 + 1.13114398828738e-05*G0_1_5 + 1.00428671857291e-06*G0_1_6 + 5.36500536500789e-05*G0_1_7 - 0.000103335817621581*G0_1_8 - 3.8691467262914e-05*G0_1_9 + 2.22910540370963e-05*G0_2_0 + 1.02542959685865e-05*G0_2_1 + 0.000226645782201444*G0_2_2 - 0.000118770118770175*G0_2_3 + 0.000247213104356078*G0_2_4 - 8.64743721886986e-05*G0_2_5 + 0.000189757332614565*G0_2_6 + 8.49943707086963e-05*G0_2_9 - 1.13642970785883e-06*G0_3_0 - 0.00015941730227452*G0_3_1 - 0.000118770118770175*G0_3_2 - 7.08814994529613e-05*G0_3_3 - 4.23386137672052e-05*G0_3_4 - 7.61143618286833e-06*G0_3_5 - 1.83150183150269e-05*G0_3_6 - 1.18928690357317e-05*G0_3_7 + 3.52028923457659e-05*G0_3_8 + 0.000139860139860205*G0_3_9 - 6.6071494642954e-07*G0_4_0 + 8.47829419258389e-05*G0_4_1 + 0.000247213104356078*G0_4_2 - 4.23386137672051e-05*G0_4_3 + 2.04557347414586e-05*G0_4_4 - 1.33200133200196e-05*G0_4_5 + 3.16350316350465e-05*G0_4_6 - 6.18429189858057e-06*G0_4_7 - 2.33100233100342e-05*G0_4_8 - 0.00022834308548605*G0_4_9 + 1.13114398828738e-05*G0_5_1 - 8.64743721886986e-05*G0_5_2 - 7.61143618286832e-06*G0_5_3 - 1.33200133200196e-05*G0_5_4 + 0.000116074401788742*G0_5_5 - 6.87407830265296e-05*G0_5_6 + 9.41915227629955e-05*G0_5_7 - 4.92364778079295e-05*G0_5_8 + 0.000145568716997357*G0_5_9 + 2.72214557928971e-06*G0_6_0 + 1.00428671857292e-06*G0_6_1 + 0.000189757332614565*G0_6_2 - 1.83150183150269e-05*G0_6_3 + 3.16350316350465e-05*G0_6_4 - 6.87407830265296e-05*G0_6_5 + 1.61743018885951e-05*G0_6_6 - 4.49550449550661e-05*G0_6_7 + 2.14071642643175e-06*G0_6_8 - 0.000218353075496035*G0_6_9 + 5.36500536500789e-05*G0_7_1 - 1.18928690357317e-05*G0_7_3 - 6.18429189858057e-06*G0_7_4 + 9.41915227629955e-05*G0_7_5 - 4.49550449550661e-05*G0_7_6 + 0.000210265924551737*G0_7_7 - 3.5202892345766e-05*G0_7_8 + 0.00013700585129163*G0_7_9 - 0.000103335817621581*G0_8_1 + 3.52028923457658e-05*G0_8_3 - 2.33100233100342e-05*G0_8_4 - 4.92364778079295e-05*G0_8_5 + 2.14071642643174e-06*G0_8_6 - 3.5202892345766e-05*G0_8_7 + 0.000194567337424572*G0_8_8 + 0.00016269444840881*G0_8_9 - 1.56985871271659e-05*G0_9_0 - 3.8691467262914e-05*G0_9_1 + 8.49943707086963e-05*G0_9_2 + 0.000139860139860205*G0_9_3 - 0.00022834308548605*G0_9_4 + 0.000145568716997357*G0_9_5 - 0.000218353075496035*G0_9_6 + 0.00013700585129163*G0_9_7 + 0.00016269444840881*G0_9_8 + 0.00054802340516652*G0_9_9; + A[20] = A[76]; + A[61] = -A[76] - 1.37957280814489e-05*G0_0_1 - 8.71483014340567e-06*G0_0_3 + 7.57840043554687e-06*G0_0_4 + 2.70893128036111e-07*G0_0_6 - 6.9308997880459e-06*G0_0_8 - 3.56786071071946e-07*G0_0_9 - 1.37957280814489e-05*G0_1_0 - 0.000263625263625388*G0_1_1 - 2.36359760169395e-05*G0_1_2 - 0.000193325193325284*G0_1_3 + 7.86250786251155e-05*G0_1_4 + 4.30786145072062e-06*G0_1_6 + 5.45750545750803e-05*G0_1_7 - 0.000111925111925165*G0_1_8 - 2.22000222000327e-05*G0_1_9 - 2.36359760169395e-05*G0_2_1 - 2.41630797186467e-05*G0_2_2 - 4.83643340786424e-06*G0_2_3 - 4.26953998382771e-05*G0_2_4 + 7.78322206894004e-06*G0_2_5 - 1.78657321514548e-05*G0_2_6 - 5.74161288447275e-06*G0_2_8 - 1.81564467278839e-05*G0_2_9 - 8.71483014340567e-06*G0_3_0 - 0.000193325193325284*G0_3_1 - 4.83643340786425e-06*G0_3_2 - 0.000330502830502986*G0_3_3 + 0.00015472622615487*G0_3_4 - 7.01679273108174e-06*G0_3_5 + 7.43304314733235e-06*G0_3_6 + 4.65011179297113e-05*G0_3_7 - 8.40825840826237e-05*G0_3_8 - 2.64021692593245e-05*G0_3_9 + 7.57840043554687e-06*G0_4_0 + 7.86250786251155e-05*G0_4_1 - 4.26953998382771e-05*G0_4_2 + 0.00015472622615487*G0_4_3 + 1.16550116550176e-05*G0_4_4 - 2.37857380714641e-06*G0_4_5 - 5.05446934018602e-06*G0_4_6 - 3.09214594929027e-05*G0_4_7 + 3.75814661529125e-05*G0_4_8 + 5.92264877979443e-05*G0_4_9 + 7.78322206894004e-06*G0_5_2 - 7.01679273108174e-06*G0_5_3 - 2.37857380714641e-06*G0_5_4 + 6.66000666000984e-06*G0_5_5 + 1.43309071880568e-05*G0_5_6 + 2.70893128036113e-07*G0_6_0 + 4.30786145072062e-06*G0_6_1 - 1.78657321514548e-05*G0_6_2 + 7.43304314733233e-06*G0_6_3 - 5.05446934018602e-06*G0_6_4 + 1.43309071880568e-05*G0_6_5 + 2.8423956995399e-05*G0_6_6 - 8.02768659911895e-06*G0_6_8 + 3.96032538889869e-05*G0_6_9 + 5.45750545750803e-05*G0_7_1 + 4.65011179297113e-05*G0_7_3 - 3.09214594929027e-05*G0_7_4 - 2.18828790257465e-05*G0_7_7 + 4.59064744779247e-05*G0_7_8 - 2.14071642643175e-06*G0_7_9 - 6.9308997880459e-06*G0_8_0 - 0.000111925111925165*G0_8_1 - 5.74161288447274e-06*G0_8_2 - 8.40825840826237e-05*G0_8_3 + 3.75814661529125e-05*G0_8_4 - 8.02768659911894e-06*G0_8_6 + 4.59064744779247e-05*G0_8_7 - 7.57575757576115e-05*G0_8_8 - 3.56786071071948e-07*G0_9_0 - 2.22000222000327e-05*G0_9_1 - 1.81564467278839e-05*G0_9_2 - 2.64021692593245e-05*G0_9_3 + 5.92264877979443e-05*G0_9_4 + 3.96032538889869e-05*G0_9_6 - 2.14071642643175e-06*G0_9_7 + 0.000132724418438767*G0_9_9; + A[139] = A[61] + 1.06991773658492e-05*G0_0_0 - 2.53714539428941e-06*G0_0_1 - 1.21901907616251e-05*G0_0_2 + 1.82555539698484e-05*G0_0_3 + 2.05151990866373e-05*G0_0_4 - 1.78987678987763e-05*G0_0_6 + 2.50344893202154e-05*G0_0_7 - 3.72841444270191e-05*G0_0_8 + 1.70068027210965e-05*G0_0_9 - 2.53714539428941e-06*G0_1_0 + 0.000308271974938787*G0_1_1 + 7.14453095405814e-06*G0_1_2 + 9.95036709322892e-05*G0_1_3 - 0.000106005106005156*G0_1_4 + 2.47371675943221e-05*G0_1_5 - 2.35478806907489e-05*G0_1_6 + 9.27643784787063e-06*G0_1_7 - 7.37357880215339e-06*G0_1_8 - 8.0871509442976e-05*G0_1_9 - 1.21901907616251e-05*G0_2_0 + 7.14453095405814e-06*G0_2_1 - 5.69492236159171e-05*G0_2_2 - 4.04357547214872e-06*G0_2_3 - 0.000106679035250514*G0_2_4 + 4.45982588839941e-05*G0_2_5 - 6.04157747015174e-05*G0_2_6 + 3.22296750868331e-05*G0_2_7 - 2.84834213405775e-05*G0_2_8 - 5.92264877979441e-05*G0_2_9 + 1.82555539698484e-05*G0_3_0 + 9.95036709322892e-05*G0_3_1 - 4.04357547214872e-06*G0_3_2 + 0.000404238618524523*G0_3_3 + 0.000344298558584434*G0_3_4 - 9.52618809762115e-05*G0_3_5 + 0.000132189239332159*G0_3_6 + 6.77893535036673e-06*G0_3_7 - 0.000153774796632011*G0_3_8 + 0.000229056657628194*G0_3_9 + 2.05151990866373e-05*G0_4_0 - 0.000106005106005156*G0_4_1 - 0.000106679035250514*G0_4_2 + 0.000344298558584434*G0_4_3 - 3.35378906807637e-05*G0_4_4 - 0.000132189239332159*G0_4_6 - 0.000109890109890161*G0_4_7 + 0.000146995861281644*G0_4_8 + 0.000177679463393832*G0_4_9 + 2.47371675943221e-05*G0_5_1 + 4.45982588839941e-05*G0_5_2 - 9.52618809762115e-05*G0_5_3 + 1.42714428428779e-05*G0_5_5 + 4.5847010132746e-05*G0_5_6 + 4.78093335236418e-05*G0_5_7 - 2.56885971171807e-05*G0_5_9 - 1.78987678987763e-05*G0_6_0 - 2.35478806907489e-05*G0_6_1 - 6.04157747015174e-05*G0_6_2 + 0.000132189239332159*G0_6_3 - 0.000132189239332159*G0_6_4 + 4.5847010132746e-05*G0_6_5 - 0.000211574140145668*G0_6_6 - 3.51434280005874e-05*G0_6_7 + 4.72741544170338e-05*G0_6_8 - 8.66990152704848e-05*G0_6_9 + 2.50344893202154e-05*G0_7_0 + 9.27643784787063e-06*G0_7_1 + 3.22296750868331e-05*G0_7_2 + 6.77893535036675e-06*G0_7_3 - 0.000109890109890161*G0_7_4 + 4.78093335236417e-05*G0_7_5 - 3.51434280005874e-05*G0_7_6 + 8.56286570572728e-06*G0_7_7 + 0.000113457970600881*G0_7_8 + 1.92664478378855e-05*G0_7_9 - 3.72841444270191e-05*G0_8_0 - 7.37357880215339e-06*G0_8_1 - 2.84834213405776e-05*G0_8_2 - 0.000153774796632011*G0_8_3 + 0.000146995861281644*G0_8_4 + 4.72741544170338e-05*G0_8_6 + 0.000113457970600881*G0_8_7 - 0.000221564150135682*G0_8_8 - 5.1377194234361e-05*G0_8_9 + 1.70068027210965e-05*G0_9_0 - 8.0871509442976e-05*G0_9_1 - 5.92264877979441e-05*G0_9_2 + 0.000229056657628194*G0_9_3 + 0.000177679463393832*G0_9_4 - 2.56885971171806e-05*G0_9_5 - 8.66990152704847e-05*G0_9_6 + 1.92664478378855e-05*G0_9_7 - 5.1377194234361e-05*G0_9_8 + 0.000295418866847577*G0_9_9; + A[170] = -A[139] + 2.74505036409928e-05*G0_0_0 + 1.19809643619224e-05*G0_0_1 + 3.98190874381537e-06*G0_0_2 + 5.82486296772285e-05*G0_0_3 + 1.5117157974308e-05*G0_0_4 + 1.58571587143094e-06*G0_0_7 + 6.02572031143742e-05*G0_0_8 + 0.00010212010212015*G0_0_9 + 1.19809643619224e-05*G0_1_0 + 8.0413413746785e-05*G0_1_1 + 1.0031121142237e-05*G0_1_2 - 6.87143544286708e-06*G0_1_3 - 4.49286163572089e-05*G0_1_4 + 1.13114398828737e-05*G0_1_5 - 3.73171801743406e-05*G0_1_7 + 0.000119351547923033*G0_1_8 - 2.2834308548605e-05*G0_1_9 + 3.98190874381537e-06*G0_2_0 + 1.0031121142237e-05*G0_2_1 + 1.37311248422425e-05*G0_2_2 + 2.11428782857394e-07*G0_2_3 - 5.40200540200792e-05*G0_2_4 + 1.13114398828737e-05*G0_2_5 - 1.12057254914449e-05*G0_2_6 - 7.71715057429702e-06*G0_2_7 + 6.96657839515309e-05*G0_2_8 - 6.34286348572357e-07*G0_2_9 + 5.82486296772285e-05*G0_3_0 - 6.87143544286713e-06*G0_3_1 + 2.1142878285738e-07*G0_3_2 + 0.000575614861329418*G0_3_3 + 7.61143618286829e-05*G0_3_4 - 8.46772275344102e-05*G0_3_5 - 3.90086104372003e-05*G0_3_6 - 0.000214071642643172*G0_3_7 + 0.000462394748109251*G0_3_8 + 0.000496646210932158*G0_3_9 + 1.5117157974308e-05*G0_4_0 - 4.49286163572089e-05*G0_4_1 - 5.40200540200792e-05*G0_4_2 + 7.61143618286828e-05*G0_4_3 + 0.000407211835783457*G0_4_4 - 8.46772275344104e-05*G0_4_5 + 0.000123685837971611*G0_4_6 + 8.56286570572677e-06*G0_4_7 - 0.000248323105466079*G0_4_8 + 0.000171257314114538*G0_4_9 + 1.13114398828737e-05*G0_5_1 + 1.13114398828737e-05*G0_5_2 - 8.46772275344102e-05*G0_5_3 - 8.46772275344103e-05*G0_5_4 + 8.94343751487028e-05*G0_5_5 - 7.32600732601078e-05*G0_5_6 + 8.9434375148703e-05*G0_5_7 - 7.32600732601078e-05*G0_5_8 - 0.000159840159840235*G0_5_9 - 1.12057254914449e-05*G0_6_2 - 3.90086104372003e-05*G0_6_3 + 0.000123685837971611*G0_6_4 - 7.32600732601078e-05*G0_6_5 + 0.000157937300794518*G0_6_6 - 1.61743018885954e-05*G0_6_7 - 8.46772275344101e-05*G0_6_8 + 7.99200799201177e-05*G0_6_9 + 1.58571587143093e-06*G0_7_0 - 3.73171801743405e-05*G0_7_1 - 7.71715057429702e-06*G0_7_2 - 0.000214071642643172*G0_7_3 + 8.56286570572671e-06*G0_7_4 + 8.9434375148703e-05*G0_7_5 - 1.61743018885954e-05*G0_7_6 + 0.000148423005565933*G0_7_7 - 0.000382474668189134*G0_7_8 - 0.00027401170258326*G0_7_9 + 6.02572031143742e-05*G0_8_0 + 0.000119351547923033*G0_8_1 + 6.96657839515309e-05*G0_8_2 + 0.000462394748109251*G0_8_3 - 0.000248323105466079*G0_8_4 - 7.32600732601078e-05*G0_8_5 - 8.46772275344101e-05*G0_8_6 - 0.000382474668189134*G0_8_7 + 0.00139003853289633*G0_8_8 + 0.000565149136577973*G0_8_9 + 0.00010212010212015*G0_9_0 - 2.2834308548605e-05*G0_9_1 - 6.34286348572357e-07*G0_9_2 + 0.000496646210932158*G0_9_3 + 0.000171257314114538*G0_9_4 - 0.000159840159840235*G0_9_5 + 7.99200799201177e-05*G0_9_6 - 0.00027401170258326*G0_9_7 + 0.000565149136577973*G0_9_8 + 0.000924789496218502*G0_9_9; + A[70] = A[170] - 2.01121629693153e-05*G0_0_0 + 8.98572327144175e-06*G0_0_1 + 1.14523924047775e-07*G0_0_2 - 1.32142989285998e-07*G0_0_3 - 4.35807578664927e-05*G0_0_4 - 1.69407312264536e-05*G0_0_6 - 1.50643007785939e-06*G0_0_7 + 1.42714428428781e-05*G0_0_8 - 5.50243407386524e-05*G0_0_9 + 8.98572327144175e-06*G0_1_0 + 0.000111863445196831*G0_1_1 + 1.34022356244641e-05*G0_1_2 + 0.000232915232915342*G0_1_3 - 8.53379424808396e-05*G0_1_4 - 7.42643599786802e-06*G0_1_5 - 2.26493083636047e-05*G0_1_6 - 4.98179069607874e-05*G0_1_7 + 0.000144115144115212*G0_1_8 + 0.0001170258313116*G0_1_9 + 1.14523924047778e-07*G0_2_0 + 1.34022356244641e-05*G0_2_1 - 3.00728078506e-05*G0_2_2 + 6.16314902029478e-05*G0_2_3 - 1.75750175750261e-05*G0_2_4 - 1.71785886071669e-06*G0_2_5 - 2.13014498728886e-05*G0_2_6 - 2.83578855007559e-05*G0_2_7 - 4.58007600864958e-05*G0_2_8 - 3.98014683729156e-05*G0_2_9 - 1.32142989286012e-07*G0_3_0 + 0.000232915232915342*G0_3_1 + 6.16314902029478e-05*G0_3_2 - 0.000112506541078024*G0_3_3 - 0.000197421625993147*G0_3_4 + 1.68878740307391e-05*G0_3_5 + 5.6847913990798e-05*G0_3_6 - 1.07035821321584e-05*G0_3_7 - 0.000115598687027313*G0_3_8 - 0.000329670329670485*G0_3_9 - 4.35807578664927e-05*G0_4_0 - 8.53379424808397e-05*G0_4_1 - 1.75750175750261e-05*G0_4_2 - 0.000197421625993147*G0_4_3 - 0.000284477427334705*G0_4_4 + 0.000119642262499462*G0_4_5 - 0.00017649017649026*G0_4_6 + 0.000113457970600881*G0_4_7 + 0.000126302269159471*G0_4_8 - 0.000119880119880177*G0_4_9 - 7.42643599786802e-06*G0_5_1 - 1.71785886071669e-06*G0_5_2 + 1.68878740307391e-05*G0_5_3 + 0.000119642262499462*G0_5_4 - 6.80272108843855e-05*G0_5_5 + 0.000131059416773764*G0_5_6 - 8.51529422958394e-05*G0_5_7 + 1.1179296893588e-05*G0_5_8 + 0.000142714428428782*G0_5_9 - 1.69407312264536e-05*G0_6_0 - 2.26493083636047e-05*G0_6_1 - 2.13014498728886e-05*G0_6_2 + 5.6847913990798e-05*G0_6_3 - 0.00017649017649026*G0_6_4 + 0.000131059416773764*G0_6_5 - 0.000205033062176016*G0_6_6 + 7.39736454022516e-05*G0_6_7 + 0.000108225108225159*G0_6_8 + 5.70857713715077e-06*G0_6_9 - 1.50643007785939e-06*G0_7_0 - 4.98179069607874e-05*G0_7_1 - 2.83578855007559e-05*G0_7_2 - 1.07035821321584e-05*G0_7_3 + 0.000113457970600881*G0_7_4 - 8.51529422958394e-05*G0_7_5 + 7.39736454022516e-05*G0_7_6 - 0.00020836306550602*G0_7_7 - 7.13572142143856e-06*G0_7_8 + 1.71257314114542e-05*G0_7_9 + 1.42714428428781e-05*G0_8_0 + 0.000144115144115212*G0_8_1 - 4.58007600864958e-05*G0_8_2 - 0.000115598687027313*G0_8_3 + 0.000126302269159471*G0_8_4 + 1.1179296893588e-05*G0_8_5 + 0.000108225108225159*G0_8_6 - 7.13572142143867e-06*G0_8_7 - 0.00117810760667959*G0_8_8 - 0.000603682032253744*G0_8_9 - 5.50243407386525e-05*G0_9_0 + 0.0001170258313116*G0_9_1 - 3.98014683729156e-05*G0_9_2 - 0.000329670329670485*G0_9_3 - 0.000119880119880177*G0_9_4 + 0.000142714428428782*G0_9_5 + 5.70857713715073e-06*G0_9_6 + 1.71257314114542e-05*G0_9_7 - 0.000603682032253744*G0_9_8 - 0.000950478093335683*G0_9_9; + A[86] = A[170]; + A[57] = A[139] - 6.16667283334257e-06*G0_0_0 + 1.4095252190493e-07*G0_0_1 - 2.9952410904806e-06*G0_0_2 - 0.000117025831311601*G0_0_3 - 2.85428856857567e-06*G0_0_4 - 3.45686059971938e-05*G0_0_6 + 3.01286015571872e-05*G0_0_7 - 1.45885860171644e-05*G0_0_8 - 0.000119880119880176*G0_0_9 + 1.40952521904934e-07*G0_1_0 + 4.78533811867367e-05*G0_1_1 - 8.24572253144073e-06*G0_1_2 - 7.92857935715457e-06*G0_1_3 + 1.49057291914505e-05*G0_1_4 + 7.70657913515418e-05*G0_1_5 + 7.29429300858205e-06*G0_1_7 + 4.34486148772067e-05*G0_1_8 + 0.000159840159840235*G0_1_9 - 2.9952410904806e-06*G0_2_0 - 8.24572253144073e-06*G0_2_1 - 2.7027646075278e-05*G0_2_2 - 4.24971853543481e-05*G0_2_3 - 7.29429300858228e-06*G0_2_4 + 3.13971742543319e-05*G0_2_5 - 5.89886304172296e-05*G0_2_6 + 1.99800199800292e-05*G0_2_7 - 3.71057513914832e-05*G0_2_8 - 0.000108462965605874*G0_2_9 - 0.000117025831311601*G0_3_0 - 7.92857935715457e-06*G0_3_1 - 4.24971853543481e-05*G0_3_2 - 0.00229199372056623*G0_3_3 + 0.000319680319680471*G0_3_4 + 4.28143285286344e-05*G0_3_5 + 4.28143285286345e-05*G0_3_6 + 0.00038532895675771*G0_3_7 - 0.000530897673755067*G0_3_8 - 0.00125017839303612*G0_3_9 - 2.85428856857567e-06*G0_4_0 + 1.49057291914505e-05*G0_4_1 - 7.29429300858227e-06*G0_4_2 + 0.000319680319680471*G0_4_3 - 0.000331097473954773*G0_4_4 + 4.28143285286347e-05*G0_4_5 - 8.56286570572692e-05*G0_4_6 - 4.28143285286342e-05*G0_4_7 + 0.000145568716997357*G0_4_8 + 0.000239760239760353*G0_4_9 + 7.70657913515418e-05*G0_5_1 + 3.13971742543319e-05*G0_5_2 + 4.28143285286344e-05*G0_5_3 + 4.28143285286346e-05*G0_5_4 + 0.000724989296418208*G0_5_5 + 3.13971742543324e-05*G0_5_6 + 0.000222634508348897*G0_5_7 - 0.000196945911231718*G0_5_8 + 0.000753532182103964*G0_5_9 - 3.45686059971938e-05*G0_6_0 - 5.89886304172296e-05*G0_6_2 + 4.28143285286345e-05*G0_6_3 - 8.56286570572693e-05*G0_6_4 + 3.13971742543323e-05*G0_6_5 + 0.000108462965605873*G0_6_6 - 2.56885971171801e-05*G0_6_7 + 4.28143285286344e-05*G0_6_8 + 0.000239760239760353*G0_6_9 + 3.01286015571872e-05*G0_7_0 + 7.29429300858205e-06*G0_7_1 + 1.99800199800292e-05*G0_7_2 + 0.00038532895675771*G0_7_3 - 4.28143285286341e-05*G0_7_4 + 0.000222634508348898*G0_7_5 - 2.56885971171801e-05*G0_7_6 - 1.14171542743045e-05*G0_7_7 - 2.85428856857556e-05*G0_7_8 + 0.000411017553874889*G0_7_9 - 1.45885860171643e-05*G0_8_0 + 4.34486148772067e-05*G0_8_1 - 3.71057513914832e-05*G0_8_2 - 0.000530897673755067*G0_8_3 + 0.000145568716997357*G0_8_4 - 0.000196945911231718*G0_8_5 + 4.28143285286344e-05*G0_8_6 - 2.85428856857556e-05*G0_8_7 - 0.000122734408448753*G0_8_8 - 0.000770657913515419*G0_8_9 - 0.000119880119880176*G0_9_0 + 0.000159840159840235*G0_9_1 - 0.000108462965605874*G0_9_2 - 0.00125017839303612*G0_9_3 + 0.000239760239760353*G0_9_4 + 0.000753532182103964*G0_9_5 + 0.000239760239760353*G0_9_6 + 0.000411017553874889*G0_9_7 - 0.000770657913515419*G0_9_8 - 0.000513771942343619*G0_9_9; + A[153] = A[57] - 3.77400377400554e-05*G0_0_0 - 3.77047996095792e-05*G0_0_1 - 6.73048292096225e-06*G0_0_2 - 8.0871509442976e-05*G0_0_3 + 4.09114694829173e-05*G0_0_4 + 6.12086326372328e-05*G0_0_6 + 9.83143840287178e-06*G0_0_7 - 8.24572253144069e-05*G0_0_8 + 9.51429522858537e-06*G0_0_9 - 3.77047996095792e-05*G0_1_0 - 0.00039713373046725*G0_1_1 - 3.84095622191041e-05*G0_1_2 - 0.000410700410700603*G0_1_3 + 0.000224854510568902*G0_1_4 - 9.99000999001468e-05*G0_1_5 + 2.94943152086148e-05*G0_1_6 + 0.000136054421768772*G0_1_7 - 0.000366300366300538*G0_1_8 - 0.000232148803577484*G0_1_9 - 6.73048292096225e-06*G0_2_0 - 3.84095622191041e-05*G0_2_1 + 2.17419265038417e-05*G0_2_2 - 0.00011290297004588*G0_2_3 + 0.000143031571603068*G0_2_4 - 5.8037200894371e-05*G0_2_5 + 0.000112268683697308*G0_2_6 + 2.85428856857572e-06*G0_2_7 - 5.80372008943711e-05*G0_2_8 + 6.27943485086639e-05*G0_2_9 - 8.0871509442976e-05*G0_3_0 - 0.000410700410700603*G0_3_1 - 0.00011290297004588*G0_3_2 - 0.000522334808049338*G0_3_3 + 0.000205508776937444*G0_3_4 + 0.000231197374054626*G0_3_5 - 8.56286570572717e-06*G0_3_6 + 0.000322534608249045*G0_3_7 - 0.000576566290852276*G0_3_8 + 5.13771942343615e-05*G0_3_9 + 4.09114694829173e-05*G0_4_0 + 0.000224854510568902*G0_4_1 + 0.000143031571603068*G0_4_2 + 0.000205508776937444*G0_4_3 - 0.000171257314114537*G0_4_4 - 4.28143285286347e-05*G0_4_5 + 5.13771942343617e-05*G0_4_6 - 0.000105608677037298*G0_4_7 + 0.000254031682603231*G0_4_8 - 0.000102754388468723*G0_4_9 - 9.99000999001468e-05*G0_5_1 - 5.8037200894371e-05*G0_5_2 + 0.000231197374054626*G0_5_3 - 4.28143285286347e-05*G0_5_4 - 0.00103325246182437*G0_5_5 + 2.85428856857505e-06*G0_5_6 - 0.000450977593834948*G0_5_7 + 0.000379620379620558*G0_5_8 - 0.000787783644926871*G0_5_9 + 6.12086326372328e-05*G0_6_0 + 2.94943152086148e-05*G0_6_1 + 0.000112268683697308*G0_6_2 - 8.56286570572715e-06*G0_6_3 + 5.13771942343617e-05*G0_6_4 + 2.85428856857509e-06*G0_6_5 - 0.00014271442842878*G0_6_6 + 7.13572142143902e-05*G0_6_7 + 2.85428856857567e-06*G0_6_8 - 0.000171257314114538*G0_6_9 + 9.83143840287179e-06*G0_7_0 + 0.000136054421768772*G0_7_1 + 2.85428856857572e-06*G0_7_2 + 0.000322534608249045*G0_7_3 - 0.000105608677037298*G0_7_4 - 0.000450977593834948*G0_7_5 + 7.13572142143902e-05*G0_7_6 - 0.000422434708149192*G0_7_7 + 0.000536606250892217*G0_7_8 - 0.000171257314114536*G0_7_9 - 8.2457225314407e-05*G0_8_0 - 0.000366300366300538*G0_8_1 - 5.80372008943711e-05*G0_8_2 - 0.000576566290852276*G0_8_3 + 0.000254031682603231*G0_8_4 + 0.000379620379620558*G0_8_5 + 2.85428856857567e-06*G0_8_6 + 0.000536606250892217*G0_8_7 - 0.00084201512772981*G0_8_8 + 0.000188383045525991*G0_8_9 + 9.51429522858537e-06*G0_9_0 - 0.000232148803577484*G0_9_1 + 6.27943485086639e-05*G0_9_2 + 5.13771942343615e-05*G0_9_3 - 0.000102754388468723*G0_9_4 - 0.000787783644926871*G0_9_5 - 0.000171257314114538*G0_9_6 - 0.000171257314114536*G0_9_7 + 0.000188383045525991*G0_9_8 - 0.000924789496218498*G0_9_9; + A[154] = A[70]; + A[15] = A[1]; + A[8] = A[76] + 0.000212644498358884*G0_0_0 - 1.24478695907326e-05*G0_0_3 - 1.66500166500245e-06*G0_0_4 + 0.000160474446188807*G0_0_5 - 8.20607963465491e-05*G0_0_6 + 0.000108383679812302*G0_0_7 - 5.77993435136563e-05*G0_0_8 + 2.2992880135748e-05*G0_0_9 - 0.000212644498358884*G0_1_1 - 0.000160474446188807*G0_1_3 + 8.20607963465492e-05*G0_1_4 + 1.24478695907326e-05*G0_1_5 + 1.66500166500245e-06*G0_1_6 + 5.77993435136565e-05*G0_1_7 - 0.000108383679812302*G0_1_8 - 2.29928801357481e-05*G0_1_9 - 3.2295746581476e-05*G0_2_3 + 5.7455771741513e-05*G0_2_4 + 3.22957465814761e-05*G0_2_5 - 5.74557717415131e-05*G0_2_6 - 1.24478695907326e-05*G0_3_0 - 0.000160474446188807*G0_3_1 - 3.2295746581476e-05*G0_3_2 - 0.000186955901241703*G0_3_3 + 2.64021692593245e-05*G0_3_4 - 4.99500499500727e-06*G0_3_6 + 3.73436087721978e-05*G0_3_7 - 5.89886304172297e-05*G0_3_8 - 5.70857713715127e-06*G0_3_9 - 1.66500166500245e-06*G0_4_0 + 8.20607963465492e-05*G0_4_1 + 5.7455771741513e-05*G0_4_2 + 2.64021692593245e-05*G0_4_3 + 4.2814328528633e-06*G0_4_4 + 4.99500499500742e-06*G0_4_5 - 8.32500832501228e-06*G0_4_7 + 2.16450216450319e-05*G0_4_8 - 9.99000999001465e-06*G0_4_9 + 0.000160474446188807*G0_5_0 + 1.24478695907326e-05*G0_5_1 + 3.22957465814761e-05*G0_5_2 + 4.99500499500742e-06*G0_5_4 + 0.000186955901241703*G0_5_5 - 2.64021692593242e-05*G0_5_6 + 5.89886304172293e-05*G0_5_7 - 3.73436087721977e-05*G0_5_8 + 5.70857713715125e-06*G0_5_9 - 8.20607963465491e-05*G0_6_0 + 1.66500166500245e-06*G0_6_1 - 5.74557717415131e-05*G0_6_2 - 4.99500499500727e-06*G0_6_3 - 2.64021692593243e-05*G0_6_5 - 4.28143285286384e-06*G0_6_6 - 2.16450216450317e-05*G0_6_7 + 8.32500832501223e-06*G0_6_8 + 9.99000999001461e-06*G0_6_9 + 0.000108383679812302*G0_7_0 + 5.77993435136565e-05*G0_7_1 + 3.73436087721978e-05*G0_7_3 - 8.32500832501228e-06*G0_7_4 + 5.89886304172293e-05*G0_7_5 - 2.16450216450317e-05*G0_7_6 + 1.56985871271657e-05*G0_7_7 - 2.56885971171806e-05*G0_7_9 - 5.77993435136563e-05*G0_8_0 - 0.000108383679812302*G0_8_1 - 5.89886304172297e-05*G0_8_3 + 2.16450216450319e-05*G0_8_4 - 3.73436087721977e-05*G0_8_5 + 8.32500832501223e-06*G0_8_6 - 1.56985871271662e-05*G0_8_8 + 2.56885971171805e-05*G0_8_9 + 2.2992880135748e-05*G0_9_0 - 2.29928801357481e-05*G0_9_1 - 5.70857713715127e-06*G0_9_3 - 9.99000999001464e-06*G0_9_4 + 5.70857713715125e-06*G0_9_5 + 9.99000999001462e-06*G0_9_6 - 2.56885971171806e-05*G0_9_7 + 2.56885971171805e-05*G0_9_8; + A[7] = -A[8] - 0.000263625263625388*G0_0_0 - 1.37957280814488e-05*G0_0_1 - 2.36359760169395e-05*G0_0_2 + 4.3078614507206e-06*G0_0_4 - 0.000193325193325284*G0_0_5 + 7.86250786251154e-05*G0_0_6 - 0.000111925111925164*G0_0_7 + 5.45750545750801e-05*G0_0_8 - 2.22000222000326e-05*G0_0_9 - 1.37957280814488e-05*G0_1_0 + 2.70893128036115e-07*G0_1_4 - 8.71483014340563e-06*G0_1_5 + 7.57840043554683e-06*G0_1_6 - 6.93089978804586e-06*G0_1_7 - 3.56786071071958e-07*G0_1_9 - 2.36359760169395e-05*G0_2_0 - 2.41630797186467e-05*G0_2_2 + 7.78322206894005e-06*G0_2_3 - 1.78657321514549e-05*G0_2_4 - 4.83643340786419e-06*G0_2_5 - 4.26953998382772e-05*G0_2_6 - 5.74161288447269e-06*G0_2_7 - 1.81564467278839e-05*G0_2_9 + 7.78322206894005e-06*G0_3_2 + 6.66000666000951e-06*G0_3_3 + 1.43309071880569e-05*G0_3_4 - 7.01679273108176e-06*G0_3_5 - 2.37857380714633e-06*G0_3_6 + 4.3078614507206e-06*G0_4_0 + 2.70893128036115e-07*G0_4_1 - 1.78657321514549e-05*G0_4_2 + 1.43309071880569e-05*G0_4_3 + 2.84239569953986e-05*G0_4_4 + 7.4330431473325e-06*G0_4_5 - 5.05446934018623e-06*G0_4_6 - 8.02768659911894e-06*G0_4_7 + 3.96032538889867e-05*G0_4_9 - 0.000193325193325284*G0_5_0 - 8.71483014340563e-06*G0_5_1 - 4.8364334078642e-06*G0_5_2 - 7.01679273108175e-06*G0_5_3 + 7.4330431473325e-06*G0_5_4 - 0.000330502830502986*G0_5_5 + 0.00015472622615487*G0_5_6 - 8.40825840826233e-05*G0_5_7 + 4.65011179297111e-05*G0_5_8 - 2.64021692593243e-05*G0_5_9 + 7.86250786251153e-05*G0_6_0 + 7.57840043554683e-06*G0_6_1 - 4.26953998382771e-05*G0_6_2 - 2.37857380714633e-06*G0_6_3 - 5.05446934018623e-06*G0_6_4 + 0.00015472622615487*G0_6_5 + 1.16550116550171e-05*G0_6_6 + 3.75814661529122e-05*G0_6_7 - 3.09214594929025e-05*G0_6_8 + 5.92264877979442e-05*G0_6_9 - 0.000111925111925164*G0_7_0 - 6.93089978804586e-06*G0_7_1 - 5.74161288447268e-06*G0_7_2 - 8.02768659911894e-06*G0_7_4 - 8.40825840826233e-05*G0_7_5 + 3.75814661529122e-05*G0_7_6 - 7.57575757576113e-05*G0_7_7 + 4.59064744779246e-05*G0_7_8 + 5.45750545750801e-05*G0_8_0 + 4.65011179297111e-05*G0_8_5 - 3.09214594929025e-05*G0_8_6 + 4.59064744779246e-05*G0_8_7 - 2.18828790257465e-05*G0_8_8 - 2.14071642643181e-06*G0_8_9 - 2.22000222000326e-05*G0_9_0 - 3.56786071071959e-07*G0_9_1 - 1.81564467278839e-05*G0_9_2 + 3.96032538889867e-05*G0_9_4 - 2.64021692593243e-05*G0_9_5 + 5.92264877979442e-05*G0_9_6 - 2.14071642643181e-06*G0_9_8 + 0.000132724418438766*G0_9_9; + A[186] = -A[8] + 0.000605567272234223*G0_0_0 + 6.8379592189148e-05*G0_0_1 + 7.90038885277351e-05*G0_0_2 - 4.38186152472073e-05*G0_0_3 - 0.000113431542003024*G0_0_4 + 0.000963850963851416*G0_0_5 - 0.00046916046916069*G0_0_6 + 0.000634550634550932*G0_0_7 - 0.000314500314500462*G0_0_8 + 0.000117660117660173*G0_0_9 + 6.8379592189148e-05*G0_1_0 + 2.92652673605193e-05*G0_1_1 + 3.28566201582229e-05*G0_1_2 - 8.26422254994073e-05*G0_1_4 + 0.000501429787144309*G0_1_5 - 0.000248772391629652*G0_1_6 + 0.00035728821443124*G0_1_7 - 0.000169010883296677*G0_1_8 + 0.000262118833547529*G0_1_9 + 7.90038885277351e-05*G0_2_0 + 3.28566201582229e-05*G0_2_1 - 6.64180029259709e-05*G0_2_2 + 2.59000259000384e-06*G0_2_3 - 9.66758109615709e-05*G0_2_4 + 0.000547389118817947*G0_2_5 - 0.000319046033331898*G0_2_6 + 0.000354909640624093*G0_2_7 - 0.000185105899391701*G0_2_8 + 0.000301286015571871*G0_2_9 - 4.38186152472073e-05*G0_3_0 + 2.59000259000384e-06*G0_3_2 - 0.000441463298606363*G0_3_3 + 0.000274249559963975*G0_3_4 - 0.00051615051615076*G0_3_5 + 0.000405784691499169*G0_3_6 - 0.000209076637648165*G0_3_7 - 0.000368203225346256*G0_3_9 - 0.000113431542003024*G0_4_0 - 8.26422254994073e-05*G0_4_1 - 9.66758109615709e-05*G0_4_2 + 0.000274249559963975*G0_4_3 - 0.000988059559488596*G0_4_4 - 2.37857380714309e-07*G0_4_5 - 0.000405546834118454*G0_4_6 - 0.000191950906236711*G0_4_7 + 0.000214785214785316*G0_4_8 - 0.000903382331954185*G0_4_9 + 0.000963850963851416*G0_5_0 + 0.000501429787144309*G0_5_1 + 0.000547389118817947*G0_5_2 - 0.00051615051615076*G0_5_3 - 2.37857380714254e-07*G0_5_4 + 0.00655011655011963*G0_5_5 - 0.00192141192141282*G0_5_6 + 0.00325008325008478*G0_5_7 - 0.00184482184482271*G0_5_8 + 0.00333666333666491*G0_5_9 - 0.00046916046916069*G0_6_0 - 0.000248772391629652*G0_6_1 - 0.000319046033331898*G0_6_2 + 0.000405784691499169*G0_6_3 - 0.000405546834118454*G0_6_4 - 0.00192141192141282*G0_6_5 + 0.000195043052186001*G0_6_6 - 0.00140526140526207*G0_6_7 + 0.000821083678226922*G0_6_8 - 0.00171542742971395*G0_6_9 + 0.000634550634550932*G0_7_0 + 0.00035728821443124*G0_7_1 + 0.000354909640624093*G0_7_2 - 0.000209076637648165*G0_7_3 - 0.000191950906236711*G0_7_4 + 0.00325008325008478*G0_7_5 - 0.00140526140526207*G0_7_6 + 0.00323343323343475*G0_7_7 - 0.00142191142191209*G0_7_8 + 0.00245754245754362*G0_7_9 - 0.000314500314500462*G0_8_0 - 0.000169010883296677*G0_8_1 - 0.000185105899391701*G0_8_2 + 0.000214785214785316*G0_8_4 - 0.00184482184482271*G0_8_5 + 0.000821083678226922*G0_8_6 - 0.00142191142191209*G0_8_7 + 0.000614623471766618*G0_8_8 - 0.00121592693021322*G0_8_9 + 0.000117660117660173*G0_9_0 + 0.000262118833547529*G0_9_1 + 0.000301286015571872*G0_9_2 - 0.000368203225346256*G0_9_3 - 0.000903382331954185*G0_9_4 + 0.00333666333666491*G0_9_5 - 0.00171542742971395*G0_9_6 + 0.00245754245754362*G0_9_7 - 0.00121592693021322*G0_9_8 - 8.56286570572676e-05*G0_9_9; + A[218] = A[186] - 0.000393539441158673*G0_0_0 - 2.08609732419354e-05*G0_0_1 - 0.00013700585129163*G0_0_3 + 0.000441463298606363*G0_0_4 - 0.0010097838669272*G0_0_5 + 0.000862629434058411*G0_0_6 - 0.000578469149897993*G0_0_7 + 0.000243565957851787*G0_0_8 + 0.000213120213120314*G0_0_9 - 2.08609732419353e-05*G0_1_0 + 2.08609732419355e-05*G0_1_2 - 0.000162377305234524*G0_1_3 + 0.000416091844663469*G0_1_4 - 0.000715475001189623*G0_1_5 + 0.000715475001189623*G0_1_6 - 0.000416091844663469*G0_1_7 + 0.000162377305234525*G0_1_8 + 2.08609732419355e-05*G0_2_1 + 0.000393539441158674*G0_2_2 - 0.000243565957851787*G0_2_3 + 0.000578469149897993*G0_2_4 - 0.000862629434058411*G0_2_5 + 0.0010097838669272*G0_2_6 - 0.000441463298606363*G0_2_7 + 0.00013700585129163*G0_2_8 - 0.000213120213120313*G0_2_9 - 0.00013700585129163*G0_3_0 - 0.000162377305234524*G0_3_1 - 0.000243565957851787*G0_3_2 + 0.00100470957613862*G0_3_3 - 0.00159840159840235*G0_3_4 + 0.00127872127872188*G0_3_5 - 0.00214642500356887*G0_3_6 + 0.000411017553874891*G0_3_7 - 0.000822035107749779*G0_3_9 + 0.000441463298606363*G0_4_0 + 0.000416091844663469*G0_4_1 + 0.000578469149897993*G0_4_2 - 0.00159840159840235*G0_4_3 + 0.00401883830455448*G0_4_4 - 0.00132438989581909*G0_4_5 + 0.00347081489938796*G0_4_6 - 0.00041101755387489*G0_4_8 + 0.00328814043099912*G0_4_9 - 0.0010097838669272*G0_5_0 - 0.000715475001189623*G0_5_1 - 0.000862629434058411*G0_5_2 + 0.00127872127872188*G0_5_3 - 0.00132438989581909*G0_5_4 - 0.00602825745683171*G0_5_5 - 0.00347081489938796*G0_5_7 + 0.00214642500356887*G0_5_8 - 0.00493221064649868*G0_5_9 + 0.000862629434058411*G0_6_0 + 0.000715475001189624*G0_6_1 + 0.0010097838669272*G0_6_2 - 0.00214642500356887*G0_6_3 + 0.00347081489938796*G0_6_4 + 0.00602825745683172*G0_6_6 + 0.00132438989581909*G0_6_7 - 0.00127872127872188*G0_6_8 + 0.00493221064649868*G0_6_9 - 0.000578469149897993*G0_7_0 - 0.000416091844663469*G0_7_1 - 0.000441463298606363*G0_7_2 + 0.000411017553874891*G0_7_3 - 0.00347081489938796*G0_7_5 + 0.00132438989581909*G0_7_6 - 0.00401883830455448*G0_7_7 + 0.00159840159840235*G0_7_8 - 0.00328814043099912*G0_7_9 + 0.000243565957851787*G0_8_0 + 0.000162377305234525*G0_8_1 + 0.00013700585129163*G0_8_2 - 0.00041101755387489*G0_8_4 + 0.00214642500356887*G0_8_5 - 0.00127872127872188*G0_8_6 + 0.00159840159840235*G0_8_7 - 0.00100470957613862*G0_8_8 + 0.000822035107749782*G0_8_9 + 0.000213120213120313*G0_9_0 - 0.000213120213120313*G0_9_2 - 0.000822035107749779*G0_9_3 + 0.00328814043099912*G0_9_4 - 0.00493221064649868*G0_9_5 + 0.00493221064649868*G0_9_6 - 0.00328814043099912*G0_9_7 + 0.000822035107749782*G0_9_8; + A[89] = A[218] + 2.98819346438534e-05*G0_0_0 - 1.32495370590672e-05*G0_0_2 - 4.56686170972101e-05*G0_0_3 + 0.00013700585129163*G0_0_4 + 4.82057624914994e-05*G0_0_5 - 0.000142080142080209*G0_0_6 + 4.56686170972099e-05*G0_0_7 - 4.56686170972099e-05*G0_0_8 - 4.566861709721e-05*G0_0_9 - 2.98819346438534e-05*G0_1_1 + 1.32495370590671e-05*G0_1_2 - 4.82057624914995e-05*G0_1_3 + 0.000142080142080209*G0_1_4 + 4.56686170972099e-05*G0_1_5 - 0.00013700585129163*G0_1_6 + 4.566861709721e-05*G0_1_7 - 4.56686170972099e-05*G0_1_8 + 4.566861709721e-05*G0_1_9 - 1.32495370590671e-05*G0_2_0 + 1.32495370590671e-05*G0_2_1 - 0.000106560106560157*G0_2_3 + 0.000266400266400392*G0_2_4 + 0.000106560106560157*G0_2_5 - 0.000266400266400392*G0_2_6 + 4.566861709721e-05*G0_2_7 - 4.56686170972099e-05*G0_2_8 - 4.56686170972101e-05*G0_3_0 - 4.82057624914995e-05*G0_3_1 - 0.000106560106560157*G0_3_2 - 0.000228343085486049*G0_3_3 - 0.000570857713715125*G0_3_4 + 0.000411017553874889*G0_3_6 + 0.00013700585129163*G0_3_7 - 0.00027401170258326*G0_3_8 - 0.00041101755387489*G0_3_9 + 0.00013700585129163*G0_4_0 + 0.000142080142080209*G0_4_1 + 0.000266400266400392*G0_4_2 - 0.000570857713715125*G0_4_3 + 0.0031968031968047*G0_4_4 - 0.00041101755387489*G0_4_5 - 0.00027401170258326*G0_4_7 + 0.00013700585129163*G0_4_8 + 0.00082203510774978*G0_4_9 + 4.82057624914994e-05*G0_5_0 + 4.56686170972099e-05*G0_5_1 + 0.000106560106560157*G0_5_2 - 0.00041101755387489*G0_5_4 + 0.000228343085486049*G0_5_5 + 0.000570857713715126*G0_5_6 + 0.00027401170258326*G0_5_7 - 0.00013700585129163*G0_5_8 + 0.000411017553874889*G0_5_9 - 0.000142080142080209*G0_6_0 - 0.00013700585129163*G0_6_1 - 0.000266400266400392*G0_6_2 + 0.000411017553874889*G0_6_3 + 0.000570857713715126*G0_6_5 - 0.0031968031968047*G0_6_6 - 0.000137005851291629*G0_6_7 + 0.00027401170258326*G0_6_8 - 0.00082203510774978*G0_6_9 + 4.56686170972099e-05*G0_7_0 + 4.56686170972099e-05*G0_7_1 + 4.566861709721e-05*G0_7_2 + 0.00013700585129163*G0_7_3 - 0.00027401170258326*G0_7_4 + 0.00027401170258326*G0_7_5 - 0.000137005851291629*G0_7_6 + 0.00041101755387489*G0_7_7 + 0.00041101755387489*G0_7_9 - 4.56686170972099e-05*G0_8_0 - 4.56686170972099e-05*G0_8_1 - 4.56686170972099e-05*G0_8_2 - 0.00027401170258326*G0_8_3 + 0.00013700585129163*G0_8_4 - 0.00013700585129163*G0_8_5 + 0.00027401170258326*G0_8_6 - 0.00041101755387489*G0_8_8 - 0.00041101755387489*G0_8_9 - 4.566861709721e-05*G0_9_0 + 4.566861709721e-05*G0_9_1 - 0.000411017553874889*G0_9_3 + 0.00082203510774978*G0_9_4 + 0.000411017553874889*G0_9_5 - 0.00082203510774978*G0_9_6 + 0.00041101755387489*G0_9_7 - 0.00041101755387489*G0_9_8; + A[215] = A[89]; + A[198] = A[186] - 0.00036365750651482*G0_0_0 - 3.41105103010024e-05*G0_0_2 + 0.000532800532800783*G0_0_3 - 0.00013700585129163*G0_0_4 - 0.000799200799201174*G0_0_5 + 0.000304457447314733*G0_0_6 - 0.000695177838035307*G0_0_7 + 0.000613989185418046*G0_0_8 + 0.000167451596023104*G0_0_9 + 0.00036365750651482*G0_1_1 + 3.41105103010026e-05*G0_1_2 + 0.000799200799201175*G0_1_3 - 0.000304457447314733*G0_1_4 - 0.000532800532800783*G0_1_5 + 0.00013700585129163*G0_1_6 - 0.000613989185418046*G0_1_7 + 0.000695177838035308*G0_1_8 - 0.000167451596023104*G0_1_9 - 3.41105103010024e-05*G0_2_0 + 3.41105103010026e-05*G0_2_1 + 0.000512503369646467*G0_2_3 - 0.000164914450628814*G0_2_4 - 0.000512503369646467*G0_2_5 + 0.000164914450628814*G0_2_6 - 0.000532800532800783*G0_2_7 + 0.000532800532800783*G0_2_8 + 0.000532800532800784*G0_3_0 + 0.000799200799201175*G0_3_1 + 0.000512503369646467*G0_3_2 + 0.00680462394748429*G0_3_3 - 0.00216925931211747*G0_3_4 - 0.00041101755387489*G0_3_6 - 0.00159840159840235*G0_3_7 + 0.0031968031968047*G0_3_8 + 0.00369915798487401*G0_3_9 - 0.00013700585129163*G0_4_0 - 0.000304457447314733*G0_4_1 - 0.000164914450628814*G0_4_2 - 0.00216925931211747*G0_4_3 + 0.00118738404452746*G0_4_4 + 0.00041101755387489*G0_4_5 + 0.00100470957613862*G0_4_7 - 0.00159840159840235*G0_4_8 - 0.000822035107749779*G0_4_9 - 0.000799200799201174*G0_5_0 - 0.000532800532800783*G0_5_1 - 0.000512503369646468*G0_5_2 + 0.00041101755387489*G0_5_4 - 0.00680462394748428*G0_5_5 + 0.00216925931211747*G0_5_6 - 0.0031968031968047*G0_5_7 + 0.00159840159840235*G0_5_8 - 0.00369915798487401*G0_5_9 + 0.000304457447314733*G0_6_0 + 0.00013700585129163*G0_6_1 + 0.000164914450628814*G0_6_2 - 0.00041101755387489*G0_6_3 + 0.00216925931211747*G0_6_5 - 0.00118738404452746*G0_6_6 + 0.00159840159840235*G0_6_7 - 0.00100470957613862*G0_6_8 + 0.000822035107749782*G0_6_9 - 0.000695177838035308*G0_7_0 - 0.000613989185418046*G0_7_1 - 0.000532800532800783*G0_7_2 - 0.00159840159840235*G0_7_3 + 0.00100470957613862*G0_7_4 - 0.0031968031968047*G0_7_5 + 0.00159840159840235*G0_7_6 - 0.00260311117454097*G0_7_7 - 0.00369915798487401*G0_7_9 + 0.000613989185418046*G0_8_0 + 0.000695177838035308*G0_8_1 + 0.000532800532800783*G0_8_2 + 0.0031968031968047*G0_8_3 - 0.00159840159840235*G0_8_4 + 0.00159840159840235*G0_8_5 - 0.00100470957613862*G0_8_6 + 0.00260311117454097*G0_8_8 + 0.00369915798487401*G0_8_9 + 0.000167451596023104*G0_9_0 - 0.000167451596023104*G0_9_1 + 0.00369915798487401*G0_9_3 - 0.000822035107749779*G0_9_4 - 0.00369915798487401*G0_9_5 + 0.000822035107749782*G0_9_6 - 0.00369915798487401*G0_9_7 + 0.00369915798487401*G0_9_8; + A[37] = A[107]; + A[148] = A[149] + 3.94667061333913e-05*G0_0_0 + 2.48076438552745e-05*G0_0_1 + 2.02971631543156e-05*G0_0_2 + 0.000223268794697471*G0_0_3 - 0.000142080142080209*G0_0_4 - 6.08914894629467e-05*G0_0_6 + 0.000152228723657367*G0_0_8 + 0.000121782978925894*G0_0_9 + 2.48076438552745e-05*G0_1_0 + 0.000158994444708805*G0_1_1 + 3.49562254324324e-05*G0_1_2 + 0.000243565957851786*G0_1_3 - 0.00018267446838884*G0_1_4 + 1.01485815771576e-05*G0_1_5 - 5.07429078857889e-05*G0_1_6 - 3.04457447314735e-05*G0_1_7 + 0.000334903192046207*G0_1_8 + 0.00018267446838884*G0_1_9 + 2.02971631543156e-05*G0_2_0 + 3.49562254324324e-05*G0_2_1 + 0.000152228723657367*G0_2_3 - 6.08914894629465e-05*G0_2_4 - 1.01485815771578e-05*G0_2_5 - 4.05943263086309e-05*G0_2_6 + 1.01485815771575e-05*G0_2_7 + 4.05943263086311e-05*G0_2_8 + 0.000223268794697471*G0_3_0 + 0.000243565957851786*G0_3_1 + 0.000152228723657367*G0_3_2 + 0.00200941915227724*G0_3_3 - 0.0004566861709721*G0_3_4 - 0.00027401170258326*G0_3_5 - 0.000822035107749781*G0_3_7 + 0.00109604681033304*G0_3_8 + 0.00109604681033304*G0_3_9 - 0.000142080142080209*G0_4_0 - 0.00018267446838884*G0_4_1 - 6.08914894629465e-05*G0_4_2 - 0.0004566861709721*G0_4_3 - 0.000456686170972099*G0_4_4 + 0.00027401170258326*G0_4_5 - 0.00027401170258326*G0_4_6 + 0.00027401170258326*G0_4_7 - 0.00027401170258326*G0_4_8 - 0.000548023405166519*G0_4_9 + 1.01485815771576e-05*G0_5_1 - 1.01485815771578e-05*G0_5_2 - 0.00027401170258326*G0_5_3 + 0.00027401170258326*G0_5_4 - 0.00036534893677768*G0_5_5 + 0.00018267446838884*G0_5_6 + 0.000365348936777679*G0_5_7 - 0.00018267446838884*G0_5_8 - 6.08914894629467e-05*G0_6_0 - 5.07429078857889e-05*G0_6_1 - 4.05943263086309e-05*G0_6_2 - 0.00027401170258326*G0_6_4 + 0.00018267446838884*G0_6_5 - 9.13372341944207e-05*G0_6_6 - 0.00018267446838884*G0_6_7 + 9.13372341944202e-05*G0_6_8 - 3.04457447314734e-05*G0_7_1 + 1.01485815771575e-05*G0_7_2 - 0.00082203510774978*G0_7_3 + 0.00027401170258326*G0_7_4 + 0.000365348936777679*G0_7_5 - 0.00018267446838884*G0_7_6 + 0.00219209362066608*G0_7_7 - 0.00109604681033304*G0_7_8 + 0.000152228723657367*G0_8_0 + 0.000334903192046207*G0_8_1 + 4.05943263086311e-05*G0_8_2 + 0.00109604681033304*G0_8_3 - 0.00027401170258326*G0_8_4 - 0.00018267446838884*G0_8_5 + 9.13372341944202e-05*G0_8_6 - 0.00109604681033304*G0_8_7 + 0.00054802340516652*G0_8_8 + 0.000121782978925894*G0_9_0 + 0.00018267446838884*G0_9_1 + 0.00109604681033304*G0_9_3 - 0.000548023405166519*G0_9_4; + A[123] = -A[94] + 2.74505036409925e-05*G0_0_0 + 3.98190874381536e-06*G0_0_1 + 1.19809643619224e-05*G0_0_2 + 1.51171579743079e-05*G0_0_3 + 5.82486296772285e-05*G0_0_4 + 1.58571587143043e-06*G0_0_5 + 6.02572031143746e-05*G0_0_6 + 0.00010212010212015*G0_0_9 + 3.98190874381536e-06*G0_1_0 + 1.37311248422424e-05*G0_1_1 + 1.0031121142237e-05*G0_1_2 - 5.40200540200793e-05*G0_1_3 + 2.11428782857434e-07*G0_1_4 - 7.71715057429715e-06*G0_1_5 + 6.9665783951531e-05*G0_1_6 + 1.13114398828737e-05*G0_1_7 - 1.1205725491445e-05*G0_1_8 - 6.34286348572344e-07*G0_1_9 + 1.19809643619224e-05*G0_2_0 + 1.0031121142237e-05*G0_2_1 + 8.04134137467851e-05*G0_2_2 - 4.49286163572089e-05*G0_2_3 - 6.87143544286708e-06*G0_2_4 - 3.73171801743408e-05*G0_2_5 + 0.000119351547923033*G0_2_6 + 1.13114398828737e-05*G0_2_7 - 2.28343085486049e-05*G0_2_9 + 1.51171579743079e-05*G0_3_0 - 5.40200540200793e-05*G0_3_1 - 4.49286163572089e-05*G0_3_2 + 0.000407211835783456*G0_3_3 + 7.61143618286829e-05*G0_3_4 + 8.56286570572701e-06*G0_3_5 - 0.00024832310546608*G0_3_6 - 8.46772275344102e-05*G0_3_7 + 0.000123685837971611*G0_3_8 + 0.000171257314114537*G0_3_9 + 5.82486296772285e-05*G0_4_0 + 2.11428782857434e-07*G0_4_1 - 6.87143544286708e-06*G0_4_2 + 7.61143618286829e-05*G0_4_3 + 0.000575614861329418*G0_4_4 - 0.000214071642643172*G0_4_5 + 0.000462394748109251*G0_4_6 - 8.46772275344103e-05*G0_4_7 - 3.90086104372002e-05*G0_4_8 + 0.000496646210932159*G0_4_9 + 1.58571587143043e-06*G0_5_0 - 7.71715057429715e-06*G0_5_1 - 3.73171801743408e-05*G0_5_2 + 8.56286570572698e-06*G0_5_3 - 0.000214071642643172*G0_5_4 + 0.000148423005565931*G0_5_5 - 0.000382474668189134*G0_5_6 + 8.94343751487027e-05*G0_5_7 - 1.6174301888595e-05*G0_5_8 - 0.00027401170258326*G0_5_9 + 6.02572031143746e-05*G0_6_0 + 6.9665783951531e-05*G0_6_1 + 0.000119351547923033*G0_6_2 - 0.00024832310546608*G0_6_3 + 0.000462394748109251*G0_6_4 - 0.000382474668189134*G0_6_5 + 0.00139003853289633*G0_6_6 - 7.32600732601078e-05*G0_6_7 - 8.46772275344101e-05*G0_6_8 + 0.000565149136577974*G0_6_9 + 1.13114398828737e-05*G0_7_1 + 1.13114398828737e-05*G0_7_2 - 8.46772275344102e-05*G0_7_3 - 8.46772275344103e-05*G0_7_4 + 8.94343751487027e-05*G0_7_5 - 7.32600732601078e-05*G0_7_6 + 8.94343751487027e-05*G0_7_7 - 7.32600732601077e-05*G0_7_8 - 0.000159840159840235*G0_7_9 - 1.1205725491445e-05*G0_8_1 + 0.000123685837971611*G0_8_3 - 3.90086104372002e-05*G0_8_4 - 1.6174301888595e-05*G0_8_5 - 8.46772275344101e-05*G0_8_6 - 7.32600732601077e-05*G0_8_7 + 0.000157937300794518*G0_8_8 + 7.99200799201177e-05*G0_8_9 + 0.00010212010212015*G0_9_0 - 6.3428634857233e-07*G0_9_1 - 2.28343085486049e-05*G0_9_2 + 0.000171257314114537*G0_9_3 + 0.000496646210932159*G0_9_4 - 0.00027401170258326*G0_9_5 + 0.000565149136577974*G0_9_6 - 0.000159840159840235*G0_9_7 + 7.99200799201177e-05*G0_9_8 + 0.000924789496218502*G0_9_9; + A[50] = A[123] - 1.83238278476458e-06*G0_0_0 + 2.65930424660708e-05*G0_0_1 + 3.61778139556087e-06*G0_0_2 + 6.3428634857236e-05*G0_0_3 - 3.29828901257627e-05*G0_0_4 - 5.49714835429373e-06*G0_0_5 - 4.86286200572145e-05*G0_0_6 - 3.55200355200522e-05*G0_0_7 + 6.59657802515255e-05*G0_0_8 + 7.6114361828683e-06*G0_0_9 + 2.65930424660709e-05*G0_1_0 + 0.000347635903191622*G0_1_1 + 6.65295903391454e-05*G0_1_2 + 0.00050150907293788*G0_1_3 - 0.000163223020365954*G0_1_4 - 7.61143618286835e-06*G0_1_5 - 4.44000444000653e-05*G0_1_6 - 0.000122205836491608*G0_1_7 + 0.000235531664103203*G0_1_8 + 8.11886526172622e-05*G0_1_9 + 3.61778139556086e-06*G0_2_0 + 6.65295903391454e-05*G0_2_1 + 0.000128266794933522*G0_2_2 + 1.7337160194311e-05*G0_2_3 + 0.000236800236800348*G0_2_4 + 1.14171542743026e-05*G0_2_5 - 8.88000888001307e-05*G0_2_6 - 3.80571809143417e-05*G0_2_7 + 6.72343529486703e-05*G0_2_8 + 4.82057624914995e-05*G0_2_9 + 6.34286348572361e-05*G0_3_0 + 0.00050150907293788*G0_3_1 + 1.7337160194311e-05*G0_3_2 + 0.000974263831407145*G0_3_3 - 0.000783977926835438*G0_3_4 - 4.94743351886441e-05*G0_3_5 + 6.46972075543809e-05*G0_3_6 - 0.000258788830217523*G0_3_7 + 0.000528994814709349*G0_3_8 + 0.000274011702583259*G0_3_9 - 3.29828901257628e-05*G0_4_0 - 0.000163223020365954*G0_4_1 + 0.000236800236800348*G0_4_2 - 0.000783977926835438*G0_4_3 + 0.000574663431806559*G0_4_4 + 3.04457447314734e-05*G0_4_5 - 9.51429522858541e-05*G0_4_6 + 0.000140811569383064*G0_4_7 - 0.000270205984491826*G0_4_8 - 0.000205508776937445*G0_4_9 - 5.49714835429373e-06*G0_5_0 - 7.61143618286835e-06*G0_5_1 + 1.14171542743026e-05*G0_5_2 - 4.94743351886441e-05*G0_5_3 + 3.04457447314734e-05*G0_5_4 - 4.56686170972098e-05*G0_5_5 + 0.000262594548308958*G0_5_6 - 4.56686170972101e-05*G0_5_8 + 6.85029256458151e-05*G0_5_9 - 4.86286200572145e-05*G0_6_0 - 4.44000444000653e-05*G0_6_1 - 8.88000888001307e-05*G0_6_2 + 6.4697207554381e-05*G0_6_3 - 9.5142952285854e-05*G0_6_4 + 0.000262594548308957*G0_6_5 - 0.000970458113315712*G0_6_6 + 4.56686170972101e-05*G0_6_7 - 0.00027401170258326*G0_6_9 - 3.55200355200522e-05*G0_7_0 - 0.000122205836491608*G0_7_1 - 3.80571809143417e-05*G0_7_2 - 0.000258788830217523*G0_7_3 + 0.000140811569383064*G0_7_4 + 4.56686170972101e-05*G0_7_6 + 9.89486703772885e-05*G0_7_7 - 0.000243565957851787*G0_7_8 - 0.000114171542743025*G0_7_9 + 6.59657802515255e-05*G0_8_0 + 0.000235531664103203*G0_8_1 + 6.72343529486702e-05*G0_8_2 + 0.000528994814709349*G0_8_3 - 0.000270205984491826*G0_8_4 - 4.56686170972101e-05*G0_8_5 - 0.000243565957851787*G0_8_7 + 0.000578469149897993*G0_8_8 + 0.000296846011131865*G0_8_9 + 7.6114361828683e-06*G0_9_0 + 8.11886526172622e-05*G0_9_1 + 4.82057624914995e-05*G0_9_2 + 0.000274011702583259*G0_9_3 - 0.000205508776937445*G0_9_4 + 6.85029256458151e-05*G0_9_5 - 0.00027401170258326*G0_9_6 - 0.000114171542743025*G0_9_7 + 0.000296846011131865*G0_9_8 + 0.00013700585129163*G0_9_9; + A[65] = -A[50] - 9.23239018477548e-06*G0_0_0 + 3.86444830889456e-06*G0_0_1 - 3.30651124302074e-05*G0_0_2 + 2.33628805057486e-05*G0_0_3 - 8.70029441458422e-05*G0_0_4 + 4.08057550914886e-05*G0_0_5 - 7.11457854315332e-05*G0_0_6 + 1.41657284514494e-05*G0_0_7 + 8.77429448858436e-06*G0_0_8 - 5.20114805829337e-05*G0_0_9 + 3.86444830889457e-06*G0_1_0 + 0.000104586771253487*G0_1_1 - 4.5081314922606e-05*G0_1_2 + 0.000347271775843368*G0_1_3 - 0.000244200244200359*G0_1_4 + 2.65343122486104e-05*G0_1_5 - 8.41486555772666e-05*G0_1_6 - 4.01714687429162e-05*G0_1_7 + 9.5248666677283e-05*G0_1_8 + 3.8691467262914e-05*G0_1_9 - 3.30651124302074e-05*G0_2_0 - 4.5081314922606e-05*G0_2_1 - 0.000458800458800675*G0_2_2 + 0.000356468927897667*G0_2_3 - 0.000743700743701094*G0_2_4 + 0.000150748722177365*G0_2_5 - 0.00029230029230043*G0_2_6 + 3.70000370000555e-06*G0_2_7 + 2.0508591937173e-05*G0_2_8 - 0.000113537256394453*G0_2_9 + 2.33628805057486e-05*G0_3_0 + 0.000347271775843368*G0_3_1 + 0.000356468927897667*G0_3_2 - 0.000696446410732454*G0_3_3 + 0.000416726131012042*G0_3_4 - 0.000106560106560157*G0_3_5 + 0.000315874601589036*G0_3_6 - 6.66000666000997e-06*G0_3_7 + 4.75714761429295e-06*G0_3_8 - 0.000102754388468722*G0_3_9 - 8.70029441458422e-05*G0_4_0 - 0.000244200244200359*G0_4_1 - 0.000743700743701094*G0_4_2 + 0.000416726131012042*G0_4_3 - 0.000764949336378266*G0_4_4 + 0.000324437467294763*G0_4_5 - 0.000640312068883798*G0_4_6 + 9.32400932401373e-05*G0_4_7 + 1.9028590457168e-06*G0_4_8 - 0.000308263165406167*G0_4_9 + 4.08057550914886e-05*G0_5_0 + 2.65343122486104e-05*G0_5_1 + 0.000150748722177365*G0_5_2 - 0.000106560106560157*G0_5_3 + 0.000324437467294763*G0_5_4 - 0.000148423005565932*G0_5_5 + 0.000288283145426138*G0_5_6 - 3.61543218686246e-05*G0_5_7 - 1.61743018885951e-05*G0_5_8 + 0.000188383045525991*G0_5_9 - 7.11457854315332e-05*G0_6_0 - 8.41486555772666e-05*G0_6_1 - 0.00029230029230043*G0_6_2 + 0.000315874601589036*G0_6_3 - 0.000640312068883798*G0_6_4 + 0.000288283145426138*G0_6_5 - 0.000645069216498091*G0_6_6 + 5.232862375722e-05*G0_6_7 + 6.3745778031522e-05*G0_6_8 - 0.000291137433994714*G0_6_9 + 1.41657284514494e-05*G0_7_0 - 4.01714687429162e-05*G0_7_1 + 3.70000370000555e-06*G0_7_2 - 6.66000666000997e-06*G0_7_3 + 9.32400932401373e-05*G0_7_4 - 3.61543218686247e-05*G0_7_5 + 5.232862375722e-05*G0_7_6 - 3.42514628229074e-05*G0_7_7 - 4.28143285286346e-05*G0_7_8 + 5.13771942343613e-05*G0_7_9 + 8.77429448858436e-06*G0_8_0 + 9.52486666772829e-05*G0_8_1 + 2.0508591937173e-05*G0_8_2 + 4.75714761429295e-06*G0_8_3 + 1.9028590457168e-06*G0_8_4 - 1.61743018885951e-05*G0_8_5 + 6.3745778031522e-05*G0_8_6 - 4.28143285286346e-05*G0_8_7 - 8.56286570572686e-05*G0_8_8 - 0.000119880119880176*G0_8_9 - 5.20114805829337e-05*G0_9_0 + 3.8691467262914e-05*G0_9_1 - 0.000113537256394453*G0_9_2 - 0.000102754388468722*G0_9_3 - 0.000308263165406167*G0_9_4 + 0.000188383045525991*G0_9_5 - 0.000291137433994714*G0_9_6 + 5.13771942343613e-05*G0_9_7 - 0.000119880119880176*G0_9_8 - 0.00068502925645815*G0_9_9; + A[79] = A[65]; + A[85] = A[139] - 2.36800236800348e-05*G0_0_0 + 2.46666913333698e-06*G0_0_1 - 3.42514628229075e-05*G0_0_3 - 7.61143618286829e-06*G0_0_4 - 3.42514628229074e-05*G0_0_5 + 3.04457447314733e-05*G0_0_6 - 7.16743573886768e-05*G0_0_7 - 1.26857269714472e-05*G0_0_8 - 8.75315161029859e-05*G0_0_9 + 2.46666913333697e-06*G0_1_0 - 2.46666913333694e-06*G0_1_2 + 3.74228945657691e-05*G0_1_3 + 4.31314717029207e-05*G0_1_4 - 2.66400266400392e-05*G0_1_5 + 2.66400266400392e-05*G0_1_6 - 4.31314717029206e-05*G0_1_7 - 3.74228945657693e-05*G0_1_8 - 2.46666913333694e-06*G0_2_1 + 2.36800236800349e-05*G0_2_2 + 1.26857269714471e-05*G0_2_3 + 7.16743573886771e-05*G0_2_4 - 3.04457447314734e-05*G0_2_5 + 3.42514628229076e-05*G0_2_6 + 7.61143618286825e-06*G0_2_7 + 3.42514628229075e-05*G0_2_8 + 8.75315161029858e-05*G0_2_9 - 3.42514628229075e-05*G0_3_0 + 3.74228945657691e-05*G0_3_1 + 1.26857269714471e-05*G0_3_2 - 0.000251177394034655*G0_3_3 - 0.000268303125446109*G0_3_4 + 9.13372341944201e-05*G0_3_5 - 7.99200799201177e-05*G0_3_6 + 0.000102754388468723*G0_3_7 - 0.000205508776937445*G0_3_9 - 7.61143618286828e-06*G0_4_0 + 4.31314717029207e-05*G0_4_1 + 7.16743573886771e-05*G0_4_2 - 0.000268303125446109*G0_4_3 - 0.000182674468388839*G0_4_4 + 2.28343085486048e-05*G0_4_5 + 5.70857713715129e-05*G0_4_6 - 0.000102754388468722*G0_4_8 - 0.000308263165406167*G0_4_9 - 3.42514628229074e-05*G0_5_0 - 2.66400266400392e-05*G0_5_1 - 3.04457447314734e-05*G0_5_2 + 9.13372341944201e-05*G0_5_3 + 2.28343085486048e-05*G0_5_4 - 6.85029256458146e-05*G0_5_5 - 5.70857713715126e-05*G0_5_7 + 7.99200799201174e-05*G0_5_8 + 0.000102754388468722*G0_5_9 + 3.04457447314733e-05*G0_6_0 + 2.66400266400392e-05*G0_6_1 + 3.42514628229076e-05*G0_6_2 - 7.99200799201177e-05*G0_6_3 + 5.70857713715129e-05*G0_6_4 + 6.85029256458153e-05*G0_6_6 - 2.28343085486049e-05*G0_6_7 - 9.13372341944201e-05*G0_6_8 - 0.000102754388468722*G0_6_9 - 7.16743573886768e-05*G0_7_0 - 4.31314717029206e-05*G0_7_1 + 7.61143618286825e-06*G0_7_2 + 0.000102754388468723*G0_7_3 - 5.70857713715126e-05*G0_7_5 - 2.28343085486049e-05*G0_7_6 + 0.000182674468388839*G0_7_7 + 0.000268303125446109*G0_7_8 + 0.000308263165406167*G0_7_9 - 1.26857269714472e-05*G0_8_0 - 3.74228945657693e-05*G0_8_1 + 3.42514628229075e-05*G0_8_2 - 0.000102754388468722*G0_8_4 + 7.99200799201174e-05*G0_8_5 - 9.13372341944201e-05*G0_8_6 + 0.000268303125446109*G0_8_7 + 0.000251177394034655*G0_8_8 + 0.000205508776937445*G0_8_9 - 8.75315161029859e-05*G0_9_0 + 8.75315161029858e-05*G0_9_2 - 0.000205508776937445*G0_9_3 - 0.000308263165406167*G0_9_4 + 0.000102754388468722*G0_9_5 - 0.000102754388468722*G0_9_6 + 0.000308263165406167*G0_9_7 + 0.000205508776937445*G0_9_8; + A[138] = -A[85] + 1.37311248422424e-05*G0_0_0 + 1.0031121142237e-05*G0_0_1 + 3.98190874381539e-06*G0_0_2 + 6.9665783951531e-05*G0_0_3 - 7.717150574297e-06*G0_0_4 - 1.12057254914452e-05*G0_0_5 + 1.13114398828739e-05*G0_0_6 - 5.40200540200797e-05*G0_0_7 + 2.11428782857543e-07*G0_0_8 - 6.34286348572337e-07*G0_0_9 + 1.0031121142237e-05*G0_1_0 + 8.04134137467849e-05*G0_1_1 + 1.19809643619224e-05*G0_1_2 + 0.000119351547923032*G0_1_3 - 3.73171801743404e-05*G0_1_4 + 1.13114398828738e-05*G0_1_6 - 4.49286163572091e-05*G0_1_7 - 6.87143544286718e-06*G0_1_8 - 2.2834308548605e-05*G0_1_9 + 3.98190874381539e-06*G0_2_0 + 1.19809643619224e-05*G0_2_1 + 2.74505036409929e-05*G0_2_2 + 6.02572031143741e-05*G0_2_3 + 1.58571587143124e-06*G0_2_4 + 1.51171579743078e-05*G0_2_7 + 5.82486296772285e-05*G0_2_8 + 0.00010212010212015*G0_2_9 + 6.9665783951531e-05*G0_3_0 + 0.000119351547923032*G0_3_1 + 6.02572031143741e-05*G0_3_2 + 0.00139003853289633*G0_3_3 - 0.000382474668189134*G0_3_4 - 8.46772275344102e-05*G0_3_5 - 7.32600732601078e-05*G0_3_6 - 0.00024832310546608*G0_3_7 + 0.000462394748109251*G0_3_8 + 0.000565149136577973*G0_3_9 - 7.71715057429699e-06*G0_4_0 - 3.73171801743404e-05*G0_4_1 + 1.58571587143124e-06*G0_4_2 - 0.000382474668189134*G0_4_3 + 0.000148423005565934*G0_4_4 - 1.61743018885954e-05*G0_4_5 + 8.94343751487034e-05*G0_4_6 + 8.56286570572698e-06*G0_4_7 - 0.000214071642643172*G0_4_8 - 0.00027401170258326*G0_4_9 - 1.12057254914452e-05*G0_5_0 - 8.46772275344102e-05*G0_5_3 - 1.61743018885954e-05*G0_5_4 + 0.000157937300794518*G0_5_5 - 7.32600732601077e-05*G0_5_6 + 0.00012368583797161*G0_5_7 - 3.90086104372002e-05*G0_5_8 + 7.99200799201172e-05*G0_5_9 + 1.13114398828739e-05*G0_6_0 + 1.13114398828738e-05*G0_6_1 - 7.32600732601079e-05*G0_6_3 + 8.94343751487034e-05*G0_6_4 - 7.32600732601077e-05*G0_6_5 + 8.94343751487033e-05*G0_6_6 - 8.467722753441e-05*G0_6_7 - 8.46772275344103e-05*G0_6_8 - 0.000159840159840235*G0_6_9 - 5.40200540200797e-05*G0_7_0 - 4.49286163572091e-05*G0_7_1 + 1.51171579743078e-05*G0_7_2 - 0.00024832310546608*G0_7_3 + 8.56286570572698e-06*G0_7_4 + 0.00012368583797161*G0_7_5 - 8.46772275344101e-05*G0_7_6 + 0.000407211835783455*G0_7_7 + 7.61143618286833e-05*G0_7_8 + 0.000171257314114537*G0_7_9 + 2.11428782857543e-07*G0_8_0 - 6.87143544286718e-06*G0_8_1 + 5.82486296772285e-05*G0_8_2 + 0.000462394748109251*G0_8_3 - 0.000214071642643172*G0_8_4 - 3.90086104372003e-05*G0_8_5 - 8.46772275344103e-05*G0_8_6 + 7.61143618286833e-05*G0_8_7 + 0.000575614861329418*G0_8_8 + 0.000496646210932159*G0_8_9 - 6.34286348572323e-07*G0_9_0 - 2.2834308548605e-05*G0_9_1 + 0.00010212010212015*G0_9_2 + 0.000565149136577973*G0_9_3 - 0.00027401170258326*G0_9_4 + 7.99200799201172e-05*G0_9_5 - 0.000159840159840235*G0_9_6 + 0.000171257314114537*G0_9_7 + 0.000496646210932159*G0_9_8 + 0.000924789496218504*G0_9_9; + A[66] = A[94]; + A[137] = A[21] + 1.82357325214553e-05*G0_0_5 - 4.75714761429271e-07*G0_0_6 - 1.82357325214554e-05*G0_0_7 + 4.75714761429271e-07*G0_0_8 - 2.29576420052719e-05*G0_1_1 - 3.24543181686191e-05*G0_1_3 + 1.8764304478599e-05*G0_1_4 + 9.51429522858547e-06*G0_1_5 + 2.32571661143204e-06*G0_1_7 - 2.82785997071844e-05*G0_1_8 - 1.30028701457333e-05*G0_1_9 + 2.29576420052718e-05*G0_2_2 - 1.8764304478599e-05*G0_2_3 + 3.24543181686191e-05*G0_2_4 - 2.32571661143196e-06*G0_2_5 + 2.82785997071844e-05*G0_2_6 - 9.51429522858538e-06*G0_2_7 + 1.30028701457334e-05*G0_2_9 - 3.24543181686191e-05*G0_3_1 - 1.8764304478599e-05*G0_3_2 - 4.28143285286345e-06*G0_3_3 - 6.66000666000984e-06*G0_3_5 + 1.52228723657367e-05*G0_3_7 - 2.47371675943221e-05*G0_3_8 + 8.56286570572678e-06*G0_3_9 + 1.8764304478599e-05*G0_4_1 + 3.24543181686191e-05*G0_4_2 + 4.2814328528634e-06*G0_4_4 - 1.52228723657367e-05*G0_4_5 + 2.47371675943221e-05*G0_4_6 + 6.66000666000974e-06*G0_4_7 - 8.56286570572691e-06*G0_4_9 + 1.82357325214554e-05*G0_5_0 + 9.51429522858547e-06*G0_5_1 - 2.32571661143196e-06*G0_5_2 - 6.66000666000983e-06*G0_5_3 - 1.52228723657367e-05*G0_5_4 + 0.00028067170924327*G0_5_5 - 8.03957946815469e-05*G0_5_6 - 2.85428856857564e-05*G0_5_8 + 5.70857713715129e-05*G0_5_9 - 4.75714761429271e-07*G0_6_0 + 2.82785997071844e-05*G0_6_2 + 2.47371675943221e-05*G0_6_4 - 8.03957946815469e-05*G0_6_5 + 3.37757480614782e-05*G0_6_6 + 2.85428856857562e-05*G0_6_7 - 1.99800199800295e-05*G0_6_9 - 1.82357325214554e-05*G0_7_0 + 2.32571661143205e-06*G0_7_1 - 9.51429522858538e-06*G0_7_2 + 1.52228723657367e-05*G0_7_3 + 6.66000666000974e-06*G0_7_4 + 2.85428856857562e-05*G0_7_6 - 0.000280671709243269*G0_7_7 + 8.03957946815467e-05*G0_7_8 - 5.70857713715121e-05*G0_7_9 + 4.75714761429268e-07*G0_8_0 - 2.82785997071844e-05*G0_8_1 - 2.47371675943221e-05*G0_8_3 - 2.85428856857564e-05*G0_8_5 + 8.03957946815467e-05*G0_8_7 - 3.37757480614782e-05*G0_8_8 + 1.99800199800292e-05*G0_8_9 - 1.30028701457334e-05*G0_9_1 + 1.30028701457334e-05*G0_9_2 + 8.56286570572679e-06*G0_9_3 - 8.56286570572691e-06*G0_9_4 + 5.70857713715129e-05*G0_9_5 - 1.99800199800295e-05*G0_9_6 - 5.70857713715121e-05*G0_9_7 + 1.99800199800292e-05*G0_9_8; + A[181] = A[137] + 2.35155790711456e-05*G0_0_0 + 2.53185967471801e-05*G0_0_5 + 5.33857676715073e-06*G0_0_6 + 2.30985945271768e-05*G0_0_7 - 1.65443022585958e-05*G0_0_8 + 1.77600177600262e-05*G0_0_9 - 3.53790829981478e-05*G0_1_1 - 1.82357325214555e-05*G0_1_3 + 1.63328734757384e-05*G0_1_4 - 3.92993250136293e-05*G0_1_5 + 1.29500129500196e-06*G0_1_6 + 5.81429152857968e-07*G0_1_7 - 3.54143211286246e-06*G0_1_8 - 4.31314717029207e-05*G0_1_9 + 8.61572290144132e-06*G0_2_4 - 9.14429485858497e-06*G0_2_5 + 1.36900136900202e-05*G0_2_6 + 1.01750101750148e-05*G0_2_7 + 3.61543218686245e-05*G0_2_9 - 1.82357325214555e-05*G0_3_1 + 7.92065077779734e-05*G0_3_3 - 4.49550449550662e-05*G0_3_4 + 6.35079206508079e-05*G0_3_5 - 9.27643784787084e-06*G0_3_6 - 1.66500166500233e-06*G0_3_7 + 1.47471576043073e-05*G0_3_8 + 0.000132724418438767*G0_3_9 + 1.63328734757384e-05*G0_4_1 + 8.61572290144132e-06*G0_4_2 - 4.49550449550662e-05*G0_4_3 + 1.92664478378855e-05*G0_4_4 - 9.27643784787072e-06*G0_4_5 - 1.45093002235926e-05*G0_4_7 - 8.99100899101322e-05*G0_4_9 + 2.53185967471801e-05*G0_5_0 - 3.92993250136293e-05*G0_5_1 - 9.14429485858497e-06*G0_5_2 + 6.35079206508079e-05*G0_5_3 - 9.27643784787072e-06*G0_5_4 - 0.000390799676514147*G0_5_5 + 4.51929023357834e-06*G0_5_6 - 7.65900765901135e-05*G0_5_7 + 0.000112506541078023*G0_5_8 - 0.000278293135436124*G0_5_9 + 5.33857676715073e-06*G0_6_0 + 1.29500129500196e-06*G0_6_1 + 1.36900136900202e-05*G0_6_2 - 9.27643784787085e-06*G0_6_3 + 4.51929023357834e-06*G0_6_5 - 4.54307597164954e-05*G0_6_6 - 3.59164644879096e-05*G0_6_7 - 3.09214594929044e-06*G0_6_8 - 8.99100899101319e-05*G0_6_9 + 2.30985945271768e-05*G0_7_0 + 5.81429152857961e-07*G0_7_1 + 1.01750101750148e-05*G0_7_2 - 1.66500166500233e-06*G0_7_3 - 1.45093002235926e-05*G0_7_4 - 7.65900765901135e-05*G0_7_5 - 3.59164644879096e-05*G0_7_6 + 0.000280909566623983*G0_7_7 - 5.94643451786532e-06*G0_7_8 + 1.85528756957405e-05*G0_7_9 - 1.65443022585958e-05*G0_8_0 - 3.54143211286246e-06*G0_8_1 + 1.47471576043073e-05*G0_8_3 + 0.000112506541078023*G0_8_5 - 3.09214594929044e-06*G0_8_6 - 5.94643451786532e-06*G0_8_7 - 4.4479330193637e-05*G0_8_8 + 0.000155558726987372*G0_8_9 + 1.77600177600262e-05*G0_9_0 - 4.31314717029207e-05*G0_9_1 + 3.61543218686245e-05*G0_9_2 + 0.000132724418438767*G0_9_3 - 8.99100899101322e-05*G0_9_4 - 0.000278293135436125*G0_9_5 - 8.99100899101319e-05*G0_9_6 + 1.85528756957405e-05*G0_9_7 + 0.000155558726987372*G0_9_8 - 7.70657913515433e-05*G0_9_9; + A[27] = A[181]; + A[91] = A[21]; + A[168] = A[56]; + A[109] = A[123] - 2.01121629693152e-05*G0_0_0 + 1.14523924047758e-07*G0_0_1 + 8.98572327144175e-06*G0_0_2 - 4.35807578664926e-05*G0_0_3 - 1.32142989285917e-07*G0_0_4 - 1.50643007785903e-06*G0_0_5 + 1.42714428428779e-05*G0_0_6 - 1.69407312264536e-05*G0_0_8 - 5.50243407386523e-05*G0_0_9 + 1.14523924047758e-07*G0_1_0 - 3.00728078506e-05*G0_1_1 + 1.34022356244641e-05*G0_1_2 - 1.75750175750262e-05*G0_1_3 + 6.16314902029477e-05*G0_1_4 - 2.83578855007558e-05*G0_1_5 - 4.58007600864961e-05*G0_1_6 - 1.71785886071665e-06*G0_1_7 - 2.13014498728886e-05*G0_1_8 - 3.98014683729159e-05*G0_1_9 + 8.98572327144174e-06*G0_2_0 + 1.34022356244641e-05*G0_2_1 + 0.000111863445196831*G0_2_2 - 8.53379424808397e-05*G0_2_3 + 0.000232915232915342*G0_2_4 - 4.98179069607874e-05*G0_2_5 + 0.000144115144115211*G0_2_6 - 7.42643599786802e-06*G0_2_7 - 2.26493083636048e-05*G0_2_8 + 0.0001170258313116*G0_2_9 - 4.35807578664926e-05*G0_3_0 - 1.75750175750262e-05*G0_3_1 - 8.53379424808397e-05*G0_3_2 - 0.000284477427334704*G0_3_3 - 0.000197421625993146*G0_3_4 + 0.000113457970600881*G0_3_5 + 0.000126302269159472*G0_3_6 + 0.000119642262499462*G0_3_7 - 0.00017649017649026*G0_3_8 - 0.000119880119880175*G0_3_9 - 1.32142989285917e-07*G0_4_0 + 6.16314902029477e-05*G0_4_1 + 0.000232915232915342*G0_4_2 - 0.000197421625993146*G0_4_3 - 0.000112506541078022*G0_4_4 - 1.07035821321584e-05*G0_4_5 - 0.000115598687027314*G0_4_6 + 1.68878740307389e-05*G0_4_7 + 5.68479139907983e-05*G0_4_8 - 0.000329670329670484*G0_4_9 - 1.50643007785903e-06*G0_5_0 - 2.83578855007558e-05*G0_5_1 - 4.98179069607874e-05*G0_5_2 + 0.000113457970600881*G0_5_3 - 1.07035821321584e-05*G0_5_4 - 0.000208363065506021*G0_5_5 - 7.13572142143834e-06*G0_5_6 - 8.51529422958393e-05*G0_5_7 + 7.39736454022515e-05*G0_5_8 + 1.7125731411454e-05*G0_5_9 + 1.42714428428779e-05*G0_6_0 - 4.58007600864961e-05*G0_6_1 + 0.000144115144115211*G0_6_2 + 0.000126302269159472*G0_6_3 - 0.000115598687027314*G0_6_4 - 7.13572142143856e-06*G0_6_5 - 0.00117810760667959*G0_6_6 + 1.1179296893588e-05*G0_6_7 + 0.000108225108225159*G0_6_8 - 0.000603682032253746*G0_6_9 - 1.71785886071665e-06*G0_7_1 - 7.42643599786802e-06*G0_7_2 + 0.000119642262499462*G0_7_3 + 1.68878740307389e-05*G0_7_4 - 8.51529422958393e-05*G0_7_5 + 1.1179296893588e-05*G0_7_6 - 6.80272108843858e-05*G0_7_7 + 0.000131059416773764*G0_7_8 + 0.000142714428428781*G0_7_9 - 1.69407312264536e-05*G0_8_0 - 2.13014498728887e-05*G0_8_1 - 2.26493083636048e-05*G0_8_2 - 0.00017649017649026*G0_8_3 + 5.68479139907983e-05*G0_8_4 + 7.39736454022515e-05*G0_8_5 + 0.000108225108225159*G0_8_6 + 0.000131059416773764*G0_8_7 - 0.000205033062176017*G0_8_8 + 5.70857713715088e-06*G0_8_9 - 5.50243407386523e-05*G0_9_0 - 3.98014683729159e-05*G0_9_1 + 0.0001170258313116*G0_9_2 - 0.000119880119880175*G0_9_3 - 0.000329670329670484*G0_9_4 + 1.71257314114541e-05*G0_9_5 - 0.000603682032253746*G0_9_6 + 0.000142714428428781*G0_9_7 + 5.70857713715088e-06*G0_9_8 - 0.000950478093335683*G0_9_9; + A[184] = A[72]; + A[213] = A[57] + 2.02971631543156e-05*G0_0_1 + 3.49562254324324e-05*G0_0_2 + 1.01485815771579e-05*G0_0_3 + 4.05943263086312e-05*G0_0_4 - 6.08914894629467e-05*G0_0_5 + 0.000152228723657367*G0_0_6 - 4.05943263086313e-05*G0_0_7 - 1.01485815771577e-05*G0_0_8 + 2.02971631543156e-05*G0_1_0 + 3.94667061333917e-05*G0_1_1 + 2.48076438552746e-05*G0_1_2 + 0.000152228723657367*G0_1_4 - 0.000142080142080209*G0_1_5 + 0.000223268794697471*G0_1_6 - 6.08914894629467e-05*G0_1_7 + 0.000121782978925893*G0_1_9 + 3.49562254324324e-05*G0_2_0 + 2.48076438552746e-05*G0_2_1 + 0.000158994444708805*G0_2_2 - 3.04457447314734e-05*G0_2_3 + 0.000334903192046207*G0_2_4 - 0.00018267446838884*G0_2_5 + 0.000243565957851787*G0_2_6 - 5.07429078857888e-05*G0_2_7 + 1.01485815771579e-05*G0_2_8 + 0.00018267446838884*G0_2_9 + 1.01485815771579e-05*G0_3_0 - 3.04457447314734e-05*G0_3_2 + 0.00219209362066608*G0_3_3 - 0.00109604681033304*G0_3_4 + 0.00027401170258326*G0_3_5 - 0.00082203510774978*G0_3_6 - 0.000182674468388841*G0_3_7 + 0.000365348936777681*G0_3_8 + 4.05943263086312e-05*G0_4_0 + 0.000152228723657367*G0_4_1 + 0.000334903192046207*G0_4_2 - 0.00109604681033304*G0_4_3 + 0.000548023405166521*G0_4_4 - 0.000274011702583261*G0_4_5 + 0.00109604681033304*G0_4_6 + 9.13372341944195e-05*G0_4_7 - 0.00018267446838884*G0_4_8 - 6.08914894629467e-05*G0_5_0 - 0.000142080142080209*G0_5_1 - 0.00018267446838884*G0_5_2 + 0.00027401170258326*G0_5_3 - 0.000274011702583261*G0_5_4 - 0.000456686170972099*G0_5_5 - 0.000456686170972101*G0_5_6 - 0.000274011702583259*G0_5_7 + 0.00027401170258326*G0_5_8 - 0.00054802340516652*G0_5_9 + 0.000152228723657367*G0_6_0 + 0.000223268794697471*G0_6_1 + 0.000243565957851787*G0_6_2 - 0.00082203510774978*G0_6_3 + 0.00109604681033304*G0_6_4 - 0.000456686170972101*G0_6_5 + 0.00200941915227724*G0_6_6 - 0.00027401170258326*G0_6_8 + 0.00109604681033304*G0_6_9 - 4.05943263086313e-05*G0_7_0 - 6.08914894629467e-05*G0_7_1 - 5.07429078857888e-05*G0_7_2 - 0.000182674468388841*G0_7_3 + 9.13372341944195e-05*G0_7_4 - 0.000274011702583259*G0_7_5 - 9.13372341944178e-05*G0_7_7 + 0.000182674468388839*G0_7_8 - 1.01485815771577e-05*G0_8_0 + 1.01485815771579e-05*G0_8_2 + 0.000365348936777681*G0_8_3 - 0.00018267446838884*G0_8_4 + 0.00027401170258326*G0_8_5 - 0.00027401170258326*G0_8_6 + 0.000182674468388839*G0_8_7 - 0.000365348936777678*G0_8_8 + 0.000121782978925893*G0_9_1 + 0.00018267446838884*G0_9_2 - 0.00054802340516652*G0_9_5 + 0.00109604681033304*G0_9_6; + A[204] = A[148]; + A[2] = -4.08696242029767e-05*G0_0_0 - 1.84192644510191e-06*G0_0_1 - 5.90257038670015e-06*G0_0_2 + 1.72281422281503e-06*G0_0_3 - 2.80275280275412e-05*G0_0_5 + 1.07630464773372e-05*G0_0_6 - 2.03500203500299e-05*G0_0_7 + 1.06705463848371e-05*G0_0_8 - 3.76607519464839e-06*G0_0_9 - 1.84192644510191e-06*G0_1_0 + 2.66708600042059e-06*G0_1_1 - 1.84192644510192e-06*G0_1_2 + 5.36996072710612e-06*G0_1_3 - 3.3366104794692e-06*G0_1_4 - 1.24049231192146e-06*G0_1_5 - 1.24049231192147e-06*G0_1_6 - 3.33661047946919e-06*G0_1_7 + 5.36996072710611e-06*G0_1_8 + 2.87411001696851e-06*G0_1_9 - 5.90257038670015e-06*G0_2_0 - 1.84192644510192e-06*G0_2_1 - 4.08696242029769e-05*G0_2_2 + 1.06705463848371e-05*G0_2_3 - 2.035002035003e-05*G0_2_4 + 1.07630464773373e-05*G0_2_5 - 2.80275280275413e-05*G0_2_6 + 1.72281422281503e-06*G0_2_8 - 3.7660751946484e-06*G0_2_9 + 1.72281422281503e-06*G0_3_0 + 5.36996072710612e-06*G0_3_1 + 1.06705463848371e-05*G0_3_2 + 1.20415298986785e-06*G0_3_3 + 1.07035821321586e-06*G0_3_4 - 1.88799295942242e-06*G0_3_5 + 6.05049712192855e-06*G0_3_6 - 2.83942248228097e-06*G0_3_7 + 5.67884496456194e-06*G0_3_8 - 2.94348508634361e-06*G0_3_9 - 3.3366104794692e-06*G0_4_1 - 2.035002035003e-05*G0_4_2 + 1.07035821321586e-06*G0_4_3 - 2.80969030969165e-06*G0_4_4 + 4.04357547214881e-06*G0_4_5 - 1.00940725940774e-05*G0_4_6 - 2.83942248228098e-06*G0_4_8 + 3.21107463964757e-06*G0_4_9 - 2.80275280275412e-05*G0_5_0 - 1.24049231192146e-06*G0_5_1 + 1.07630464773373e-05*G0_5_2 - 1.88799295942242e-06*G0_5_3 + 4.04357547214881e-06*G0_5_4 - 4.21453546453744e-05*G0_5_5 + 2.55548023405287e-05*G0_5_6 - 1.00940725940773e-05*G0_5_7 + 6.05049712192853e-06*G0_5_8 + 1.07630464773372e-05*G0_6_0 - 1.24049231192147e-06*G0_6_1 - 2.80275280275413e-05*G0_6_2 + 6.05049712192855e-06*G0_6_3 - 1.00940725940774e-05*G0_6_4 + 2.55548023405286e-05*G0_6_5 - 4.21453546453745e-05*G0_6_6 + 4.04357547214879e-06*G0_6_7 - 1.88799295942242e-06*G0_6_8 - 2.03500203500299e-05*G0_7_0 - 3.33661047946919e-06*G0_7_1 - 2.83942248228097e-06*G0_7_3 - 1.00940725940773e-05*G0_7_5 + 4.04357547214879e-06*G0_7_6 - 2.80969030969159e-06*G0_7_7 + 1.07035821321583e-06*G0_7_8 + 3.21107463964758e-06*G0_7_9 + 1.06705463848371e-05*G0_8_0 + 5.36996072710611e-06*G0_8_1 + 1.72281422281503e-06*G0_8_2 + 5.67884496456194e-06*G0_8_3 - 2.83942248228098e-06*G0_8_4 + 6.05049712192853e-06*G0_8_5 - 1.88799295942242e-06*G0_8_6 + 1.07035821321583e-06*G0_8_7 + 1.2041529898679e-06*G0_8_8 - 2.94348508634359e-06*G0_8_9 - 3.76607519464839e-06*G0_9_0 + 2.87411001696851e-06*G0_9_1 - 3.7660751946484e-06*G0_9_2 - 2.94348508634361e-06*G0_9_3 + 3.21107463964757e-06*G0_9_4 + 3.21107463964758e-06*G0_9_7 - 2.94348508634359e-06*G0_9_8 + 1.01684030255507e-05*G0_9_9; + A[133] = A[108] - 2.70276460752778e-05*G0_0_0 - 2.99524109048063e-06*G0_0_1 - 8.24572253144071e-06*G0_0_2 + 1.99800199800292e-05*G0_0_3 - 3.7105751391483e-05*G0_0_4 - 7.29429300858198e-06*G0_0_5 - 4.24971853543483e-05*G0_0_6 - 5.89886304172295e-05*G0_0_7 + 3.13971742543317e-05*G0_0_8 - 0.000108462965605874*G0_0_9 - 2.99524109048063e-06*G0_1_0 - 6.16667283334293e-06*G0_1_1 + 1.4095252190491e-07*G0_1_2 + 3.01286015571864e-05*G0_1_3 - 1.4588586017164e-05*G0_1_4 - 2.85428856857553e-06*G0_1_5 - 0.000117025831311601*G0_1_6 - 3.45686059971935e-05*G0_1_7 - 0.000119880119880176*G0_1_9 - 8.24572253144071e-06*G0_2_0 + 1.4095252190491e-07*G0_2_1 + 4.78533811867373e-05*G0_2_2 + 7.29429300858177e-06*G0_2_3 + 4.34486148772068e-05*G0_2_4 + 1.49057291914504e-05*G0_2_5 - 7.92857935715441e-06*G0_2_6 + 7.70657913515417e-05*G0_2_8 + 0.000159840159840235*G0_2_9 + 1.99800199800292e-05*G0_3_0 + 3.01286015571864e-05*G0_3_1 + 7.29429300858178e-06*G0_3_2 - 1.14171542743071e-05*G0_3_3 - 2.85428856857546e-05*G0_3_4 - 4.28143285286344e-05*G0_3_5 + 0.00038532895675771*G0_3_6 - 2.56885971171799e-05*G0_3_7 + 0.000222634508348897*G0_3_8 + 0.000411017553874888*G0_3_9 - 3.7105751391483e-05*G0_4_0 - 1.4588586017164e-05*G0_4_1 + 4.34486148772068e-05*G0_4_2 - 2.85428856857547e-05*G0_4_3 - 0.000122734408448752*G0_4_4 + 0.000145568716997357*G0_4_5 - 0.000530897673755067*G0_4_6 + 4.28143285286342e-05*G0_4_7 - 0.000196945911231717*G0_4_8 - 0.000770657913515418*G0_4_9 - 7.29429300858196e-06*G0_5_0 - 2.85428856857553e-06*G0_5_1 + 1.49057291914504e-05*G0_5_2 - 4.28143285286344e-05*G0_5_3 + 0.000145568716997357*G0_5_4 - 0.000331097473954772*G0_5_5 + 0.00031968031968047*G0_5_6 - 8.56286570572688e-05*G0_5_7 + 4.28143285286343e-05*G0_5_8 + 0.000239760239760353*G0_5_9 - 4.24971853543483e-05*G0_6_0 - 0.000117025831311601*G0_6_1 - 7.92857935715441e-06*G0_6_2 + 0.00038532895675771*G0_6_3 - 0.000530897673755067*G0_6_4 + 0.00031968031968047*G0_6_5 - 0.00229199372056623*G0_6_6 + 4.28143285286349e-05*G0_6_7 + 4.28143285286343e-05*G0_6_8 - 0.00125017839303612*G0_6_9 - 5.89886304172295e-05*G0_7_0 - 3.45686059971935e-05*G0_7_1 - 2.56885971171799e-05*G0_7_3 + 4.28143285286342e-05*G0_7_4 - 8.56286570572688e-05*G0_7_5 + 4.28143285286349e-05*G0_7_6 + 0.000108462965605873*G0_7_7 + 3.13971742543324e-05*G0_7_8 + 0.000239760239760353*G0_7_9 + 3.13971742543317e-05*G0_8_0 + 7.70657913515417e-05*G0_8_2 + 0.000222634508348897*G0_8_3 - 0.000196945911231717*G0_8_4 + 4.28143285286343e-05*G0_8_5 + 4.28143285286343e-05*G0_8_6 + 3.13971742543325e-05*G0_8_7 + 0.000724989296418207*G0_8_8 + 0.000753532182103963*G0_8_9 - 0.000108462965605874*G0_9_0 - 0.000119880119880176*G0_9_1 + 0.000159840159840235*G0_9_2 + 0.000411017553874888*G0_9_3 - 0.000770657913515418*G0_9_4 + 0.000239760239760353*G0_9_5 - 0.00125017839303612*G0_9_6 + 0.000239760239760353*G0_9_7 + 0.000753532182103963*G0_9_8 - 0.000513771942343615*G0_9_9; + A[132] = A[133] + 0.000158994444708805*G0_0_0 + 3.49562254324323e-05*G0_0_1 + 2.48076438552745e-05*G0_0_2 - 5.07429078857888e-05*G0_0_3 + 1.01485815771577e-05*G0_0_4 + 0.000334903192046206*G0_0_5 - 3.04457447314733e-05*G0_0_6 + 0.000243565957851786*G0_0_7 - 0.00018267446838884*G0_0_8 + 0.00018267446838884*G0_0_9 + 3.49562254324323e-05*G0_1_0 + 2.02971631543155e-05*G0_1_2 - 4.0594326308631e-05*G0_1_3 - 1.01485815771578e-05*G0_1_4 + 4.05943263086307e-05*G0_1_5 + 1.01485815771577e-05*G0_1_6 + 0.000152228723657366*G0_1_7 - 6.08914894629465e-05*G0_1_8 + 2.48076438552745e-05*G0_2_0 + 2.02971631543155e-05*G0_2_1 + 3.9466706133391e-05*G0_2_2 - 6.08914894629465e-05*G0_2_3 + 0.000152228723657367*G0_2_5 + 0.000223268794697471*G0_2_7 - 0.000142080142080209*G0_2_8 + 0.000121782978925893*G0_2_9 - 5.07429078857888e-05*G0_3_0 - 4.0594326308631e-05*G0_3_1 - 6.08914894629465e-05*G0_3_2 - 9.13372341944201e-05*G0_3_3 + 0.00018267446838884*G0_3_4 + 9.13372341944202e-05*G0_3_5 - 0.00018267446838884*G0_3_6 - 0.00027401170258326*G0_3_8 + 1.01485815771577e-05*G0_4_0 - 1.01485815771578e-05*G0_4_1 + 0.00018267446838884*G0_4_3 - 0.00036534893677768*G0_4_4 - 0.000182674468388839*G0_4_5 + 0.00036534893677768*G0_4_6 - 0.00027401170258326*G0_4_7 + 0.00027401170258326*G0_4_8 + 0.000334903192046206*G0_5_0 + 4.05943263086307e-05*G0_5_1 + 0.000152228723657367*G0_5_2 + 9.13372341944201e-05*G0_5_3 - 0.000182674468388839*G0_5_4 + 0.000548023405166515*G0_5_5 - 0.00109604681033304*G0_5_6 + 0.00109604681033304*G0_5_7 - 0.000274011702583259*G0_5_8 - 3.04457447314733e-05*G0_6_0 + 1.01485815771577e-05*G0_6_1 - 0.00018267446838884*G0_6_3 + 0.00036534893677768*G0_6_4 - 0.00109604681033304*G0_6_5 + 0.00219209362066608*G0_6_6 - 0.000822035107749779*G0_6_7 + 0.00027401170258326*G0_6_8 + 0.000243565957851786*G0_7_0 + 0.000152228723657366*G0_7_1 + 0.000223268794697471*G0_7_2 - 0.00027401170258326*G0_7_4 + 0.00109604681033304*G0_7_5 - 0.000822035107749779*G0_7_6 + 0.00200941915227724*G0_7_7 - 0.000456686170972099*G0_7_8 + 0.00109604681033304*G0_7_9 - 0.00018267446838884*G0_8_0 - 6.08914894629465e-05*G0_8_1 - 0.000142080142080209*G0_8_2 - 0.00027401170258326*G0_8_3 + 0.00027401170258326*G0_8_4 - 0.000274011702583259*G0_8_5 + 0.00027401170258326*G0_8_6 - 0.000456686170972099*G0_8_7 - 0.0004566861709721*G0_8_8 - 0.000548023405166518*G0_8_9 + 0.00018267446838884*G0_9_0 + 0.000121782978925893*G0_9_2 + 0.00109604681033304*G0_9_7 - 0.000548023405166518*G0_9_8; + A[188] = A[132]; + A[68] = A[133] + 2.17419265038413e-05*G0_0_0 - 6.7304829209623e-06*G0_0_1 - 3.84095622191042e-05*G0_0_2 + 2.85428856857578e-06*G0_0_3 - 5.80372008943711e-05*G0_0_4 + 0.000143031571603067*G0_0_5 - 0.00011290297004588*G0_0_6 + 0.000112268683697308*G0_0_7 - 5.80372008943709e-05*G0_0_8 + 6.27943485086638e-05*G0_0_9 - 6.7304829209623e-06*G0_1_0 - 3.77400377400554e-05*G0_1_1 - 3.77047996095793e-05*G0_1_2 + 9.83143840287158e-06*G0_1_3 - 8.2457225314407e-05*G0_1_4 + 4.09114694829172e-05*G0_1_5 - 8.08715094429761e-05*G0_1_6 + 6.12086326372328e-05*G0_1_7 + 9.51429522858517e-06*G0_1_9 - 3.84095622191042e-05*G0_2_0 - 3.77047996095793e-05*G0_2_1 - 0.000397133730467251*G0_2_2 + 0.000136054421768772*G0_2_3 - 0.000366300366300539*G0_2_4 + 0.000224854510568902*G0_2_5 - 0.000410700410700605*G0_2_6 + 2.94943152086149e-05*G0_2_7 - 9.99000999001468e-05*G0_2_8 - 0.000232148803577484*G0_2_9 + 2.85428856857577e-06*G0_3_0 + 9.83143840287158e-06*G0_3_1 + 0.000136054421768772*G0_3_2 - 0.000422434708149192*G0_3_3 + 0.000536606250892217*G0_3_4 - 0.000105608677037298*G0_3_5 + 0.000322534608249045*G0_3_6 + 7.13572142143904e-05*G0_3_7 - 0.000450977593834948*G0_3_8 - 0.000171257314114536*G0_3_9 - 5.80372008943711e-05*G0_4_0 - 8.2457225314407e-05*G0_4_1 - 0.000366300366300539*G0_4_2 + 0.000536606250892218*G0_4_3 - 0.000842015127729809*G0_4_4 + 0.000254031682603231*G0_4_5 - 0.000576566290852276*G0_4_6 + 2.8542885685758e-06*G0_4_7 + 0.000379620379620558*G0_4_8 + 0.000188383045525991*G0_4_9 + 0.000143031571603067*G0_5_0 + 4.09114694829172e-05*G0_5_1 + 0.000224854510568902*G0_5_2 - 0.000105608677037298*G0_5_3 + 0.000254031682603231*G0_5_4 - 0.000171257314114539*G0_5_5 + 0.000205508776937446*G0_5_6 + 5.13771942343609e-05*G0_5_7 - 4.2814328528634e-05*G0_5_8 - 0.000102754388468723*G0_5_9 - 0.00011290297004588*G0_6_0 - 8.08715094429761e-05*G0_6_1 - 0.000410700410700605*G0_6_2 + 0.000322534608249045*G0_6_3 - 0.000576566290852276*G0_6_4 + 0.000205508776937446*G0_6_5 - 0.000522334808049339*G0_6_6 - 8.56286570572667e-06*G0_6_7 + 0.000231197374054625*G0_6_8 + 5.13771942343608e-05*G0_6_9 + 0.000112268683697308*G0_7_0 + 6.12086326372328e-05*G0_7_1 + 2.94943152086149e-05*G0_7_2 + 7.13572142143904e-05*G0_7_3 + 2.85428856857578e-06*G0_7_4 + 5.13771942343609e-05*G0_7_5 - 8.56286570572667e-06*G0_7_6 - 0.000142714428428781*G0_7_7 + 2.8542885685756e-06*G0_7_8 - 0.000171257314114537*G0_7_9 - 5.80372008943709e-05*G0_8_0 - 9.99000999001468e-05*G0_8_2 - 0.000450977593834948*G0_8_3 + 0.000379620379620558*G0_8_4 - 4.2814328528634e-05*G0_8_5 + 0.000231197374054625*G0_8_6 + 2.85428856857558e-06*G0_8_7 - 0.00103325246182437*G0_8_8 - 0.000787783644926871*G0_8_9 + 6.27943485086638e-05*G0_9_0 + 9.51429522858518e-06*G0_9_1 - 0.000232148803577484*G0_9_2 - 0.000171257314114536*G0_9_3 + 0.000188383045525991*G0_9_4 - 0.000102754388468723*G0_9_5 + 5.13771942343608e-05*G0_9_6 - 0.000171257314114537*G0_9_7 - 0.000787783644926871*G0_9_8 - 0.0009247894962185*G0_9_9; + A[45] = A[47] - 5.76143433286565e-06*G0_0_3 - 1.00428671857291e-05*G0_0_4 + 1.847358990217e-05*G0_0_5 + 1.09942967085876e-05*G0_0_7 - 5.41786256072226e-06*G0_0_8 + 1.42714428428778e-06*G0_0_9 + 1.80066846733597e-05*G0_1_1 + 3.92200392200576e-05*G0_1_3 - 3.16614602329037e-05*G0_1_4 + 1.58571587143093e-07*G0_1_7 - 3.17143174286189e-07*G0_1_9 - 0.000228554514268908*G0_2_2 + 7.8968650397259e-05*G0_2_3 - 0.000177758749187404*G0_2_4 + 5.95172023743734e-05*G0_2_5 - 0.000122364408078752*G0_2_6 + 5.41786256072219e-06*G0_2_8 - 3.45686059971938e-05*G0_2_9 - 5.76143433286565e-06*G0_3_0 + 3.92200392200576e-05*G0_3_1 + 7.89686503972591e-05*G0_3_2 - 0.000241900956186785*G0_3_3 + 0.000106322249179442*G0_3_4 - 5.9464345178659e-06*G0_3_5 + 4.1149326863632e-05*G0_3_6 + 3.40136054421929e-05*G0_3_7 - 3.44893202036224e-05*G0_3_8 - 6.70757813615274e-05*G0_3_9 - 1.00428671857291e-05*G0_4_0 - 3.16614602329037e-05*G0_4_1 - 0.000177758749187404*G0_4_2 + 0.000106322249179442*G0_4_3 - 0.000221920936206755*G0_4_4 + 4.68579040007833e-05*G0_4_5 - 8.80072308644153e-05*G0_4_6 - 1.66500166500245e-06*G0_4_7 + 4.75714761429363e-07*G0_4_8 + 9.99000999001473e-06*G0_4_9 + 1.847358990217e-05*G0_5_0 + 5.95172023743734e-05*G0_5_2 - 5.9464345178659e-06*G0_5_3 + 4.68579040007833e-05*G0_5_4 - 4.59064744779247e-05*G0_5_5 + 5.11393368536467e-05*G0_5_6 + 4.28143285286349e-06*G0_5_8 - 1.28442985585903e-05*G0_5_9 - 0.000122364408078752*G0_6_2 + 4.1149326863632e-05*G0_6_3 - 8.80072308644153e-05*G0_6_4 + 5.11393368536468e-05*G0_6_5 - 6.58864944579542e-05*G0_6_6 - 4.28143285286342e-06*G0_6_8 + 2.14071642643172e-05*G0_6_9 + 1.09942967085876e-05*G0_7_0 + 1.58571587143096e-07*G0_7_1 + 3.40136054421929e-05*G0_7_3 - 1.66500166500245e-06*G0_7_4 - 1.18928690357336e-06*G0_7_7 - 4.75714761429092e-07*G0_7_8 - 4.28143285286339e-06*G0_7_9 - 5.41786256072226e-06*G0_8_0 + 5.41786256072219e-06*G0_8_2 - 3.44893202036224e-05*G0_8_3 + 4.75714761429363e-07*G0_8_4 + 4.28143285286349e-06*G0_8_5 - 4.28143285286342e-06*G0_8_6 - 4.75714761429105e-07*G0_8_7 + 3.44893202036218e-05*G0_8_8 + 1.42714428428778e-06*G0_9_0 - 3.17143174286189e-07*G0_9_1 - 3.45686059971938e-05*G0_9_2 - 6.70757813615274e-05*G0_9_3 + 9.99000999001473e-06*G0_9_4 - 1.28442985585903e-05*G0_9_5 + 2.14071642643172e-05*G0_9_6 - 4.28143285286339e-06*G0_9_7 + 8.56286570572652e-06*G0_9_9; + A[120] = A[8]; + A[92] = A[36]; + A[179] = A[85] - 2.70276460752778e-05*G0_0_0 - 8.24572253144069e-06*G0_0_1 - 2.9952410904806e-06*G0_0_2 - 3.71057513914831e-05*G0_0_3 + 1.99800199800294e-05*G0_0_4 - 5.89886304172296e-05*G0_0_5 + 3.13971742543319e-05*G0_0_6 - 7.29429300858215e-06*G0_0_7 - 4.24971853543481e-05*G0_0_8 - 0.000108462965605874*G0_0_9 - 8.24572253144068e-06*G0_1_0 + 4.78533811867372e-05*G0_1_1 + 1.40952521904934e-07*G0_1_2 + 4.34486148772068e-05*G0_1_3 + 7.29429300858208e-06*G0_1_4 + 7.7065791351542e-05*G0_1_6 + 1.49057291914504e-05*G0_1_7 - 7.92857935715452e-06*G0_1_8 + 0.000159840159840235*G0_1_9 - 2.9952410904806e-06*G0_2_0 + 1.40952521904934e-07*G0_2_1 - 6.16667283334251e-06*G0_2_2 - 1.45885860171641e-05*G0_2_3 + 3.01286015571867e-05*G0_2_4 - 3.45686059971936e-05*G0_2_5 - 2.85428856857562e-06*G0_2_7 - 0.0001170258313116*G0_2_8 - 0.000119880119880176*G0_2_9 - 3.71057513914831e-05*G0_3_0 + 4.34486148772068e-05*G0_3_1 - 1.45885860171641e-05*G0_3_2 - 0.000122734408448751*G0_3_3 - 2.85428856857561e-05*G0_3_4 + 4.28143285286345e-05*G0_3_5 - 0.000196945911231718*G0_3_6 + 0.000145568716997357*G0_3_7 - 0.000530897673755065*G0_3_8 - 0.000770657913515418*G0_3_9 + 1.99800199800294e-05*G0_4_0 + 7.29429300858209e-06*G0_4_1 + 3.01286015571867e-05*G0_4_2 - 2.85428856857562e-05*G0_4_3 - 1.14171542743031e-05*G0_4_4 - 2.56885971171807e-05*G0_4_5 + 0.000222634508348899*G0_4_6 - 4.28143285286344e-05*G0_4_7 + 0.000385328956757709*G0_4_8 + 0.00041101755387489*G0_4_9 - 5.89886304172296e-05*G0_5_0 - 3.45686059971936e-05*G0_5_2 + 4.28143285286345e-05*G0_5_3 - 2.56885971171808e-05*G0_5_4 + 0.000108462965605874*G0_5_5 + 3.13971742543317e-05*G0_5_6 - 8.56286570572688e-05*G0_5_7 + 4.28143285286347e-05*G0_5_8 + 0.000239760239760352*G0_5_9 + 3.13971742543319e-05*G0_6_0 + 7.7065791351542e-05*G0_6_1 - 0.000196945911231718*G0_6_3 + 0.000222634508348899*G0_6_4 + 3.13971742543317e-05*G0_6_5 + 0.00072498929641821*G0_6_6 + 4.28143285286342e-05*G0_6_7 + 4.28143285286341e-05*G0_6_8 + 0.000753532182103966*G0_6_9 - 7.29429300858213e-06*G0_7_0 + 1.49057291914504e-05*G0_7_1 - 2.85428856857562e-06*G0_7_2 + 0.000145568716997357*G0_7_3 - 4.28143285286344e-05*G0_7_4 - 8.56286570572688e-05*G0_7_5 + 4.28143285286343e-05*G0_7_6 - 0.000331097473954772*G0_7_7 + 0.00031968031968047*G0_7_8 + 0.000239760239760352*G0_7_9 - 4.24971853543481e-05*G0_8_0 - 7.92857935715446e-06*G0_8_1 - 0.0001170258313116*G0_8_2 - 0.000530897673755065*G0_8_3 + 0.000385328956757709*G0_8_4 + 4.28143285286347e-05*G0_8_5 + 4.28143285286342e-05*G0_8_6 + 0.00031968031968047*G0_8_7 - 0.00229199372056623*G0_8_8 - 0.00125017839303612*G0_8_9 - 0.000108462965605874*G0_9_0 + 0.000159840159840235*G0_9_1 - 0.000119880119880176*G0_9_2 - 0.000770657913515418*G0_9_3 + 0.00041101755387489*G0_9_4 + 0.000239760239760352*G0_9_5 + 0.000753532182103966*G0_9_6 + 0.000239760239760352*G0_9_7 - 0.00125017839303612*G0_9_8 - 0.00051377194234361*G0_9_9; + A[191] = A[179] + 0.000158994444708805*G0_0_0 + 2.48076438552745e-05*G0_0_1 + 3.49562254324323e-05*G0_0_2 + 1.01485815771576e-05*G0_0_3 - 5.07429078857889e-05*G0_0_4 + 0.000243565957851786*G0_0_5 - 0.00018267446838884*G0_0_6 + 0.000334903192046207*G0_0_7 - 3.04457447314733e-05*G0_0_8 + 0.00018267446838884*G0_0_9 + 2.48076438552744e-05*G0_1_0 + 3.94667061333909e-05*G0_1_1 + 2.02971631543156e-05*G0_1_2 - 6.08914894629467e-05*G0_1_4 + 0.000223268794697471*G0_1_5 - 0.000142080142080209*G0_1_6 + 0.000152228723657367*G0_1_7 + 0.000121782978925894*G0_1_9 + 3.49562254324323e-05*G0_2_0 + 2.02971631543156e-05*G0_2_1 - 1.01485815771579e-05*G0_2_3 - 4.0594326308631e-05*G0_2_4 + 0.000152228723657367*G0_2_5 - 6.08914894629467e-05*G0_2_6 + 4.05943263086313e-05*G0_2_7 + 1.01485815771573e-05*G0_2_8 + 1.01485815771576e-05*G0_3_0 - 1.01485815771579e-05*G0_3_2 - 0.000365348936777681*G0_3_3 + 0.000182674468388841*G0_3_4 - 0.00027401170258326*G0_3_5 + 0.000274011702583261*G0_3_6 - 0.00018267446838884*G0_3_7 + 0.000365348936777678*G0_3_8 - 5.07429078857889e-05*G0_4_0 - 6.08914894629467e-05*G0_4_1 - 4.0594326308631e-05*G0_4_2 + 0.000182674468388841*G0_4_3 - 9.13372341944216e-05*G0_4_4 - 0.000274011702583261*G0_4_6 + 9.13372341944198e-05*G0_4_7 - 0.000182674468388839*G0_4_8 + 0.000243565957851786*G0_5_0 + 0.000223268794697471*G0_5_1 + 0.000152228723657367*G0_5_2 - 0.00027401170258326*G0_5_3 + 0.00200941915227724*G0_5_5 - 0.0004566861709721*G0_5_6 + 0.00109604681033304*G0_5_7 - 0.00082203510774978*G0_5_8 + 0.00109604681033304*G0_5_9 - 0.00018267446838884*G0_6_0 - 0.000142080142080209*G0_6_1 - 6.08914894629467e-05*G0_6_2 + 0.000274011702583261*G0_6_3 - 0.000274011702583261*G0_6_4 - 0.0004566861709721*G0_6_5 - 0.000456686170972101*G0_6_6 - 0.00027401170258326*G0_6_7 + 0.000274011702583261*G0_6_8 - 0.000548023405166521*G0_6_9 + 0.000334903192046207*G0_7_0 + 0.000152228723657367*G0_7_1 + 4.05943263086313e-05*G0_7_2 - 0.00018267446838884*G0_7_3 + 9.13372341944198e-05*G0_7_4 + 0.00109604681033304*G0_7_5 - 0.00027401170258326*G0_7_6 + 0.000548023405166521*G0_7_7 - 0.00109604681033304*G0_7_8 - 3.04457447314733e-05*G0_8_0 + 1.01485815771573e-05*G0_8_2 + 0.000365348936777678*G0_8_3 - 0.000182674468388839*G0_8_4 - 0.000822035107749781*G0_8_5 + 0.000274011702583261*G0_8_6 - 0.00109604681033304*G0_8_7 + 0.00219209362066608*G0_8_8 + 0.00018267446838884*G0_9_0 + 0.000121782978925894*G0_9_1 + 0.00109604681033304*G0_9_5 - 0.000548023405166521*G0_9_6; + A[169] = A[179] + 2.17419265038414e-05*G0_0_0 - 3.84095622191041e-05*G0_0_1 - 6.73048292096228e-06*G0_0_2 - 5.80372008943709e-05*G0_0_3 + 2.85428856857551e-06*G0_0_4 + 0.000112268683697308*G0_0_5 - 5.80372008943711e-05*G0_0_6 + 0.000143031571603067*G0_0_7 - 0.00011290297004588*G0_0_8 + 6.27943485086637e-05*G0_0_9 - 3.84095622191041e-05*G0_1_0 - 0.000397133730467251*G0_1_1 - 3.77047996095792e-05*G0_1_2 - 0.000366300366300538*G0_1_3 + 0.000136054421768771*G0_1_4 + 2.94943152086149e-05*G0_1_5 - 9.99000999001471e-05*G0_1_6 + 0.000224854510568902*G0_1_7 - 0.000410700410700604*G0_1_8 - 0.000232148803577484*G0_1_9 - 6.73048292096228e-06*G0_2_0 - 3.77047996095792e-05*G0_2_1 - 3.77400377400556e-05*G0_2_2 - 8.24572253144069e-05*G0_2_3 + 9.83143840287153e-06*G0_2_4 + 6.12086326372329e-05*G0_2_5 + 4.09114694829173e-05*G0_2_7 - 8.08715094429761e-05*G0_2_8 + 9.51429522858553e-06*G0_2_9 - 5.80372008943709e-05*G0_3_0 - 0.000366300366300538*G0_3_1 - 8.24572253144069e-05*G0_3_2 - 0.000842015127729808*G0_3_3 + 0.000536606250892218*G0_3_4 + 2.85428856857539e-06*G0_3_5 + 0.000379620379620559*G0_3_6 + 0.00025403168260323*G0_3_7 - 0.000576566290852276*G0_3_8 + 0.000188383045525992*G0_3_9 + 2.85428856857551e-06*G0_4_0 + 0.000136054421768771*G0_4_1 + 9.83143840287153e-06*G0_4_2 + 0.000536606250892218*G0_4_3 - 0.000422434708149193*G0_4_4 + 7.1357214214391e-05*G0_4_5 - 0.000450977593834949*G0_4_6 - 0.000105608677037298*G0_4_7 + 0.000322534608249046*G0_4_8 - 0.000171257314114539*G0_4_9 + 0.000112268683697308*G0_5_0 + 2.94943152086149e-05*G0_5_1 + 6.12086326372329e-05*G0_5_2 + 2.8542885685754e-06*G0_5_3 + 7.1357214214391e-05*G0_5_4 - 0.000142714428428782*G0_5_5 + 2.85428856857619e-06*G0_5_6 + 5.13771942343612e-05*G0_5_7 - 8.56286570572693e-06*G0_5_8 - 0.000171257314114537*G0_5_9 - 5.80372008943711e-05*G0_6_0 - 9.9900099900147e-05*G0_6_1 + 0.000379620379620559*G0_6_3 - 0.000450977593834949*G0_6_4 + 2.85428856857619e-06*G0_6_5 - 0.00103325246182438*G0_6_6 - 4.28143285286341e-05*G0_6_7 + 0.000231197374054626*G0_6_8 - 0.000787783644926874*G0_6_9 + 0.000143031571603067*G0_7_0 + 0.000224854510568902*G0_7_1 + 4.09114694829173e-05*G0_7_2 + 0.00025403168260323*G0_7_3 - 0.000105608677037298*G0_7_4 + 5.13771942343612e-05*G0_7_5 - 4.28143285286341e-05*G0_7_6 - 0.000171257314114537*G0_7_7 + 0.000205508776937445*G0_7_8 - 0.000102754388468722*G0_7_9 - 0.00011290297004588*G0_8_0 - 0.000410700410700604*G0_8_1 - 8.08715094429761e-05*G0_8_2 - 0.000576566290852276*G0_8_3 + 0.000322534608249046*G0_8_4 - 8.56286570572694e-06*G0_8_5 + 0.000231197374054626*G0_8_6 + 0.000205508776937445*G0_8_7 - 0.000522334808049339*G0_8_8 + 5.13771942343613e-05*G0_8_9 + 6.27943485086637e-05*G0_9_0 - 0.000232148803577484*G0_9_1 + 9.51429522858556e-06*G0_9_2 + 0.000188383045525992*G0_9_3 - 0.000171257314114539*G0_9_4 - 0.000171257314114537*G0_9_5 - 0.000787783644926874*G0_9_6 - 0.000102754388468722*G0_9_7 + 5.13771942343613e-05*G0_9_8 - 0.000924789496218505*G0_9_9; + A[71] = A[169]; + A[116] = A[158] - 2.46666913333694e-06*G0_0_1 + 2.46666913333698e-06*G0_0_2 + 2.66400266400393e-05*G0_0_3 - 2.66400266400393e-05*G0_0_4 - 3.74228945657691e-05*G0_0_5 - 4.31314717029207e-05*G0_0_6 + 3.74228945657693e-05*G0_0_7 + 4.31314717029207e-05*G0_0_8 - 2.46666913333694e-06*G0_1_0 + 2.36800236800352e-05*G0_1_1 + 3.42514628229078e-05*G0_1_3 - 3.04457447314735e-05*G0_1_4 + 3.42514628229075e-05*G0_1_5 + 7.61143618286829e-06*G0_1_6 + 1.2685726971447e-05*G0_1_7 + 7.16743573886773e-05*G0_1_8 + 8.7531516102986e-05*G0_1_9 + 2.46666913333698e-06*G0_2_0 - 2.36800236800349e-05*G0_2_2 + 3.04457447314736e-05*G0_2_3 - 3.42514628229077e-05*G0_2_4 - 1.2685726971447e-05*G0_2_5 - 7.1674357388677e-05*G0_2_6 - 3.42514628229075e-05*G0_2_7 - 7.61143618286817e-06*G0_2_8 - 8.75315161029858e-05*G0_2_9 + 2.66400266400393e-05*G0_3_0 + 3.42514628229078e-05*G0_3_1 + 3.04457447314736e-05*G0_3_2 + 6.85029256458162e-05*G0_3_3 - 9.13372341944202e-05*G0_3_5 - 2.28343085486051e-05*G0_3_6 - 7.99200799201179e-05*G0_3_7 + 5.70857713715137e-05*G0_3_8 - 0.000102754388468722*G0_3_9 - 2.66400266400393e-05*G0_4_0 - 3.04457447314735e-05*G0_4_1 - 3.42514628229077e-05*G0_4_2 - 6.85029256458154e-05*G0_4_4 + 7.99200799201178e-05*G0_4_5 - 5.70857713715127e-05*G0_4_6 + 9.13372341944203e-05*G0_4_7 + 2.28343085486044e-05*G0_4_8 + 0.000102754388468722*G0_4_9 - 3.74228945657691e-05*G0_5_0 + 3.42514628229075e-05*G0_5_1 - 1.2685726971447e-05*G0_5_2 - 9.13372341944202e-05*G0_5_3 + 7.99200799201178e-05*G0_5_4 + 0.000251177394034655*G0_5_5 + 0.000268303125446109*G0_5_6 - 0.000102754388468723*G0_5_8 + 0.000205508776937445*G0_5_9 - 4.31314717029207e-05*G0_6_0 + 7.61143618286829e-06*G0_6_1 - 7.1674357388677e-05*G0_6_2 - 2.28343085486051e-05*G0_6_3 - 5.70857713715127e-05*G0_6_4 + 0.000268303125446109*G0_6_5 + 0.00018267446838884*G0_6_6 + 0.000102754388468722*G0_6_7 + 0.000308263165406167*G0_6_9 + 3.74228945657693e-05*G0_7_0 + 1.2685726971447e-05*G0_7_1 - 3.42514628229075e-05*G0_7_2 - 7.99200799201179e-05*G0_7_3 + 9.13372341944203e-05*G0_7_4 + 0.000102754388468722*G0_7_6 - 0.000251177394034654*G0_7_7 - 0.00026830312544611*G0_7_8 - 0.000205508776937445*G0_7_9 + 4.31314717029208e-05*G0_8_0 + 7.16743573886773e-05*G0_8_1 - 7.61143618286816e-06*G0_8_2 + 5.70857713715137e-05*G0_8_3 + 2.28343085486044e-05*G0_8_4 - 0.000102754388468723*G0_8_5 - 0.00026830312544611*G0_8_7 - 0.000182674468388838*G0_8_8 - 0.000308263165406166*G0_8_9 + 8.7531516102986e-05*G0_9_1 - 8.75315161029858e-05*G0_9_2 - 0.000102754388468722*G0_9_3 + 0.000102754388468722*G0_9_4 + 0.000205508776937445*G0_9_5 + 0.000308263165406167*G0_9_6 - 0.000205508776937445*G0_9_7 - 0.000308263165406166*G0_9_8; + A[103] = A[116] + 4.78533811867368e-05*G0_0_0 + 1.40952521904927e-07*G0_0_1 - 8.24572253144069e-06*G0_0_2 + 7.70657913515417e-05*G0_0_3 - 7.92857935715436e-06*G0_0_5 + 1.49057291914505e-05*G0_0_6 + 4.34486148772067e-05*G0_0_7 + 7.29429300858197e-06*G0_0_8 + 0.000159840159840235*G0_0_9 + 1.40952521904927e-07*G0_1_0 - 6.1666728333429e-06*G0_1_1 - 2.99524109048062e-06*G0_1_2 - 3.45686059971935e-05*G0_1_4 - 0.000117025831311601*G0_1_5 - 2.85428856857565e-06*G0_1_6 - 1.45885860171641e-05*G0_1_7 + 3.01286015571867e-05*G0_1_8 - 0.000119880119880176*G0_1_9 - 8.2457225314407e-06*G0_2_0 - 2.99524109048062e-06*G0_2_1 - 2.70276460752777e-05*G0_2_2 + 3.13971742543316e-05*G0_2_3 - 5.89886304172293e-05*G0_2_4 - 4.24971853543483e-05*G0_2_5 - 7.29429300858198e-06*G0_2_6 - 3.7105751391483e-05*G0_2_7 + 1.99800199800291e-05*G0_2_8 - 0.000108462965605874*G0_2_9 + 7.70657913515417e-05*G0_3_0 + 3.13971742543316e-05*G0_3_2 + 0.000724989296418207*G0_3_3 + 3.13971742543328e-05*G0_3_4 + 4.28143285286348e-05*G0_3_5 + 4.28143285286347e-05*G0_3_6 - 0.000196945911231717*G0_3_7 + 0.000222634508348897*G0_3_8 + 0.000753532182103964*G0_3_9 - 3.45686059971935e-05*G0_4_1 - 5.89886304172293e-05*G0_4_2 + 3.13971742543328e-05*G0_4_3 + 0.000108462965605874*G0_4_4 + 4.28143285286342e-05*G0_4_5 - 8.56286570572688e-05*G0_4_6 + 4.2814328528634e-05*G0_4_7 - 2.56885971171796e-05*G0_4_8 + 0.000239760239760353*G0_4_9 - 7.92857935715436e-06*G0_5_0 - 0.000117025831311601*G0_5_1 - 4.24971853543483e-05*G0_5_2 + 4.28143285286348e-05*G0_5_3 + 4.28143285286341e-05*G0_5_4 - 0.00229199372056622*G0_5_5 + 0.000319680319680469*G0_5_6 - 0.000530897673755066*G0_5_7 + 0.00038532895675771*G0_5_8 - 0.00125017839303612*G0_5_9 + 1.49057291914505e-05*G0_6_0 - 2.85428856857565e-06*G0_6_1 - 7.29429300858197e-06*G0_6_2 + 4.28143285286347e-05*G0_6_3 - 8.56286570572688e-05*G0_6_4 + 0.00031968031968047*G0_6_5 - 0.000331097473954773*G0_6_6 + 0.000145568716997357*G0_6_7 - 4.28143285286342e-05*G0_6_8 + 0.000239760239760353*G0_6_9 + 4.34486148772067e-05*G0_7_0 - 1.45885860171641e-05*G0_7_1 - 3.7105751391483e-05*G0_7_2 - 0.000196945911231717*G0_7_3 + 4.2814328528634e-05*G0_7_4 - 0.000530897673755066*G0_7_5 + 0.000145568716997357*G0_7_6 - 0.000122734408448752*G0_7_7 - 2.85428856857552e-05*G0_7_8 - 0.000770657913515418*G0_7_9 + 7.29429300858197e-06*G0_8_0 + 3.01286015571867e-05*G0_8_1 + 1.99800199800291e-05*G0_8_2 + 0.000222634508348897*G0_8_3 - 2.56885971171796e-05*G0_8_4 + 0.00038532895675771*G0_8_5 - 4.28143285286342e-05*G0_8_6 - 2.85428856857551e-05*G0_8_7 - 1.1417154274306e-05*G0_8_8 + 0.000411017553874889*G0_8_9 + 0.000159840159840235*G0_9_0 - 0.000119880119880176*G0_9_1 - 0.000108462965605874*G0_9_2 + 0.000753532182103964*G0_9_3 + 0.000239760239760353*G0_9_4 - 0.00125017839303612*G0_9_5 + 0.000239760239760353*G0_9_6 - 0.000770657913515418*G0_9_7 + 0.000411017553874889*G0_9_8 - 0.000513771942343618*G0_9_9; + A[100] = A[103] - 0.00039713373046725*G0_0_0 - 3.77047996095792e-05*G0_0_1 - 3.8409562219104e-05*G0_0_2 - 9.99000999001468e-05*G0_0_3 + 2.94943152086147e-05*G0_0_4 - 0.000410700410700604*G0_0_5 + 0.000224854510568902*G0_0_6 - 0.000366300366300538*G0_0_7 + 0.000136054421768771*G0_0_8 - 0.000232148803577484*G0_0_9 - 3.77047996095792e-05*G0_1_0 - 3.77400377400554e-05*G0_1_1 - 6.73048292096227e-06*G0_1_2 + 6.12086326372328e-05*G0_1_4 - 8.0871509442976e-05*G0_1_5 + 4.09114694829173e-05*G0_1_6 - 8.2457225314407e-05*G0_1_7 + 9.83143840287168e-06*G0_1_8 + 9.5142952285854e-06*G0_1_9 - 3.8409562219104e-05*G0_2_0 - 6.73048292096227e-06*G0_2_1 + 2.17419265038415e-05*G0_2_2 - 5.80372008943709e-05*G0_2_3 + 0.000112268683697308*G0_2_4 - 0.00011290297004588*G0_2_5 + 0.000143031571603067*G0_2_6 - 5.80372008943712e-05*G0_2_7 + 2.85428856857572e-06*G0_2_8 + 6.27943485086639e-05*G0_2_9 - 9.99000999001468e-05*G0_3_0 - 5.80372008943709e-05*G0_3_2 - 0.00103325246182437*G0_3_3 + 2.85428856857505e-06*G0_3_4 + 0.000231197374054626*G0_3_5 - 4.28143285286347e-05*G0_3_6 + 0.000379620379620558*G0_3_7 - 0.000450977593834948*G0_3_8 - 0.000787783644926871*G0_3_9 + 2.94943152086147e-05*G0_4_0 + 6.12086326372328e-05*G0_4_1 + 0.000112268683697308*G0_4_2 + 2.85428856857507e-06*G0_4_3 - 0.000142714428428781*G0_4_4 - 8.56286570572681e-06*G0_4_5 + 5.13771942343613e-05*G0_4_6 + 2.8542885685758e-06*G0_4_7 + 7.13572142143901e-05*G0_4_8 - 0.000171257314114538*G0_4_9 - 0.000410700410700604*G0_5_0 - 8.0871509442976e-05*G0_5_1 - 0.00011290297004588*G0_5_2 + 0.000231197374054626*G0_5_3 - 8.56286570572682e-06*G0_5_4 - 0.000522334808049343*G0_5_5 + 0.000205508776937446*G0_5_6 - 0.000576566290852276*G0_5_7 + 0.000322534608249046*G0_5_8 + 5.13771942343606e-05*G0_5_9 + 0.000224854510568902*G0_6_0 + 4.09114694829173e-05*G0_6_1 + 0.000143031571603067*G0_6_2 - 4.28143285286347e-05*G0_6_3 + 5.13771942343613e-05*G0_6_4 + 0.000205508776937446*G0_6_5 - 0.000171257314114538*G0_6_6 + 0.000254031682603231*G0_6_7 - 0.000105608677037298*G0_6_8 - 0.000102754388468722*G0_6_9 - 0.000366300366300538*G0_7_0 - 8.2457225314407e-05*G0_7_1 - 5.80372008943712e-05*G0_7_2 + 0.000379620379620558*G0_7_3 + 2.85428856857578e-06*G0_7_4 - 0.000576566290852276*G0_7_5 + 0.000254031682603231*G0_7_6 - 0.00084201512772981*G0_7_7 + 0.000536606250892217*G0_7_8 + 0.000188383045525991*G0_7_9 + 0.000136054421768771*G0_8_0 + 9.83143840287168e-06*G0_8_1 + 2.85428856857574e-06*G0_8_2 - 0.000450977593834948*G0_8_3 + 7.13572142143901e-05*G0_8_4 + 0.000322534608249046*G0_8_5 - 0.000105608677037298*G0_8_6 + 0.000536606250892217*G0_8_7 - 0.000422434708149192*G0_8_8 - 0.000171257314114537*G0_8_9 - 0.000232148803577484*G0_9_0 + 9.51429522858541e-06*G0_9_1 + 6.2794348508664e-05*G0_9_2 - 0.000787783644926871*G0_9_3 - 0.000171257314114538*G0_9_4 + 5.13771942343606e-05*G0_9_5 - 0.000102754388468722*G0_9_6 + 0.000188383045525991*G0_9_7 - 0.000171257314114537*G0_9_8 - 0.0009247894962185*G0_9_9; + A[129] = -A[116] + 8.04134137467848e-05*G0_0_0 + 1.19809643619224e-05*G0_0_1 + 1.0031121142237e-05*G0_0_2 + 1.13114398828739e-05*G0_0_3 - 6.87143544286697e-06*G0_0_5 - 4.4928616357209e-05*G0_0_6 + 0.000119351547923032*G0_0_7 - 3.73171801743402e-05*G0_0_8 - 2.28343085486048e-05*G0_0_9 + 1.19809643619224e-05*G0_1_0 + 2.74505036409931e-05*G0_1_1 + 3.98190874381539e-06*G0_1_2 + 5.82486296772285e-05*G0_1_5 + 1.5117157974308e-05*G0_1_6 + 6.0257203114374e-05*G0_1_7 + 1.5857158714314e-06*G0_1_8 + 0.00010212010212015*G0_1_9 + 1.0031121142237e-05*G0_2_0 + 3.98190874381539e-06*G0_2_1 + 1.37311248422423e-05*G0_2_2 + 1.1311439882874e-05*G0_2_3 - 1.12057254914452e-05*G0_2_4 + 2.11428782857583e-07*G0_2_5 - 5.40200540200796e-05*G0_2_6 + 6.96657839515308e-05*G0_2_7 - 7.71715057429688e-06*G0_2_8 - 6.34286348572384e-07*G0_2_9 + 1.13114398828739e-05*G0_3_0 + 1.1311439882874e-05*G0_3_2 + 8.94343751487042e-05*G0_3_3 - 7.32600732601082e-05*G0_3_4 - 8.46772275344104e-05*G0_3_5 - 8.46772275344104e-05*G0_3_6 - 7.32600732601083e-05*G0_3_7 + 8.9434375148704e-05*G0_3_8 - 0.000159840159840234*G0_3_9 - 1.12057254914452e-05*G0_4_2 - 7.32600732601081e-05*G0_4_3 + 0.000157937300794518*G0_4_4 - 3.90086104372e-05*G0_4_5 + 0.00012368583797161*G0_4_6 - 8.46772275344097e-05*G0_4_7 - 1.61743018885958e-05*G0_4_8 + 7.99200799201171e-05*G0_4_9 - 6.87143544286697e-06*G0_5_0 + 5.82486296772285e-05*G0_5_1 + 2.1142878285757e-07*G0_5_2 - 8.46772275344104e-05*G0_5_3 - 3.90086104372e-05*G0_5_4 + 0.000575614861329417*G0_5_5 + 7.61143618286833e-05*G0_5_6 + 0.00046239474810925*G0_5_7 - 0.000214071642643172*G0_5_8 + 0.000496646210932159*G0_5_9 - 4.4928616357209e-05*G0_6_0 + 1.5117157974308e-05*G0_6_1 - 5.40200540200796e-05*G0_6_2 - 8.46772275344104e-05*G0_6_3 + 0.00012368583797161*G0_6_4 + 7.61143618286833e-05*G0_6_5 + 0.000407211835783456*G0_6_6 - 0.000248323105466079*G0_6_7 + 8.56286570572682e-06*G0_6_8 + 0.000171257314114538*G0_6_9 + 0.000119351547923033*G0_7_0 + 6.0257203114374e-05*G0_7_1 + 6.96657839515308e-05*G0_7_2 - 7.32600732601083e-05*G0_7_3 - 8.46772275344097e-05*G0_7_4 + 0.00046239474810925*G0_7_5 - 0.000248323105466079*G0_7_6 + 0.00139003853289633*G0_7_7 - 0.000382474668189135*G0_7_8 + 0.000565149136577973*G0_7_9 - 3.73171801743403e-05*G0_8_0 + 1.5857158714314e-06*G0_8_1 - 7.71715057429688e-06*G0_8_2 + 8.9434375148704e-05*G0_8_3 - 1.61743018885958e-05*G0_8_4 - 0.000214071642643172*G0_8_5 + 8.56286570572682e-06*G0_8_6 - 0.000382474668189134*G0_8_7 + 0.000148423005565935*G0_8_8 - 0.000274011702583259*G0_8_9 - 2.28343085486049e-05*G0_9_0 + 0.00010212010212015*G0_9_1 - 6.34286348572384e-07*G0_9_2 - 0.000159840159840234*G0_9_3 + 7.99200799201171e-05*G0_9_4 + 0.000496646210932159*G0_9_5 + 0.000171257314114538*G0_9_6 + 0.000565149136577973*G0_9_7 - 0.000274011702583259*G0_9_8 + 0.000924789496218503*G0_9_9; + A[104] = A[103] + 3.94667061333912e-05*G0_0_0 + 2.02971631543155e-05*G0_0_1 + 2.48076438552745e-05*G0_0_2 - 0.000142080142080209*G0_0_3 + 0.000223268794697471*G0_0_4 + 0.000152228723657367*G0_0_6 - 6.08914894629465e-05*G0_0_8 + 0.000121782978925893*G0_0_9 + 2.02971631543155e-05*G0_1_0 + 3.49562254324323e-05*G0_1_2 - 6.08914894629466e-05*G0_1_3 + 0.000152228723657367*G0_1_4 + 1.01485815771577e-05*G0_1_5 + 4.05943263086312e-05*G0_1_6 - 1.01485815771577e-05*G0_1_7 - 4.05943263086312e-05*G0_1_8 + 2.48076438552745e-05*G0_2_0 + 3.49562254324323e-05*G0_2_1 + 0.000158994444708805*G0_2_2 - 0.00018267446838884*G0_2_3 + 0.000243565957851787*G0_2_4 - 3.04457447314736e-05*G0_2_5 + 0.000334903192046207*G0_2_6 + 1.01485815771576e-05*G0_2_7 - 5.07429078857886e-05*G0_2_8 + 0.00018267446838884*G0_2_9 - 0.000142080142080209*G0_3_0 - 6.08914894629466e-05*G0_3_1 - 0.00018267446838884*G0_3_2 - 0.000456686170972099*G0_3_3 - 0.000456686170972101*G0_3_4 + 0.00027401170258326*G0_3_5 - 0.00027401170258326*G0_3_6 + 0.00027401170258326*G0_3_7 - 0.000274011702583259*G0_3_8 - 0.00054802340516652*G0_3_9 + 0.000223268794697471*G0_4_0 + 0.000152228723657367*G0_4_1 + 0.000243565957851787*G0_4_2 - 0.000456686170972101*G0_4_3 + 0.00200941915227724*G0_4_4 - 0.00082203510774978*G0_4_5 + 0.00109604681033304*G0_4_6 - 0.00027401170258326*G0_4_7 + 0.00109604681033304*G0_4_9 + 1.01485815771577e-05*G0_5_1 - 3.04457447314737e-05*G0_5_2 + 0.00027401170258326*G0_5_3 - 0.00082203510774978*G0_5_4 + 0.00219209362066607*G0_5_5 - 0.00109604681033304*G0_5_6 + 0.00036534893677768*G0_5_7 - 0.00018267446838884*G0_5_8 + 0.000152228723657367*G0_6_0 + 4.05943263086312e-05*G0_6_1 + 0.000334903192046207*G0_6_2 - 0.00027401170258326*G0_6_3 + 0.00109604681033304*G0_6_4 - 0.00109604681033304*G0_6_5 + 0.00054802340516652*G0_6_6 - 0.00018267446838884*G0_6_7 + 9.13372341944197e-05*G0_6_8 - 1.01485815771577e-05*G0_7_1 + 1.01485815771576e-05*G0_7_2 + 0.00027401170258326*G0_7_3 - 0.00027401170258326*G0_7_4 + 0.00036534893677768*G0_7_5 - 0.00018267446838884*G0_7_6 - 0.000365348936777679*G0_7_7 + 0.00018267446838884*G0_7_8 - 6.08914894629465e-05*G0_8_0 - 4.05943263086312e-05*G0_8_1 - 5.07429078857886e-05*G0_8_2 - 0.000274011702583259*G0_8_3 - 0.00018267446838884*G0_8_5 + 9.13372341944197e-05*G0_8_6 + 0.00018267446838884*G0_8_7 - 9.13372341944189e-05*G0_8_8 + 0.000121782978925893*G0_9_0 + 0.00018267446838884*G0_9_2 - 0.00054802340516652*G0_9_3 + 0.00109604681033304*G0_9_4; + A[216] = A[104]; + A[201] = A[103]; + A[143] = A[129]; + A[219] = A[149]; + A[189] = A[186] + 1.32495370590671e-05*G0_0_1 - 1.3249537059067e-05*G0_0_2 - 4.56686170972102e-05*G0_0_3 + 4.566861709721e-05*G0_0_4 - 0.000266400266400391*G0_0_5 + 0.000106560106560156*G0_0_6 + 0.000266400266400392*G0_0_7 - 0.000106560106560157*G0_0_8 + 1.32495370590671e-05*G0_1_0 - 2.98819346438536e-05*G0_1_1 - 4.566861709721e-05*G0_1_3 + 4.566861709721e-05*G0_1_4 - 0.00013700585129163*G0_1_5 + 4.56686170972101e-05*G0_1_6 + 0.000142080142080209*G0_1_7 - 4.82057624914993e-05*G0_1_8 + 4.56686170972099e-05*G0_1_9 - 1.3249537059067e-05*G0_2_0 + 2.98819346438535e-05*G0_2_2 - 4.56686170972101e-05*G0_2_3 + 4.56686170972101e-05*G0_2_4 - 0.000142080142080209*G0_2_5 + 4.82057624914997e-05*G0_2_6 + 0.00013700585129163*G0_2_7 - 4.56686170972101e-05*G0_2_8 - 4.56686170972104e-05*G0_2_9 - 4.56686170972101e-05*G0_3_0 - 4.56686170972099e-05*G0_3_1 - 4.56686170972101e-05*G0_3_2 - 0.00041101755387489*G0_3_3 + 0.000274011702583261*G0_3_5 - 0.00013700585129163*G0_3_6 + 0.00013700585129163*G0_3_7 - 0.00027401170258326*G0_3_8 - 0.00041101755387489*G0_3_9 + 4.566861709721e-05*G0_4_0 + 4.566861709721e-05*G0_4_1 + 4.56686170972101e-05*G0_4_2 + 0.00041101755387489*G0_4_4 - 0.00013700585129163*G0_4_5 + 0.00027401170258326*G0_4_6 - 0.00027401170258326*G0_4_7 + 0.00013700585129163*G0_4_8 + 0.00041101755387489*G0_4_9 - 0.000266400266400391*G0_5_0 - 0.00013700585129163*G0_5_1 - 0.000142080142080209*G0_5_2 + 0.000274011702583261*G0_5_3 - 0.00013700585129163*G0_5_4 - 0.0031968031968047*G0_5_5 + 0.000570857713715125*G0_5_6 + 0.00041101755387489*G0_5_8 - 0.000822035107749782*G0_5_9 + 0.000106560106560156*G0_6_0 + 4.56686170972101e-05*G0_6_1 + 4.82057624914997e-05*G0_6_2 - 0.00013700585129163*G0_6_3 + 0.00027401170258326*G0_6_4 + 0.000570857713715125*G0_6_5 + 0.00022834308548605*G0_6_6 - 0.00041101755387489*G0_6_7 + 0.00041101755387489*G0_6_9 + 0.000266400266400392*G0_7_0 + 0.000142080142080209*G0_7_1 + 0.00013700585129163*G0_7_2 + 0.00013700585129163*G0_7_3 - 0.00027401170258326*G0_7_4 - 0.00041101755387489*G0_7_6 + 0.0031968031968047*G0_7_7 - 0.000570857713715127*G0_7_8 + 0.000822035107749777*G0_7_9 - 0.000106560106560157*G0_8_0 - 4.82057624914993e-05*G0_8_1 - 4.56686170972101e-05*G0_8_2 - 0.00027401170258326*G0_8_3 + 0.00013700585129163*G0_8_4 + 0.000411017553874891*G0_8_5 - 0.000570857713715127*G0_8_7 - 0.00022834308548605*G0_8_8 - 0.00041101755387489*G0_8_9 + 4.56686170972099e-05*G0_9_1 - 4.56686170972105e-05*G0_9_2 - 0.00041101755387489*G0_9_3 + 0.00041101755387489*G0_9_4 - 0.000822035107749782*G0_9_5 + 0.00041101755387489*G0_9_6 + 0.000822035107749777*G0_9_7 - 0.00041101755387489*G0_9_8; + A[55] = A[153]; + A[29] = A[211]; + A[130] = A[158]; + A[73] = A[199]; + A[43] = A[45] + 1.0175010175015e-05*G0_0_3 + 8.6157229014412e-06*G0_0_5 + 1.36900136900201e-05*G0_0_7 - 9.14429485858484e-06*G0_0_8 + 3.61543218686247e-05*G0_0_9 + 2.35155790711458e-05*G0_1_1 + 2.30985945271768e-05*G0_1_3 - 1.65443022585957e-05*G0_1_4 + 5.3385767671507e-06*G0_1_7 + 2.53185967471801e-05*G0_1_8 + 1.77600177600261e-05*G0_1_9 - 3.5379082998147e-05*G0_2_2 + 5.81429152857975e-07*G0_2_3 - 3.54143211286221e-06*G0_2_4 + 1.63328734757382e-05*G0_2_5 - 1.82357325214553e-05*G0_2_6 + 1.2950012950019e-06*G0_2_7 - 3.92993250136292e-05*G0_2_8 - 4.31314717029205e-05*G0_2_9 + 1.0175010175015e-05*G0_3_0 + 2.30985945271769e-05*G0_3_1 + 5.81429152857965e-07*G0_3_2 + 0.000280909566623985*G0_3_3 - 5.94643451786608e-06*G0_3_4 - 1.45093002235928e-05*G0_3_5 - 1.66500166500253e-06*G0_3_6 - 3.591646448791e-05*G0_3_7 - 7.65900765901123e-05*G0_3_8 + 1.85528756957419e-05*G0_3_9 - 1.65443022585957e-05*G0_4_1 - 3.54143211286221e-06*G0_4_2 - 5.94643451786608e-06*G0_4_3 - 4.44793301936365e-05*G0_4_4 + 1.47471576043075e-05*G0_4_6 - 3.09214594929024e-06*G0_4_7 + 0.000112506541078022*G0_4_8 + 0.000155558726987371*G0_4_9 + 8.6157229014412e-06*G0_5_0 + 1.63328734757382e-05*G0_5_2 - 1.45093002235928e-05*G0_5_3 + 1.92664478378856e-05*G0_5_5 - 4.49550449550662e-05*G0_5_6 - 9.27643784787077e-06*G0_5_8 - 8.99100899101322e-05*G0_5_9 - 1.82357325214553e-05*G0_6_2 - 1.66500166500253e-06*G0_6_3 + 1.47471576043075e-05*G0_6_4 - 4.49550449550662e-05*G0_6_5 + 7.92065077779738e-05*G0_6_6 - 9.27643784787083e-06*G0_6_7 + 6.35079206508076e-05*G0_6_8 + 0.000132724418438767*G0_6_9 + 1.36900136900201e-05*G0_7_0 + 5.3385767671507e-06*G0_7_1 + 1.2950012950019e-06*G0_7_2 - 3.59164644879101e-05*G0_7_3 - 3.09214594929024e-06*G0_7_4 - 9.27643784787083e-06*G0_7_6 - 4.54307597164952e-05*G0_7_7 + 4.51929023357788e-06*G0_7_8 - 8.99100899101323e-05*G0_7_9 - 9.14429485858484e-06*G0_8_0 + 2.53185967471801e-05*G0_8_1 - 3.92993250136292e-05*G0_8_2 - 7.65900765901123e-05*G0_8_3 + 0.000112506541078022*G0_8_4 - 9.27643784787077e-06*G0_8_5 + 6.35079206508076e-05*G0_8_6 + 4.51929023357787e-06*G0_8_7 - 0.000390799676514146*G0_8_8 - 0.000278293135436123*G0_8_9 + 3.61543218686247e-05*G0_9_0 + 1.77600177600261e-05*G0_9_1 - 4.31314717029205e-05*G0_9_2 + 1.85528756957419e-05*G0_9_3 + 0.000155558726987371*G0_9_4 - 8.99100899101322e-05*G0_9_5 + 0.000132724418438767*G0_9_6 - 8.99100899101323e-05*G0_9_7 - 0.000278293135436123*G0_9_8 - 7.70657913515408e-05*G0_9_9; + A[146] = A[174]; + A[75] = A[5]; + A[150] = A[10]; + A[183] = A[57]; + A[178] = A[218] + 3.41105103010025e-05*G0_0_1 - 3.41105103010026e-05*G0_0_2 + 0.000532800532800783*G0_0_3 - 0.000532800532800783*G0_0_4 + 0.000164914450628814*G0_0_5 - 0.000512503369646468*G0_0_6 - 0.000164914450628814*G0_0_7 + 0.000512503369646468*G0_0_8 + 3.41105103010025e-05*G0_1_0 + 0.00036365750651482*G0_1_1 + 0.000695177838035308*G0_1_3 - 0.000613989185418046*G0_1_4 + 0.00013700585129163*G0_1_5 - 0.000532800532800783*G0_1_6 - 0.000304457447314733*G0_1_7 + 0.000799200799201175*G0_1_8 - 0.000167451596023103*G0_1_9 - 3.41105103010026e-05*G0_2_0 - 0.00036365750651482*G0_2_2 + 0.000613989185418045*G0_2_3 - 0.000695177838035308*G0_2_4 + 0.000304457447314734*G0_2_5 - 0.000799200799201175*G0_2_6 - 0.00013700585129163*G0_2_7 + 0.000532800532800783*G0_2_8 + 0.000167451596023103*G0_2_9 + 0.000532800532800783*G0_3_0 + 0.000695177838035308*G0_3_1 + 0.000613989185418045*G0_3_2 + 0.00260311117454097*G0_3_3 - 0.00100470957613862*G0_3_5 + 0.00159840159840235*G0_3_6 - 0.00159840159840235*G0_3_7 + 0.0031968031968047*G0_3_8 + 0.00369915798487401*G0_3_9 - 0.000532800532800783*G0_4_0 - 0.000613989185418046*G0_4_1 - 0.000695177838035308*G0_4_2 - 0.00260311117454097*G0_4_4 + 0.00159840159840235*G0_4_5 - 0.0031968031968047*G0_4_6 + 0.00100470957613862*G0_4_7 - 0.00159840159840235*G0_4_8 - 0.00369915798487401*G0_4_9 + 0.000164914450628814*G0_5_0 + 0.00013700585129163*G0_5_1 + 0.000304457447314734*G0_5_2 - 0.00100470957613862*G0_5_3 + 0.00159840159840235*G0_5_4 - 0.00118738404452746*G0_5_5 + 0.00216925931211748*G0_5_6 - 0.000411017553874891*G0_5_8 + 0.000822035107749779*G0_5_9 - 0.000512503369646468*G0_6_0 - 0.000532800532800783*G0_6_1 - 0.000799200799201175*G0_6_2 + 0.00159840159840235*G0_6_3 - 0.0031968031968047*G0_6_4 + 0.00216925931211748*G0_6_5 - 0.00680462394748429*G0_6_6 + 0.000411017553874892*G0_6_7 - 0.00369915798487401*G0_6_9 - 0.000164914450628814*G0_7_0 - 0.000304457447314733*G0_7_1 - 0.00013700585129163*G0_7_2 - 0.00159840159840235*G0_7_3 + 0.00100470957613862*G0_7_4 + 0.000411017553874892*G0_7_6 + 0.00118738404452746*G0_7_7 - 0.00216925931211748*G0_7_8 - 0.000822035107749782*G0_7_9 + 0.000512503369646468*G0_8_0 + 0.000799200799201175*G0_8_1 + 0.000532800532800783*G0_8_2 + 0.0031968031968047*G0_8_3 - 0.00159840159840235*G0_8_4 - 0.00041101755387489*G0_8_5 - 0.00216925931211748*G0_8_7 + 0.00680462394748429*G0_8_8 + 0.00369915798487401*G0_8_9 - 0.000167451596023103*G0_9_1 + 0.000167451596023103*G0_9_2 + 0.00369915798487401*G0_9_3 - 0.00369915798487401*G0_9_4 + 0.000822035107749778*G0_9_5 - 0.00369915798487401*G0_9_6 - 0.000822035107749781*G0_9_7 + 0.00369915798487401*G0_9_8; + A[119] = A[163] - 9.51429522858544e-06*G0_0_1 + 9.51429522858544e-06*G0_0_2 + 0.000468103325246403*G0_0_3 - 0.000468103325246402*G0_0_4 + 2.0931449502888e-05*G0_0_5 - 0.000395794681509153*G0_0_6 - 2.09314495028878e-05*G0_0_7 + 0.000395794681509154*G0_0_8 - 9.51429522858545e-06*G0_1_0 + 0.000249485963771795*G0_1_1 + 0.00043004614433206*G0_1_3 - 0.000449074734789231*G0_1_4 + 0.000171257314114537*G0_1_5 - 9.13372341944196e-05*G0_1_6 - 5.32800532800783e-05*G0_1_7 + 0.000614623471766618*G0_1_8 + 0.000422434708149193*G0_1_9 + 9.51429522858543e-06*G0_2_0 - 0.000249485963771795*G0_2_2 + 0.000449074734789232*G0_2_3 - 0.000430046144332061*G0_2_4 + 5.32800532800785e-05*G0_2_5 - 0.000614623471766618*G0_2_6 - 0.000171257314114537*G0_2_7 + 9.13372341944198e-05*G0_2_8 - 0.000422434708149193*G0_2_9 + 0.000468103325246403*G0_3_0 + 0.00043004614433206*G0_3_1 + 0.000449074734789232*G0_3_2 + 0.00287712287712423*G0_3_3 - 0.000959040959041409*G0_3_5 + 0.000274011702583259*G0_3_6 - 0.00140430997573921*G0_3_7 + 0.00167832167832247*G0_3_8 + 0.00154131582703084*G0_3_9 - 0.000468103325246402*G0_4_0 - 0.000449074734789231*G0_4_1 - 0.000430046144332061*G0_4_2 - 0.00287712287712422*G0_4_4 + 0.00140430997573921*G0_4_5 - 0.00167832167832246*G0_4_6 + 0.00095904095904141*G0_4_7 - 0.000274011702583261*G0_4_8 - 0.00154131582703083*G0_4_9 + 2.09314495028881e-05*G0_5_0 + 0.000171257314114537*G0_5_1 + 5.32800532800785e-05*G0_5_2 - 0.000959040959041409*G0_5_3 + 0.00140430997573921*G0_5_4 - 0.000205508776937447*G0_5_5 + 0.00179820179820264*G0_5_6 - 0.000513771942343611*G0_5_8 + 0.00102754388468722*G0_5_9 - 0.000395794681509153*G0_6_0 - 9.13372341944197e-05*G0_6_1 - 0.000614623471766618*G0_6_2 + 0.000274011702583259*G0_6_3 - 0.00167832167832246*G0_6_4 + 0.00179820179820264*G0_6_5 - 0.000205508776937442*G0_6_6 + 0.000513771942343613*G0_6_7 + 0.000719280719281064*G0_6_9 - 2.09314495028878e-05*G0_7_0 - 5.32800532800783e-05*G0_7_1 - 0.000171257314114537*G0_7_2 - 0.00140430997573921*G0_7_3 + 0.00095904095904141*G0_7_4 + 0.000513771942343613*G0_7_6 + 0.000205508776937442*G0_7_7 - 0.00179820179820264*G0_7_8 - 0.00102754388468723*G0_7_9 + 0.000395794681509154*G0_8_0 + 0.000614623471766618*G0_8_1 + 9.13372341944198e-05*G0_8_2 + 0.00167832167832247*G0_8_3 - 0.00027401170258326*G0_8_4 - 0.000513771942343612*G0_8_5 - 0.00179820179820264*G0_8_7 + 0.000205508776937444*G0_8_8 - 0.000719280719281057*G0_8_9 + 0.000422434708149193*G0_9_1 - 0.000422434708149193*G0_9_2 + 0.00154131582703084*G0_9_3 - 0.00154131582703083*G0_9_4 + 0.00102754388468722*G0_9_5 + 0.000719280719281064*G0_9_6 - 0.00102754388468723*G0_9_7 - 0.000719280719281058*G0_9_8; + A[220] = A[164]; + A[197] = A[43]; + A[19] = A[61]; + A[12] = A[36] + 0.000226645782201444*G0_0_0 + 2.22910540370962e-05*G0_0_1 + 1.02542959685864e-05*G0_0_2 + 0.000247213104356077*G0_0_5 - 0.000118770118770175*G0_0_6 + 0.000189757332614564*G0_0_7 - 8.64743721886984e-05*G0_0_8 + 8.49943707086964e-05*G0_0_9 + 2.22910540370962e-05*G0_1_0 - 6.60714946429631e-07*G0_1_5 - 1.13642970785877e-06*G0_1_6 + 2.72214557928965e-06*G0_1_7 - 1.5698587127166e-05*G0_1_9 + 1.02542959685864e-05*G0_2_0 - 0.000201755916041726*G0_2_2 + 5.3650053650079e-05*G0_2_3 - 0.000103335817621581*G0_2_4 + 8.4782941925839e-05*G0_2_5 - 0.00015941730227452*G0_2_6 + 1.00428671857291e-06*G0_2_7 + 1.13114398828738e-05*G0_2_8 - 3.86914672629141e-05*G0_2_9 + 5.3650053650079e-05*G0_3_2 + 0.000210265924551738*G0_3_3 - 3.52028923457661e-05*G0_3_4 - 6.18429189858049e-06*G0_3_5 - 1.18928690357318e-05*G0_3_6 - 4.49550449550662e-05*G0_3_7 + 9.41915227629957e-05*G0_3_8 + 0.00013700585129163*G0_3_9 - 0.000103335817621581*G0_4_2 - 3.52028923457661e-05*G0_4_3 + 0.000194567337424572*G0_4_4 - 2.33100233100343e-05*G0_4_5 + 3.52028923457662e-05*G0_4_6 + 2.14071642643174e-06*G0_4_7 - 4.92364778079295e-05*G0_4_8 + 0.000162694448408811*G0_4_9 + 0.000247213104356077*G0_5_0 - 6.60714946429628e-07*G0_5_1 + 8.47829419258391e-05*G0_5_2 - 6.18429189858048e-06*G0_5_3 - 2.33100233100343e-05*G0_5_4 + 2.04557347414575e-05*G0_5_5 - 4.23386137672048e-05*G0_5_6 + 3.16350316350461e-05*G0_5_7 - 1.33200133200193e-05*G0_5_8 - 0.00022834308548605*G0_5_9 - 0.000118770118770175*G0_6_0 - 1.13642970785877e-06*G0_6_1 - 0.00015941730227452*G0_6_2 - 1.18928690357318e-05*G0_6_3 + 3.52028923457662e-05*G0_6_4 - 4.23386137672047e-05*G0_6_5 - 7.08814994529614e-05*G0_6_6 - 1.83150183150267e-05*G0_6_7 - 7.61143618286843e-06*G0_6_8 + 0.000139860139860206*G0_6_9 + 0.000189757332614564*G0_7_0 + 2.72214557928965e-06*G0_7_1 + 1.00428671857291e-06*G0_7_2 - 4.49550449550662e-05*G0_7_3 + 2.14071642643174e-06*G0_7_4 + 3.1635031635046e-05*G0_7_5 - 1.83150183150267e-05*G0_7_6 + 1.61743018885948e-05*G0_7_7 - 6.87407830265296e-05*G0_7_8 - 0.000218353075496036*G0_7_9 - 8.64743721886984e-05*G0_8_0 + 1.13114398828738e-05*G0_8_2 + 9.41915227629957e-05*G0_8_3 - 4.92364778079295e-05*G0_8_4 - 1.33200133200193e-05*G0_8_5 - 7.61143618286842e-06*G0_8_6 - 6.87407830265296e-05*G0_8_7 + 0.000116074401788742*G0_8_8 + 0.000145568716997357*G0_8_9 + 8.49943707086964e-05*G0_9_0 - 1.5698587127166e-05*G0_9_1 - 3.86914672629141e-05*G0_9_2 + 0.00013700585129163*G0_9_3 + 0.000162694448408811*G0_9_4 - 0.00022834308548605*G0_9_5 + 0.000139860139860206*G0_9_6 - 0.000218353075496036*G0_9_7 + 0.000145568716997357*G0_9_8 + 0.000548023405166521*G0_9_9; + A[54] = A[138]; + A[33] = A[47]; + A[24] = A[137] - 1.80066846733599e-05*G0_0_0 - 1.58571587143049e-07*G0_0_6 - 3.92200392200577e-05*G0_0_7 + 3.16614602329037e-05*G0_0_8 + 3.17143174286182e-07*G0_0_9 + 0.000228554514268908*G0_1_1 + 0.000122364408078751*G0_1_3 - 5.95172023743732e-05*G0_1_4 - 5.41786256072233e-06*G0_1_5 - 7.89686503972592e-05*G0_1_7 + 0.000177758749187404*G0_1_8 + 3.45686059971936e-05*G0_1_9 - 1.847358990217e-05*G0_2_4 + 5.4178625607222e-06*G0_2_5 - 1.09942967085875e-05*G0_2_6 + 5.76143433286554e-06*G0_2_7 + 1.00428671857291e-05*G0_2_8 - 1.42714428428785e-06*G0_2_9 + 0.000122364408078751*G0_3_1 + 6.5886494457954e-05*G0_3_3 - 5.11393368536466e-05*G0_3_4 + 4.28143285286345e-06*G0_3_5 - 4.1149326863632e-05*G0_3_7 + 8.80072308644151e-05*G0_3_8 - 2.14071642643171e-05*G0_3_9 - 5.95172023743732e-05*G0_4_1 - 1.847358990217e-05*G0_4_2 - 5.11393368536466e-05*G0_4_3 + 4.59064744779247e-05*G0_4_4 - 4.28143285286342e-06*G0_4_5 + 5.94643451786598e-06*G0_4_7 - 4.68579040007832e-05*G0_4_8 + 1.28442985585904e-05*G0_4_9 - 5.41786256072233e-06*G0_5_1 + 5.4178625607222e-06*G0_5_2 + 4.28143285286345e-06*G0_5_3 - 4.28143285286342e-06*G0_5_4 - 3.44893202036225e-05*G0_5_5 + 4.75714761429363e-07*G0_5_6 + 3.44893202036217e-05*G0_5_7 - 4.75714761429159e-07*G0_5_8 - 1.58571587143055e-07*G0_6_0 - 1.09942967085875e-05*G0_6_2 + 4.75714761429363e-07*G0_6_5 + 1.18928690357313e-06*G0_6_6 - 3.40136054421927e-05*G0_6_7 + 1.66500166500238e-06*G0_6_8 + 4.28143285286359e-06*G0_6_9 - 3.92200392200577e-05*G0_7_0 - 7.89686503972592e-05*G0_7_1 + 5.76143433286554e-06*G0_7_2 - 4.11493268636319e-05*G0_7_3 + 5.94643451786598e-06*G0_7_4 + 3.44893202036217e-05*G0_7_5 - 3.40136054421927e-05*G0_7_6 + 0.000241900956186783*G0_7_7 - 0.000106322249179442*G0_7_8 + 6.70757813615267e-05*G0_7_9 + 3.16614602329037e-05*G0_8_0 + 0.000177758749187404*G0_8_1 + 1.00428671857291e-05*G0_8_2 + 8.80072308644151e-05*G0_8_3 - 4.68579040007832e-05*G0_8_4 - 4.75714761429159e-07*G0_8_5 + 1.66500166500238e-06*G0_8_6 - 0.000106322249179442*G0_8_7 + 0.000221920936206755*G0_8_8 - 9.99000999001454e-06*G0_8_9 + 3.17143174286182e-07*G0_9_0 + 3.45686059971936e-05*G0_9_1 - 1.42714428428784e-06*G0_9_2 - 2.14071642643171e-05*G0_9_3 + 1.28442985585904e-05*G0_9_4 + 4.28143285286359e-06*G0_9_6 + 6.70757813615267e-05*G0_9_7 - 9.99000999001454e-06*G0_9_8 - 8.5628657057273e-06*G0_9_9; + A[25] = -A[24] - 2.41630797186467e-05*G0_0_0 - 2.36359760169395e-05*G0_0_1 - 5.74161288447271e-06*G0_0_3 - 1.78657321514549e-05*G0_0_5 + 7.78322206894004e-06*G0_0_6 - 4.26953998382771e-05*G0_0_7 - 4.83643340786422e-06*G0_0_8 - 1.81564467278839e-05*G0_0_9 - 2.36359760169395e-05*G0_1_0 - 0.000263625263625388*G0_1_1 - 1.37957280814489e-05*G0_1_2 - 0.000111925111925165*G0_1_3 + 5.45750545750803e-05*G0_1_4 + 4.30786145072064e-06*G0_1_5 + 7.86250786251157e-05*G0_1_7 - 0.000193325193325284*G0_1_8 - 2.22000222000326e-05*G0_1_9 - 1.37957280814489e-05*G0_2_1 - 6.93089978804591e-06*G0_2_3 + 2.70893128036093e-07*G0_2_5 + 7.57840043554682e-06*G0_2_7 - 8.71483014340566e-06*G0_2_8 - 3.56786071071975e-07*G0_2_9 - 5.74161288447271e-06*G0_3_0 - 0.000111925111925165*G0_3_1 - 6.93089978804591e-06*G0_3_2 - 7.57575757576114e-05*G0_3_3 + 4.59064744779247e-05*G0_3_4 - 8.02768659911895e-06*G0_3_5 + 3.75814661529124e-05*G0_3_7 - 8.40825840826235e-05*G0_3_8 + 5.45750545750803e-05*G0_4_1 + 4.59064744779247e-05*G0_4_3 - 2.18828790257465e-05*G0_4_4 - 3.09214594929026e-05*G0_4_7 + 4.65011179297112e-05*G0_4_8 - 2.14071642643171e-06*G0_4_9 - 1.78657321514549e-05*G0_5_0 + 4.30786145072063e-06*G0_5_1 + 2.70893128036094e-07*G0_5_2 - 8.02768659911895e-06*G0_5_3 + 2.84239569953989e-05*G0_5_5 + 1.43309071880568e-05*G0_5_6 - 5.0544693401862e-06*G0_5_7 + 7.43304314733242e-06*G0_5_8 + 3.96032538889867e-05*G0_5_9 + 7.78322206894003e-06*G0_6_0 + 1.43309071880568e-05*G0_6_5 + 6.6600066600097e-06*G0_6_6 - 2.37857380714624e-06*G0_6_7 - 7.0167927310818e-06*G0_6_8 - 4.26953998382771e-05*G0_7_0 + 7.86250786251157e-05*G0_7_1 + 7.57840043554682e-06*G0_7_2 + 3.75814661529124e-05*G0_7_3 - 3.09214594929026e-05*G0_7_4 - 5.05446934018623e-06*G0_7_5 - 2.37857380714623e-06*G0_7_6 + 1.16550116550166e-05*G0_7_7 + 0.000154726226154871*G0_7_8 + 5.92264877979439e-05*G0_7_9 - 4.83643340786422e-06*G0_8_0 - 0.000193325193325284*G0_8_1 - 8.71483014340566e-06*G0_8_2 - 8.40825840826235e-05*G0_8_3 + 4.65011179297112e-05*G0_8_4 + 7.43304314733242e-06*G0_8_5 - 7.0167927310818e-06*G0_8_6 + 0.000154726226154871*G0_8_7 - 0.000330502830502986*G0_8_8 - 2.64021692593244e-05*G0_8_9 - 1.81564467278839e-05*G0_9_0 - 2.22000222000326e-05*G0_9_1 - 3.56786071071973e-07*G0_9_2 - 2.14071642643172e-06*G0_9_4 + 3.96032538889867e-05*G0_9_5 + 5.92264877979439e-05*G0_9_7 - 2.64021692593244e-05*G0_9_8 + 0.000132724418438766*G0_9_9; + A[26] = -A[25] + 2.74549084073022e-05*G0_0_0 + 2.24672446894775e-05*G0_0_1 + 6.73268530411704e-06*G0_0_3 - 5.2196480767934e-06*G0_0_4 + 1.9345733631457e-05*G0_0_5 - 1.03467960610867e-05*G0_0_6 + 1.74032316889541e-05*G0_0_7 + 8.48357991215537e-06*G0_0_8 + 2.24672446894775e-05*G0_1_0 + 0.000211208544541977*G0_1_1 + 9.41445385890274e-06*G0_1_2 + 7.12250712251049e-05*G0_1_3 - 3.97750397750586e-05*G0_1_4 + 4.25500425500624e-06*G0_1_5 - 9.62000962001415e-06*G0_1_6 - 8.23250823251212e-05*G0_1_7 + 0.000211825211825312*G0_1_8 + 2.22000222000326e-05*G0_1_9 + 9.41445385890274e-06*G0_2_1 + 3.16482459339754e-06*G0_2_3 + 8.51661565947681e-06*G0_2_5 + 7.0498284784032e-06*G0_2_7 - 5.7548271834013e-06*G0_2_8 + 4.71750471750697e-06*G0_2_9 + 6.73268530411704e-06*G0_3_0 + 7.12250712251049e-05*G0_3_1 + 3.16482459339754e-06*G0_3_2 + 5.41125541125797e-05*G0_3_3 - 8.3250083250123e-06*G0_3_4 - 9.93054564483607e-06*G0_3_5 + 1.57580514723446e-05*G0_3_6 - 3.3300033300049e-05*G0_3_7 + 2.91375291375431e-05*G0_3_8 - 5.2196480767934e-06*G0_4_0 - 3.97750397750586e-05*G0_4_1 - 8.3250083250123e-06*G0_4_3 - 1.61743018885952e-05*G0_4_4 + 2.55696684268236e-06*G0_4_5 - 1.8315018315027e-05*G0_4_6 + 3.80571809143424e-06*G0_4_7 + 4.16250416250595e-06*G0_4_8 - 1.92664478378856e-05*G0_4_9 + 1.9345733631457e-05*G0_5_0 + 4.25500425500624e-06*G0_5_1 + 8.51661565947682e-06*G0_5_2 - 9.93054564483607e-06*G0_5_3 + 2.55696684268236e-06*G0_5_4 + 6.64811379097407e-05*G0_5_5 - 2.18234146805678e-05*G0_5_6 + 6.01184529756241e-05*G0_5_7 - 2.58669901527167e-05*G0_5_8 + 5.3874696731865e-05*G0_5_9 - 1.03467960610867e-05*G0_6_0 - 9.62000962001414e-06*G0_6_1 + 1.57580514723446e-05*G0_6_3 - 1.8315018315027e-05*G0_6_4 - 2.18234146805678e-05*G0_6_5 - 2.66400266400392e-05*G0_6_6 - 3.42514628229076e-05*G0_6_7 + 2.96132438989721e-05*G0_6_8 - 4.56686170972101e-05*G0_6_9 + 1.74032316889541e-05*G0_7_0 - 8.23250823251212e-05*G0_7_1 + 7.04982847840321e-06*G0_7_2 - 3.33000333000491e-05*G0_7_3 + 3.80571809143424e-06*G0_7_4 + 6.01184529756241e-05*G0_7_5 - 3.42514628229076e-05*G0_7_6 + 0.000201940916226726*G0_7_7 - 0.000137362637362702*G0_7_8 + 7.06436420722467e-05*G0_7_9 + 8.48357991215537e-06*G0_8_0 + 0.000211825211825312*G0_8_1 - 5.7548271834013e-06*G0_8_2 + 2.91375291375431e-05*G0_8_3 + 4.16250416250596e-06*G0_8_4 - 2.58669901527167e-05*G0_8_5 + 2.96132438989721e-05*G0_8_6 - 0.000137362637362702*G0_8_7 + 1.24875124875192e-05*G0_8_8 - 7.492507492511e-05*G0_8_9 + 2.22000222000326e-05*G0_9_1 + 4.71750471750697e-06*G0_9_2 - 1.92664478378856e-05*G0_9_4 + 5.3874696731865e-05*G0_9_5 - 4.56686170972101e-05*G0_9_6 + 7.06436420722467e-05*G0_9_7 - 7.492507492511e-05*G0_9_8 - 2.14071642643171e-05*G0_9_9; + A[46] = A[26] + 1.51993802787525e-05*G0_0_0 - 2.02677980455853e-05*G0_0_1 - 7.05643562786754e-06*G0_0_4 + 1.86057328914559e-05*G0_0_5 + 3.99336113622016e-05*G0_0_7 - 5.12450512450754e-05*G0_0_8 - 2.02677980455853e-05*G0_1_0 + 2.02677980455853e-05*G0_1_2 + 0.000284900284900419*G0_1_3 - 0.000114700114700168*G0_1_4 + 7.77000777001144e-06*G0_1_5 - 7.77000777001147e-06*G0_1_6 + 0.000114700114700169*G0_1_7 - 0.000284900284900419*G0_1_8 + 2.02677980455853e-05*G0_2_1 - 1.51993802787525e-05*G0_2_2 + 5.12450512450753e-05*G0_2_3 - 3.99336113622016e-05*G0_2_4 - 1.8605732891456e-05*G0_2_6 + 7.05643562786752e-06*G0_2_7 + 0.000284900284900419*G0_3_1 + 5.12450512450754e-05*G0_3_2 + 0.00033300033300049*G0_3_3 - 0.000166500166500245*G0_3_4 - 1.16550116550172e-05*G0_3_5 + 2.33100233100343e-05*G0_3_6 - 7.05643562786754e-06*G0_4_0 - 0.000114700114700168*G0_4_1 - 3.99336113622016e-05*G0_4_2 - 0.000166500166500245*G0_4_3 - 6.66000666000998e-06*G0_4_4 + 2.11693068836026e-05*G0_4_5 - 4.44793301936368e-05*G0_4_6 - 5.99400599400881e-05*G0_4_9 + 1.86057328914559e-05*G0_5_0 + 7.77000777001144e-06*G0_5_1 - 1.16550116550172e-05*G0_5_3 + 2.11693068836026e-05*G0_5_4 + 6.42214927929516e-05*G0_5_5 + 4.44793301936369e-05*G0_5_7 - 2.33100233100343e-05*G0_5_8 + 6.42214927929516e-05*G0_5_9 - 7.77000777001147e-06*G0_6_1 - 1.8605732891456e-05*G0_6_2 + 2.33100233100343e-05*G0_6_3 - 4.44793301936368e-05*G0_6_4 - 6.42214927929515e-05*G0_6_6 - 2.11693068836026e-05*G0_6_7 + 1.16550116550171e-05*G0_6_8 - 6.42214927929516e-05*G0_6_9 + 3.99336113622016e-05*G0_7_0 + 0.000114700114700169*G0_7_1 + 7.05643562786752e-06*G0_7_2 + 4.44793301936369e-05*G0_7_5 - 2.11693068836026e-05*G0_7_6 + 6.66000666000977e-06*G0_7_7 + 0.000166500166500245*G0_7_8 + 5.99400599400882e-05*G0_7_9 - 5.12450512450754e-05*G0_8_0 - 0.000284900284900419*G0_8_1 - 2.33100233100343e-05*G0_8_5 + 1.16550116550171e-05*G0_8_6 + 0.000166500166500245*G0_8_7 - 0.00033300033300049*G0_8_8 - 5.99400599400881e-05*G0_9_4 + 6.42214927929516e-05*G0_9_5 - 6.42214927929516e-05*G0_9_6 + 5.99400599400882e-05*G0_9_7; + A[18] = A[46]; + A[62] = -A[47] - 1.37957280814489e-05*G0_0_2 + 7.57840043554686e-06*G0_0_3 - 8.71483014340568e-06*G0_0_4 - 6.93089978804591e-06*G0_0_6 + 2.708931280361e-07*G0_0_8 - 3.56786071071954e-07*G0_0_9 - 2.41630797186467e-05*G0_1_1 - 2.36359760169395e-05*G0_1_2 - 4.26953998382771e-05*G0_1_3 - 4.83643340786425e-06*G0_1_4 - 5.74161288447274e-06*G0_1_6 + 7.78322206894004e-06*G0_1_7 - 1.78657321514549e-05*G0_1_8 - 1.81564467278838e-05*G0_1_9 - 1.37957280814489e-05*G0_2_0 - 2.36359760169395e-05*G0_2_1 - 0.000263625263625388*G0_2_2 + 7.86250786251157e-05*G0_2_3 - 0.000193325193325284*G0_2_4 + 5.45750545750804e-05*G0_2_5 - 0.000111925111925165*G0_2_6 + 4.30786145072057e-06*G0_2_8 - 2.22000222000327e-05*G0_2_9 + 7.57840043554686e-06*G0_3_0 - 4.26953998382771e-05*G0_3_1 + 7.86250786251157e-05*G0_3_2 + 1.16550116550169e-05*G0_3_3 + 0.00015472622615487*G0_3_4 - 3.09214594929026e-05*G0_3_5 + 3.75814661529124e-05*G0_3_6 - 2.37857380714633e-06*G0_3_7 - 5.05446934018604e-06*G0_3_8 + 5.92264877979442e-05*G0_3_9 - 8.71483014340567e-06*G0_4_0 - 4.83643340786426e-06*G0_4_1 - 0.000193325193325284*G0_4_2 + 0.00015472622615487*G0_4_3 - 0.000330502830502986*G0_4_4 + 4.65011179297113e-05*G0_4_5 - 8.40825840826237e-05*G0_4_6 - 7.01679273108171e-06*G0_4_7 + 7.43304314733235e-06*G0_4_8 - 2.64021692593245e-05*G0_4_9 + 5.45750545750804e-05*G0_5_2 - 3.09214594929026e-05*G0_5_3 + 4.65011179297113e-05*G0_5_4 - 2.18828790257465e-05*G0_5_5 + 4.59064744779247e-05*G0_5_6 - 2.14071642643171e-06*G0_5_9 - 6.93089978804591e-06*G0_6_0 - 5.74161288447274e-06*G0_6_1 - 0.000111925111925165*G0_6_2 + 3.75814661529125e-05*G0_6_3 - 8.40825840826237e-05*G0_6_4 + 4.59064744779247e-05*G0_6_5 - 7.57575757576114e-05*G0_6_6 - 8.02768659911895e-06*G0_6_8 + 7.78322206894004e-06*G0_7_1 - 2.37857380714631e-06*G0_7_3 - 7.01679273108171e-06*G0_7_4 + 6.66000666000979e-06*G0_7_7 + 1.43309071880568e-05*G0_7_8 + 2.70893128036101e-07*G0_8_0 - 1.78657321514549e-05*G0_8_1 + 4.30786145072057e-06*G0_8_2 - 5.05446934018604e-06*G0_8_3 + 7.43304314733235e-06*G0_8_4 - 8.02768659911895e-06*G0_8_6 + 1.43309071880568e-05*G0_8_7 + 2.84239569953989e-05*G0_8_8 + 3.96032538889867e-05*G0_8_9 - 3.56786071071954e-07*G0_9_0 - 1.81564467278838e-05*G0_9_1 - 2.22000222000327e-05*G0_9_2 + 5.92264877979442e-05*G0_9_3 - 2.64021692593245e-05*G0_9_4 - 2.14071642643171e-06*G0_9_5 + 3.96032538889867e-05*G0_9_8 + 0.000132724418438766*G0_9_9; + A[35] = -A[62] + 9.41445385890274e-06*G0_0_2 + 7.04982847840322e-06*G0_0_3 - 5.75482718340132e-06*G0_0_4 + 3.1648245933975e-06*G0_0_6 + 8.5166156594768e-06*G0_0_8 + 4.71750471750694e-06*G0_0_9 + 2.74549084073022e-05*G0_1_1 + 2.24672446894775e-05*G0_1_2 + 1.74032316889541e-05*G0_1_3 + 8.4835799121554e-06*G0_1_4 - 5.21964807679339e-06*G0_1_5 + 6.73268530411704e-06*G0_1_6 - 1.03467960610867e-05*G0_1_7 + 1.9345733631457e-05*G0_1_8 + 9.41445385890274e-06*G0_2_0 + 2.24672446894775e-05*G0_2_1 + 0.000211208544541977*G0_2_2 - 8.23250823251212e-05*G0_2_3 + 0.000211825211825312*G0_2_4 - 3.97750397750585e-05*G0_2_5 + 7.12250712251048e-05*G0_2_6 - 9.62000962001419e-06*G0_2_7 + 4.25500425500628e-06*G0_2_8 + 2.22000222000327e-05*G0_2_9 + 7.04982847840321e-06*G0_3_0 + 1.74032316889541e-05*G0_3_1 - 8.23250823251212e-05*G0_3_2 + 0.000201940916226725*G0_3_3 - 0.000137362637362702*G0_3_4 + 3.80571809143417e-06*G0_3_5 - 3.33000333000489e-05*G0_3_6 - 3.42514628229075e-05*G0_3_7 + 6.0118452975624e-05*G0_3_8 + 7.06436420722467e-05*G0_3_9 - 5.75482718340132e-06*G0_4_0 + 8.48357991215539e-06*G0_4_1 + 0.000211825211825312*G0_4_2 - 0.000137362637362702*G0_4_3 + 1.24875124875181e-05*G0_4_4 + 4.16250416250613e-06*G0_4_5 + 2.91375291375428e-05*G0_4_6 + 2.96132438989721e-05*G0_4_7 - 2.58669901527165e-05*G0_4_8 - 7.49250749251101e-05*G0_4_9 - 5.21964807679339e-06*G0_5_1 - 3.97750397750585e-05*G0_5_2 + 3.80571809143418e-06*G0_5_3 + 4.16250416250613e-06*G0_5_4 - 1.61743018885952e-05*G0_5_5 - 8.32500832501219e-06*G0_5_6 - 1.83150183150269e-05*G0_5_7 + 2.5569668426823e-06*G0_5_8 - 1.92664478378855e-05*G0_5_9 + 3.1648245933975e-06*G0_6_0 + 6.73268530411704e-06*G0_6_1 + 7.12250712251048e-05*G0_6_2 - 3.33000333000489e-05*G0_6_3 + 2.91375291375429e-05*G0_6_4 - 8.3250083250122e-06*G0_6_5 + 5.41125541125795e-05*G0_6_6 + 1.57580514723446e-05*G0_6_7 - 9.93054564483601e-06*G0_6_8 - 1.03467960610867e-05*G0_7_1 - 9.62000962001419e-06*G0_7_2 - 3.42514628229075e-05*G0_7_3 + 2.96132438989721e-05*G0_7_4 - 1.83150183150269e-05*G0_7_5 + 1.57580514723446e-05*G0_7_6 - 2.66400266400391e-05*G0_7_7 - 2.18234146805678e-05*G0_7_8 - 4.566861709721e-05*G0_7_9 + 8.51661565947681e-06*G0_8_0 + 1.9345733631457e-05*G0_8_1 + 4.25500425500627e-06*G0_8_2 + 6.0118452975624e-05*G0_8_3 - 2.58669901527165e-05*G0_8_4 + 2.55696684268231e-06*G0_8_5 - 9.93054564483601e-06*G0_8_6 - 2.18234146805678e-05*G0_8_7 + 6.64811379097405e-05*G0_8_8 + 5.38746967318649e-05*G0_8_9 + 4.71750471750694e-06*G0_9_0 + 2.22000222000327e-05*G0_9_2 + 7.06436420722467e-05*G0_9_3 - 7.49250749251101e-05*G0_9_4 - 1.92664478378855e-05*G0_9_5 - 4.566861709721e-05*G0_9_7 + 5.38746967318649e-05*G0_9_8 - 2.14071642643173e-05*G0_9_9; + A[122] = A[35] - 1.51993802787525e-05*G0_0_0 + 2.02677980455854e-05*G0_0_2 + 7.05643562786752e-06*G0_0_3 - 3.99336113622016e-05*G0_0_5 + 5.12450512450753e-05*G0_0_6 - 1.86057328914559e-05*G0_0_7 + 1.51993802787525e-05*G0_1_1 - 2.02677980455854e-05*G0_1_2 + 3.99336113622016e-05*G0_1_3 - 5.12450512450754e-05*G0_1_4 - 7.05643562786752e-06*G0_1_5 + 1.86057328914559e-05*G0_1_8 + 2.02677980455854e-05*G0_2_0 - 2.02677980455854e-05*G0_2_1 + 0.000114700114700169*G0_2_3 - 0.000284900284900419*G0_2_4 - 0.000114700114700169*G0_2_5 + 0.000284900284900419*G0_2_6 - 7.77000777001144e-06*G0_2_7 + 7.77000777001142e-06*G0_2_8 + 7.05643562786752e-06*G0_3_0 + 3.99336113622016e-05*G0_3_1 + 0.000114700114700169*G0_3_2 + 6.66000666000962e-06*G0_3_3 + 0.000166500166500245*G0_3_4 - 2.11693068836026e-05*G0_3_7 + 4.44793301936368e-05*G0_3_8 + 5.99400599400881e-05*G0_3_9 - 5.12450512450754e-05*G0_4_1 - 0.000284900284900419*G0_4_2 + 0.000166500166500245*G0_4_3 - 0.00033300033300049*G0_4_4 + 1.16550116550172e-05*G0_4_7 - 2.33100233100343e-05*G0_4_8 - 3.99336113622016e-05*G0_5_0 - 7.05643562786752e-06*G0_5_1 - 0.000114700114700169*G0_5_2 - 6.6600066600096e-06*G0_5_5 - 0.000166500166500245*G0_5_6 - 4.44793301936367e-05*G0_5_7 + 2.11693068836025e-05*G0_5_8 - 5.99400599400881e-05*G0_5_9 + 5.12450512450753e-05*G0_6_0 + 0.000284900284900419*G0_6_2 - 0.000166500166500245*G0_6_5 + 0.00033300033300049*G0_6_6 + 2.33100233100342e-05*G0_6_7 - 1.16550116550171e-05*G0_6_8 - 1.86057328914559e-05*G0_7_0 - 7.77000777001144e-06*G0_7_2 - 2.11693068836026e-05*G0_7_3 + 1.16550116550172e-05*G0_7_4 - 4.44793301936367e-05*G0_7_5 + 2.33100233100342e-05*G0_7_6 - 6.42214927929514e-05*G0_7_7 - 6.42214927929516e-05*G0_7_9 + 1.86057328914559e-05*G0_8_1 + 7.77000777001142e-06*G0_8_2 + 4.44793301936368e-05*G0_8_3 - 2.33100233100343e-05*G0_8_4 + 2.11693068836025e-05*G0_8_5 - 1.16550116550171e-05*G0_8_6 + 6.42214927929516e-05*G0_8_8 + 6.42214927929515e-05*G0_8_9 + 5.99400599400881e-05*G0_9_3 - 5.99400599400881e-05*G0_9_5 - 6.42214927929516e-05*G0_9_7 + 6.42214927929515e-05*G0_9_8; + A[160] = -A[35] + 0.000589052335084357*G0_0_0 + 0.00016648548394588*G0_0_1 + 6.79714171777983e-05*G0_0_2 + 7.95765081479741e-05*G0_0_3 - 2.80143137286112e-06*G0_0_4 + 0.000322904608619046*G0_0_5 - 0.000127676556248045*G0_0_6 + 0.000292855292855429*G0_0_7 - 0.000396455396455582*G0_0_8 + 0.00016648548394588*G0_1_0 + 0.000573852954805606*G0_1_1 + 8.82392152233837e-05*G0_1_2 + 0.000282970997256844*G0_1_3 - 7.64315050029692e-05*G0_1_4 + 8.66329437758416e-05*G0_1_5 - 2.8014313728611e-06*G0_1_6 - 0.00038326752612485*G0_1_7 + 0.000274249559963974*G0_1_8 + 6.79714171777983e-05*G0_2_0 + 8.82392152233837e-05*G0_2_1 + 0.000736318355366321*G0_2_2 - 0.000117527974670888*G0_2_3 + 0.000447541876113516*G0_2_4 - 2.8278599707188e-06*G0_2_5 + 0.000162641591213097*G0_2_6 + 0.000242429528143928*G0_2_7 + 0.000234659520373917*G0_2_8 + 0.000403723260866308*G0_2_9 + 7.95765081479741e-05*G0_3_0 + 0.000282970997256844*G0_3_1 - 0.000117527974670888*G0_3_2 + 0.00147994862280646*G0_3_3 - 0.000825602968460499*G0_3_4 - 0.000151039436753794*G0_3_5 - 0.000188145188145276*G0_3_6 - 0.000435279006707784*G0_3_7 + 0.00133580705009339*G0_3_8 + 0.000877693734837004*G0_3_9 - 2.80143137286112e-06*G0_4_0 - 7.64315050029692e-05*G0_4_1 + 0.000447541876113516*G0_4_2 - 0.000825602968460499*G0_4_3 + 0.000893392321964171*G0_4_4 - 0.000188145188145277*G0_4_5 + 0.000376290376290553*G0_4_6 - 0.00026116740402467*G0_4_7 - 0.00090052804338561*G0_4_8 - 0.000834879406308371*G0_4_9 + 0.000322904608619046*G0_5_0 + 8.66329437758416e-05*G0_5_1 - 2.82785997071877e-06*G0_5_2 - 0.000151039436753794*G0_5_3 - 0.000188145188145277*G0_5_4 + 0.00148660862946647*G0_5_5 - 0.000659102801960254*G0_5_6 + 0.00138028638028703*G0_5_7 - 0.000456448313591386*G0_5_8 + 0.000937633794777093*G0_5_9 - 0.000127676556248045*G0_6_0 - 2.8014313728611e-06*G0_6_1 + 0.000162641591213097*G0_6_2 - 0.000188145188145276*G0_6_3 + 0.000376290376290553*G0_6_4 - 0.000659102801960255*G0_6_5 + 0.000560391988963681*G0_6_6 - 0.000923838066695645*G0_6_7 - 0.000249512392369653*G0_6_8 - 0.000834879406308372*G0_6_9 + 0.000292855292855429*G0_7_0 - 0.00038326752612485*G0_7_1 + 0.000242429528143928*G0_7_2 - 0.000435279006707784*G0_7_3 - 0.00026116740402467*G0_7_4 + 0.00138028638028703*G0_7_5 - 0.000923838066695645*G0_7_6 + 0.00568193711051122*G0_7_7 + 0.000576328433471563*G0_7_8 + 0.00187241330098561*G0_7_9 - 0.000396455396455582*G0_8_0 + 0.000274249559963974*G0_8_1 + 0.000234659520373917*G0_8_2 + 0.00133580705009339*G0_8_3 - 0.00090052804338561*G0_8_4 - 0.000456448313591386*G0_8_5 - 0.000249512392369653*G0_8_6 + 0.000576328433471563*G0_8_7 + 0.00561771561771826*G0_8_8 + 0.00180819180819266*G0_8_9 + 0.000403723260866308*G0_9_2 + 0.000877693734837004*G0_9_3 - 0.000834879406308371*G0_9_4 + 0.000937633794777093*G0_9_5 - 0.000834879406308372*G0_9_6 + 0.00187241330098561*G0_9_7 + 0.00180819180819266*G0_9_8 + 0.00315113457970749*G0_9_9; + A[38] = A[122]; + A[44] = A[212]; + A[141] = A[99]; + A[95] = -A[108] + 1.37311248422425e-05*G0_0_0 + 3.98190874381543e-06*G0_0_1 + 1.0031121142237e-05*G0_0_2 - 7.71715057429697e-06*G0_0_3 + 6.9665783951531e-05*G0_0_4 - 5.40200540200793e-05*G0_0_5 + 2.11428782857448e-07*G0_0_6 - 1.12057254914451e-05*G0_0_7 + 1.13114398828738e-05*G0_0_8 - 6.34286348572249e-07*G0_0_9 + 3.98190874381543e-06*G0_1_0 + 2.74505036409932e-05*G0_1_1 + 1.19809643619225e-05*G0_1_2 + 1.58571587143156e-06*G0_1_3 + 6.02572031143741e-05*G0_1_4 + 1.51171579743079e-05*G0_1_5 + 5.82486296772286e-05*G0_1_6 + 0.00010212010212015*G0_1_9 + 1.0031121142237e-05*G0_2_0 + 1.19809643619225e-05*G0_2_1 + 8.04134137467851e-05*G0_2_2 - 3.73171801743405e-05*G0_2_3 + 0.000119351547923033*G0_2_4 - 4.49286163572089e-05*G0_2_5 - 6.87143544286724e-06*G0_2_6 + 1.13114398828739e-05*G0_2_8 - 2.28343085486048e-05*G0_2_9 - 7.71715057429696e-06*G0_3_0 + 1.58571587143157e-06*G0_3_1 - 3.73171801743405e-05*G0_3_2 + 0.000148423005565937*G0_3_3 - 0.000382474668189135*G0_3_4 + 8.56286570572685e-06*G0_3_5 - 0.000214071642643172*G0_3_6 - 1.61743018885958e-05*G0_3_7 + 8.94343751487041e-05*G0_3_8 - 0.000274011702583259*G0_3_9 + 6.9665783951531e-05*G0_4_0 + 6.02572031143741e-05*G0_4_1 + 0.000119351547923033*G0_4_2 - 0.000382474668189135*G0_4_3 + 0.00139003853289633*G0_4_4 - 0.00024832310546608*G0_4_5 + 0.000462394748109252*G0_4_6 - 8.467722753441e-05*G0_4_7 - 7.32600732601081e-05*G0_4_8 + 0.000565149136577974*G0_4_9 - 5.40200540200793e-05*G0_5_0 + 1.51171579743079e-05*G0_5_1 - 4.49286163572089e-05*G0_5_2 + 8.56286570572685e-06*G0_5_3 - 0.00024832310546608*G0_5_4 + 0.000407211835783456*G0_5_5 + 7.61143618286826e-05*G0_5_6 + 0.000123685837971611*G0_5_7 - 8.46772275344103e-05*G0_5_8 + 0.000171257314114537*G0_5_9 + 2.11428782857434e-07*G0_6_0 + 5.82486296772285e-05*G0_6_1 - 6.87143544286724e-06*G0_6_2 - 0.000214071642643172*G0_6_3 + 0.000462394748109252*G0_6_4 + 7.61143618286826e-05*G0_6_5 + 0.000575614861329418*G0_6_6 - 3.90086104372004e-05*G0_6_7 - 8.46772275344102e-05*G0_6_8 + 0.000496646210932159*G0_6_9 - 1.12057254914451e-05*G0_7_0 - 1.61743018885958e-05*G0_7_3 - 8.467722753441e-05*G0_7_4 + 0.000123685837971611*G0_7_5 - 3.90086104372004e-05*G0_7_6 + 0.000157937300794518*G0_7_7 - 7.32600732601082e-05*G0_7_8 + 7.99200799201171e-05*G0_7_9 + 1.13114398828739e-05*G0_8_0 + 1.13114398828739e-05*G0_8_2 + 8.94343751487041e-05*G0_8_3 - 7.32600732601081e-05*G0_8_4 - 8.46772275344103e-05*G0_8_5 - 8.46772275344102e-05*G0_8_6 - 7.32600732601082e-05*G0_8_7 + 8.94343751487039e-05*G0_8_8 - 0.000159840159840234*G0_8_9 - 6.34286348572249e-07*G0_9_0 + 0.00010212010212015*G0_9_1 - 2.28343085486048e-05*G0_9_2 - 0.000274011702583259*G0_9_3 + 0.000565149136577974*G0_9_4 + 0.000171257314114537*G0_9_5 + 0.000496646210932159*G0_9_6 + 7.99200799201171e-05*G0_9_7 - 0.000159840159840234*G0_9_8 + 0.000924789496218503*G0_9_9; + A[126] = A[95] + 0.000347635903191621*G0_0_0 + 2.65930424660708e-05*G0_0_1 + 6.65295903391454e-05*G0_0_2 - 7.61143618286833e-06*G0_0_3 - 4.44000444000653e-05*G0_0_4 + 0.000501509072937879*G0_0_5 - 0.000163223020365954*G0_0_6 + 0.000235531664103203*G0_0_7 - 0.000122205836491608*G0_0_8 + 8.1188652617262e-05*G0_0_9 + 2.65930424660708e-05*G0_1_0 - 1.83238278476459e-06*G0_1_1 + 3.61778139556086e-06*G0_1_2 - 5.4971483542937e-06*G0_1_3 - 4.86286200572144e-05*G0_1_4 + 6.34286348572359e-05*G0_1_5 - 3.29828901257627e-05*G0_1_6 + 6.59657802515254e-05*G0_1_7 - 3.55200355200521e-05*G0_1_8 + 7.61143618286829e-06*G0_1_9 + 6.65295903391454e-05*G0_2_0 + 3.61778139556086e-06*G0_2_1 + 0.000128266794933522*G0_2_2 + 1.14171542743026e-05*G0_2_3 - 8.88000888001308e-05*G0_2_4 + 1.73371601943108e-05*G0_2_5 + 0.000236800236800348*G0_2_6 + 6.72343529486701e-05*G0_2_7 - 3.80571809143416e-05*G0_2_8 + 4.82057624914995e-05*G0_2_9 - 7.61143618286833e-06*G0_3_0 - 5.4971483542937e-06*G0_3_1 + 1.14171542743027e-05*G0_3_2 - 4.56686170972099e-05*G0_3_3 + 0.000262594548308958*G0_3_4 - 4.94743351886441e-05*G0_3_5 + 3.04457447314734e-05*G0_3_6 - 4.56686170972101e-05*G0_3_7 + 6.85029256458152e-05*G0_3_9 - 4.44000444000653e-05*G0_4_0 - 4.86286200572144e-05*G0_4_1 - 8.88000888001308e-05*G0_4_2 + 0.000262594548308958*G0_4_3 - 0.000970458113315713*G0_4_4 + 6.4697207554381e-05*G0_4_5 - 9.51429522858544e-05*G0_4_6 + 4.56686170972099e-05*G0_4_8 - 0.000274011702583261*G0_4_9 + 0.000501509072937879*G0_5_0 + 6.34286348572358e-05*G0_5_1 + 1.73371601943108e-05*G0_5_2 - 4.94743351886441e-05*G0_5_3 + 6.4697207554381e-05*G0_5_4 + 0.000974263831407142*G0_5_5 - 0.000783977926835437*G0_5_6 + 0.000528994814709348*G0_5_7 - 0.000258788830217522*G0_5_8 + 0.000274011702583259*G0_5_9 - 0.000163223020365954*G0_6_0 - 3.29828901257627e-05*G0_6_1 + 0.000236800236800348*G0_6_2 + 3.04457447314734e-05*G0_6_3 - 9.51429522858544e-05*G0_6_4 - 0.000783977926835437*G0_6_5 + 0.000574663431806559*G0_6_6 - 0.000270205984491825*G0_6_7 + 0.000140811569383064*G0_6_8 - 0.000205508776937445*G0_6_9 + 0.000235531664103203*G0_7_0 + 6.59657802515254e-05*G0_7_1 + 6.723435294867e-05*G0_7_2 - 4.56686170972101e-05*G0_7_3 + 0.000528994814709348*G0_7_5 - 0.000270205984491826*G0_7_6 + 0.000578469149897992*G0_7_7 - 0.000243565957851786*G0_7_8 + 0.000296846011131865*G0_7_9 - 0.000122205836491608*G0_8_0 - 3.55200355200521e-05*G0_8_1 - 3.80571809143416e-05*G0_8_2 + 4.56686170972099e-05*G0_8_4 - 0.000258788830217522*G0_8_5 + 0.000140811569383064*G0_8_6 - 0.000243565957851786*G0_8_7 + 9.89486703772882e-05*G0_8_8 - 0.000114171542743025*G0_8_9 + 8.11886526172621e-05*G0_9_0 + 7.6114361828683e-06*G0_9_1 + 4.82057624914995e-05*G0_9_2 + 6.85029256458152e-05*G0_9_3 - 0.00027401170258326*G0_9_4 + 0.000274011702583259*G0_9_5 - 0.000205508776937445*G0_9_6 + 0.000296846011131865*G0_9_7 - 0.000114171542743025*G0_9_8 + 0.00013700585129163*G0_9_9; + A[97] = -A[126] - 0.000458800458800674*G0_0_0 - 3.30651124302073e-05*G0_0_1 - 4.50813149226059e-05*G0_0_2 + 3.70000370000544e-06*G0_0_3 + 2.05085919371731e-05*G0_0_4 - 0.000743700743701092*G0_0_5 + 0.000356468927897667*G0_0_6 - 0.000292300292300429*G0_0_7 + 0.000150748722177364*G0_0_8 - 0.000113537256394452*G0_0_9 - 3.30651124302073e-05*G0_1_0 - 9.23239018477545e-06*G0_1_1 + 3.86444830889462e-06*G0_1_2 + 1.41657284514494e-05*G0_1_3 + 8.77429448858438e-06*G0_1_4 - 8.7002944145842e-05*G0_1_5 + 2.33628805057486e-05*G0_1_6 - 7.11457854315331e-05*G0_1_7 + 4.08057550914885e-05*G0_1_8 - 5.20114805829335e-05*G0_1_9 - 4.50813149226059e-05*G0_2_0 + 3.86444830889462e-06*G0_2_1 + 0.000104586771253488*G0_2_2 - 4.01714687429163e-05*G0_2_3 + 9.5248666677283e-05*G0_2_4 - 0.000244200244200359*G0_2_5 + 0.000347271775843368*G0_2_6 - 8.41486555772665e-05*G0_2_7 + 2.65343122486105e-05*G0_2_8 + 3.86914672629141e-05*G0_2_9 + 3.70000370000544e-06*G0_3_0 + 1.41657284514494e-05*G0_3_1 - 4.01714687429162e-05*G0_3_2 - 3.4251462822907e-05*G0_3_3 - 4.28143285286347e-05*G0_3_4 + 9.32400932401371e-05*G0_3_5 - 6.66000666001008e-06*G0_3_6 + 5.23286237572198e-05*G0_3_7 - 3.61543218686245e-05*G0_3_8 + 5.13771942343616e-05*G0_3_9 + 2.05085919371731e-05*G0_4_0 + 8.7742944885844e-06*G0_4_1 + 9.5248666677283e-05*G0_4_2 - 4.28143285286347e-05*G0_4_3 - 8.56286570572675e-05*G0_4_4 + 1.90285904571669e-06*G0_4_5 + 4.75714761429327e-06*G0_4_6 + 6.37457780315221e-05*G0_4_7 - 1.61743018885952e-05*G0_4_8 - 0.000119880119880176*G0_4_9 - 0.000743700743701092*G0_5_0 - 8.7002944145842e-05*G0_5_1 - 0.000244200244200359*G0_5_2 + 9.32400932401371e-05*G0_5_3 + 1.90285904571669e-06*G0_5_4 - 0.000764949336378264*G0_5_5 + 0.00041672613101204*G0_5_6 - 0.000640312068883797*G0_5_7 + 0.000324437467294763*G0_5_8 - 0.000308263165406167*G0_5_9 + 0.000356468927897667*G0_6_0 + 2.33628805057486e-05*G0_6_1 + 0.000347271775843368*G0_6_2 - 6.66000666001008e-06*G0_6_3 + 4.75714761429327e-06*G0_6_4 + 0.00041672613101204*G0_6_5 - 0.000696446410732451*G0_6_6 + 0.000315874601589035*G0_6_7 - 0.000106560106560157*G0_6_8 - 0.000102754388468722*G0_6_9 - 0.000292300292300429*G0_7_0 - 7.11457854315331e-05*G0_7_1 - 8.41486555772665e-05*G0_7_2 + 5.23286237572198e-05*G0_7_3 + 6.37457780315221e-05*G0_7_4 - 0.000640312068883797*G0_7_5 + 0.000315874601589035*G0_7_6 - 0.000645069216498091*G0_7_7 + 0.000288283145426138*G0_7_8 - 0.000291137433994714*G0_7_9 + 0.000150748722177364*G0_8_0 + 4.08057550914885e-05*G0_8_1 + 2.65343122486105e-05*G0_8_2 - 3.61543218686245e-05*G0_8_3 - 1.61743018885953e-05*G0_8_4 + 0.000324437467294763*G0_8_5 - 0.000106560106560157*G0_8_6 + 0.000288283145426138*G0_8_7 - 0.000148423005565932*G0_8_8 + 0.000188383045525991*G0_8_9 - 0.000113537256394452*G0_9_0 - 5.20114805829335e-05*G0_9_1 + 3.86914672629141e-05*G0_9_2 + 5.13771942343615e-05*G0_9_3 - 0.000119880119880176*G0_9_4 - 0.000308263165406167*G0_9_5 - 0.000102754388468722*G0_9_6 - 0.000291137433994714*G0_9_7 + 0.000188383045525991*G0_9_8 - 0.000685029256458149*G0_9_9; + A[111] = A[97]; + A[113] = -A[126] + 0.000104586771253487*G0_0_0 + 3.86444830889459e-06*G0_0_1 - 4.50813149226059e-05*G0_0_2 + 2.65343122486104e-05*G0_0_3 - 8.41486555772664e-05*G0_0_4 + 0.000347271775843368*G0_0_5 - 0.000244200244200359*G0_0_6 + 9.52486666772828e-05*G0_0_7 - 4.01714687429162e-05*G0_0_8 + 3.86914672629141e-05*G0_0_9 + 3.86444830889459e-06*G0_1_0 - 9.23239018477548e-06*G0_1_1 - 3.30651124302073e-05*G0_1_2 + 4.08057550914885e-05*G0_1_3 - 7.11457854315331e-05*G0_1_4 + 2.33628805057484e-05*G0_1_5 - 8.7002944145842e-05*G0_1_6 + 8.77429448858435e-06*G0_1_7 + 1.41657284514494e-05*G0_1_8 - 5.20114805829335e-05*G0_1_9 - 4.50813149226059e-05*G0_2_0 - 3.30651124302073e-05*G0_2_1 - 0.000458800458800674*G0_2_2 + 0.000150748722177364*G0_2_3 - 0.00029230029230043*G0_2_4 + 0.000356468927897667*G0_2_5 - 0.000743700743701093*G0_2_6 + 2.05085919371732e-05*G0_2_7 + 3.70000370000532e-06*G0_2_8 - 0.000113537256394453*G0_2_9 + 2.65343122486104e-05*G0_3_0 + 4.08057550914885e-05*G0_3_1 + 0.000150748722177365*G0_3_2 - 0.000148423005565932*G0_3_3 + 0.000288283145426137*G0_3_4 - 0.000106560106560156*G0_3_5 + 0.000324437467294762*G0_3_6 - 1.61743018885952e-05*G0_3_7 - 3.61543218686244e-05*G0_3_8 + 0.000188383045525991*G0_3_9 - 8.41486555772664e-05*G0_4_0 - 7.11457854315331e-05*G0_4_1 - 0.00029230029230043*G0_4_2 + 0.000288283145426137*G0_4_3 - 0.000645069216498089*G0_4_4 + 0.000315874601589035*G0_4_5 - 0.000640312068883798*G0_4_6 + 6.37457780315222e-05*G0_4_7 + 5.23286237572195e-05*G0_4_8 - 0.000291137433994713*G0_4_9 + 0.000347271775843368*G0_5_0 + 2.33628805057484e-05*G0_5_1 + 0.000356468927897667*G0_5_2 - 0.000106560106560156*G0_5_3 + 0.000315874601589035*G0_5_4 - 0.000696446410732455*G0_5_5 + 0.00041672613101204*G0_5_6 + 4.75714761429252e-06*G0_5_7 - 6.6600066600091e-06*G0_5_8 - 0.000102754388468724*G0_5_9 - 0.000244200244200359*G0_6_0 - 8.70029441458419e-05*G0_6_1 - 0.000743700743701093*G0_6_2 + 0.000324437467294762*G0_6_3 - 0.000640312068883798*G0_6_4 + 0.00041672613101204*G0_6_5 - 0.000764949336378263*G0_6_6 + 1.90285904571713e-06*G0_6_7 + 9.32400932401367e-05*G0_6_8 - 0.000308263165406166*G0_6_9 + 9.52486666772828e-05*G0_7_0 + 8.77429448858435e-06*G0_7_1 + 2.05085919371732e-05*G0_7_2 - 1.61743018885952e-05*G0_7_3 + 6.37457780315222e-05*G0_7_4 + 4.75714761429262e-06*G0_7_5 + 1.90285904571702e-06*G0_7_6 - 8.56286570572679e-05*G0_7_7 - 4.28143285286344e-05*G0_7_8 - 0.000119880119880176*G0_7_9 - 4.01714687429162e-05*G0_8_0 + 1.41657284514494e-05*G0_8_1 + 3.70000370000532e-06*G0_8_2 - 3.61543218686244e-05*G0_8_3 + 5.23286237572195e-05*G0_8_4 - 6.6600066600091e-06*G0_8_5 + 9.32400932401367e-05*G0_8_6 - 4.28143285286344e-05*G0_8_7 - 3.42514628229073e-05*G0_8_8 + 5.13771942343613e-05*G0_8_9 + 3.86914672629141e-05*G0_9_0 - 5.20114805829335e-05*G0_9_1 - 0.000113537256394453*G0_9_2 + 0.000188383045525991*G0_9_3 - 0.000291137433994713*G0_9_4 - 0.000102754388468724*G0_9_5 - 0.000308263165406166*G0_9_6 - 0.000119880119880176*G0_9_7 + 5.13771942343613e-05*G0_9_8 - 0.000685029256458149*G0_9_9; + A[127] = A[113]; + A[78] = A[50]; + A[172] = A[116]; + A[155] = A[85]; + A[105] = A[7]; + A[98] = A[126]; + A[180] = A[12]; + A[173] = -A[41] + 6.49438744677143e-05*G0_0_0 + 8.34262739025032e-06*G0_0_1 + 1.40864426578778e-05*G0_0_2 - 1.45621574193072e-05*G0_0_3 + 7.87572216144012e-05*G0_0_5 - 1.09942967085874e-05*G0_0_6 + 8.62629434058409e-05*G0_0_7 - 3.96428967857725e-05*G0_0_8 + 5.26457669315059e-05*G0_0_9 + 8.34262739025032e-06*G0_1_0 - 2.28989117878116e-05*G0_1_1 - 3.49386063671943e-05*G0_1_3 + 2.5160025160037e-05*G0_1_4 + 1.90550190550281e-05*G0_1_6 + 3.11328882757601e-05*G0_1_7 - 3.49914635629087e-05*G0_1_8 + 9.19715205429923e-06*G0_1_9 + 1.40864426578778e-05*G0_2_0 + 3.19433652767139e-05*G0_2_2 - 1.99800199800295e-05*G0_2_3 + 3.12386026671889e-05*G0_2_4 + 4.60914746629252e-05*G0_2_6 - 8.85358028215589e-06*G0_2_8 + 1.744287458574e-05*G0_2_9 - 1.45621574193072e-05*G0_3_0 - 3.49386063671943e-05*G0_3_1 - 1.99800199800295e-05*G0_3_2 - 2.14071642643175e-06*G0_3_3 - 4.21007563864905e-05*G0_3_4 + 3.59164644879101e-05*G0_3_5 - 9.68079539508568e-05*G0_3_6 + 4.04357547214891e-06*G0_3_7 + 9.03858046715595e-06*G0_3_8 - 3.56786071071955e-05*G0_3_9 + 2.5160025160037e-05*G0_4_1 + 3.12386026671889e-05*G0_4_2 - 4.21007563864905e-05*G0_4_3 + 9.77593834737153e-05*G0_4_4 - 6.82650682651005e-05*G0_4_5 + 0.000165073022215957*G0_4_6 - 1.16550116550172e-05*G0_4_7 - 1.30821559393048e-05*G0_4_8 + 8.42015127729812e-05*G0_4_9 + 7.87572216144012e-05*G0_5_0 + 3.59164644879101e-05*G0_5_3 - 6.82650682651005e-05*G0_5_4 + 0.000149612292469505*G0_5_5 - 0.000221445221445326*G0_5_6 + 0.000125112982255898*G0_5_7 - 5.11393368536464e-05*G0_5_8 - 5.56586270872251e-05*G0_5_9 - 1.09942967085874e-05*G0_6_0 + 1.90550190550281e-05*G0_6_1 + 4.60914746629252e-05*G0_6_2 - 9.68079539508568e-05*G0_6_3 + 0.000165073022215957*G0_6_4 - 0.000221445221445326*G0_6_5 + 0.000507825507825748*G0_6_6 - 7.39736454022517e-05*G0_6_7 + 4.51929023357806e-06*G0_6_8 + 0.000141287284144494*G0_6_9 + 8.62629434058409e-05*G0_7_0 + 3.11328882757601e-05*G0_7_1 + 4.0435754721489e-06*G0_7_3 - 1.16550116550172e-05*G0_7_4 + 0.000125112982255898*G0_7_5 - 7.39736454022517e-05*G0_7_6 + 0.000113457970600881*G0_7_7 - 9.49050949051393e-05*G0_7_8 - 9.99000999001471e-06*G0_7_9 - 3.96428967857725e-05*G0_8_0 - 3.49914635629087e-05*G0_8_1 - 8.85358028215589e-06*G0_8_2 + 9.03858046715595e-06*G0_8_3 - 1.30821559393048e-05*G0_8_4 - 5.11393368536464e-05*G0_8_5 + 4.51929023357806e-06*G0_8_6 - 9.49050949051393e-05*G0_8_7 + 0.000120593692022319*G0_8_8 - 1.42714428428802e-06*G0_8_9 + 5.26457669315059e-05*G0_9_0 + 9.19715205429923e-06*G0_9_1 + 1.744287458574e-05*G0_9_2 - 3.56786071071955e-05*G0_9_3 + 8.42015127729812e-05*G0_9_4 - 5.56586270872251e-05*G0_9_5 + 0.000141287284144494*G0_9_6 - 9.99000999001473e-06*G0_9_7 - 1.42714428428797e-06*G0_9_8 + 5.99400599400879e-05*G0_9_9; + A[118] = A[202]; + A[217] = A[119]; + A[6] = A[90]; + A[22] = A[106]; + A[9] = A[135]; + A[49] = -A[50] - 9.23239018477547e-06*G0_0_0 - 3.30651124302074e-05*G0_0_1 + 3.86444830889459e-06*G0_0_2 - 8.7002944145842e-05*G0_0_3 + 2.33628805057486e-05*G0_0_4 + 1.41657284514494e-05*G0_0_5 + 8.77429448858432e-06*G0_0_6 + 4.08057550914885e-05*G0_0_7 - 7.1145785431533e-05*G0_0_8 - 5.20114805829335e-05*G0_0_9 - 3.30651124302074e-05*G0_1_0 - 0.000458800458800674*G0_1_1 - 4.50813149226059e-05*G0_1_2 - 0.000743700743701092*G0_1_3 + 0.000356468927897667*G0_1_4 + 3.70000370000544e-06*G0_1_5 + 2.0508591937173e-05*G0_1_6 + 0.000150748722177365*G0_1_7 - 0.00029230029230043*G0_1_8 - 0.000113537256394453*G0_1_9 + 3.86444830889458e-06*G0_2_0 - 4.50813149226059e-05*G0_2_1 + 0.000104586771253487*G0_2_2 - 0.000244200244200359*G0_2_3 + 0.000347271775843368*G0_2_4 - 4.01714687429163e-05*G0_2_5 + 9.5248666677283e-05*G0_2_6 + 2.65343122486104e-05*G0_2_7 - 8.41486555772664e-05*G0_2_8 + 3.86914672629141e-05*G0_2_9 - 8.7002944145842e-05*G0_3_0 - 0.000743700743701092*G0_3_1 - 0.000244200244200359*G0_3_2 - 0.000764949336378263*G0_3_3 + 0.00041672613101204*G0_3_4 + 9.32400932401372e-05*G0_3_5 + 1.90285904571707e-06*G0_3_6 + 0.000324437467294762*G0_3_7 - 0.000640312068883798*G0_3_8 - 0.000308263165406167*G0_3_9 + 2.33628805057486e-05*G0_4_0 + 0.000356468927897667*G0_4_1 + 0.000347271775843368*G0_4_2 + 0.00041672613101204*G0_4_3 - 0.000696446410732453*G0_4_4 - 6.66000666000986e-06*G0_4_5 + 4.75714761429284e-06*G0_4_6 - 0.000106560106560157*G0_4_7 + 0.000315874601589035*G0_4_8 - 0.000102754388468722*G0_4_9 + 1.41657284514494e-05*G0_5_0 + 3.70000370000545e-06*G0_5_1 - 4.01714687429163e-05*G0_5_2 + 9.32400932401372e-05*G0_5_3 - 6.66000666000986e-06*G0_5_4 - 3.42514628229076e-05*G0_5_5 - 4.28143285286345e-05*G0_5_6 - 3.61543218686246e-05*G0_5_7 + 5.23286237572198e-05*G0_5_8 + 5.13771942343611e-05*G0_5_9 + 8.77429448858432e-06*G0_6_0 + 2.0508591937173e-05*G0_6_1 + 9.5248666677283e-05*G0_6_2 + 1.90285904571707e-06*G0_6_3 + 4.75714761429295e-06*G0_6_4 - 4.28143285286345e-05*G0_6_5 - 8.56286570572691e-05*G0_6_6 - 1.61743018885951e-05*G0_6_7 + 6.37457780315222e-05*G0_6_8 - 0.000119880119880176*G0_6_9 + 4.08057550914885e-05*G0_7_0 + 0.000150748722177365*G0_7_1 + 2.65343122486104e-05*G0_7_2 + 0.000324437467294762*G0_7_3 - 0.000106560106560157*G0_7_4 - 3.61543218686247e-05*G0_7_5 - 1.61743018885951e-05*G0_7_6 - 0.000148423005565933*G0_7_7 + 0.000288283145426138*G0_7_8 + 0.000188383045525991*G0_7_9 - 7.1145785431533e-05*G0_8_0 - 0.00029230029230043*G0_8_1 - 8.41486555772664e-05*G0_8_2 - 0.000640312068883798*G0_8_3 + 0.000315874601589035*G0_8_4 + 5.23286237572198e-05*G0_8_5 + 6.37457780315222e-05*G0_8_6 + 0.000288283145426138*G0_8_7 - 0.000645069216498091*G0_8_8 - 0.000291137433994713*G0_8_9 - 5.20114805829335e-05*G0_9_0 - 0.000113537256394453*G0_9_1 + 3.86914672629141e-05*G0_9_2 - 0.000308263165406167*G0_9_3 - 0.000102754388468722*G0_9_4 + 5.1377194234361e-05*G0_9_5 - 0.000119880119880176*G0_9_6 + 0.000188383045525991*G0_9_7 - 0.000291137433994713*G0_9_8 - 0.000685029256458149*G0_9_9; + A[34] = A[62]; + A[147] = A[189]; + A[124] = A[68]; + A[84] = -A[137] - 2.28989117878115e-05*G0_0_0 + 8.34262739025035e-06*G0_0_1 + 1.9055019055028e-05*G0_0_4 - 3.49386063671942e-05*G0_0_5 + 2.5160025160037e-05*G0_0_6 - 3.49914635629086e-05*G0_0_7 + 3.11328882757601e-05*G0_0_8 + 9.19715205429921e-06*G0_0_9 + 8.34262739025035e-06*G0_1_0 + 6.49438744677145e-05*G0_1_1 + 1.40864426578778e-05*G0_1_2 + 7.87572216144014e-05*G0_1_3 - 1.09942967085876e-05*G0_1_4 - 1.45621574193071e-05*G0_1_5 - 3.96428967857726e-05*G0_1_7 + 8.62629434058411e-05*G0_1_8 + 5.26457669315059e-05*G0_1_9 + 1.40864426578778e-05*G0_2_1 + 3.19433652767135e-05*G0_2_2 + 4.60914746629247e-05*G0_2_4 - 1.99800199800294e-05*G0_2_5 + 3.12386026671887e-05*G0_2_6 - 8.85358028215592e-06*G0_2_7 + 1.74428745857399e-05*G0_2_9 + 7.87572216144014e-05*G0_3_1 + 0.000149612292469505*G0_3_3 - 0.000221445221445325*G0_3_4 + 3.591646448791e-05*G0_3_5 - 6.82650682651003e-05*G0_3_6 - 5.11393368536465e-05*G0_3_7 + 0.000125112982255898*G0_3_8 - 5.56586270872248e-05*G0_3_9 + 1.9055019055028e-05*G0_4_0 - 1.09942967085876e-05*G0_4_1 + 4.60914746629247e-05*G0_4_2 - 0.000221445221445325*G0_4_3 + 0.000507825507825745*G0_4_4 - 9.68079539508565e-05*G0_4_5 + 0.000165073022215957*G0_4_6 + 4.51929023357809e-06*G0_4_7 - 7.39736454022515e-05*G0_4_8 + 0.000141287284144493*G0_4_9 - 3.49386063671942e-05*G0_5_0 - 1.45621574193071e-05*G0_5_1 - 1.99800199800294e-05*G0_5_2 + 3.591646448791e-05*G0_5_3 - 9.68079539508565e-05*G0_5_4 - 2.14071642643183e-06*G0_5_5 - 4.21007563864903e-05*G0_5_6 + 9.03858046715598e-06*G0_5_7 + 4.04357547214883e-06*G0_5_8 - 3.56786071071955e-05*G0_5_9 + 2.5160025160037e-05*G0_6_0 + 3.12386026671887e-05*G0_6_2 - 6.82650682651003e-05*G0_6_3 + 0.000165073022215957*G0_6_4 - 4.21007563864903e-05*G0_6_5 + 9.7759383473715e-05*G0_6_6 - 1.30821559393047e-05*G0_6_7 - 1.16550116550171e-05*G0_6_8 + 8.4201512772981e-05*G0_6_9 - 3.49914635629086e-05*G0_7_0 - 3.96428967857726e-05*G0_7_1 - 8.85358028215592e-06*G0_7_2 - 5.11393368536465e-05*G0_7_3 + 4.51929023357809e-06*G0_7_4 + 9.03858046715595e-06*G0_7_5 - 1.30821559393047e-05*G0_7_6 + 0.00012059369202232*G0_7_7 - 9.49050949051395e-05*G0_7_8 - 1.42714428428805e-06*G0_7_9 + 3.11328882757601e-05*G0_8_0 + 8.62629434058411e-05*G0_8_1 + 0.000125112982255898*G0_8_3 - 7.39736454022515e-05*G0_8_4 + 4.04357547214884e-06*G0_8_5 - 1.16550116550171e-05*G0_8_6 - 9.49050949051395e-05*G0_8_7 + 0.000113457970600881*G0_8_8 - 9.99000999001457e-06*G0_8_9 + 9.19715205429922e-06*G0_9_0 + 5.26457669315059e-05*G0_9_1 + 1.74428745857399e-05*G0_9_2 - 5.56586270872248e-05*G0_9_3 + 0.000141287284144493*G0_9_4 - 3.56786071071955e-05*G0_9_5 + 8.4201512772981e-05*G0_9_6 - 1.42714428428805e-06*G0_9_7 - 9.99000999001457e-06*G0_9_8 + 5.99400599400879e-05*G0_9_9; + A[67] = A[109]; + A[161] = A[175]; + A[136] = A[24]; + A[96] = A[144] - 0.000114124558569057*G0_0_1 + 0.000114124558569057*G0_0_2 - 6.21600621600913e-05*G0_0_3 + 6.21600621600913e-05*G0_0_4 + 0.00162800162800239*G0_0_5 - 0.000503200503200739*G0_0_6 - 0.0016280016280024*G0_0_7 + 0.000503200503200741*G0_0_8 - 0.000114124558569057*G0_1_0 - 0.000126011554583042*G0_1_1 - 0.000106137248994442*G0_1_3 + 8.41486555772665e-05*G0_1_4 + 0.000186480186480274*G0_1_5 + 2.02971631543157e-05*G0_1_6 - 0.000393680393680579*G0_1_7 - 4.22857565715058e-07*G0_1_8 + 1.26857269714473e-05*G0_1_9 + 0.000114124558569057*G0_2_0 + 0.000126011554583043*G0_2_2 - 8.41486555772666e-05*G0_2_3 + 0.000106137248994442*G0_2_4 + 0.000393680393680579*G0_2_5 + 4.22857565715113e-07*G0_2_6 - 0.000186480186480275*G0_2_7 - 2.02971631543153e-05*G0_2_8 - 1.26857269714471e-05*G0_2_9 - 6.21600621600913e-05*G0_3_0 - 0.000106137248994442*G0_3_1 - 8.41486555772666e-05*G0_3_2 - 0.000342514628229075*G0_3_3 - 0.000186480186480274*G0_3_5 - 6.08914894629468e-05*G0_3_6 + 0.000186480186480275*G0_3_7 - 0.000247371675943221*G0_3_8 - 0.00041101755387489*G0_3_9 + 6.21600621600913e-05*G0_4_0 + 8.41486555772665e-05*G0_4_1 + 0.000106137248994442*G0_4_2 + 0.000342514628229075*G0_4_4 - 0.000186480186480274*G0_4_5 + 0.000247371675943221*G0_4_6 + 0.000186480186480274*G0_4_7 + 6.08914894629467e-05*G0_4_8 + 0.00041101755387489*G0_4_9 + 0.00162800162800239*G0_5_0 + 0.000186480186480274*G0_5_1 + 0.000393680393680579*G0_5_2 - 0.000186480186480274*G0_5_3 - 0.000186480186480274*G0_5_4 + 0.00932400932401371*G0_5_5 - 0.00242424242424356*G0_5_6 - 0.000559440559440822*G0_5_8 + 0.00111888111888164*G0_5_9 - 0.000503200503200739*G0_6_0 + 2.02971631543157e-05*G0_6_1 + 4.2285756571514e-07*G0_6_2 - 6.08914894629468e-05*G0_6_3 + 0.000247371675943221*G0_6_4 - 0.00242424242424356*G0_6_5 + 0.00117216117216172*G0_6_6 + 0.000559440559440825*G0_6_7 + 0.000159840159840235*G0_6_9 - 0.0016280016280024*G0_7_0 - 0.000393680393680578*G0_7_1 - 0.000186480186480275*G0_7_2 + 0.000186480186480275*G0_7_3 + 0.000186480186480274*G0_7_4 + 0.000559440559440825*G0_7_6 - 0.0093240093240137*G0_7_7 + 0.00242424242424357*G0_7_8 - 0.00111888111888164*G0_7_9 + 0.000503200503200741*G0_8_0 - 4.22857565715031e-07*G0_8_1 - 2.02971631543153e-05*G0_8_2 - 0.000247371675943221*G0_8_3 + 6.08914894629467e-05*G0_8_4 - 0.000559440559440822*G0_8_5 + 0.00242424242424357*G0_8_7 - 0.00117216117216172*G0_8_8 - 0.000159840159840235*G0_8_9 + 1.26857269714473e-05*G0_9_1 - 1.26857269714471e-05*G0_9_2 - 0.00041101755387489*G0_9_3 + 0.00041101755387489*G0_9_4 + 0.00111888111888164*G0_9_5 + 0.000159840159840235*G0_9_6 - 0.00111888111888165*G0_9_7 - 0.000159840159840235*G0_9_8; + A[81] = A[95]; + A[167] = A[41]; + A[156] = A[100]; + A[112] = A[160] - 0.000130372273229477*G0_0_1 + 0.000130372273229477*G0_0_2 - 0.00012059369202232*G0_0_3 + 0.00012059369202232*G0_0_4 - 4.32900432900643e-05*G0_0_5 - 0.000243090243090357*G0_0_6 + 4.32900432900639e-05*G0_0_7 + 0.000243090243090358*G0_0_8 - 0.000130372273229477*G0_1_0 - 0.000539196253482221*G0_1_1 - 0.000453594025022809*G0_1_3 + 0.000287093858522565*G0_1_4 + 0.000156272299129515*G0_1_5 + 0.000276865991151835*G0_1_6 + 0.000530184101612923*G0_1_7 - 0.000410303981732746*G0_1_8 + 0.000349650349650514*G0_1_9 + 0.000130372273229477*G0_2_0 + 0.000539196253482221*G0_2_2 - 0.000287093858522565*G0_2_3 + 0.000453594025022809*G0_2_4 - 0.000530184101612922*G0_2_5 + 0.000410303981732746*G0_2_6 - 0.000156272299129516*G0_2_7 - 0.000276865991151836*G0_2_8 - 0.000349650349650514*G0_2_9 - 0.00012059369202232*G0_3_0 - 0.000453594025022809*G0_3_1 - 0.000287093858522565*G0_3_2 - 0.001066076780363*G0_3_3 - 5.35179106607927e-05*G0_3_5 - 0.000830597973455507*G0_3_6 + 0.000361781076066962*G0_3_7 - 0.00119237904952247*G0_3_8 - 0.00177251320108546*G0_3_9 + 0.00012059369202232*G0_4_0 + 0.000287093858522565*G0_4_1 + 0.000453594025022809*G0_4_2 + 0.00106607678036299*G0_4_4 - 0.000361781076066959*G0_4_5 + 0.00119237904952247*G0_4_6 + 5.35179106607934e-05*G0_4_7 + 0.000830597973455507*G0_4_8 + 0.00177251320108546*G0_4_9 - 4.32900432900643e-05*G0_5_0 + 0.000156272299129515*G0_5_1 - 0.000530184101612922*G0_5_2 - 5.35179106607927e-05*G0_5_3 - 0.000361781076066959*G0_5_4 + 0.00428571428571629*G0_5_5 + 0.00111959469102379*G0_5_6 - 0.000468816897388545*G0_5_8 + 0.000937633794777092*G0_5_9 - 0.000243090243090357*G0_6_0 + 0.000276865991151835*G0_6_1 + 0.000410303981732746*G0_6_2 - 0.000830597973455507*G0_6_3 + 0.00119237904952247*G0_6_4 + 0.00111959469102379*G0_6_5 + 0.00535179106607929*G0_6_6 + 0.000468816897388547*G0_6_7 + 0.00271014699586256*G0_6_9 + 4.32900432900639e-05*G0_7_0 + 0.000530184101612923*G0_7_1 - 0.000156272299129516*G0_7_2 + 0.000361781076066962*G0_7_3 + 5.35179106607934e-05*G0_7_4 + 0.000468816897388547*G0_7_6 - 0.00428571428571631*G0_7_7 - 0.00111959469102379*G0_7_8 - 0.000937633794777095*G0_7_9 + 0.000243090243090358*G0_8_0 - 0.000410303981732746*G0_8_1 - 0.000276865991151836*G0_8_2 - 0.00119237904952247*G0_8_3 + 0.000830597973455507*G0_8_4 - 0.000468816897388545*G0_8_5 - 0.00111959469102379*G0_8_7 - 0.0053517910660793*G0_8_8 - 0.00271014699586256*G0_8_9 + 0.000349650349650514*G0_9_1 - 0.000349650349650514*G0_9_2 - 0.00177251320108546*G0_9_3 + 0.00177251320108546*G0_9_4 + 0.000937633794777092*G0_9_5 + 0.00271014699586256*G0_9_6 - 0.000937633794777095*G0_9_7 - 0.00271014699586256*G0_9_8; + A[185] = A[94] - 6.16667283334225e-06*G0_0_0 - 2.99524109048059e-06*G0_0_1 + 1.40952521904998e-07*G0_0_2 - 2.85428856857557e-06*G0_0_3 - 0.000117025831311601*G0_0_4 + 3.01286015571876e-05*G0_0_5 - 1.45885860171646e-05*G0_0_6 - 3.45686059971938e-05*G0_0_8 - 0.000119880119880176*G0_0_9 - 2.99524109048059e-06*G0_1_0 - 2.7027646075278e-05*G0_1_1 - 8.24572253144074e-06*G0_1_2 - 7.29429300858213e-06*G0_1_3 - 4.24971853543484e-05*G0_1_4 + 1.99800199800294e-05*G0_1_5 - 3.71057513914832e-05*G0_1_6 + 3.13971742543318e-05*G0_1_7 - 5.89886304172296e-05*G0_1_8 - 0.000108462965605874*G0_1_9 + 1.40952521904995e-07*G0_2_0 - 8.24572253144074e-06*G0_2_1 + 4.7853381186737e-05*G0_2_2 + 1.49057291914506e-05*G0_2_3 - 7.92857935715479e-06*G0_2_4 + 7.29429300858212e-06*G0_2_5 + 4.34486148772067e-05*G0_2_6 + 7.70657913515417e-05*G0_2_7 + 0.000159840159840235*G0_2_9 - 2.85428856857557e-06*G0_3_0 - 7.29429300858213e-06*G0_3_1 + 1.49057291914506e-05*G0_3_2 - 0.000331097473954773*G0_3_3 + 0.000319680319680471*G0_3_4 - 4.28143285286346e-05*G0_3_5 + 0.000145568716997357*G0_3_6 + 4.28143285286343e-05*G0_3_7 - 8.5628657057269e-05*G0_3_8 + 0.000239760239760353*G0_3_9 - 0.000117025831311601*G0_4_0 - 4.24971853543484e-05*G0_4_1 - 7.92857935715484e-06*G0_4_2 + 0.000319680319680471*G0_4_3 - 0.00229199372056623*G0_4_4 + 0.00038532895675771*G0_4_5 - 0.000530897673755067*G0_4_6 + 4.28143285286349e-05*G0_4_7 + 4.28143285286345e-05*G0_4_8 - 0.00125017839303612*G0_4_9 + 3.01286015571877e-05*G0_5_0 + 1.99800199800294e-05*G0_5_1 + 7.29429300858213e-06*G0_5_2 - 4.28143285286347e-05*G0_5_3 + 0.00038532895675771*G0_5_4 - 1.1417154274302e-05*G0_5_5 - 2.85428856857557e-05*G0_5_6 + 0.000222634508348898*G0_5_7 - 2.56885971171805e-05*G0_5_8 + 0.000411017553874889*G0_5_9 - 1.45885860171646e-05*G0_6_0 - 3.71057513914832e-05*G0_6_1 + 4.34486148772068e-05*G0_6_2 + 0.000145568716997357*G0_6_3 - 0.000530897673755067*G0_6_4 - 2.85428856857558e-05*G0_6_5 - 0.000122734408448753*G0_6_6 - 0.000196945911231718*G0_6_7 + 4.28143285286344e-05*G0_6_8 - 0.000770657913515419*G0_6_9 + 3.13971742543318e-05*G0_7_1 + 7.70657913515417e-05*G0_7_2 + 4.28143285286343e-05*G0_7_3 + 4.28143285286349e-05*G0_7_4 + 0.000222634508348898*G0_7_5 - 0.000196945911231718*G0_7_6 + 0.000724989296418207*G0_7_7 + 3.13971742543323e-05*G0_7_8 + 0.000753532182103963*G0_7_9 - 3.45686059971938e-05*G0_8_0 - 5.89886304172296e-05*G0_8_1 - 8.5628657057269e-05*G0_8_3 + 4.28143285286344e-05*G0_8_4 - 2.56885971171805e-05*G0_8_5 + 4.28143285286344e-05*G0_8_6 + 3.13971742543323e-05*G0_8_7 + 0.000108462965605873*G0_8_8 + 0.000239760239760352*G0_8_9 - 0.000119880119880176*G0_9_0 - 0.000108462965605874*G0_9_1 + 0.000159840159840235*G0_9_2 + 0.000239760239760353*G0_9_3 - 0.00125017839303612*G0_9_4 + 0.000411017553874889*G0_9_5 - 0.000770657913515419*G0_9_6 + 0.000753532182103963*G0_9_7 + 0.000239760239760353*G0_9_8 - 0.000513771942343616*G0_9_9; + A[110] = A[185] - 3.77400377400554e-05*G0_0_0 - 6.73048292096223e-06*G0_0_1 - 3.77047996095792e-05*G0_0_2 + 4.09114694829172e-05*G0_0_3 - 8.08715094429757e-05*G0_0_4 + 9.83143840287139e-06*G0_0_5 - 8.24572253144067e-05*G0_0_6 + 6.12086326372329e-05*G0_0_8 + 9.5142952285854e-06*G0_0_9 - 6.73048292096224e-06*G0_1_0 + 2.17419265038417e-05*G0_1_1 - 3.8409562219104e-05*G0_1_2 + 0.000143031571603067*G0_1_3 - 0.00011290297004588*G0_1_4 + 2.85428856857563e-06*G0_1_5 - 5.80372008943709e-05*G0_1_6 - 5.80372008943709e-05*G0_1_7 + 0.000112268683697308*G0_1_8 + 6.27943485086641e-05*G0_1_9 - 3.77047996095792e-05*G0_2_0 - 3.8409562219104e-05*G0_2_1 - 0.00039713373046725*G0_2_2 + 0.000224854510568902*G0_2_3 - 0.000410700410700603*G0_2_4 + 0.000136054421768772*G0_2_5 - 0.000366300366300538*G0_2_6 - 9.99000999001465e-05*G0_2_7 + 2.94943152086147e-05*G0_2_8 - 0.000232148803577484*G0_2_9 + 4.09114694829172e-05*G0_3_0 + 0.000143031571603067*G0_3_1 + 0.000224854510568902*G0_3_2 - 0.000171257314114537*G0_3_3 + 0.000205508776937443*G0_3_4 - 0.000105608677037298*G0_3_5 + 0.000254031682603229*G0_3_6 - 4.28143285286344e-05*G0_3_7 + 5.13771942343617e-05*G0_3_8 - 0.000102754388468723*G0_3_9 - 8.08715094429757e-05*G0_4_0 - 0.00011290297004588*G0_4_1 - 0.000410700410700603*G0_4_2 + 0.000205508776937443*G0_4_3 - 0.000522334808049333*G0_4_4 + 0.000322534608249045*G0_4_5 - 0.000576566290852274*G0_4_6 + 0.000231197374054625*G0_4_7 - 8.56286570572744e-06*G0_4_8 + 5.13771942343628e-05*G0_4_9 + 9.83143840287138e-06*G0_5_0 + 2.85428856857563e-06*G0_5_1 + 0.000136054421768772*G0_5_2 - 0.000105608677037298*G0_5_3 + 0.000322534608249044*G0_5_4 - 0.000422434708149191*G0_5_5 + 0.000536606250892216*G0_5_6 - 0.000450977593834947*G0_5_7 + 7.13572142143904e-05*G0_5_8 - 0.000171257314114537*G0_5_9 - 8.24572253144067e-05*G0_6_0 - 5.80372008943709e-05*G0_6_1 - 0.000366300366300538*G0_6_2 + 0.000254031682603229*G0_6_3 - 0.000576566290852274*G0_6_4 + 0.000536606250892216*G0_6_5 - 0.000842015127729807*G0_6_6 + 0.000379620379620557*G0_6_7 + 2.85428856857531e-06*G0_6_8 + 0.000188383045525992*G0_6_9 - 5.80372008943709e-05*G0_7_1 - 9.99000999001465e-05*G0_7_2 - 4.28143285286344e-05*G0_7_3 + 0.000231197374054625*G0_7_4 - 0.000450977593834947*G0_7_5 + 0.000379620379620557*G0_7_6 - 0.00103325246182437*G0_7_7 + 2.85428856857502e-06*G0_7_8 - 0.00078778364492687*G0_7_9 + 6.12086326372329e-05*G0_8_0 + 0.000112268683697308*G0_8_1 + 2.94943152086147e-05*G0_8_2 + 5.13771942343617e-05*G0_8_3 - 8.56286570572743e-06*G0_8_4 + 7.13572142143904e-05*G0_8_5 + 2.85428856857531e-06*G0_8_6 + 2.85428856857504e-06*G0_8_7 - 0.00014271442842878*G0_8_8 - 0.000171257314114538*G0_8_9 + 9.51429522858541e-06*G0_9_0 + 6.27943485086641e-05*G0_9_1 - 0.000232148803577484*G0_9_2 - 0.000102754388468723*G0_9_3 + 5.13771942343628e-05*G0_9_4 - 0.000171257314114537*G0_9_5 + 0.000188383045525992*G0_9_6 - 0.00078778364492687*G0_9_7 - 0.000171257314114538*G0_9_8 - 0.000924789496218498*G0_9_9; + A[82] = A[110]; + A[88] = A[185] + 3.49562254324324e-05*G0_0_1 + 2.02971631543156e-05*G0_0_2 + 4.05943263086308e-05*G0_0_3 + 1.0148581577158e-05*G0_0_4 - 4.05943263086312e-05*G0_0_5 - 1.01485815771576e-05*G0_0_6 - 6.08914894629467e-05*G0_0_7 + 0.000152228723657367*G0_0_8 + 3.49562254324324e-05*G0_1_0 + 0.000158994444708805*G0_1_1 + 2.48076438552747e-05*G0_1_2 + 0.000334903192046206*G0_1_3 - 3.0445744731473e-05*G0_1_4 - 5.07429078857889e-05*G0_1_5 + 1.01485815771579e-05*G0_1_6 - 0.00018267446838884*G0_1_7 + 0.000243565957851787*G0_1_8 + 0.00018267446838884*G0_1_9 + 2.02971631543156e-05*G0_2_0 + 2.48076438552747e-05*G0_2_1 + 3.94667061333919e-05*G0_2_2 + 0.000152228723657366*G0_2_3 - 6.08914894629467e-05*G0_2_5 - 0.000142080142080209*G0_2_7 + 0.000223268794697471*G0_2_8 + 0.000121782978925893*G0_2_9 + 4.05943263086308e-05*G0_3_0 + 0.000334903192046206*G0_3_1 + 0.000152228723657366*G0_3_2 + 0.000548023405166519*G0_3_3 - 0.00109604681033304*G0_3_4 + 9.13372341944203e-05*G0_3_5 - 0.000182674468388841*G0_3_6 - 0.00027401170258326*G0_3_7 + 0.00109604681033304*G0_3_8 + 1.0148581577158e-05*G0_4_0 - 3.0445744731473e-05*G0_4_1 - 0.00109604681033304*G0_4_3 + 0.00219209362066608*G0_4_4 - 0.000182674468388841*G0_4_5 + 0.000365348936777681*G0_4_6 + 0.000274011702583259*G0_4_7 - 0.00082203510774978*G0_4_8 - 4.05943263086312e-05*G0_5_0 - 5.07429078857889e-05*G0_5_1 - 6.08914894629467e-05*G0_5_2 + 9.13372341944203e-05*G0_5_3 - 0.000182674468388841*G0_5_4 - 9.13372341944189e-05*G0_5_5 + 0.000182674468388839*G0_5_6 - 0.000274011702583259*G0_5_7 - 1.01485815771576e-05*G0_6_0 + 1.01485815771579e-05*G0_6_1 - 0.000182674468388841*G0_6_3 + 0.000365348936777681*G0_6_4 + 0.000182674468388839*G0_6_5 - 0.000365348936777679*G0_6_6 + 0.000274011702583259*G0_6_7 - 0.00027401170258326*G0_6_8 - 6.08914894629467e-05*G0_7_0 - 0.00018267446838884*G0_7_1 - 0.000142080142080209*G0_7_2 - 0.00027401170258326*G0_7_3 + 0.000274011702583259*G0_7_4 - 0.000274011702583259*G0_7_5 + 0.00027401170258326*G0_7_6 - 0.000456686170972098*G0_7_7 - 0.0004566861709721*G0_7_8 - 0.000548023405166518*G0_7_9 + 0.000152228723657367*G0_8_0 + 0.000243565957851787*G0_8_1 + 0.000223268794697471*G0_8_2 + 0.00109604681033304*G0_8_3 - 0.00082203510774978*G0_8_4 - 0.00027401170258326*G0_8_6 - 0.0004566861709721*G0_8_7 + 0.00200941915227724*G0_8_8 + 0.00109604681033304*G0_8_9 + 0.00018267446838884*G0_9_1 + 0.000121782978925893*G0_9_2 - 0.000548023405166518*G0_9_7 + 0.00109604681033304*G0_9_8; + A[200] = A[88]; + A[203] = A[133]; + A[3] = A[45]; + A[59] = A[213]; + A[17] = A[31]; + A[134] = A[218]; + A[69] = A[139]; + A[48] = A[176] - 0.000126011554583042*G0_0_0 - 0.000114124558569057*G0_0_1 + 0.000186480186480274*G0_0_3 + 2.02971631543154e-05*G0_0_4 - 0.000106137248994442*G0_0_5 + 8.41486555772665e-05*G0_0_6 - 4.22857565714679e-07*G0_0_7 - 0.000393680393680579*G0_0_8 + 1.26857269714474e-05*G0_0_9 - 0.000114124558569057*G0_1_0 + 0.000114124558569057*G0_1_2 + 0.00162800162800239*G0_1_3 - 0.00050320050320074*G0_1_4 - 6.21600621600913e-05*G0_1_5 + 6.21600621600913e-05*G0_1_6 + 0.00050320050320074*G0_1_7 - 0.00162800162800239*G0_1_8 + 0.000114124558569057*G0_2_1 + 0.000126011554583043*G0_2_2 + 0.000393680393680579*G0_2_3 + 4.22857565715004e-07*G0_2_4 - 8.41486555772666e-05*G0_2_5 + 0.000106137248994442*G0_2_6 - 2.02971631543156e-05*G0_2_7 - 0.000186480186480274*G0_2_8 - 1.2685726971447e-05*G0_2_9 + 0.000186480186480274*G0_3_0 + 0.00162800162800239*G0_3_1 + 0.000393680393680579*G0_3_2 + 0.00932400932401372*G0_3_3 - 0.00242424242424357*G0_3_4 - 0.000186480186480274*G0_3_5 - 0.000186480186480274*G0_3_6 - 0.000559440559440823*G0_3_7 + 0.00111888111888165*G0_3_9 + 2.02971631543154e-05*G0_4_0 - 0.00050320050320074*G0_4_1 + 4.22857565715004e-07*G0_4_2 - 0.00242424242424357*G0_4_3 + 0.00117216117216172*G0_4_4 - 6.08914894629469e-05*G0_4_5 + 0.000247371675943221*G0_4_6 + 0.000559440559440823*G0_4_8 + 0.000159840159840235*G0_4_9 - 0.000106137248994442*G0_5_0 - 6.21600621600913e-05*G0_5_1 - 8.41486555772666e-05*G0_5_2 - 0.000186480186480274*G0_5_3 - 6.08914894629469e-05*G0_5_4 - 0.000342514628229075*G0_5_5 - 0.000247371675943221*G0_5_7 + 0.000186480186480275*G0_5_8 - 0.00041101755387489*G0_5_9 + 8.41486555772665e-05*G0_6_0 + 6.21600621600913e-05*G0_6_1 + 0.000106137248994442*G0_6_2 - 0.000186480186480274*G0_6_3 + 0.000247371675943221*G0_6_4 + 0.000342514628229075*G0_6_6 + 6.08914894629466e-05*G0_6_7 + 0.000186480186480274*G0_6_8 + 0.00041101755387489*G0_6_9 - 4.22857565714733e-07*G0_7_0 + 0.00050320050320074*G0_7_1 - 2.02971631543156e-05*G0_7_2 - 0.000559440559440823*G0_7_3 - 0.000247371675943221*G0_7_5 + 6.08914894629466e-05*G0_7_6 - 0.00117216117216172*G0_7_7 + 0.00242424242424357*G0_7_8 - 0.000159840159840236*G0_7_9 - 0.000393680393680579*G0_8_0 - 0.00162800162800239*G0_8_1 - 0.000186480186480274*G0_8_2 + 0.000559440559440822*G0_8_4 + 0.000186480186480275*G0_8_5 + 0.000186480186480274*G0_8_6 + 0.00242424242424357*G0_8_7 - 0.00932400932401371*G0_8_8 - 0.00111888111888164*G0_8_9 + 1.26857269714474e-05*G0_9_0 - 1.2685726971447e-05*G0_9_2 + 0.00111888111888165*G0_9_3 + 0.000159840159840235*G0_9_4 - 0.00041101755387489*G0_9_5 + 0.00041101755387489*G0_9_6 - 0.000159840159840236*G0_9_7 - 0.00111888111888164*G0_9_8; + A[39] = A[137]; + A[121] = A[8] - 0.000228554514268907*G0_0_0 + 5.41786256072226e-06*G0_0_4 - 0.000177758749187404*G0_0_5 + 7.89686503972588e-05*G0_0_6 - 0.000122364408078751*G0_0_7 + 5.95172023743731e-05*G0_0_8 - 3.45686059971936e-05*G0_0_9 + 1.09942967085876e-05*G0_1_3 - 5.41786256072223e-06*G0_1_4 - 1.0042867185729e-05*G0_1_5 - 5.7614343328656e-06*G0_1_6 + 1.84735899021699e-05*G0_1_8 + 1.42714428428782e-06*G0_1_9 + 1.80066846733599e-05*G0_2_2 + 1.58571587143076e-07*G0_2_3 - 3.16614602329037e-05*G0_2_5 + 3.92200392200577e-05*G0_2_6 - 3.17143174286168e-07*G0_2_9 + 1.09942967085876e-05*G0_3_1 + 1.58571587143076e-07*G0_3_2 - 1.18928690357316e-06*G0_3_3 - 4.75714761429336e-07*G0_3_4 - 1.66500166500244e-06*G0_3_5 + 3.40136054421928e-05*G0_3_6 - 4.28143285286346e-06*G0_3_9 + 5.41786256072226e-06*G0_4_0 - 5.41786256072223e-06*G0_4_1 - 4.75714761429349e-07*G0_4_3 + 3.44893202036223e-05*G0_4_4 + 4.75714761429173e-07*G0_4_5 - 3.4489320203622e-05*G0_4_6 - 4.28143285286342e-06*G0_4_7 + 4.28143285286339e-06*G0_4_8 - 0.000177758749187404*G0_5_0 - 1.0042867185729e-05*G0_5_1 - 3.16614602329037e-05*G0_5_2 - 1.66500166500245e-06*G0_5_3 + 4.75714761429187e-07*G0_5_4 - 0.000221920936206754*G0_5_5 + 0.000106322249179442*G0_5_6 - 8.80072308644149e-05*G0_5_7 + 4.68579040007831e-05*G0_5_8 + 9.99000999001473e-06*G0_5_9 + 7.89686503972588e-05*G0_6_0 - 5.7614343328656e-06*G0_6_1 + 3.92200392200577e-05*G0_6_2 + 3.40136054421928e-05*G0_6_3 - 3.4489320203622e-05*G0_6_4 + 0.000106322249179442*G0_6_5 - 0.000241900956186784*G0_6_6 + 4.11493268636319e-05*G0_6_7 - 5.94643451786589e-06*G0_6_8 - 6.70757813615272e-05*G0_6_9 - 0.000122364408078751*G0_7_0 - 4.28143285286342e-06*G0_7_4 - 8.80072308644149e-05*G0_7_5 + 4.11493268636319e-05*G0_7_6 - 6.58864944579539e-05*G0_7_7 + 5.11393368536465e-05*G0_7_8 + 2.14071642643171e-05*G0_7_9 + 5.95172023743731e-05*G0_8_0 + 1.84735899021699e-05*G0_8_1 + 4.28143285286339e-06*G0_8_4 + 4.68579040007831e-05*G0_8_5 - 5.94643451786589e-06*G0_8_6 + 5.11393368536465e-05*G0_8_7 - 4.59064744779245e-05*G0_8_8 - 1.28442985585903e-05*G0_8_9 - 3.45686059971936e-05*G0_9_0 + 1.42714428428782e-06*G0_9_1 - 3.17143174286168e-07*G0_9_2 - 4.28143285286346e-06*G0_9_3 + 9.99000999001473e-06*G0_9_5 - 6.70757813615272e-05*G0_9_6 + 2.14071642643171e-05*G0_9_7 - 1.28442985585903e-05*G0_9_8 + 8.56286570572696e-06*G0_9_9; + A[14] = A[121] - 3.53790829981471e-05*G0_0_0 + 1.29500129500191e-06*G0_0_3 - 3.92993250136292e-05*G0_0_4 - 3.54143211286229e-06*G0_0_5 + 5.81429152857961e-07*G0_0_6 - 1.82357325214553e-05*G0_0_7 + 1.63328734757382e-05*G0_0_8 - 4.31314717029206e-05*G0_0_9 + 1.36900136900202e-05*G0_1_3 - 9.14429485858491e-06*G0_1_4 + 1.01750101750149e-05*G0_1_6 + 8.61572290144129e-06*G0_1_8 + 3.61543218686245e-05*G0_1_9 + 2.35155790711457e-05*G0_2_2 + 5.33857676715069e-06*G0_2_3 + 2.53185967471801e-05*G0_2_4 - 1.65443022585957e-05*G0_2_5 + 2.30985945271768e-05*G0_2_6 + 1.77600177600261e-05*G0_2_9 + 1.29500129500191e-06*G0_3_0 + 1.36900136900202e-05*G0_3_1 + 5.3385767671507e-06*G0_3_2 - 4.54307597164955e-05*G0_3_3 + 4.51929023357825e-06*G0_3_4 - 3.0921459492903e-06*G0_3_5 - 3.59164644879098e-05*G0_3_6 - 9.27643784787079e-06*G0_3_7 - 8.99100899101321e-05*G0_3_9 - 3.92993250136293e-05*G0_4_0 - 9.14429485858491e-06*G0_4_1 + 2.53185967471801e-05*G0_4_2 + 4.51929023357826e-06*G0_4_3 - 0.000390799676514146*G0_4_4 + 0.000112506541078023*G0_4_5 - 7.65900765901128e-05*G0_4_6 + 6.35079206508077e-05*G0_4_7 - 9.27643784787083e-06*G0_4_8 - 0.000278293135436124*G0_4_9 - 3.54143211286229e-06*G0_5_0 - 1.65443022585958e-05*G0_5_2 - 3.09214594929029e-06*G0_5_3 + 0.000112506541078023*G0_5_4 - 4.44793301936369e-05*G0_5_5 - 5.94643451786597e-06*G0_5_6 + 1.47471576043075e-05*G0_5_7 + 0.000155558726987372*G0_5_9 + 5.81429152857968e-07*G0_6_0 + 1.01750101750149e-05*G0_6_1 + 2.30985945271768e-05*G0_6_2 - 3.59164644879098e-05*G0_6_3 - 7.65900765901127e-05*G0_6_4 - 5.94643451786594e-06*G0_6_5 + 0.000280909566623984*G0_6_6 - 1.66500166500257e-06*G0_6_7 - 1.45093002235927e-05*G0_6_8 + 1.85528756957414e-05*G0_6_9 - 1.82357325214553e-05*G0_7_0 - 9.27643784787079e-06*G0_7_3 + 6.35079206508077e-05*G0_7_4 + 1.47471576043075e-05*G0_7_5 - 1.66500166500257e-06*G0_7_6 + 7.92065077779739e-05*G0_7_7 - 4.49550449550662e-05*G0_7_8 + 0.000132724418438767*G0_7_9 + 1.63328734757382e-05*G0_8_0 + 8.61572290144129e-06*G0_8_1 - 9.27643784787085e-06*G0_8_4 - 1.45093002235927e-05*G0_8_6 - 4.49550449550662e-05*G0_8_7 + 1.92664478378857e-05*G0_8_8 - 8.99100899101321e-05*G0_8_9 - 4.31314717029206e-05*G0_9_0 + 3.61543218686245e-05*G0_9_1 + 1.77600177600261e-05*G0_9_2 - 8.9910089910132e-05*G0_9_3 - 0.000278293135436124*G0_9_4 + 0.000155558726987372*G0_9_5 + 1.85528756957413e-05*G0_9_6 + 0.000132724418438767*G0_9_7 - 8.99100899101321e-05*G0_9_8 - 7.7065791351542e-05*G0_9_9; + A[210] = A[14]; + A[87] = A[185]; + A[64] = A[160] - 0.00053919625348222*G0_0_0 - 0.000130372273229477*G0_0_1 + 0.000156272299129515*G0_0_3 + 0.000276865991151836*G0_0_4 - 0.000453594025022809*G0_0_5 + 0.000287093858522565*G0_0_6 - 0.000410303981732745*G0_0_7 + 0.000530184101612922*G0_0_8 + 0.000349650349650514*G0_0_9 - 0.000130372273229477*G0_1_0 + 0.000130372273229477*G0_1_2 - 4.32900432900645e-05*G0_1_3 - 0.000243090243090357*G0_1_4 - 0.00012059369202232*G0_1_5 + 0.00012059369202232*G0_1_6 + 0.000243090243090358*G0_1_7 + 4.32900432900637e-05*G0_1_8 + 0.000130372273229477*G0_2_1 + 0.000539196253482222*G0_2_2 - 0.000530184101612923*G0_2_3 + 0.000410303981732746*G0_2_4 - 0.000287093858522565*G0_2_5 + 0.00045359402502281*G0_2_6 - 0.000276865991151836*G0_2_7 - 0.000156272299129516*G0_2_8 - 0.000349650349650514*G0_2_9 + 0.000156272299129515*G0_3_0 - 4.32900432900644e-05*G0_3_1 - 0.000530184101612923*G0_3_2 + 0.0042857142857163*G0_3_3 + 0.00111959469102379*G0_3_4 - 5.35179106607921e-05*G0_3_5 - 0.00036178107606696*G0_3_6 - 0.000468816897388544*G0_3_7 + 0.00093763379477709*G0_3_9 + 0.000276865991151836*G0_4_0 - 0.000243090243090357*G0_4_1 + 0.000410303981732746*G0_4_2 + 0.00111959469102379*G0_4_3 + 0.0053517910660793*G0_4_4 - 0.000830597973455507*G0_4_5 + 0.00119237904952247*G0_4_6 + 0.000468816897388548*G0_4_8 + 0.00271014699586256*G0_4_9 - 0.000453594025022809*G0_5_0 - 0.00012059369202232*G0_5_1 - 0.000287093858522565*G0_5_2 - 5.3517910660792e-05*G0_5_3 - 0.000830597973455507*G0_5_4 - 0.001066076780363*G0_5_5 - 0.00119237904952247*G0_5_7 + 0.000361781076066961*G0_5_8 - 0.00177251320108546*G0_5_9 + 0.000287093858522565*G0_6_0 + 0.00012059369202232*G0_6_1 + 0.00045359402502281*G0_6_2 - 0.00036178107606696*G0_6_3 + 0.00119237904952247*G0_6_4 + 0.001066076780363*G0_6_6 + 0.000830597973455507*G0_6_7 + 5.3517910660794e-05*G0_6_8 + 0.00177251320108546*G0_6_9 - 0.000410303981732745*G0_7_0 + 0.000243090243090358*G0_7_1 - 0.000276865991151836*G0_7_2 - 0.000468816897388544*G0_7_3 - 0.00119237904952247*G0_7_5 + 0.000830597973455507*G0_7_6 - 0.0053517910660793*G0_7_7 - 0.00111959469102379*G0_7_8 - 0.00271014699586256*G0_7_9 + 0.000530184101612922*G0_8_0 + 4.32900432900637e-05*G0_8_1 - 0.000156272299129516*G0_8_2 + 0.000468816897388548*G0_8_4 + 0.000361781076066961*G0_8_5 + 5.35179106607941e-05*G0_8_6 - 0.00111959469102379*G0_8_7 - 0.00428571428571631*G0_8_8 - 0.000937633794777095*G0_8_9 + 0.000349650349650514*G0_9_0 - 0.000349650349650514*G0_9_2 + 0.00093763379477709*G0_9_3 + 0.00271014699586256*G0_9_4 - 0.00177251320108546*G0_9_5 + 0.00177251320108546*G0_9_6 - 0.00271014699586256*G0_9_7 - 0.000937633794777095*G0_9_8; + A[162] = A[214] - 0.000249485963771795*G0_0_0 + 9.51429522858552e-06*G0_0_1 - 0.000171257314114537*G0_0_3 + 9.133723419442e-05*G0_0_4 - 0.00043004614433206*G0_0_5 + 0.000449074734789232*G0_0_6 - 0.000614623471766618*G0_0_7 + 5.32800532800782e-05*G0_0_8 - 0.000422434708149192*G0_0_9 + 9.51429522858554e-06*G0_1_0 - 9.51429522858542e-06*G0_1_2 - 2.09314495028879e-05*G0_1_3 + 0.000395794681509153*G0_1_4 - 0.000468103325246403*G0_1_5 + 0.000468103325246403*G0_1_6 - 0.000395794681509154*G0_1_7 + 2.09314495028881e-05*G0_1_8 - 9.51429522858542e-06*G0_2_1 + 0.000249485963771795*G0_2_2 - 5.32800532800784e-05*G0_2_3 + 0.000614623471766617*G0_2_4 - 0.000449074734789232*G0_2_5 + 0.000430046144332061*G0_2_6 - 9.13372341944205e-05*G0_2_7 + 0.000171257314114538*G0_2_8 + 0.000422434708149192*G0_2_9 - 0.000171257314114537*G0_3_0 - 2.09314495028879e-05*G0_3_1 - 5.32800532800784e-05*G0_3_2 + 0.000205508776937448*G0_3_3 - 0.00179820179820264*G0_3_4 + 0.000959040959041411*G0_3_5 - 0.00140430997573921*G0_3_6 + 0.000513771942343612*G0_3_7 - 0.00102754388468722*G0_3_9 + 9.133723419442e-05*G0_4_0 + 0.000395794681509153*G0_4_1 + 0.000614623471766617*G0_4_2 - 0.00179820179820264*G0_4_3 + 0.000205508776937446*G0_4_4 - 0.00027401170258326*G0_4_5 + 0.00167832167832247*G0_4_6 - 0.000513771942343613*G0_4_8 - 0.000719280719281057*G0_4_9 - 0.00043004614433206*G0_5_0 - 0.000468103325246403*G0_5_1 - 0.000449074734789232*G0_5_2 + 0.00095904095904141*G0_5_3 - 0.00027401170258326*G0_5_4 - 0.00287712287712423*G0_5_5 - 0.00167832167832247*G0_5_7 + 0.00140430997573921*G0_5_8 - 0.00154131582703084*G0_5_9 + 0.000449074734789232*G0_6_0 + 0.000468103325246403*G0_6_1 + 0.000430046144332061*G0_6_2 - 0.00140430997573921*G0_6_3 + 0.00167832167832247*G0_6_4 + 0.00287712287712423*G0_6_6 + 0.00027401170258326*G0_6_7 - 0.00095904095904141*G0_6_8 + 0.00154131582703084*G0_6_9 - 0.000614623471766618*G0_7_0 - 0.000395794681509154*G0_7_1 - 9.13372341944205e-05*G0_7_2 + 0.000513771942343612*G0_7_3 - 0.00167832167832247*G0_7_5 + 0.00027401170258326*G0_7_6 - 0.000205508776937449*G0_7_7 + 0.00179820179820264*G0_7_8 + 0.000719280719281054*G0_7_9 + 5.32800532800782e-05*G0_8_0 + 2.09314495028881e-05*G0_8_1 + 0.000171257314114538*G0_8_2 - 0.000513771942343613*G0_8_4 + 0.00140430997573921*G0_8_5 - 0.00095904095904141*G0_8_6 + 0.00179820179820264*G0_8_7 - 0.000205508776937443*G0_8_8 + 0.00102754388468723*G0_8_9 - 0.000422434708149192*G0_9_0 + 0.000422434708149192*G0_9_2 - 0.00102754388468722*G0_9_3 - 0.000719280719281057*G0_9_4 - 0.00154131582703084*G0_9_5 + 0.00154131582703084*G0_9_6 + 0.000719280719281054*G0_9_7 + 0.00102754388468723*G0_9_8; + A[93] = A[51]; + A[166] = A[26]; + A[115] = A[157]; + A[190] = A[162]; + A[206] = A[178]; + A[0] = 0.000999386416053554*G0_0_0 + 3.59208692542194e-05*G0_0_1 + 3.59208692542195e-05*G0_0_2 - 3.00625300625435e-06*G0_0_3 - 3.00625300625442e-06*G0_0_4 + 0.000332306582306739*G0_0_5 - 0.000157134532134606*G0_0_6 + 0.000332306582306738*G0_0_7 - 0.000157134532134606*G0_0_8 + 3.60750360750529e-05*G0_0_9 + 3.59208692542194e-05*G0_1_0 + 6.98449111147853e-06*G0_1_1 + 2.56228926863968e-06*G0_1_2 + 1.15790294361778e-06*G0_1_3 + 1.55862655862729e-05*G0_1_5 - 6.23219373219664e-06*G0_1_6 + 2.37840862840974e-05*G0_1_7 - 7.7121952121988e-06*G0_1_8 + 4.92562992563224e-06*G0_1_9 + 3.59208692542195e-05*G0_2_0 + 2.56228926863968e-06*G0_2_1 + 6.98449111147854e-06*G0_2_2 + 1.15790294361778e-06*G0_2_4 + 2.37840862840975e-05*G0_2_5 - 7.71219521219882e-06*G0_2_6 + 1.55862655862729e-05*G0_2_7 - 6.23219373219665e-06*G0_2_8 + 4.92562992563224e-06*G0_2_9 - 3.00625300625435e-06*G0_3_0 + 1.15790294361778e-06*G0_3_1 + 3.45785167213902e-05*G0_3_3 - 1.15806812235438e-05*G0_3_4 - 7.38844488844837e-06*G0_3_5 - 4.26656676656879e-06*G0_3_6 - 1.39443889443955e-05*G0_3_7 + 1.82109557109643e-05*G0_3_8 + 1.31118881118943e-05*G0_3_9 - 3.00625300625442e-06*G0_4_0 + 1.15790294361778e-06*G0_4_2 - 1.15806812235438e-05*G0_4_3 + 3.45785167213902e-05*G0_4_4 - 1.39443889443955e-05*G0_4_5 + 1.82109557109643e-05*G0_4_6 - 7.38844488844834e-06*G0_4_7 - 4.26656676656879e-06*G0_4_8 + 1.31118881118943e-05*G0_4_9 + 0.000332306582306739*G0_5_0 + 1.55862655862729e-05*G0_5_1 + 2.37840862840975e-05*G0_5_2 - 7.38844488844837e-06*G0_5_3 - 1.39443889443955e-05*G0_5_4 + 0.00027888777888791*G0_5_5 - 0.000123834498834557*G0_5_6 + 0.000139443889443955*G0_5_7 - 6.97219447219775e-05*G0_5_8 + 3.12187812187958e-05*G0_5_9 - 0.000157134532134606*G0_6_0 - 6.23219373219664e-06*G0_6_1 - 7.71219521219882e-06*G0_6_2 - 4.26656676656879e-06*G0_6_3 + 1.82109557109643e-05*G0_6_4 - 0.000123834498834557*G0_6_5 + 7.28438228438571e-05*G0_6_6 - 6.97219447219774e-05*G0_6_7 + 3.01781551781694e-05*G0_6_8 - 6.24375624375916e-06*G0_6_9 + 0.000332306582306738*G0_7_0 + 2.37840862840974e-05*G0_7_1 + 1.55862655862729e-05*G0_7_2 - 1.39443889443955e-05*G0_7_3 - 7.38844488844834e-06*G0_7_4 + 0.000139443889443955*G0_7_5 - 6.97219447219774e-05*G0_7_6 + 0.00027888777888791*G0_7_7 - 0.000123834498834557*G0_7_8 + 3.12187812187959e-05*G0_7_9 - 0.000157134532134606*G0_8_0 - 7.71219521219879e-06*G0_8_1 - 6.23219373219665e-06*G0_8_2 + 1.82109557109643e-05*G0_8_3 - 4.26656676656879e-06*G0_8_4 - 6.97219447219775e-05*G0_8_5 + 3.01781551781694e-05*G0_8_6 - 0.000123834498834557*G0_8_7 + 7.28438228438571e-05*G0_8_8 - 6.24375624375914e-06*G0_8_9 + 3.60750360750529e-05*G0_9_0 + 4.92562992563224e-06*G0_9_1 + 4.92562992563224e-06*G0_9_2 + 1.31118881118943e-05*G0_9_3 + 1.31118881118943e-05*G0_9_4 + 3.12187812187958e-05*G0_9_5 - 6.24375624375916e-06*G0_9_6 + 3.12187812187959e-05*G0_9_7 - 6.24375624375914e-06*G0_9_8 + 7.49250749251103e-05*G0_9_9; + A[58] = A[198]; + A[28] = A[165] - 0.000201755916041725*G0_0_0 + 1.02542959685866e-05*G0_0_1 + 1.00428671857297e-06*G0_0_3 + 1.13114398828737e-05*G0_0_4 - 0.00010333581762158*G0_0_5 + 5.36500536500788e-05*G0_0_6 - 0.00015941730227452*G0_0_7 + 8.47829419258389e-05*G0_0_8 - 3.86914672629139e-05*G0_0_9 + 1.02542959685866e-05*G0_1_0 + 0.000226645782201445*G0_1_1 + 2.22910540370963e-05*G0_1_2 + 0.000189757332614565*G0_1_3 - 8.64743721886987e-05*G0_1_4 - 0.000118770118770175*G0_1_7 + 0.000247213104356078*G0_1_8 + 8.49943707086964e-05*G0_1_9 + 2.22910540370963e-05*G0_2_1 + 2.72214557928981e-06*G0_2_3 - 1.13642970785882e-06*G0_2_7 - 6.60714946429425e-07*G0_2_8 - 1.56985871271658e-05*G0_2_9 + 1.00428671857298e-06*G0_3_0 + 0.000189757332614565*G0_3_1 + 2.7221455792898e-06*G0_3_2 + 1.61743018885962e-05*G0_3_3 - 6.87407830265299e-05*G0_3_4 + 2.14071642643157e-06*G0_3_5 - 4.49550449550662e-05*G0_3_6 - 1.83150183150273e-05*G0_3_7 + 3.16350316350472e-05*G0_3_8 - 0.000218353075496035*G0_3_9 + 1.13114398828737e-05*G0_4_0 - 8.64743721886987e-05*G0_4_1 - 6.87407830265299e-05*G0_4_3 + 0.000116074401788742*G0_4_4 - 4.92364778079296e-05*G0_4_5 + 9.41915227629958e-05*G0_4_6 - 7.61143618286827e-06*G0_4_7 - 1.332001332002e-05*G0_4_8 + 0.000145568716997357*G0_4_9 - 0.00010333581762158*G0_5_0 + 2.14071642643156e-06*G0_5_3 - 4.92364778079296e-05*G0_5_4 + 0.000194567337424573*G0_5_5 - 3.52028923457663e-05*G0_5_6 + 3.52028923457664e-05*G0_5_7 - 2.33100233100346e-05*G0_5_8 + 0.000162694448408811*G0_5_9 + 5.36500536500788e-05*G0_6_0 - 4.49550449550662e-05*G0_6_3 + 9.41915227629958e-05*G0_6_4 - 3.52028923457663e-05*G0_6_5 + 0.000210265924551738*G0_6_6 - 1.18928690357319e-05*G0_6_7 - 6.18429189858054e-06*G0_6_8 + 0.00013700585129163*G0_6_9 - 0.00015941730227452*G0_7_0 - 0.000118770118770175*G0_7_1 - 1.13642970785882e-06*G0_7_2 - 1.83150183150273e-05*G0_7_3 - 7.61143618286826e-06*G0_7_4 + 3.52028923457664e-05*G0_7_5 - 1.18928690357319e-05*G0_7_6 - 7.08814994529607e-05*G0_7_7 - 4.23386137672058e-05*G0_7_8 + 0.000139860139860205*G0_7_9 + 8.47829419258389e-05*G0_8_0 + 0.000247213104356078*G0_8_1 - 6.60714946429428e-07*G0_8_2 + 3.16350316350472e-05*G0_8_3 - 1.332001332002e-05*G0_8_4 - 2.33100233100346e-05*G0_8_5 - 6.18429189858053e-06*G0_8_6 - 4.23386137672058e-05*G0_8_7 + 2.04557347414601e-05*G0_8_8 - 0.000228343085486049*G0_8_9 - 3.86914672629139e-05*G0_9_0 + 8.49943707086964e-05*G0_9_1 - 1.56985871271658e-05*G0_9_2 - 0.000218353075496035*G0_9_3 + 0.000145568716997357*G0_9_4 + 0.000162694448408811*G0_9_5 + 0.00013700585129163*G0_9_6 + 0.000139860139860205*G0_9_7 - 0.000228343085486049*G0_9_8 + 0.000548023405166523*G0_9_9; + A[131] = A[173]; + A[74] = A[214]; + A[40] = 3.32691999358822e-05*G0_0_0 + 8.45054416483384e-06*G0_0_1 + 7.50351940828484e-06*G0_0_2 + 6.79875679875999e-06*G0_0_3 - 9.85125985126449e-06*G0_0_4 + 4.33693290836351e-05*G0_0_5 - 2.28739514453908e-05*G0_0_6 + 5.44296972868657e-05*G0_0_7 + 3.21107463964758e-05*G0_0_9 + 8.45054416483384e-06*G0_1_0 + 3.32691999358822e-05*G0_1_1 + 7.50351940828485e-06*G0_1_2 + 4.33693290836352e-05*G0_1_3 - 2.28739514453908e-05*G0_1_4 + 6.79875679875998e-06*G0_1_5 - 9.85125985126448e-06*G0_1_6 + 5.44296972868657e-05*G0_1_8 + 3.21107463964758e-05*G0_1_9 + 7.50351940828484e-06*G0_2_0 + 7.50351940828485e-06*G0_2_1 + 5.30333863667453e-06*G0_2_2 + 5.47071975643658e-06*G0_2_3 + 3.33000333000496e-06*G0_2_4 + 5.4707197564366e-06*G0_2_5 + 3.33000333000491e-06*G0_2_6 - 7.47268604411812e-06*G0_2_7 - 7.47268604411813e-06*G0_2_8 - 7.61143618286831e-06*G0_2_9 + 6.79875679875999e-06*G0_3_0 + 4.33693290836352e-05*G0_3_1 + 5.47071975643658e-06*G0_3_2 + 7.08220351077827e-05*G0_3_3 - 4.15655772798826e-05*G0_3_4 - 6.24375624375919e-06*G0_3_5 + 1.24875124875182e-06*G0_3_6 - 4.87012987013216e-05*G0_3_7 + 5.45882688740089e-05*G0_3_8 + 1.0703582132159e-06*G0_3_9 - 9.85125985126449e-06*G0_4_0 - 2.28739514453908e-05*G0_4_1 + 3.33000333000496e-06*G0_4_2 - 4.15655772798826e-05*G0_4_3 + 1.62337662337739e-05*G0_4_4 + 1.24875124875182e-06*G0_4_5 - 2.49750249750365e-06*G0_4_6 + 4.01384329955947e-05*G0_4_7 - 5.88697017268723e-06*G0_4_8 + 2.03368060511013e-05*G0_4_9 + 4.33693290836351e-05*G0_5_0 + 6.79875679875998e-06*G0_5_1 + 5.4707197564366e-06*G0_5_2 - 6.24375624375918e-06*G0_5_3 + 1.24875124875182e-06*G0_5_4 + 7.08220351077826e-05*G0_5_5 - 4.15655772798825e-05*G0_5_6 + 5.45882688740089e-05*G0_5_7 - 4.87012987013216e-05*G0_5_8 + 1.07035821321592e-06*G0_5_9 - 2.28739514453908e-05*G0_6_0 - 9.85125985126448e-06*G0_6_1 + 3.33000333000491e-06*G0_6_2 + 1.24875124875182e-06*G0_6_3 - 2.49750249750365e-06*G0_6_4 - 4.15655772798825e-05*G0_6_5 + 1.62337662337739e-05*G0_6_6 - 5.88697017268726e-06*G0_6_7 + 4.01384329955948e-05*G0_6_8 + 2.03368060511013e-05*G0_6_9 + 5.44296972868657e-05*G0_7_0 - 7.47268604411812e-06*G0_7_2 - 4.87012987013216e-05*G0_7_3 + 4.01384329955947e-05*G0_7_4 + 5.45882688740089e-05*G0_7_5 - 5.88697017268726e-06*G0_7_6 - 1.26659055230542e-05*G0_7_7 - 0.000166797488226138*G0_7_8 - 8.45582988440528e-05*G0_7_9 + 5.44296972868658e-05*G0_8_1 - 7.47268604411813e-06*G0_8_2 + 5.45882688740089e-05*G0_8_3 - 5.88697017268724e-06*G0_8_4 - 4.87012987013216e-05*G0_8_5 + 4.01384329955948e-05*G0_8_6 - 0.000166797488226138*G0_8_7 - 1.26659055230542e-05*G0_8_8 - 8.45582988440529e-05*G0_8_9 + 3.21107463964758e-05*G0_9_0 + 3.21107463964758e-05*G0_9_1 - 7.61143618286831e-06*G0_9_2 + 1.07035821321589e-06*G0_9_3 + 2.03368060511013e-05*G0_9_4 + 1.07035821321592e-06*G0_9_5 + 2.03368060511013e-05*G0_9_6 - 8.45582988440528e-05*G0_9_7 - 8.45582988440529e-05*G0_9_8 - 0.000173398030540969*G0_9_9; + A[193] = -A[40] - 8.51309184642918e-05*G0_0_0 + 4.56620099477458e-05*G0_0_1 - 4.3239388477504e-05*G0_0_2 - 0.000449887414173341*G0_0_3 + 8.14859743431556e-05*G0_0_4 + 0.000104260818546582*G0_0_5 + 0.000175023389309186*G0_0_6 - 6.46179217608046e-06*G0_0_7 - 0.000289631003916855*G0_0_8 - 0.000515912658770045*G0_0_9 + 4.56620099477458e-05*G0_1_0 - 8.51309184642919e-05*G0_1_1 - 4.32393884775041e-05*G0_1_2 + 0.000104260818546582*G0_1_3 + 0.000175023389309186*G0_1_4 - 0.00044988741417334*G0_1_5 + 8.14859743431557e-05*G0_1_6 - 0.000289631003916855*G0_1_7 - 6.46179217608067e-06*G0_1_8 - 0.000515912658770044*G0_1_9 - 4.3239388477504e-05*G0_2_0 - 4.32393884775041e-05*G0_2_1 - 0.00010108938680372*G0_2_3 + 0.000125112982255898*G0_2_4 - 0.00010108938680372*G0_2_5 + 0.000125112982255898*G0_2_6 + 8.38645481503018e-05*G0_2_7 + 8.38645481503018e-05*G0_2_8 + 0.000540411968983651*G0_2_9 - 0.000449887414173341*G0_3_0 + 0.000104260818546582*G0_3_1 - 0.00010108938680372*G0_3_2 - 0.00376534180105786*G0_3_3 + 0.000232446125303378*G0_3_4 + 0.00122680890538091*G0_3_5 + 0.00159536891679824*G0_3_7 - 0.00158948194662555*G0_3_8 - 0.00164299985728635*G0_3_9 + 8.14859743431556e-05*G0_4_0 + 0.000175023389309186*G0_4_1 + 0.000125112982255898*G0_4_2 + 0.000232446125303378*G0_4_3 - 0.000531789638932747*G0_4_4 - 0.000370879120879296*G0_4_7 - 0.00162373340944846*G0_4_9 + 0.000104260818546582*G0_5_0 - 0.00044988741417334*G0_5_1 - 0.00010108938680372*G0_5_2 + 0.00122680890538091*G0_5_3 - 0.00376534180105786*G0_5_5 + 0.000232446125303378*G0_5_6 - 0.00158948194662555*G0_5_7 + 0.00159536891679824*G0_5_8 - 0.00164299985728635*G0_5_9 + 0.000175023389309186*G0_6_0 + 8.14859743431556e-05*G0_6_1 + 0.000125112982255898*G0_6_2 + 0.000232446125303378*G0_6_5 - 0.000531789638932747*G0_6_6 - 0.000370879120879295*G0_6_8 - 0.00162373340944846*G0_6_9 - 6.46179217608045e-06*G0_7_0 - 0.000289631003916855*G0_7_1 + 8.38645481503018e-05*G0_7_2 + 0.00159536891679824*G0_7_3 - 0.000370879120879296*G0_7_4 - 0.00158948194662555*G0_7_5 - 0.000560689310689576*G0_7_7 + 0.00175128442985668*G0_7_8 + 0.00155951191665551*G0_7_9 - 0.000289631003916855*G0_8_0 - 6.46179217608071e-06*G0_8_1 + 8.38645481503018e-05*G0_8_2 - 0.00158948194662555*G0_8_3 + 0.00159536891679824*G0_8_5 - 0.000370879120879296*G0_8_6 + 0.00175128442985668*G0_8_7 - 0.000560689310689577*G0_8_8 + 0.00155951191665551*G0_8_9 - 0.000515912658770045*G0_9_0 - 0.000515912658770044*G0_9_1 + 0.000540411968983651*G0_9_2 - 0.00164299985728635*G0_9_3 - 0.00162373340944846*G0_9_4 - 0.00164299985728635*G0_9_5 - 0.00162373340944846*G0_9_6 + 0.00155951191665551*G0_9_7 + 0.0015595119166555*G0_9_8 - 0.000173398030540973*G0_9_9; + A[192] = -A[193] + 0.000331520331520487*G0_0_0 - 8.79543736687006e-05*G0_0_2 - 0.00018267446838884*G0_0_3 + 0.00036534893677768*G0_0_4 - 0.000365348936777679*G0_0_5 + 0.00027401170258326*G0_0_6 - 0.000487131915703572*G0_0_7 - 0.000213120213120314*G0_0_8 - 0.00219209362066608*G0_0_9 + 0.000115017257874455*G0_1_1 + 4.0594326308631e-05*G0_1_2 - 0.000304457447314733*G0_1_3 + 0.000152228723657367*G0_1_4 + 0.0009133723419442*G0_1_5 - 0.00018267446838884*G0_1_6 + 0.000761143618286832*G0_1_7 - 0.000791589363018306*G0_1_8 + 0.00109604681033304*G0_1_9 - 8.79543736687007e-05*G0_2_0 + 4.0594326308631e-05*G0_2_1 + 0.000236800236800348*G0_2_2 - 0.000152228723657367*G0_2_3 - 0.000243565957851786*G0_2_4 + 0.000943818086675671*G0_2_5 - 0.000608914894629467*G0_2_6 + 0.00146139574711072*G0_2_7 - 0.00018267446838884*G0_2_8 + 0.00219209362066608*G0_2_9 - 0.00018267446838884*G0_3_0 - 0.000304457447314733*G0_3_1 - 0.000152228723657367*G0_3_2 - 0.00164407021549956*G0_3_3 - 0.000822035107749781*G0_3_5 - 0.00328814043099913*G0_3_9 + 0.00036534893677768*G0_4_0 + 0.000152228723657367*G0_4_1 - 0.000243565957851786*G0_4_2 + 0.00164407021549956*G0_4_4 - 0.00164407021549956*G0_4_5 + 0.00164407021549956*G0_4_6 - 0.00246610532324934*G0_4_7 - 0.00328814043099912*G0_4_9 - 0.00036534893677768*G0_5_0 + 0.000913372341944199*G0_5_1 + 0.000943818086675671*G0_5_2 - 0.000822035107749781*G0_5_3 - 0.00164407021549956*G0_5_4 + 0.00931639788783084*G0_5_5 - 0.00383616383616564*G0_5_6 + 0.0082203510774978*G0_5_7 - 0.00328814043099912*G0_5_8 + 0.0131525617239965*G0_5_9 + 0.00027401170258326*G0_6_0 - 0.00018267446838884*G0_6_1 - 0.000608914894629467*G0_6_2 + 0.00164407021549956*G0_6_4 - 0.00383616383616564*G0_6_5 + 0.0027401170258326*G0_6_6 - 0.00493221064649868*G0_6_7 + 0.000822035107749781*G0_6_8 - 0.00657628086199824*G0_6_9 - 0.000487131915703572*G0_7_0 + 0.000761143618286832*G0_7_1 + 0.00146139574711072*G0_7_2 - 0.00246610532324934*G0_7_4 + 0.0082203510774978*G0_7_5 - 0.00493221064649868*G0_7_6 + 0.01260453831883*G0_7_7 - 0.00219209362066608*G0_7_8 + 0.0164407021549956*G0_7_9 - 0.000213120213120314*G0_8_0 - 0.000791589363018307*G0_8_1 - 0.00018267446838884*G0_8_2 - 0.00328814043099912*G0_8_5 + 0.000822035107749781*G0_8_6 - 0.00219209362066608*G0_8_7 + 0.0027401170258326*G0_8_8 - 0.00328814043099912*G0_8_9 - 0.00219209362066608*G0_9_0 + 0.00109604681033304*G0_9_1 + 0.00219209362066608*G0_9_2 - 0.00328814043099913*G0_9_3 - 0.00328814043099912*G0_9_4 + 0.0131525617239965*G0_9_5 - 0.00657628086199824*G0_9_6 + 0.0164407021549956*G0_9_7 - 0.00328814043099912*G0_9_8 + 0.0394576851719894*G0_9_9; + A[208] = -A[193] + 0.000115017257874455*G0_0_0 + 4.05943263086311e-05*G0_0_2 + 0.0009133723419442*G0_0_3 - 0.00018267446838884*G0_0_4 - 0.000304457447314733*G0_0_5 + 0.000152228723657367*G0_0_6 - 0.000791589363018307*G0_0_7 + 0.000761143618286833*G0_0_8 + 0.00109604681033304*G0_0_9 + 0.000331520331520488*G0_1_1 - 8.79543736687007e-05*G0_1_2 - 0.00036534893677768*G0_1_3 + 0.00027401170258326*G0_1_4 - 0.00018267446838884*G0_1_5 + 0.00036534893677768*G0_1_6 - 0.000213120213120314*G0_1_7 - 0.000487131915703573*G0_1_8 - 0.00219209362066608*G0_1_9 + 4.05943263086311e-05*G0_2_0 - 8.79543736687007e-05*G0_2_1 + 0.000236800236800348*G0_2_2 + 0.000943818086675672*G0_2_3 - 0.000608914894629466*G0_2_4 - 0.000152228723657367*G0_2_5 - 0.000243565957851786*G0_2_6 - 0.00018267446838884*G0_2_7 + 0.00146139574711072*G0_2_8 + 0.00219209362066608*G0_2_9 + 0.0009133723419442*G0_3_0 - 0.00036534893677768*G0_3_1 + 0.000943818086675672*G0_3_2 + 0.00931639788783084*G0_3_3 - 0.00383616383616564*G0_3_4 - 0.000822035107749781*G0_3_5 - 0.00164407021549956*G0_3_6 - 0.00328814043099912*G0_3_7 + 0.0082203510774978*G0_3_8 + 0.0131525617239965*G0_3_9 - 0.00018267446838884*G0_4_0 + 0.00027401170258326*G0_4_1 - 0.000608914894629466*G0_4_2 - 0.00383616383616564*G0_4_3 + 0.0027401170258326*G0_4_4 + 0.00164407021549956*G0_4_6 + 0.00082203510774978*G0_4_7 - 0.00493221064649868*G0_4_8 - 0.00657628086199824*G0_4_9 - 0.000304457447314733*G0_5_0 - 0.00018267446838884*G0_5_1 - 0.000152228723657367*G0_5_2 - 0.000822035107749782*G0_5_3 - 0.00164407021549956*G0_5_5 - 0.00328814043099913*G0_5_9 + 0.000152228723657367*G0_6_0 + 0.00036534893677768*G0_6_1 - 0.000243565957851786*G0_6_2 - 0.00164407021549956*G0_6_3 + 0.00164407021549956*G0_6_4 + 0.00164407021549956*G0_6_6 - 0.00246610532324934*G0_6_8 - 0.00328814043099912*G0_6_9 - 0.000791589363018307*G0_7_0 - 0.000213120213120314*G0_7_1 - 0.00018267446838884*G0_7_2 - 0.00328814043099912*G0_7_3 + 0.00082203510774978*G0_7_4 + 0.0027401170258326*G0_7_7 - 0.00219209362066608*G0_7_8 - 0.00328814043099912*G0_7_9 + 0.000761143618286834*G0_8_0 - 0.000487131915703573*G0_8_1 + 0.00146139574711072*G0_8_2 + 0.0082203510774978*G0_8_3 - 0.00493221064649868*G0_8_4 - 0.00246610532324934*G0_8_6 - 0.00219209362066608*G0_8_7 + 0.01260453831883*G0_8_8 + 0.0164407021549956*G0_8_9 + 0.00109604681033304*G0_9_0 - 0.00219209362066608*G0_9_1 + 0.00219209362066608*G0_9_2 + 0.0131525617239965*G0_9_3 - 0.00657628086199824*G0_9_4 - 0.00328814043099913*G0_9_5 - 0.00328814043099912*G0_9_6 - 0.00328814043099912*G0_9_7 + 0.0164407021549956*G0_9_8 + 0.0394576851719895*G0_9_9; + A[222] = A[193] - 8.79543736687009e-05*G0_0_1 + 8.79543736687007e-05*G0_0_2 + 0.000548023405166521*G0_0_3 - 0.00054802340516652*G0_0_4 - 0.000121782978925894*G0_0_5 - 0.000487131915703573*G0_0_6 + 0.000121782978925893*G0_0_7 + 0.000487131915703574*G0_0_8 - 8.79543736687009e-05*G0_1_0 + 0.000121782978925893*G0_1_1 + 6.08914894629463e-05*G0_1_3 - 0.000304457447314734*G0_1_4 + 0.00054802340516652*G0_1_5 + 0.000182674468388841*G0_1_7 + 0.00018267446838884*G0_1_8 + 0.00109604681033304*G0_1_9 + 8.79543736687007e-05*G0_2_0 - 0.000121782978925893*G0_2_2 + 0.000304457447314734*G0_2_3 - 6.0891489462947e-05*G0_2_4 - 0.000182674468388839*G0_2_5 - 0.00018267446838884*G0_2_6 - 0.000548023405166519*G0_2_7 - 0.00109604681033304*G0_2_9 + 0.000548023405166521*G0_3_0 + 6.08914894629463e-05*G0_3_1 + 0.000304457447314734*G0_3_2 + 0.00328814043099912*G0_3_3 - 0.00164407021549956*G0_3_5 - 0.00164407021549956*G0_3_7 + 0.00164407021549956*G0_3_8 - 0.00054802340516652*G0_4_0 - 0.000304457447314734*G0_4_1 - 6.08914894629471e-05*G0_4_2 - 0.00328814043099912*G0_4_4 + 0.00164407021549956*G0_4_5 - 0.00164407021549956*G0_4_6 + 0.00164407021549956*G0_4_7 - 0.000121782978925894*G0_5_0 + 0.00054802340516652*G0_5_1 - 0.000182674468388839*G0_5_2 - 0.00164407021549956*G0_5_3 + 0.00164407021549956*G0_5_4 + 0.00328814043099912*G0_5_5 + 0.00164407021549956*G0_5_6 - 0.00164407021549956*G0_5_8 + 0.00328814043099912*G0_5_9 - 0.000487131915703573*G0_6_0 - 0.00018267446838884*G0_6_2 - 0.00164407021549956*G0_6_4 + 0.00164407021549956*G0_6_5 + 0.00164407021549956*G0_6_7 + 0.00328814043099912*G0_6_9 + 0.000121782978925893*G0_7_0 + 0.000182674468388841*G0_7_1 - 0.000548023405166519*G0_7_2 - 0.00164407021549956*G0_7_3 + 0.00164407021549956*G0_7_4 + 0.00164407021549956*G0_7_6 - 0.00328814043099911*G0_7_7 - 0.00164407021549956*G0_7_8 - 0.00328814043099912*G0_7_9 + 0.000487131915703574*G0_8_0 + 0.00018267446838884*G0_8_1 + 0.00164407021549956*G0_8_3 - 0.00164407021549956*G0_8_5 - 0.00164407021549956*G0_8_7 - 0.00328814043099912*G0_8_9 + 0.00109604681033304*G0_9_1 - 0.00109604681033304*G0_9_2 + 0.00328814043099912*G0_9_5 + 0.00328814043099912*G0_9_6 - 0.00328814043099912*G0_9_7 - 0.00328814043099912*G0_9_8; + A[207] = A[193]; + A[194] = A[222]; + A[223] = A[193] + 0.000121782978925893*G0_0_0 - 8.79543736687009e-05*G0_0_1 + 0.000548023405166521*G0_0_3 + 6.08914894629459e-05*G0_0_5 - 0.000304457447314733*G0_0_6 + 0.000182674468388839*G0_0_7 + 0.000182674468388841*G0_0_8 + 0.00109604681033304*G0_0_9 - 8.79543736687009e-05*G0_1_0 + 8.79543736687007e-05*G0_1_2 - 0.000121782978925894*G0_1_3 - 0.000487131915703573*G0_1_4 + 0.00054802340516652*G0_1_5 - 0.00054802340516652*G0_1_6 + 0.000487131915703574*G0_1_7 + 0.000121782978925893*G0_1_8 + 8.79543736687007e-05*G0_2_1 - 0.000121782978925893*G0_2_2 - 0.000182674468388839*G0_2_3 - 0.00018267446838884*G0_2_4 + 0.000304457447314733*G0_2_5 - 6.08914894629471e-05*G0_2_6 - 0.000548023405166519*G0_2_8 - 0.00109604681033304*G0_2_9 + 0.000548023405166521*G0_3_0 - 0.000121782978925894*G0_3_1 - 0.000182674468388839*G0_3_2 + 0.00328814043099913*G0_3_3 + 0.00164407021549956*G0_3_4 - 0.00164407021549956*G0_3_5 + 0.00164407021549956*G0_3_6 - 0.00164407021549956*G0_3_7 + 0.00328814043099913*G0_3_9 - 0.000487131915703573*G0_4_1 - 0.00018267446838884*G0_4_2 + 0.00164407021549956*G0_4_3 - 0.00164407021549956*G0_4_6 + 0.00164407021549956*G0_4_8 + 0.00328814043099912*G0_4_9 + 6.08914894629459e-05*G0_5_0 + 0.00054802340516652*G0_5_1 + 0.000304457447314733*G0_5_2 - 0.00164407021549956*G0_5_3 + 0.00328814043099912*G0_5_5 + 0.00164407021549956*G0_5_7 - 0.00164407021549956*G0_5_8 - 0.000304457447314733*G0_6_0 - 0.00054802340516652*G0_6_1 - 6.08914894629471e-05*G0_6_2 + 0.00164407021549956*G0_6_3 - 0.00164407021549956*G0_6_4 - 0.00328814043099912*G0_6_6 + 0.00164407021549956*G0_6_8 + 0.000182674468388839*G0_7_0 + 0.000487131915703574*G0_7_1 - 0.00164407021549956*G0_7_3 + 0.00164407021549956*G0_7_5 - 0.00164407021549956*G0_7_8 - 0.00328814043099912*G0_7_9 + 0.000182674468388841*G0_8_0 + 0.000121782978925893*G0_8_1 - 0.000548023405166519*G0_8_2 + 0.00164407021549956*G0_8_4 - 0.00164407021549956*G0_8_5 + 0.00164407021549956*G0_8_6 - 0.00164407021549956*G0_8_7 - 0.00328814043099912*G0_8_8 - 0.00328814043099912*G0_8_9 + 0.00109604681033304*G0_9_0 - 0.00109604681033304*G0_9_2 + 0.00328814043099913*G0_9_3 + 0.00328814043099912*G0_9_4 - 0.00328814043099912*G0_9_7 - 0.00328814043099911*G0_9_8; + A[224] = -A[222] + 0.000115017257874455*G0_0_0 + 4.05943263086312e-05*G0_0_1 - 0.00018267446838884*G0_0_3 + 0.000913372341944199*G0_0_4 - 0.000791589363018307*G0_0_5 + 0.000761143618286833*G0_0_6 - 0.000304457447314734*G0_0_7 + 0.000152228723657367*G0_0_8 + 0.00109604681033304*G0_0_9 + 4.05943263086312e-05*G0_1_0 + 0.000236800236800348*G0_1_1 - 8.79543736687007e-05*G0_1_2 - 0.000608914894629466*G0_1_3 + 0.000943818086675673*G0_1_4 - 0.000182674468388841*G0_1_5 + 0.00146139574711072*G0_1_6 - 0.000152228723657367*G0_1_7 - 0.000243565957851786*G0_1_8 + 0.00219209362066608*G0_1_9 - 8.79543736687007e-05*G0_2_1 + 0.000331520331520487*G0_2_2 + 0.00027401170258326*G0_2_3 - 0.000365348936777679*G0_2_4 - 0.000213120213120313*G0_2_5 - 0.000487131915703572*G0_2_6 - 0.00018267446838884*G0_2_7 + 0.00036534893677768*G0_2_8 - 0.00219209362066608*G0_2_9 - 0.00018267446838884*G0_3_0 - 0.000608914894629466*G0_3_1 + 0.00027401170258326*G0_3_2 + 0.0027401170258326*G0_3_3 - 0.00383616383616564*G0_3_4 + 0.000822035107749782*G0_3_5 - 0.00493221064649868*G0_3_6 + 0.00164407021549956*G0_3_8 - 0.00657628086199824*G0_3_9 + 0.000913372341944199*G0_4_0 + 0.000943818086675673*G0_4_1 - 0.000365348936777679*G0_4_2 - 0.00383616383616564*G0_4_3 + 0.00931639788783083*G0_4_4 - 0.00328814043099912*G0_4_5 + 0.0082203510774978*G0_4_6 - 0.000822035107749782*G0_4_7 - 0.00164407021549956*G0_4_8 + 0.0131525617239965*G0_4_9 - 0.000791589363018307*G0_5_0 - 0.000182674468388841*G0_5_1 - 0.000213120213120313*G0_5_2 + 0.000822035107749782*G0_5_3 - 0.00328814043099912*G0_5_4 + 0.0027401170258326*G0_5_5 - 0.00219209362066609*G0_5_6 - 0.00328814043099912*G0_5_9 + 0.000761143618286833*G0_6_0 + 0.00146139574711072*G0_6_1 - 0.000487131915703572*G0_6_2 - 0.00493221064649868*G0_6_3 + 0.0082203510774978*G0_6_4 - 0.00219209362066609*G0_6_5 + 0.01260453831883*G0_6_6 - 0.00246610532324934*G0_6_8 + 0.0164407021549956*G0_6_9 - 0.000304457447314734*G0_7_0 - 0.000152228723657367*G0_7_1 - 0.00018267446838884*G0_7_2 - 0.000822035107749782*G0_7_4 - 0.00164407021549956*G0_7_7 - 0.00328814043099912*G0_7_9 + 0.000152228723657367*G0_8_0 - 0.000243565957851786*G0_8_1 + 0.00036534893677768*G0_8_2 + 0.00164407021549956*G0_8_3 - 0.00164407021549956*G0_8_4 - 0.00246610532324934*G0_8_6 + 0.00164407021549956*G0_8_8 - 0.00328814043099912*G0_8_9 + 0.00109604681033304*G0_9_0 + 0.00219209362066608*G0_9_1 - 0.00219209362066608*G0_9_2 - 0.00657628086199824*G0_9_3 + 0.0131525617239965*G0_9_4 - 0.00328814043099912*G0_9_5 + 0.0164407021549956*G0_9_6 - 0.00328814043099912*G0_9_7 - 0.00328814043099912*G0_9_8 + 0.0394576851719894*G0_9_9; + A[145] = A[159]; + A[151] = A[25]; + A[102] = A[186]; + A[177] = A[191]; + A[114] = A[142]; + A[221] = A[179]; + A[196] = A[28]; + A[209] = A[223]; + A[13] = A[195]; + A[53] = A[123]; + A[30] = A[2]; + A[23] = A[121]; + A[128] = A[80] + 0.000126011554583042*G0_0_0 + 0.000114124558569057*G0_0_2 - 2.02971631543155e-05*G0_0_3 - 0.000186480186480274*G0_0_4 + 4.22857565714327e-07*G0_0_5 + 0.000393680393680579*G0_0_6 + 0.000106137248994441*G0_0_7 - 8.41486555772664e-05*G0_0_8 - 1.26857269714471e-05*G0_0_9 - 0.000126011554583042*G0_1_1 - 0.000114124558569057*G0_1_2 - 4.22857565714272e-07*G0_1_3 - 0.00039368039368058*G0_1_4 + 2.02971631543156e-05*G0_1_5 + 0.000186480186480274*G0_1_6 + 8.41486555772665e-05*G0_1_7 - 0.000106137248994442*G0_1_8 + 1.2685726971447e-05*G0_1_9 + 0.000114124558569057*G0_2_0 - 0.000114124558569057*G0_2_1 + 0.000503200503200741*G0_2_3 - 0.0016280016280024*G0_2_4 - 0.000503200503200741*G0_2_5 + 0.00162800162800239*G0_2_6 + 6.21600621600911e-05*G0_2_7 - 6.21600621600913e-05*G0_2_8 - 2.02971631543155e-05*G0_3_0 - 4.22857565714299e-07*G0_3_1 + 0.000503200503200741*G0_3_2 - 0.00117216117216172*G0_3_3 + 0.00242424242424357*G0_3_4 - 0.000559440559440822*G0_3_6 + 6.08914894629465e-05*G0_3_7 - 0.00024737167594322*G0_3_8 - 0.000159840159840234*G0_3_9 - 0.000186480186480274*G0_4_0 - 0.00039368039368058*G0_4_1 - 0.0016280016280024*G0_4_2 + 0.00242424242424357*G0_4_3 - 0.00932400932401372*G0_4_4 + 0.000559440559440823*G0_4_5 + 0.000186480186480275*G0_4_7 + 0.000186480186480273*G0_4_8 - 0.00111888111888165*G0_4_9 + 4.22857565714327e-07*G0_5_0 + 2.02971631543156e-05*G0_5_1 - 0.000503200503200741*G0_5_2 + 0.000559440559440823*G0_5_4 + 0.00117216117216172*G0_5_5 - 0.00242424242424357*G0_5_6 + 0.00024737167594322*G0_5_7 - 6.08914894629465e-05*G0_5_8 + 0.000159840159840234*G0_5_9 + 0.000393680393680579*G0_6_0 + 0.000186480186480274*G0_6_1 + 0.00162800162800239*G0_6_2 - 0.000559440559440822*G0_6_3 - 0.00242424242424357*G0_6_5 + 0.00932400932401371*G0_6_6 - 0.000186480186480276*G0_6_7 - 0.000186480186480274*G0_6_8 + 0.00111888111888165*G0_6_9 + 0.000106137248994441*G0_7_0 + 8.41486555772665e-05*G0_7_1 + 6.21600621600911e-05*G0_7_2 + 6.08914894629465e-05*G0_7_3 + 0.000186480186480275*G0_7_4 + 0.00024737167594322*G0_7_5 - 0.000186480186480276*G0_7_6 + 0.000342514628229074*G0_7_7 + 0.000411017553874889*G0_7_9 - 8.41486555772664e-05*G0_8_0 - 0.000106137248994442*G0_8_1 - 6.21600621600913e-05*G0_8_2 - 0.00024737167594322*G0_8_3 + 0.000186480186480273*G0_8_4 - 6.08914894629465e-05*G0_8_5 - 0.000186480186480274*G0_8_6 - 0.000342514628229075*G0_8_8 - 0.00041101755387489*G0_8_9 - 1.26857269714471e-05*G0_9_0 + 1.26857269714471e-05*G0_9_1 - 0.000159840159840234*G0_9_3 - 0.00111888111888165*G0_9_4 + 0.000159840159840234*G0_9_5 + 0.00111888111888165*G0_9_6 + 0.000411017553874889*G0_9_7 - 0.00041101755387489*G0_9_8; + A[63] = A[49]; + A[140] = A[84]; + A[77] = A[35]; + A[171] = A[101]; + A[152] = A[40]; + } + + /// 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 mass_matrix_f2_p3_q4_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f2_p3_q4_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f2_p3_q4_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1))), 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 mass_matrix_f2_p3_q4_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p3_q4_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p3_q4_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p3_q4_tensor_finite_element_0(); + 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 mass_matrix_f2_p3_q4_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f2_p3_q4_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f2_p3_q4_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f2_p3_q4_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f2_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/mass_matrix_2d/mass_matrix_f3_p1_q1_excafe.h b/mass_matrix_2d/mass_matrix_f3_p1_q1_excafe.h new file mode 100644 index 0000000..e274071 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f3_p1_q1_excafe.h @@ -0,0 +1,87 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 0.33 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][1]*w[1][0] + w[0][0]*w[1][1]; + const double var_1 = var_0*w[2][1] + w[0][1]*w[1][1]*w[2][0]; + const double var_2 = w[0][0]*w[1][0]*w[2][1] + var_0*w[2][0]; + const double var_3 = var_1 + var_2; + const double var_4 = w[0][1]*w[1][2] + w[0][2]*w[1][1]; + const double var_5 = w[0][0]*w[1][2] + w[0][2]*w[1][0]; + const double var_6 = var_4*w[2][0] + var_5*w[2][1] + var_0*w[2][2]; + const double var_7 = 0.5000000000000000000000000*var_6; + const double var_8 = var_4*w[2][1] + w[0][1]*w[1][1]*w[2][2]; + const double var_9 = var_5*w[2][0] + w[0][0]*w[1][0]*w[2][2]; + const double var_10 = var_8 + var_9; + const double var_11 = w[0][1]*w[1][1]*w[2][1]; + const double var_12 = w[0][0]*w[1][0]*w[2][0]; + const double var_13 = var_11 + var_12; + const double var_14 = 0.3333333333333333148296163*var_3 + var_10 + var_13 + var_7; + const double var_15 = w[0][2]*w[1][2]*w[2][2]; + const double var_16 = -1.0000000000000000000000000*x[0][0]; + const double var_17 = x[1][0] + var_16; + const double var_18 = -1.0000000000000000000000000*x[0][1]; + const double var_19 = x[2][1] + var_18; + const double var_20 = x[2][0] + var_16; + const double var_21 = x[1][1] + var_18; + const double var_22 = var_17*var_19 + -1.0000000000000000000000000*var_20*var_21; + const double var_23 = std::abs(var_22); + const double var_24 = var_4*w[2][2] + w[0][2]*w[1][2]*w[2][1]; + const double var_25 = w[0][2]*w[1][2]*w[2][0] + var_5*w[2][2]; + const double var_26 = var_25 + var_24; + const double var_27 = 0.1666666666666666574148081*var_6; + const double var_28 = var_10 + var_15; + const double var_29 = 0.5000000000000000000000000*var_3 + 0.2500000000000000000000000*var_28 + var_27 + 0.1666666666666666574148081*var_26 + var_13; + A[1] = 0.0047619047619047623343125*var_23*var_29; + A[3] = A[1]; + const double var_30 = var_2 + var_24; + const double var_31 = 0.1000000000000000055511151*var_14 + 0.2000000000000000111022302*var_26 + var_15; + const double var_32 = var_1 + var_8; + const double var_33 = var_25 + var_9; + const double var_34 = var_30 + var_11; + const double var_35 = var_15 + var_27; + const double var_36 = var_12 + 0.2500000000000000000000000*var_34 + var_35 + 0.5000000000000000000000000*var_33 + 0.1666666666666666574148081*var_32; + A[2] = 0.0047619047619047623343125*var_23*var_36; + const double var_37 = var_2 + var_9; + const double var_38 = var_8 + var_24; + const double var_39 = var_1 + var_25; + const double var_40 = var_15 + var_7; + const double var_41 = 0.3333333333333333148296163*var_38 + var_11 + var_40 + var_39; + const double var_42 = 0.2000000000000000111022302*var_37 + var_12 + 0.1000000000000000055511151*var_41; + A[0] = 0.0238095238095238082021154*var_23*var_42; + const double var_43 = var_12 + var_30 + 0.3333333333333333148296163*var_33 + var_40; + const double var_44 = 0.2000000000000000111022302*var_32 + var_11 + 0.1000000000000000055511151*var_43; + A[4] = 0.0238095238095238082021154*var_23*var_44; + A[8] = 0.0238095238095238082021154*var_23*var_31; + A[6] = A[2]; + const double var_45 = var_12 + var_39; + const double var_46 = var_11 + var_35 + 0.2500000000000000000000000*var_45 + 0.5000000000000000000000000*var_38 + 0.1666666666666666574148081*var_37; + A[5] = 0.0047619047619047623343125*var_23*var_46; + A[7] = A[5]; + } + + 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/mass_matrix_2d/mass_matrix_f3_p1_q1_quadrature.h b/mass_matrix_2d/mass_matrix_f3_p1_q1_quadrature.h new file mode 100644 index 0000000..3d411f0 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f3_p1_q1_quadrature.h @@ -0,0 +1,1464 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F3_P1_Q1_QUADRATURE_H +#define __MASS_MATRIX_F3_P1_Q1_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p1_q1_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p1_q1_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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 mass_matrix_f3_p1_q1_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p1_q1_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p1_q1_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_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 mass_matrix_f3_p1_q1_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class mass_matrix_f3_p1_q1_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f3_p1_q1_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // 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[7][3] = \ + {{0.333333333333333, 0.333333333333333, 0.333333333333333}, + {0.101286507323456, 0.797426985353087, 0.101286507323456}, + {0.101286507323456, 0.101286507323456, 0.797426985353087}, + {0.797426985353087, 0.101286507323456, 0.101286507323456}, + {0.470142064105115, 0.0597158717897698, 0.470142064105115}, + {0.470142064105115, 0.470142064105115, 0.0597158717897697}, + {0.0597158717897699, 0.470142064105115, 0.470142064105115}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 9; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 343 + for (unsigned int ip = 0; ip < 7; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + + // Total number of operations to compute function values = 18 + for (unsigned int r = 0; r < 3; r++) + { + F0 += FE0[ip][r]*w[2][r]; + F1 += FE0[ip][r]*w[0][r]; + F2 += FE0[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 4 + double I[1]; + // Number of operations: 4 + I[0] = F0*F1*F2*W7[ip]*det; + + + // Number of operations for primary indices: 27 + for (unsigned int j = 0; j < 3; j++) + { + for (unsigned int k = 0; k < 3; k++) + { + // Number of operations to compute entry: 3 + A[j*3 + k] += FE0[ip][j]*FE0[ip][k]*I[0]; + }// 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 mass_matrix_f3_p1_q1_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f3_p1_q1_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p1_q1_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1)))), 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 3; + } + + /// 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 mass_matrix_f3_p1_q1_quadrature_finite_element_0(); + break; + } + case 1: + { + return new mass_matrix_f3_p1_q1_quadrature_finite_element_0(); + break; + } + case 2: + { + return new mass_matrix_f3_p1_q1_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p1_q1_quadrature_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p1_q1_quadrature_finite_element_0(); + 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 mass_matrix_f3_p1_q1_quadrature_dofmap_0(); + break; + } + case 1: + { + return new mass_matrix_f3_p1_q1_quadrature_dofmap_0(); + break; + } + case 2: + { + return new mass_matrix_f3_p1_q1_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p1_q1_quadrature_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p1_q1_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f3_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/mass_matrix_2d/mass_matrix_f3_p1_q1_tensor.h b/mass_matrix_2d/mass_matrix_f3_p1_q1_tensor.h new file mode 100644 index 0000000..a44c67f --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f3_p1_q1_tensor.h @@ -0,0 +1,1446 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F3_P1_Q1_TENSOR_H +#define __MASS_MATRIX_F3_P1_Q1_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p1_q1_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p1_q1_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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 mass_matrix_f3_p1_q1_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p1_q1_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p1_q1_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_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 mass_matrix_f3_p1_q1_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class mass_matrix_f3_p1_q1_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f3_p1_q1_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 54 + // Number of operations (multiply-add pairs) for tensor contraction: 127 + // Total number of operations (multiply-add pairs): 190 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0 = det*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_0_0_1 = det*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_0_0_2 = det*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_0_1_0 = det*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_0_1_1 = det*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_0_1_2 = det*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_0_2_0 = det*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_0_2_1 = det*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_0_2_2 = det*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_1_0_0 = det*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_1_0_1 = det*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_1_0_2 = det*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_1_1_0 = det*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_1_1_1 = det*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_1_1_2 = det*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_1_2_0 = det*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_1_2_1 = det*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_1_2_2 = det*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_2_0_0 = det*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_2_0_1 = det*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_2_0_2 = det*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_2_1_0 = det*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_2_1_1 = det*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_2_1_2 = det*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_2_2_0 = det*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_2_2_1 = det*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_2_2_2 = det*w[2][2]*w[0][2]*w[1][2]*(1.0); + + // Compute element tensor + A[1] = 0.00476190476190476*G0_0_0_0 + 0.00238095238095238*G0_0_0_1 + 0.00119047619047619*G0_0_0_2 + 0.00238095238095238*G0_0_1_0 + 0.00238095238095238*G0_0_1_1 + 0.000793650793650794*G0_0_1_2 + 0.00119047619047619*G0_0_2_0 + 0.000793650793650794*G0_0_2_1 + 0.000793650793650794*G0_0_2_2 + 0.00238095238095238*G0_1_0_0 + 0.00238095238095238*G0_1_0_1 + 0.000793650793650794*G0_1_0_2 + 0.00238095238095238*G0_1_1_0 + 0.00476190476190476*G0_1_1_1 + 0.00119047619047619*G0_1_1_2 + 0.000793650793650794*G0_1_2_0 + 0.00119047619047619*G0_1_2_1 + 0.000793650793650794*G0_1_2_2 + 0.00119047619047619*G0_2_0_0 + 0.000793650793650794*G0_2_0_1 + 0.000793650793650794*G0_2_0_2 + 0.000793650793650794*G0_2_1_0 + 0.00119047619047619*G0_2_1_1 + 0.000793650793650794*G0_2_1_2 + 0.000793650793650794*G0_2_2_0 + 0.000793650793650794*G0_2_2_1 + 0.00119047619047619*G0_2_2_2; + A[5] = A[1] - 0.00357142857142857*G0_0_0_0 - 0.00158730158730159*G0_0_0_1 - 0.000396825396825397*G0_0_0_2 - 0.00158730158730159*G0_0_1_0 - 0.00119047619047619*G0_0_1_1 - 0.000396825396825397*G0_0_2_0 + 0.000396825396825397*G0_0_2_2 - 0.00158730158730159*G0_1_0_0 - 0.00119047619047619*G0_1_0_1 - 0.00119047619047619*G0_1_1_0 + 0.00119047619047619*G0_1_1_2 + 0.00119047619047619*G0_1_2_1 + 0.00158730158730159*G0_1_2_2 - 0.000396825396825397*G0_2_0_0 + 0.000396825396825397*G0_2_0_2 + 0.00119047619047619*G0_2_1_1 + 0.00158730158730159*G0_2_1_2 + 0.000396825396825397*G0_2_2_0 + 0.00158730158730159*G0_2_2_1 + 0.00357142857142857*G0_2_2_2; + A[0] = A[1] + 0.019047619047619*G0_0_0_0 + 0.00238095238095238*G0_0_0_1 + 0.00357142857142857*G0_0_0_2 + 0.00238095238095238*G0_0_1_0 + 0.000396825396825397*G0_0_1_2 + 0.00357142857142857*G0_0_2_0 + 0.000396825396825397*G0_0_2_1 + 0.00158730158730159*G0_0_2_2 + 0.00238095238095238*G0_1_0_0 + 0.000396825396825397*G0_1_0_2 - 0.00238095238095238*G0_1_1_1 - 0.000396825396825397*G0_1_1_2 + 0.000396825396825397*G0_1_2_0 - 0.000396825396825397*G0_1_2_1 + 0.00357142857142857*G0_2_0_0 + 0.000396825396825397*G0_2_0_1 + 0.00158730158730159*G0_2_0_2 + 0.000396825396825397*G0_2_1_0 - 0.000396825396825397*G0_2_1_1 + 0.00158730158730159*G0_2_2_0 + 0.00119047619047619*G0_2_2_2; + A[7] = A[5]; + A[6] = A[1] - 0.00119047619047619*G0_0_0_1 + 0.00119047619047619*G0_0_0_2 - 0.00119047619047619*G0_0_1_0 - 0.00158730158730159*G0_0_1_1 + 0.00119047619047619*G0_0_2_0 + 0.00158730158730159*G0_0_2_2 - 0.00119047619047619*G0_1_0_0 - 0.00158730158730159*G0_1_0_1 - 0.00158730158730159*G0_1_1_0 - 0.00357142857142857*G0_1_1_1 - 0.000396825396825397*G0_1_1_2 - 0.000396825396825397*G0_1_2_1 + 0.000396825396825397*G0_1_2_2 + 0.00119047619047619*G0_2_0_0 + 0.00158730158730159*G0_2_0_2 - 0.000396825396825397*G0_2_1_1 + 0.000396825396825397*G0_2_1_2 + 0.00158730158730159*G0_2_2_0 + 0.000396825396825397*G0_2_2_1 + 0.00357142857142857*G0_2_2_2; + A[2] = A[6]; + A[8] = A[0] - 0.0214285714285714*G0_0_0_0 - 0.00396825396825397*G0_0_0_1 - 0.00238095238095238*G0_0_0_2 - 0.00396825396825397*G0_0_1_0 - 0.00158730158730159*G0_0_1_1 - 0.00238095238095238*G0_0_2_0 + 0.00238095238095238*G0_0_2_2 - 0.00396825396825397*G0_1_0_0 - 0.00158730158730159*G0_1_0_1 - 0.00158730158730159*G0_1_1_0 + 0.00158730158730159*G0_1_1_2 + 0.00158730158730159*G0_1_2_1 + 0.00396825396825397*G0_1_2_2 - 0.00238095238095238*G0_2_0_0 + 0.00238095238095238*G0_2_0_2 + 0.00158730158730159*G0_2_1_1 + 0.00396825396825397*G0_2_1_2 + 0.00238095238095238*G0_2_2_0 + 0.00396825396825397*G0_2_2_1 + 0.0214285714285714*G0_2_2_2; + A[3] = A[1]; + A[4] = A[0] - 0.0214285714285714*G0_0_0_0 - 0.00238095238095238*G0_0_0_1 - 0.00396825396825397*G0_0_0_2 - 0.00238095238095238*G0_0_1_0 + 0.00238095238095238*G0_0_1_1 - 0.00396825396825397*G0_0_2_0 - 0.00158730158730159*G0_0_2_2 - 0.00238095238095238*G0_1_0_0 + 0.00238095238095238*G0_1_0_1 + 0.00238095238095238*G0_1_1_0 + 0.0214285714285714*G0_1_1_1 + 0.00396825396825397*G0_1_1_2 + 0.00396825396825397*G0_1_2_1 + 0.00158730158730159*G0_1_2_2 - 0.00396825396825397*G0_2_0_0 - 0.00158730158730159*G0_2_0_2 + 0.00396825396825397*G0_2_1_1 + 0.00158730158730159*G0_2_1_2 - 0.00158730158730159*G0_2_2_0 + 0.00158730158730159*G0_2_2_1; + } + + /// 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 mass_matrix_f3_p1_q1_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f3_p1_q1_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p1_q1_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1)))), 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 3; + } + + /// 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 mass_matrix_f3_p1_q1_tensor_finite_element_0(); + break; + } + case 1: + { + return new mass_matrix_f3_p1_q1_tensor_finite_element_0(); + break; + } + case 2: + { + return new mass_matrix_f3_p1_q1_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p1_q1_tensor_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p1_q1_tensor_finite_element_0(); + 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 mass_matrix_f3_p1_q1_tensor_dofmap_0(); + break; + } + case 1: + { + return new mass_matrix_f3_p1_q1_tensor_dofmap_0(); + break; + } + case 2: + { + return new mass_matrix_f3_p1_q1_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p1_q1_tensor_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p1_q1_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f3_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/mass_matrix_2d/mass_matrix_f3_p1_q2_excafe.h b/mass_matrix_2d/mass_matrix_f3_p1_q2_excafe.h new file mode 100644 index 0000000..420f982 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f3_p1_q2_excafe.h @@ -0,0 +1,157 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 3.30 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 = -1.0000000000000000000000000*x[0][0]; + const double var_1 = x[1][0] + var_0; + const double var_2 = -1.0000000000000000000000000*x[0][1]; + const double var_3 = var_2 + x[2][1]; + const double var_4 = x[2][0] + var_0; + const double var_5 = var_2 + x[1][1]; + const double var_6 = var_1*var_3 + -1.0000000000000000000000000*var_4*var_5; + const double var_7 = std::abs(var_6); + const double var_8 = w[0][0]*w[1][2] + w[0][2]*w[1][0]; + const double var_9 = w[0][2]*w[1][2]*w[2][0] + var_8*w[2][2]; + const double var_10 = w[0][1]*w[1][0] + w[0][0]*w[1][1]; + const double var_11 = var_10*w[2][1] + w[0][1]*w[1][1]*w[2][0]; + const double var_12 = var_9 + var_11; + const double var_13 = w[0][0]*w[1][0]*w[2][0]; + const double var_14 = w[0][1]*w[1][2] + w[0][2]*w[1][1]; + const double var_15 = var_8*w[2][1] + var_14*w[2][0] + var_10*w[2][2]; + const double var_16 = w[0][1]*w[1][1]*w[2][2] + var_14*w[2][1]; + const double var_17 = var_14*w[2][2] + w[0][2]*w[1][2]*w[2][1]; + const double var_18 = var_17 + var_16; + const double var_19 = var_18 + var_15; + const double var_20 = var_8*w[2][0] + w[0][0]*w[1][0]*w[2][2]; + const double var_21 = w[0][0]*w[1][0]*w[2][1] + var_10*w[2][0]; + const double var_22 = var_20 + var_21; + const double var_23 = w[0][2]*w[1][2]*w[2][2]; + const double var_24 = w[0][1]*w[1][1]*w[2][1]; + const double var_25 = var_23 + var_24; + const double var_26 = var_22 + var_25; + const double var_27 = 0.4000000000000000222044605*var_26 + var_13 + 0.2000000000000000111022302*var_19; + A[29] = 0.0052910052910052907115812*var_27*var_7 + 0.0015873015873015873002105*var_12*var_7; + A[34] = A[29]; + const double var_28 = 0.3333333333333333148296163*var_16 + 0.1666666666666666574148081*var_11; + const double var_29 = 0.3333333333333333148296163*var_20 + 0.1666666666666666574148081*var_21; + const double var_30 = -0.2500000000000000000000000*var_13; + const double var_31 = var_17 + var_9; + const double var_32 = var_23 + 0.2500000000000000000000000*var_31; + const double var_33 = -1.0000000000000000000000000*var_32; + const double var_34 = var_30 + var_33 + var_28 + -0.5000000000000000000000000*var_29; + const double var_35 = -0.0001322751322751322840526*var_15*var_7; + const double var_36 = 0.0039682539682539680336859*var_24*var_7 + var_35; + A[9] = 0.0015873015873015873002105*var_34*var_7 + var_36; + const double var_37 = var_16 + var_11; + const double var_38 = 0.2500000000000000000000000*var_37 + var_24; + const double var_39 = -1.0000000000000000000000000*var_38; + const double var_40 = 0.3333333333333333148296163*var_17 + 0.1666666666666666574148081*var_9; + const double var_41 = 0.1666666666666666574148081*var_20 + 0.3333333333333333148296163*var_21; + const double var_42 = var_39 + var_30 + var_40 + -0.5000000000000000000000000*var_41; + const double var_43 = 0.0039682539682539680336859*var_23*var_7 + var_35; + A[15] = 0.0015873015873015873002105*var_42*var_7 + var_43; + A[20] = A[15]; + const double var_44 = var_20 + var_9; + const double var_45 = var_44 + var_15; + const double var_46 = 0.2500000000000000000000000*var_22 + var_13; + const double var_47 = var_18 + 0.3333333333333333148296163*var_12; + const double var_48 = -0.0357142857142857123031732*var_47 + -0.1666666666666666574148081*var_25 + 0.0476190476190476164042309*var_46; + A[8] = 0.0055555555555555557675773*var_48*var_7; + const double var_49 = var_13 + var_24; + const double var_50 = var_20 + var_16; + const double var_51 = var_11 + var_21; + const double var_52 = var_51 + 0.3333333333333333148296163*var_50; + const double var_53 = -0.0357142857142857123031732*var_52 + -0.1666666666666666574148081*var_49 + 0.0476190476190476164042309*var_32; + A[1] = 0.0055555555555555557675773*var_53*var_7; + A[6] = A[1]; + const double var_54 = var_17 + var_21; + const double var_55 = var_44 + 0.3333333333333333148296163*var_54; + const double var_56 = var_51 + var_15; + const double var_57 = 0.1000000000000000055511151*var_31; + const double var_58 = 0.0333333333333333328707404*var_50 + 0.0166666666666666664353702*var_56 + var_57 + 0.0500000000000000027755576*var_49 + var_23; + A[13] = A[8]; + const double var_59 = -0.2500000000000000000000000*var_23; + const double var_60 = 0.1666666666666666574148081*var_17 + 0.3333333333333333148296163*var_9; + const double var_61 = 0.1666666666666666574148081*var_16 + 0.3333333333333333148296163*var_11; + const double var_62 = -1.0000000000000000000000000*var_46; + const double var_63 = -0.5000000000000000000000000*var_60 + var_61 + var_62 + var_59; + A[11] = 0.0015873015873015873002105*var_63*var_7 + var_36; + A[31] = A[11]; + const double var_64 = var_23 + var_31; + const double var_65 = -0.0002645502645502645681051*var_15*var_7; + const double var_66 = 0.1000000000000000055511151*var_22; + const double var_67 = -1.0000000000000000000000000*var_66 + 0.2000000000000000111022302*var_13 + -0.5000000000000000000000000*var_18 + -1.0000000000000000000000000*var_25; + A[3] = 0.0013227513227513226778953*var_67*var_7 + var_65 + -0.0003968253968253968250526*var_12*var_7; + A[18] = A[3]; + const double var_68 = var_23 + var_13; + const double var_69 = 0.1000000000000000055511151*var_37; + const double var_70 = 0.0333333333333333328707404*var_54 + var_24 + var_69 + 0.0500000000000000027755576*var_68 + 0.0166666666666666664353702*var_45; + A[7] = 0.0079365079365079360673718*var_7*var_70; + const double var_71 = -1.0000000000000000000000000*var_69 + -0.5000000000000000000000000*var_44 + 0.2000000000000000111022302*var_24 + -1.0000000000000000000000000*var_68; + A[10] = var_65 + -0.0003968253968253968250526*var_54*var_7 + 0.0013227513227513226778953*var_7*var_71; + const double var_72 = -0.2500000000000000000000000*var_24; + const double var_73 = var_72 + var_33 + -0.5000000000000000000000000*var_28 + var_29; + const double var_74 = 0.0039682539682539680336859*var_13*var_7 + var_35; + A[4] = 0.0015873015873015873002105*var_7*var_73 + var_74; + const double var_75 = var_60 + var_72 + -0.5000000000000000000000000*var_61 + var_62; + A[16] = 0.0015873015873015873002105*var_7*var_75 + var_43; + A[26] = A[16]; + const double var_76 = var_49 + var_31; + const double var_77 = var_23 + 0.4000000000000000222044605*var_76 + 0.2000000000000000111022302*var_56; + const double var_78 = var_37 + var_68; + const double var_79 = 0.2000000000000000111022302*var_45 + var_24 + 0.4000000000000000222044605*var_78; + A[23] = 0.0015873015873015873002105*var_54*var_7 + 0.0052910052910052907115812*var_7*var_79; + const double var_80 = var_13 + 0.0333333333333333328707404*var_12 + 0.0500000000000000027755576*var_25 + var_66 + 0.0166666666666666664353702*var_19; + A[0] = 0.0079365079365079360673718*var_7*var_80; + const double var_81 = var_22 + var_13; + const double var_82 = 0.0666666666666666657414808*var_81 + 0.4000000000000000222044605*var_47 + 0.6666666666666666296592325*var_25; + const double var_83 = var_37 + var_24; + A[24] = A[4]; + A[22] = 0.0052910052910052907115812*var_7*var_77 + 0.0015873015873015873002105*var_50*var_7; + A[25] = A[10]; + const double var_84 = 0.0015873015873015873002105*var_15*var_7; + A[21] = 0.0158730158730158721347436*var_7*var_82 + var_84; + const double var_85 = 0.4000000000000000222044605*var_52 + 0.6666666666666666296592325*var_49 + 0.0666666666666666657414808*var_64; + A[35] = var_84 + 0.0158730158730158721347436*var_7*var_85; + const double var_86 = 0.0666666666666666657414808*var_83 + 0.6666666666666666296592325*var_68 + 0.4000000000000000222044605*var_55; + const double var_87 = var_39 + -0.5000000000000000000000000*var_40 + var_41 + var_59; + A[5] = 0.0015873015873015873002105*var_7*var_87 + var_74; + const double var_88 = 0.0476190476190476164042309*var_38 + -0.1666666666666666574148081*var_68 + -0.0357142857142857123031732*var_55; + A[2] = 0.0055555555555555557675773*var_7*var_88; + A[19] = A[9]; + const double var_89 = -0.5000000000000000000000000*var_51 + 0.2000000000000000111022302*var_23 + -1.0000000000000000000000000*var_57 + -1.0000000000000000000000000*var_49; + A[17] = var_65 + 0.0013227513227513226778953*var_7*var_89 + -0.0003968253968253968250526*var_50*var_7; + A[32] = A[17]; + A[28] = 0.0158730158730158721347436*var_7*var_86 + var_84; + A[33] = A[23]; + A[12] = A[2]; + A[27] = A[22]; + A[30] = A[5]; + A[14] = 0.0079365079365079360673718*var_58*var_7; + } + + 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/mass_matrix_2d/mass_matrix_f3_p1_q2_quadrature.h b/mass_matrix_2d/mass_matrix_f3_p1_q2_quadrature.h new file mode 100644 index 0000000..492c232 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f3_p1_q2_quadrature.h @@ -0,0 +1,3399 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F3_P1_Q2_QUADRATURE_H +#define __MASS_MATRIX_F3_P1_Q2_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p1_q2_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p1_q2_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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 mass_matrix_f3_p1_q2_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p1_q2_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p1_q2_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p1_q2_quadrature_finite_element_1() + { + // 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f3_p1_q2_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p1_q2_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p1_q2_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_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 mass_matrix_f3_p1_q2_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p1_q2_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p1_q2_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_p1_q2_quadrature_dofmap_1() + { + // 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 mass_matrix_f3_p1_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 mass_matrix_f3_p1_q2_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f3_p1_q2_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Array of quadrature weights. + static const double W16[16] = {0.0235683681933823, 0.0353880678980859, 0.0225840492823699, 0.00542322591052525, 0.0441850885223617, 0.0663442161070497, 0.0423397245217463, 0.0101672595644788, 0.0441850885223617, 0.0663442161070497, 0.0423397245217463, 0.0101672595644788, 0.0235683681933823, 0.0353880678980859, 0.0225840492823699, 0.00542322591052525}; + // Quadrature points on the UFC reference element: (0.0654669945550145, 0.0571041961145177), (0.0502101232113698, 0.276843013638124), (0.028912084224389, 0.583590432368917), (0.00970378512694614, 0.860240135656219), (0.311164552244357, 0.0571041961145177), (0.238648659731443, 0.276843013638124), (0.137419104134574, 0.583590432368917), (0.0461220799064521, 0.860240135656219), (0.631731251641125, 0.0571041961145177), (0.484508326630433, 0.276843013638124), (0.278990463496509, 0.583590432368917), (0.0936377844373285, 0.860240135656219), (0.877428809330468, 0.0571041961145177), (0.672946863150506, 0.276843013638124), (0.387497483406694, 0.583590432368917), (0.130056079216834, 0.860240135656219) + + // Value of basis functions at quadrature points. + static const double FE0[16][3] = \ + {{0.877428809330468, 0.0654669945550145, 0.0571041961145176}, + {0.672946863150506, 0.0502101232113698, 0.276843013638124}, + {0.387497483406694, 0.028912084224389, 0.583590432368917}, + {0.130056079216834, 0.0097037851269462, 0.860240135656219}, + {0.631731251641125, 0.311164552244357, 0.0571041961145176}, + {0.484508326630433, 0.238648659731443, 0.276843013638124}, + {0.278990463496509, 0.137419104134574, 0.583590432368917}, + {0.0936377844373285, 0.0461220799064521, 0.860240135656219}, + {0.311164552244357, 0.631731251641125, 0.0571041961145176}, + {0.238648659731443, 0.484508326630433, 0.276843013638124}, + {0.137419104134574, 0.278990463496509, 0.583590432368917}, + {0.046122079906452, 0.0936377844373286, 0.860240135656219}, + {0.0654669945550144, 0.877428809330468, 0.0571041961145176}, + {0.0502101232113698, 0.672946863150506, 0.276843013638124}, + {0.0289120842243889, 0.387497483406694, 0.583590432368917}, + {0.00970378512694603, 0.130056079216835, 0.860240135656219}}; + + static const double FE1[16][6] = \ + {{0.662333821555697, -0.0568951398028819, -0.0505824176867471, 0.0149537603843904, 0.200419467218139, 0.229770508331402}, + {0.232768098097706, -0.0451680102655679, -0.123558905237647, 0.0556012872999085, 0.745202550451633, 0.135154979653967}, + {-0.0871888841136517, -0.0272402669959927, 0.0975651531361617, 0.067491262932791, 0.904559295532719, 0.0448134395079725}, + {-0.0962269117343234, -0.00951545823536622, 0.619786046331442, 0.0333903417359319, 0.447517836913623, 0.00504814498869303}, + {0.166437496959, -0.117517795097495, -0.0505824176867471, 0.0710752064609914, 0.144298021141538, 0.786289488222712}, + {-0.015011689481988, -0.124742294148215, -0.123558905237647, 0.264272856643007, 0.536530981108534, 0.462509051116308}, + {-0.123319106052515, -0.0996510837722764, 0.0975651531361617, 0.320785897590582, 0.651264660874928, 0.15335447822312}, + {-0.0761017150886653, -0.0418675873966577, 0.619786046331442, 0.158704257101893, 0.322203921547661, 0.0172750775043264}, + {-0.117517795097495, 0.166437496959, -0.0505824176867471, 0.144298021141538, 0.0710752064609913, 0.786289488222712}, + {-0.124742294148215, -0.0150116894819881, -0.123558905237647, 0.536530981108534, 0.264272856643007, 0.462509051116308}, + {-0.0996510837722764, -0.123319106052515, 0.0975651531361617, 0.651264660874928, 0.320785897590582, 0.15335447822312}, + {-0.0418675873966577, -0.0761017150886653, 0.619786046331442, 0.322203921547661, 0.158704257101893, 0.0172750775043264}, + {-0.0568951398028819, 0.662333821555697, -0.0505824176867471, 0.200419467218139, 0.0149537603843903, 0.229770508331402}, + {-0.0451680102655679, 0.232768098097706, -0.123558905237647, 0.745202550451633, 0.0556012872999085, 0.135154979653967}, + {-0.0272402669959926, -0.0871888841136517, 0.0975651531361618, 0.904559295532719, 0.0674912629327909, 0.0448134395079725}, + {-0.00951545823536613, -0.0962269117343234, 0.619786046331442, 0.447517836913623, 0.0333903417359314, 0.00504814498869298}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 36; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 2080 + for (unsigned int ip = 0; ip < 16; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + + // Total number of operations to compute function values = 18 + for (unsigned int r = 0; r < 3; r++) + { + F0 += FE0[ip][r]*w[2][r]; + F1 += FE0[ip][r]*w[0][r]; + F2 += FE0[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 4 + double I[1]; + // Number of operations: 4 + I[0] = F0*F1*F2*W16[ip]*det; + + + // Number of operations for primary indices: 108 + for (unsigned int j = 0; j < 6; j++) + { + for (unsigned int k = 0; k < 6; k++) + { + // Number of operations to compute entry: 3 + A[j*6 + k] += FE1[ip][j]*FE1[ip][k]*I[0]; + }// 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 mass_matrix_f3_p1_q2_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f3_p1_q2_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p1_q2_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1)))), 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 3; + } + + /// 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 mass_matrix_f3_p1_q2_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f3_p1_q2_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f3_p1_q2_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p1_q2_quadrature_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p1_q2_quadrature_finite_element_0(); + 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 mass_matrix_f3_p1_q2_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f3_p1_q2_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f3_p1_q2_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p1_q2_quadrature_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p1_q2_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f3_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/mass_matrix_2d/mass_matrix_f3_p1_q2_tensor.h b/mass_matrix_2d/mass_matrix_f3_p1_q2_tensor.h new file mode 100644 index 0000000..dfad5f6 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f3_p1_q2_tensor.h @@ -0,0 +1,3381 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F3_P1_Q2_TENSOR_H +#define __MASS_MATRIX_F3_P1_Q2_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p1_q2_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p1_q2_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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 mass_matrix_f3_p1_q2_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p1_q2_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p1_q2_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p1_q2_tensor_finite_element_1() + { + // 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f3_p1_q2_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p1_q2_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p1_q2_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_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 mass_matrix_f3_p1_q2_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p1_q2_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p1_q2_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_p1_q2_tensor_dofmap_1() + { + // 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 mass_matrix_f3_p1_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 mass_matrix_f3_p1_q2_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f3_p1_q2_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 54 + // Number of operations (multiply-add pairs) for tensor contraction: 389 + // Total number of operations (multiply-add pairs): 452 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0 = det*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_0_0_1 = det*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_0_0_2 = det*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_0_1_0 = det*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_0_1_1 = det*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_0_1_2 = det*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_0_2_0 = det*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_0_2_1 = det*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_0_2_2 = det*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_1_0_0 = det*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_1_0_1 = det*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_1_0_2 = det*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_1_1_0 = det*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_1_1_1 = det*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_1_1_2 = det*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_1_2_0 = det*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_1_2_1 = det*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_1_2_2 = det*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_2_0_0 = det*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_2_0_1 = det*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_2_0_2 = det*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_2_1_0 = det*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_2_1_1 = det*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_2_1_2 = det*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_2_2_0 = det*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_2_2_1 = det*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_2_2_2 = det*w[2][2]*w[0][2]*w[1][2]*(1.0); + + // Compute element tensor + A[9] = -0.000396825396825396*G0_0_0_0 - 0.000132275132275132*G0_0_0_1 - 0.000264550264550264*G0_0_0_2 - 0.000132275132275132*G0_0_1_0 + 0.000264550264550264*G0_0_1_1 - 0.000132275132275132*G0_0_1_2 - 0.000264550264550264*G0_0_2_0 - 0.000132275132275132*G0_0_2_1 - 0.000396825396825396*G0_0_2_2 - 0.000132275132275132*G0_1_0_0 + 0.000264550264550264*G0_1_0_1 - 0.000132275132275132*G0_1_0_2 + 0.000264550264550264*G0_1_1_0 + 0.00396825396825396*G0_1_1_1 + 0.000529100529100528*G0_1_1_2 - 0.000132275132275132*G0_1_2_0 + 0.000529100529100528*G0_1_2_1 - 0.000396825396825396*G0_1_2_2 - 0.000264550264550264*G0_2_0_0 - 0.000132275132275132*G0_2_0_1 - 0.000396825396825396*G0_2_0_2 - 0.000132275132275132*G0_2_1_0 + 0.000529100529100528*G0_2_1_1 - 0.000396825396825396*G0_2_1_2 - 0.000396825396825396*G0_2_2_0 - 0.000396825396825396*G0_2_2_1 - 0.00158730158730158*G0_2_2_2; + A[18] = A[9] + 0.000661375661375661*G0_0_0_0 + 0.000132275132275132*G0_0_0_2 - 0.000661375661375661*G0_0_1_1 - 0.000132275132275132*G0_0_1_2 + 0.000132275132275132*G0_0_2_0 - 0.000132275132275132*G0_0_2_1 - 0.000661375661375661*G0_1_0_1 - 0.000132275132275132*G0_1_0_2 - 0.000661375661375661*G0_1_1_0 - 0.00529100529100528*G0_1_1_1 - 0.00119047619047619*G0_1_1_2 - 0.000132275132275132*G0_1_2_0 - 0.00119047619047619*G0_1_2_1 - 0.000264550264550264*G0_1_2_2 + 0.000132275132275132*G0_2_0_0 - 0.000132275132275132*G0_2_0_1 - 0.000132275132275132*G0_2_1_0 - 0.00119047619047619*G0_2_1_1 - 0.000264550264550264*G0_2_1_2 - 0.000264550264550264*G0_2_2_1 + 0.000264550264550264*G0_2_2_2; + A[13] = 0.000264550264550264*G0_0_0_0 + 6.61375661375661e-05*G0_0_0_1 + 6.61375661375661e-05*G0_0_0_2 + 6.61375661375661e-05*G0_0_1_0 - 6.6137566137566e-05*G0_0_1_1 + 6.61375661375661e-05*G0_0_2_0 - 6.6137566137566e-05*G0_0_2_2 + 6.61375661375661e-05*G0_1_0_0 - 6.6137566137566e-05*G0_1_0_1 - 6.6137566137566e-05*G0_1_1_0 - 0.000925925925925925*G0_1_1_1 - 0.000198412698412698*G0_1_1_2 - 0.000198412698412698*G0_1_2_1 - 0.000198412698412698*G0_1_2_2 + 6.61375661375661e-05*G0_2_0_0 - 6.6137566137566e-05*G0_2_0_2 - 0.000198412698412698*G0_2_1_1 - 0.000198412698412698*G0_2_1_2 - 6.6137566137566e-05*G0_2_2_0 - 0.000198412698412698*G0_2_2_1 - 0.000925925925925925*G0_2_2_2; + A[31] = A[9] - 0.00119047619047619*G0_0_0_0 - 0.000264550264550264*G0_0_0_1 - 0.000132275132275132*G0_0_0_2 - 0.000264550264550264*G0_0_1_0 + 0.000264550264550265*G0_0_1_1 - 0.000132275132275132*G0_0_2_0 + 0.000132275132275132*G0_0_2_2 - 0.000264550264550264*G0_1_0_0 + 0.000264550264550265*G0_1_0_1 + 0.000264550264550265*G0_1_1_0 - 0.000264550264550263*G0_1_1_2 - 0.000264550264550263*G0_1_2_1 + 0.000264550264550264*G0_1_2_2 - 0.000132275132275132*G0_2_0_0 + 0.000132275132275132*G0_2_0_2 - 0.000264550264550263*G0_2_1_1 + 0.000264550264550264*G0_2_1_2 + 0.000132275132275132*G0_2_2_0 + 0.000264550264550264*G0_2_2_1 + 0.00119047619047619*G0_2_2_2; + A[3] = A[18]; + A[17] = A[18] - 0.00158730158730159*G0_0_0_0 - 0.000529100529100529*G0_0_0_1 - 0.000264550264550265*G0_0_0_2 - 0.000529100529100529*G0_0_1_0 - 0.000264550264550265*G0_0_1_1 - 0.000264550264550264*G0_0_2_0 + 0.000264550264550264*G0_0_2_2 - 0.000529100529100529*G0_1_0_0 - 0.000264550264550265*G0_1_0_1 - 0.000264550264550264*G0_1_1_0 + 0.000264550264550264*G0_1_1_2 + 0.000264550264550264*G0_1_2_1 + 0.000529100529100528*G0_1_2_2 - 0.000264550264550264*G0_2_0_0 + 0.000264550264550264*G0_2_0_2 + 0.000264550264550264*G0_2_1_1 + 0.000529100529100529*G0_2_1_2 + 0.000264550264550264*G0_2_2_0 + 0.000529100529100529*G0_2_2_1 + 0.00158730158730159*G0_2_2_2; + A[24] = A[9] + 0.00436507936507936*G0_0_0_0 + 0.000396825396825396*G0_0_0_1 + 0.000793650793650793*G0_0_0_2 + 0.000396825396825396*G0_0_1_0 - 0.000396825396825396*G0_0_1_1 + 0.000793650793650793*G0_0_2_0 + 0.000396825396825396*G0_1_0_0 - 0.000396825396825396*G0_1_0_1 - 0.000396825396825396*G0_1_1_0 - 0.00436507936507936*G0_1_1_1 - 0.000793650793650792*G0_1_1_2 - 0.000793650793650792*G0_1_2_1 + 0.000793650793650793*G0_2_0_0 - 0.000793650793650792*G0_2_1_1; + A[8] = A[13]; + A[11] = A[31]; + A[30] = A[24] + 0.000264550264550265*G0_0_0_1 - 0.000264550264550265*G0_0_0_2 + 0.000264550264550265*G0_0_1_0 - 0.000264550264550264*G0_0_1_1 - 0.000264550264550265*G0_0_2_0 + 0.000264550264550264*G0_0_2_2 + 0.000264550264550265*G0_1_0_0 - 0.000264550264550264*G0_1_0_1 - 0.000264550264550264*G0_1_1_0 - 0.00119047619047619*G0_1_1_1 - 0.000132275132275132*G0_1_1_2 - 0.000132275132275132*G0_1_2_1 + 0.000132275132275132*G0_1_2_2 - 0.000264550264550265*G0_2_0_0 + 0.000264550264550264*G0_2_0_2 - 0.000132275132275132*G0_2_1_1 + 0.000132275132275132*G0_2_1_2 + 0.000264550264550264*G0_2_2_0 + 0.000132275132275132*G0_2_2_1 + 0.00119047619047619*G0_2_2_2; + A[20] = A[30] - 0.00436507936507936*G0_0_0_0 - 0.000793650793650794*G0_0_0_1 - 0.000396825396825396*G0_0_0_2 - 0.000793650793650794*G0_0_1_0 - 0.000396825396825396*G0_0_2_0 + 0.000396825396825396*G0_0_2_2 - 0.000793650793650794*G0_1_0_0 + 0.000793650793650793*G0_1_2_2 - 0.000396825396825396*G0_2_0_0 + 0.000396825396825396*G0_2_0_2 + 0.000793650793650793*G0_2_1_2 + 0.000396825396825396*G0_2_2_0 + 0.000793650793650793*G0_2_2_1 + 0.00436507936507936*G0_2_2_2; + A[4] = A[24]; + A[25] = A[18] - 0.00158730158730159*G0_0_0_0 - 0.000264550264550264*G0_0_0_1 - 0.000529100529100528*G0_0_0_2 - 0.000264550264550264*G0_0_1_0 + 0.000264550264550264*G0_0_1_1 - 0.000529100529100528*G0_0_2_0 - 0.000264550264550264*G0_0_2_2 - 0.000264550264550264*G0_1_0_0 + 0.000264550264550264*G0_1_0_1 + 0.000264550264550264*G0_1_1_0 + 0.00158730158730158*G0_1_1_1 + 0.000529100529100528*G0_1_1_2 + 0.000529100529100528*G0_1_2_1 + 0.000264550264550264*G0_1_2_2 - 0.000529100529100528*G0_2_0_0 - 0.000264550264550264*G0_2_0_2 + 0.000529100529100528*G0_2_1_1 + 0.000264550264550264*G0_2_1_2 - 0.000264550264550264*G0_2_2_0 + 0.000264550264550264*G0_2_2_1; + A[7] = -A[30] + 0.00436507936507936*G0_0_0_0 + 0.000793650793650793*G0_0_0_1 + 0.000396825396825396*G0_0_0_2 + 0.000793650793650793*G0_0_1_0 + 0.000396825396825396*G0_0_1_1 + 0.000396825396825396*G0_0_2_0 + 0.000793650793650793*G0_1_0_0 + 0.000396825396825396*G0_1_0_1 + 0.000396825396825396*G0_1_1_0 + 0.00634920634920634*G0_1_1_1 + 0.000396825396825395*G0_1_1_2 + 0.000396825396825395*G0_1_2_1 + 0.000396825396825396*G0_2_0_0 + 0.000396825396825395*G0_2_1_1; + A[34] = 0.00529100529100529*G0_0_0_0 + 0.00211640211640212*G0_0_0_1 + 0.00211640211640211*G0_0_0_2 + 0.00211640211640212*G0_0_1_0 + 0.00158730158730159*G0_0_1_1 + 0.00105820105820106*G0_0_1_2 + 0.00211640211640211*G0_0_2_0 + 0.00105820105820106*G0_0_2_1 + 0.00158730158730159*G0_0_2_2 + 0.00211640211640212*G0_1_0_0 + 0.00158730158730159*G0_1_0_1 + 0.00105820105820106*G0_1_0_2 + 0.00158730158730159*G0_1_1_0 + 0.00211640211640211*G0_1_1_1 + 0.00105820105820106*G0_1_1_2 + 0.00105820105820106*G0_1_2_0 + 0.00105820105820106*G0_1_2_1 + 0.00105820105820106*G0_1_2_2 + 0.00211640211640211*G0_2_0_0 + 0.00105820105820106*G0_2_0_1 + 0.00158730158730159*G0_2_0_2 + 0.00105820105820106*G0_2_1_0 + 0.00105820105820106*G0_2_1_1 + 0.00105820105820106*G0_2_1_2 + 0.00158730158730159*G0_2_2_0 + 0.00105820105820106*G0_2_2_1 + 0.00211640211640211*G0_2_2_2; + A[0] = -A[31] + 0.00634920634920634*G0_0_0_0 + 0.000396825396825397*G0_0_0_1 + 0.000396825396825396*G0_0_0_2 + 0.000396825396825397*G0_0_1_0 + 0.000793650793650793*G0_0_1_1 + 0.000396825396825396*G0_0_2_0 + 0.000396825396825397*G0_1_0_0 + 0.000793650793650793*G0_1_0_1 + 0.000793650793650793*G0_1_1_0 + 0.00436507936507936*G0_1_1_1 + 0.000396825396825396*G0_1_1_2 + 0.000396825396825396*G0_1_2_1 + 0.000396825396825396*G0_2_0_0 + 0.000396825396825396*G0_2_1_1; + A[29] = A[34]; + A[14] = -A[9] + 0.000396825396825396*G0_0_1_1 + 0.000396825396825396*G0_0_2_2 + 0.000396825396825396*G0_1_0_1 + 0.000396825396825396*G0_1_1_0 + 0.00436507936507936*G0_1_1_1 + 0.000793650793650792*G0_1_1_2 + 0.000793650793650792*G0_1_2_1 + 0.000396825396825397*G0_1_2_2 + 0.000396825396825396*G0_2_0_2 + 0.000793650793650792*G0_2_1_1 + 0.000396825396825397*G0_2_1_2 + 0.000396825396825397*G0_2_2_0 + 0.000396825396825397*G0_2_2_1 + 0.00634920634920635*G0_2_2_2; + A[10] = A[25]; + A[5] = A[30]; + A[26] = A[31] - 0.000793650793650793*G0_0_1_1 + 0.000793650793650792*G0_0_2_2 - 0.000793650793650793*G0_1_0_1 - 0.000793650793650793*G0_1_1_0 - 0.00436507936507936*G0_1_1_1 - 0.000396825396825396*G0_1_1_2 - 0.000396825396825396*G0_1_2_1 + 0.000396825396825396*G0_1_2_2 + 0.000793650793650792*G0_2_0_2 - 0.000396825396825396*G0_2_1_1 + 0.000396825396825396*G0_2_1_2 + 0.000793650793650792*G0_2_2_0 + 0.000396825396825396*G0_2_2_1 + 0.00436507936507936*G0_2_2_2; + A[6] = -A[13] - 0.000661375661375661*G0_0_0_0 - 0.000132275132275132*G0_0_0_1 - 0.000132275132275132*G0_0_1_0 - 0.000264550264550264*G0_0_1_1 - 0.000132275132275132*G0_1_0_0 - 0.000264550264550264*G0_1_0_1 - 0.000264550264550264*G0_1_1_0 - 0.00185185185185185*G0_1_1_1 - 0.000264550264550264*G0_1_1_2 - 0.000264550264550264*G0_1_2_1 - 0.000132275132275132*G0_1_2_2 - 0.000264550264550264*G0_2_1_1 - 0.000132275132275132*G0_2_1_2 - 0.000132275132275132*G0_2_2_1 - 0.000661375661375661*G0_2_2_2; + A[1] = A[6]; + A[23] = A[34] - 0.00317460317460317*G0_0_0_0 - 0.000529100529100529*G0_0_0_1 - 0.00105820105820106*G0_0_0_2 - 0.000529100529100529*G0_0_1_0 + 0.000529100529100529*G0_0_1_1 - 0.00105820105820106*G0_0_2_0 - 0.000529100529100528*G0_0_2_2 - 0.000529100529100529*G0_1_0_0 + 0.000529100529100529*G0_1_0_1 + 0.000529100529100529*G0_1_1_0 + 0.00317460317460317*G0_1_1_1 + 0.00105820105820106*G0_1_1_2 + 0.00105820105820106*G0_1_2_1 + 0.000529100529100529*G0_1_2_2 - 0.00105820105820106*G0_2_0_0 - 0.000529100529100528*G0_2_0_2 + 0.00105820105820106*G0_2_1_1 + 0.000529100529100529*G0_2_1_2 - 0.000529100529100529*G0_2_2_0 + 0.000529100529100528*G0_2_2_1; + A[21] = A[23] - 0.00105820105820106*G0_0_0_0 - 0.000529100529100529*G0_0_0_1 - 0.000529100529100529*G0_0_1_0 + 0.000529100529100528*G0_0_1_2 + 0.000529100529100528*G0_0_2_1 + 0.00105820105820106*G0_0_2_2 - 0.000529100529100529*G0_1_0_0 + 0.000529100529100528*G0_1_0_2 + 0.00529100529100528*G0_1_1_1 + 0.00423280423280422*G0_1_1_2 + 0.000529100529100528*G0_1_2_0 + 0.00423280423280422*G0_1_2_1 + 0.00476190476190475*G0_1_2_2 + 0.000529100529100528*G0_2_0_1 + 0.00105820105820106*G0_2_0_2 + 0.000529100529100528*G0_2_1_0 + 0.00423280423280422*G0_2_1_1 + 0.00476190476190475*G0_2_1_2 + 0.00105820105820106*G0_2_2_0 + 0.00476190476190475*G0_2_2_1 + 0.00846560846560845*G0_2_2_2; + A[28] = A[21] + 0.00952380952380952*G0_0_0_0 + 0.00105820105820106*G0_0_0_1 + 0.00529100529100528*G0_0_0_2 + 0.00105820105820106*G0_0_1_0 - 0.00105820105820106*G0_0_1_1 + 0.00529100529100528*G0_0_2_0 + 0.00423280423280423*G0_0_2_2 + 0.00105820105820106*G0_1_0_0 - 0.00105820105820106*G0_1_0_1 - 0.00105820105820106*G0_1_1_0 - 0.00952380952380951*G0_1_1_1 - 0.00529100529100528*G0_1_1_2 - 0.00529100529100528*G0_1_2_1 - 0.00423280423280423*G0_1_2_2 + 0.00529100529100528*G0_2_0_0 + 0.00423280423280423*G0_2_0_2 - 0.00529100529100528*G0_2_1_1 - 0.00423280423280423*G0_2_1_2 + 0.00423280423280423*G0_2_2_0 - 0.00423280423280423*G0_2_2_1; + A[33] = A[23]; + A[35] = A[21] + 0.00952380952380952*G0_0_0_0 + 0.00529100529100529*G0_0_0_1 + 0.00105820105820106*G0_0_0_2 + 0.00529100529100529*G0_0_1_0 + 0.00423280423280423*G0_0_1_1 + 0.00105820105820106*G0_0_2_0 - 0.00105820105820106*G0_0_2_2 + 0.00529100529100529*G0_1_0_0 + 0.00423280423280423*G0_1_0_1 + 0.00423280423280423*G0_1_1_0 - 0.00423280423280422*G0_1_1_2 - 0.00423280423280422*G0_1_2_1 - 0.00529100529100528*G0_1_2_2 + 0.00105820105820106*G0_2_0_0 - 0.00105820105820106*G0_2_0_2 - 0.00423280423280422*G0_2_1_1 - 0.00529100529100528*G0_2_1_2 - 0.00105820105820106*G0_2_2_0 - 0.00529100529100528*G0_2_2_1 - 0.00952380952380951*G0_2_2_2; + A[19] = A[9]; + A[16] = A[26]; + A[27] = A[34] - 0.00317460317460317*G0_0_0_0 - 0.00105820105820106*G0_0_0_1 - 0.000529100529100529*G0_0_0_2 - 0.00105820105820106*G0_0_1_0 - 0.000529100529100529*G0_0_1_1 - 0.000529100529100528*G0_0_2_0 + 0.000529100529100529*G0_0_2_2 - 0.00105820105820106*G0_1_0_0 - 0.000529100529100529*G0_1_0_1 - 0.000529100529100529*G0_1_1_0 + 0.000529100529100528*G0_1_1_2 + 0.000529100529100528*G0_1_2_1 + 0.00105820105820106*G0_1_2_2 - 0.000529100529100528*G0_2_0_0 + 0.000529100529100528*G0_2_0_2 + 0.000529100529100528*G0_2_1_1 + 0.00105820105820106*G0_2_1_2 + 0.000529100529100528*G0_2_2_0 + 0.00105820105820106*G0_2_2_1 + 0.00317460317460317*G0_2_2_2; + A[22] = A[27]; + A[15] = A[20]; + A[32] = A[17]; + A[2] = -A[13] - 0.000661375661375661*G0_0_0_0 - 0.000132275132275132*G0_0_0_2 - 0.000132275132275132*G0_0_2_0 - 0.000264550264550264*G0_0_2_2 - 0.00066137566137566*G0_1_1_1 - 0.000132275132275132*G0_1_1_2 - 0.000132275132275132*G0_1_2_1 - 0.000264550264550264*G0_1_2_2 - 0.000132275132275132*G0_2_0_0 - 0.000264550264550264*G0_2_0_2 - 0.000132275132275132*G0_2_1_1 - 0.000264550264550264*G0_2_1_2 - 0.000264550264550264*G0_2_2_0 - 0.000264550264550264*G0_2_2_1 - 0.00185185185185185*G0_2_2_2; + A[12] = A[2]; + } + + /// 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 mass_matrix_f3_p1_q2_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f3_p1_q2_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p1_q2_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1)))), 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 3; + } + + /// 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 mass_matrix_f3_p1_q2_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f3_p1_q2_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f3_p1_q2_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p1_q2_tensor_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p1_q2_tensor_finite_element_0(); + 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 mass_matrix_f3_p1_q2_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f3_p1_q2_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f3_p1_q2_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p1_q2_tensor_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p1_q2_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f3_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/mass_matrix_2d/mass_matrix_f3_p1_q3_excafe.h b/mass_matrix_2d/mass_matrix_f3_p1_q3_excafe.h new file mode 100644 index 0000000..708414f --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f3_p1_q3_excafe.h @@ -0,0 +1,328 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 10.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 = -1.0000000000000000000000000*x[0][0]; + const double var_1 = x[1][0] + var_0; + const double var_2 = -1.0000000000000000000000000*x[0][1]; + const double var_3 = x[2][1] + var_2; + const double var_4 = x[2][0] + var_0; + const double var_5 = x[1][1] + var_2; + const double var_6 = var_1*var_3 + -1.0000000000000000000000000*var_4*var_5; + const double var_7 = std::abs(var_6); + const double var_8 = w[0][1]*w[2][2] + w[0][2]*w[2][1]; + const double var_9 = var_8*w[1][2] + w[0][2]*w[1][1]*w[2][2]; + const double var_10 = w[0][2]*w[2][0] + w[0][0]*w[2][2]; + const double var_11 = w[0][2]*w[1][0]*w[2][2] + var_10*w[1][2]; + const double var_12 = w[0][1]*w[2][0] + w[0][0]*w[2][1]; + const double var_13 = var_12*w[1][1] + w[0][1]*w[1][0]*w[2][1]; + const double var_14 = var_12*w[1][0] + w[0][0]*w[1][1]*w[2][0]; + const double var_15 = w[0][1]*w[1][2]*w[2][1] + var_8*w[1][1]; + const double var_16 = w[0][2]*w[1][2]*w[2][2]; + const double var_17 = var_15 + var_16; + const double var_18 = w[0][1]*w[1][1]*w[2][1]; + const double var_19 = -2.7000000000000001776356839*var_18; + const double var_20 = w[0][0]*w[1][2]*w[2][0] + var_10*w[1][0]; + const double var_21 = 0.5000000000000000000000000*var_20; + const double var_22 = -0.7500000000000000000000000*var_13 + -0.2500000000000000000000000*var_11 + var_21 + var_14 + var_19 + -0.4500000000000000111022302*var_9 + -0.6750000000000000444089210*var_17; + const double var_23 = w[0][0]*w[1][0]*w[2][0]; + const double var_24 = var_12*w[1][2] + var_10*w[1][1] + var_8*w[1][0]; + const double var_25 = -0.0000405844155844155843804*var_24*var_7; + const double var_26 = 0.0024350649350649354422937*var_23*var_7 + var_25; + A[7] = var_26 + 0.0001623376623376623375215*var_22*var_7; + A[70] = A[7]; + const double var_27 = -0.0001582792207792207723072*var_24*var_7; + const double var_28 = var_23 + var_13; + const double var_29 = 0.0071428571428571426341070*var_16; + const double var_30 = 23.0000000000000000000000000*w[0][1]*w[1][1]*w[2][1]; + const double var_31 = 0.0357142857142857123031732*var_30; + const double var_32 = 0.1000000000000000055511151*var_11; + const double var_33 = var_31 + 0.1357142857142857039765005*var_28 + 0.2500000000000000000000000*var_32 + 0.0464285714285714301574615*var_20 + 0.0535714285714285684547598*var_14 + 0.0857142857142857150787307*var_9 + 0.2214285714285714190552312*var_15 + var_29; + A[37] = -0.0034090909090909089253219*var_33*var_7 + var_27; + const double var_34 = var_15 + var_9; + const double var_35 = 0.0071428571428571426341070*var_23; + const double var_36 = 0.1000000000000000055511151*var_20; + const double var_37 = var_31 + 0.2214285714285714190552312*var_13 + 0.0464285714285714301574615*var_11 + var_35 + 0.0857142857142857150787307*var_14 + 0.0535714285714285684547598*var_9 + 0.1357142857142857039765005*var_17 + 0.2500000000000000000000000*var_36; + const double var_38 = -1.0000000000000000000000000*var_14; + const double var_39 = var_15 + var_38; + const double var_40 = var_11 + var_20; + const double var_41 = var_23 + var_16; + const double var_42 = var_9 + var_14; + const double var_43 = var_15 + var_13; + const double var_44 = 0.1250000000000000000000000*var_24; + const double var_45 = 0.1666666666666666574148081*var_40 + 0.2500000000000000000000000*var_42 + var_44 + 0.5000000000000000000000000*var_41 + var_43 + 15.8750000000000000000000000*w[0][1]*w[1][1]*w[2][1]; + A[11] = 0.0002164502164502164500287*var_45*var_7; + const double var_46 = var_18 + var_14; + const double var_47 = -2.7000000000000001776356839*var_23; + const double var_48 = 0.5000000000000000000000000*var_9; + const double var_49 = -0.6750000000000000444089210*var_46 + -0.4500000000000000111022302*var_13 + var_47 + var_48 + -0.7500000000000000000000000*var_20 + var_11 + -0.2500000000000000000000000*var_15; + const double var_50 = 0.0024350649350649354422937*var_16*var_7 + var_25; + A[26] = 0.0001623376623376623375215*var_49*var_7 + var_50; + const double var_51 = var_20 + var_16; + const double var_52 = 0.0071428571428571426341070*var_18; + const double var_53 = 23.0000000000000000000000000*w[0][0]*w[1][0]*w[2][0]; + const double var_54 = 0.0357142857142857123031732*var_53; + const double var_55 = 0.1000000000000000055511151*var_15; + const double var_56 = 0.0857142857142857150787307*var_13 + 0.1357142857142857039765005*var_51 + var_52 + 0.0535714285714285684547598*var_11 + 0.2500000000000000000000000*var_55 + 0.2214285714285714190552312*var_14 + 0.0464285714285714301574615*var_9 + var_54; + A[67] = var_27 + -0.0034090909090909089253219*var_56*var_7; + const double var_57 = 0.5000000000000000000000000*var_15; + const double var_58 = var_13 + var_47 + -0.6750000000000000444089210*var_51 + -0.4500000000000000111022302*var_11 + var_57 + -0.7500000000000000000000000*var_14 + -0.2500000000000000000000000*var_9; + const double var_59 = var_18 + var_16; + const double var_60 = var_11 + var_13; + const double var_61 = var_20 + var_14; + const double var_62 = var_44 + 0.5000000000000000000000000*var_59 + 15.8750000000000000000000000*w[0][0]*w[1][0]*w[2][0] + 0.2500000000000000000000000*var_60 + 0.1666666666666666574148081*var_34 + var_61; + A[0] = 0.0002164502164502164500287*var_62*var_7; + const double var_63 = var_23 + var_11; + const double var_64 = 23.0000000000000000000000000*w[0][2]*w[1][2]*w[2][2]; + const double var_65 = 0.0357142857142857123031732*var_64; + const double var_66 = 0.1000000000000000055511151*var_13; + const double var_67 = var_65 + var_52 + 0.0535714285714285684547598*var_20 + 0.1357142857142857039765005*var_63 + 0.2500000000000000000000000*var_66 + 0.0464285714285714301574615*var_14 + 0.2214285714285714190552312*var_9 + 0.0857142857142857150787307*var_15; + A[45] = -0.0034090909090909089253219*var_67*var_7 + var_27; + const double var_68 = var_23 + var_18; + const double var_69 = var_13 + var_14; + const double var_70 = var_34 + var_69 + var_40; + const double var_71 = var_68 + 0.6000000000000000888178420*var_70 + 0.4500000000000000111022302*var_24 + var_16; + const double var_72 = 0.2000000000000000111022302*var_30; + const double var_73 = 4.4500000000000001776356839*w[0][2]*w[1][2]*w[2][2]; + const double var_74 = -1.0000000000000000000000000*var_20; + const double var_75 = -1.0000000000000000000000000*w[0][0]*w[1][0]*w[2][0]; + const double var_76 = 7.2500000000000000000000000*var_75; + const double var_77 = -1.0000000000000000000000000*w[0][1]*w[1][1]*w[2][1]; + const double var_78 = 0.0500000000000000027755576*var_77; + const double var_79 = 0.2500000000000000000000000*var_38 + var_76 + 0.7500000000000000000000000*var_74 + 0.6000000000000000888178420*var_11 + var_66 + var_78 + 0.7250000000000000888178420*var_9 + 0.2250000000000000055511151*var_15 + var_73; + const double var_80 = 0.0285714285714285705364279*var_9 + 0.0428571428571428575393654*var_11; + const double var_81 = 0.0004748376623376623440267*var_24*var_7; + const double var_82 = 0.1000000000000000055511151*var_23; + const double var_83 = 0.2000000000000000111022302*var_64; + const double var_84 = 0.1000000000000000055511151*var_14; + const double var_85 = 0.5000000000000000000000000*var_11; + const double var_86 = var_18 + var_84 + 0.2000000000000000111022302*var_13 + var_85 + 0.2600000000000000088817842*var_21 + var_82 + var_83 + 1.5000000000000000000000000*var_9 + 0.7800000000000000266453526*var_15; + A[44] = 0.0024350649350649354422937*var_7*var_86 + var_81; + const double var_87 = -2.7000000000000001776356839*var_16; + const double var_88 = 0.5000000000000000000000000*var_13; + const double var_89 = var_88 + var_87 + -0.4500000000000000111022302*var_20 + -0.2500000000000000000000000*var_14 + -0.6750000000000000444089210*var_63 + -0.7500000000000000000000000*var_9 + var_15; + const double var_90 = var_9 + var_18; + const double var_91 = 0.5000000000000000000000000*var_14; + const double var_92 = -0.2500000000000000000000000*var_13 + var_87 + var_91 + var_20 + -0.6750000000000000444089210*var_90 + -0.7500000000000000000000000*var_11 + -0.4500000000000000111022302*var_15; + A[99] = 0.0087662337662337656840617*var_7*var_71; + const double var_93 = var_30 + 1.9500000000000001776356839*var_42 + var_40; + const double var_94 = -0.6750000000000000444089210*var_28 + var_85 + -0.2500000000000000000000000*var_20 + -0.4500000000000000111022302*var_14 + var_19 + var_9 + -0.7500000000000000000000000*var_15; + A[24] = var_50 + 0.0001623376623376623375215*var_7*var_94; + A[42] = A[24]; + const double var_95 = var_21 + var_39; + const double var_96 = 0.2000000000000000111022302*var_24; + const double var_97 = var_15 + var_20; + const double var_98 = var_9 + var_11; + const double var_99 = var_16 + 0.3000000000000000444089210*var_97 + 3.1000000000000000888178420*var_68 + 1.5500000000000000444089210*var_69 + var_96 + -0.5000000000000000000000000*var_98; + A[29] = 0.0001623376623376623375215*var_7*var_99; + A[92] = A[29]; + const double var_100 = -0.0000004509379509379509376*var_24*var_7; + const double var_101 = 0.2000000000000000111022302*var_40 + 0.0500000000000000027755576*var_42 + 1.5833333333333332593184650*var_41 + 0.0138888888888888881179007*var_43 + 0.3083333333333333481363070*w[0][1]*w[1][1]*w[2][1]; + A[2] = var_100 + 0.0001623376623376623375215*var_101*var_7; + A[20] = A[2]; + const double var_102 = 0.0002191558441558441692066*var_24*var_7; + const double var_103 = 0.0428571428571428575393654*var_9 + 0.0285714285714285705364279*var_11; + const double var_104 = 0.1250000000000000000000000*var_16; + const double var_105 = -1.0000000000000000000000000*var_18; + const double var_106 = 0.0357142857142857123031732*var_105; + const double var_107 = var_106 + -0.0142857142857142852682140*var_28 + var_104 + 0.0107142857142857143848413*var_95 + var_103; + A[49] = var_102 + 0.0409090909090909088385857*var_107*var_7; + A[54] = A[45]; + const double var_108 = -1.0000000000000000000000000*var_13; + const double var_109 = 0.0003165584415584415446145*var_24*var_7; + const double var_110 = 0.0000243506493506493506282*var_24*var_7; + const double var_111 = 4.4500000000000001776356839*w[0][0]*w[1][0]*w[2][0]; + const double var_112 = -1.0000000000000000000000000*var_9; + const double var_113 = -1.0000000000000000000000000*var_11; + const double var_114 = -1.0000000000000000000000000*w[0][2]*w[1][2]*w[2][2]; + const double var_115 = 7.2500000000000000000000000*var_114; + const double var_116 = 0.2500000000000000000000000*var_112 + 0.2250000000000000055511151*var_13 + var_115 + var_111 + var_55 + 0.6000000000000000888178420*var_20 + 0.7250000000000000888178420*var_14 + var_78 + 0.7500000000000000000000000*var_113; + A[25] = var_110 + 0.0001623376623376623375215*var_116*var_7; + const double var_117 = 0.0428571428571428575393654*var_15 + 0.0285714285714285705364279*var_13; + const double var_118 = -0.8857142857142856762209249*var_41 + var_18 + -0.0285714285714285705364279*var_43 + -0.1857142857142857206298459*var_40; + const double var_119 = 0.1000000000000000055511151*var_18; + const double var_120 = 4.4500000000000001776356839*w[0][1]*w[1][1]*w[2][1]; + const double var_121 = 0.0500000000000000027755576*var_75; + const double var_122 = 0.7500000000000000000000000*var_112 + 0.7250000000000000888178420*var_13 + var_115 + var_120 + var_121 + 0.2250000000000000055511151*var_14 + 0.6000000000000000888178420*var_15 + 0.2500000000000000000000000*var_113 + var_36; + A[23] = var_110 + 0.0001623376623376623375215*var_122*var_7; + const double var_123 = 0.0428571428571428575393654*var_20 + 0.0285714285714285705364279*var_14; + const double var_124 = 0.1250000000000000000000000*var_23; + const double var_125 = -1.0000000000000000000000000*var_16; + const double var_126 = 0.0357142857142857123031732*var_125; + const double var_127 = -1.0000000000000000000000000*var_15; + const double var_128 = var_11 + var_127; + const double var_129 = var_128 + var_88; + const double var_130 = -0.0142857142857142852682140*var_90 + var_123 + var_124 + var_126 + 0.0107142857142857143848413*var_129; + A[59] = var_102 + 0.0409090909090909088385857*var_130*var_7; + A[76] = A[67]; + const double var_131 = var_113 + var_14; + const double var_132 = 0.0000365259740259740259423*var_24*var_7; + const double var_133 = 1.3000000000000000444089210*w[0][0]*w[1][0]*w[2][0]; + const double var_134 = 0.0285714285714285705364279*var_15 + 0.0428571428571428575393654*var_13; + const double var_135 = -0.0142857142857142852682140*var_64; + const double var_136 = 0.0714285714285714246063463*var_105; + const double var_137 = 0.0142857142857142852682140*var_112 + var_133 + var_134 + 0.1071428571428571369095195*var_11 + 0.3785714285714285587403083*var_20 + 0.2071428571428571285828468*var_14 + var_135 + var_136; + A[15] = 0.0005681818181818181542203*var_137*var_7 + var_132; + A[51] = A[15]; + const double var_138 = -1.0000000000000000000000000*var_23; + const double var_139 = 0.0357142857142857123031732*var_138; + const double var_140 = var_108 + var_20; + const double var_141 = var_140 + var_57; + const double var_142 = -0.0142857142857142852682140*var_46 + 0.0107142857142857143848413*var_141 + var_104 + var_80 + var_139; + A[69] = var_102 + 0.0409090909090909088385857*var_142*var_7; + A[96] = A[69]; + const double var_143 = var_48 + 0.7800000000000000266453526*var_20 + 1.5000000000000000000000000*var_11 + 0.2600000000000000088817842*var_57 + var_66 + 0.2000000000000000111022302*var_14 + var_83 + var_23 + var_119; + A[52] = A[25]; + const double var_144 = 0.0285714285714285705364279*var_20 + 0.0428571428571428575393654*var_14; + const double var_145 = var_65 + 0.2500000000000000000000000*var_84 + 0.0464285714285714301574615*var_13 + 0.0857142857142857150787307*var_20 + 0.2214285714285714190552312*var_11 + 0.1357142857142857039765005*var_90 + var_35 + 0.0535714285714285684547598*var_15; + A[36] = -0.0034090909090909089253219*var_145*var_7 + var_27; + A[63] = A[36]; + const double var_146 = -0.0142857142857142852682140*var_30; + const double var_147 = 0.0714285714285714246063463*var_125; + const double var_148 = 0.1071428571428571369095195*var_13 + var_133 + 0.2071428571428571285828468*var_20 + 0.0142857142857142852682140*var_127 + var_80 + var_146 + 0.3785714285714285587403083*var_14 + var_147; + const double var_149 = 1.5833333333333332593184650*var_59 + 0.3083333333333333481363070*w[0][0]*w[1][0]*w[2][0] + 0.0500000000000000027755576*var_60 + 0.0138888888888888881179007*var_61 + 0.2000000000000000111022302*var_34; + A[12] = var_100 + 0.0001623376623376623375215*var_149*var_7; + const double var_150 = 0.1250000000000000000000000*var_18; + const double var_151 = var_48 + var_131; + const double var_152 = 0.0107142857142857143848413*var_151 + var_134 + -0.0142857142857142852682140*var_51 + var_139 + var_150; + A[89] = 0.0409090909090909088385857*var_152*var_7 + var_102; + A[98] = A[89]; + const double var_153 = var_9 + var_74; + const double var_154 = 3.1000000000000000888178420*var_59 + var_96 + var_23 + 0.3000000000000000444089210*var_60 + -0.5000000000000000000000000*var_61 + 1.5500000000000000444089210*var_34; + A[9] = 0.0001623376623376623375215*var_154*var_7; + A[90] = A[9]; + const double var_155 = 0.0500000000000000027755576*var_114; + const double var_156 = 0.0714285714285714246063463*var_138; + const double var_157 = var_41 + 0.5000000000000000000000000*var_93; + A[38] = 0.0012175324675324677211469*var_43*var_7 + var_109 + 0.0004870129870129870125646*var_157*var_7; + const double var_158 = -0.0000852272727272727339751*var_24*var_7; + const double var_159 = -0.8857142857142856762209249*var_59 + -0.0285714285714285705364279*var_61 + var_23 + -0.1857142857142857206298459*var_34; + A[68] = -0.0002922077922077922075388*var_60*var_7 + 0.0008522727272727272313305*var_159*var_7 + var_158; + A[32] = A[23]; + const double var_160 = 0.1200000000000000094368957*var_40 + 0.0200000000000000004163336*var_18 + 0.1085714285714285687323155*var_42 + 0.7142857142857143015746146*var_41 + 0.0371428571428571441259692*var_43; + const double var_161 = 0.1000000000000000055511151*var_9; + const double var_162 = 0.1357142857142857039765005*var_46 + 0.2500000000000000000000000*var_161 + 0.0535714285714285684547598*var_13 + 0.2214285714285714190552312*var_20 + 0.0857142857142857150787307*var_11 + 0.0464285714285714301574615*var_15 + var_29 + var_54; + const double var_163 = 1.3000000000000000444089210*w[0][1]*w[1][1]*w[2][1]; + const double var_164 = 0.2071428571428571285828468*var_13 + var_144 + var_163 + var_135 + 0.1071428571428571369095195*var_9 + 0.0142857142857142852682140*var_113 + 0.3785714285714285587403083*var_15 + var_156; + const double var_165 = var_25 + 0.0024350649350649354422937*var_18*var_7; + A[13] = var_165 + 0.0001623376623376623375215*var_7*var_89; + const double var_166 = 0.1000000000000000055511151*var_16; + const double var_167 = var_166 + var_32 + 1.5000000000000000000000000*var_13 + var_72 + 0.2600000000000000088817842*var_48 + 0.2000000000000000111022302*var_20 + var_57 + 0.7800000000000000266453526*var_14 + var_23; + const double var_168 = 0.7500000000000000000000000*var_38 + var_76 + 0.6000000000000000888178420*var_13 + var_32 + 0.2500000000000000000000000*var_74 + var_120 + var_155 + 0.2250000000000000055511151*var_9 + 0.7250000000000000888178420*var_15; + A[8] = 0.0001623376623376623375215*var_168*var_7 + var_110; + A[80] = A[8]; + const double var_169 = var_91 + var_153; + const double var_170 = var_112 + var_13; + const double var_171 = var_170 + var_85; + const double var_172 = var_106 + var_144 + var_124 + -0.0142857142857142852682140*var_17 + 0.0107142857142857143848413*var_171; + A[79] = 0.0409090909090909088385857*var_172*var_7 + var_102; + const double var_173 = 1.3000000000000000444089210*w[0][2]*w[1][2]*w[2][2]; + const double var_174 = -0.0142857142857142852682140*var_53; + const double var_175 = var_173 + 0.0142857142857142852682140*var_38 + 0.3785714285714285587403083*var_11 + 0.1071428571428571369095195*var_20 + var_117 + var_174 + 0.2071428571428571285828468*var_9 + var_136; + A[16] = 0.0005681818181818181542203*var_175*var_7 + var_132; + A[61] = A[16]; + A[18] = 0.0001623376623376623375215*var_58*var_7 + var_165; + const double var_176 = -0.0001826298701298701364880*var_24*var_7; + A[56] = var_176 + -0.0042613636363636369155938*var_160*var_7; + A[58] = -0.0034090909090909089253219*var_162*var_7 + var_27; + A[97] = A[79]; + A[73] = A[37]; + const double var_177 = var_34 + var_53 + 1.9500000000000001776356839*var_60; + const double var_178 = var_61 + 0.2000000000000000111022302*var_177; + const double var_179 = 1.9500000000000001776356839*var_97 + var_64 + var_69; + const double var_180 = var_68 + 0.5000000000000000000000000*var_179; + A[46] = var_109 + 0.0004870129870129870125646*var_180*var_7 + 0.0012175324675324677211469*var_7*var_98; + A[64] = A[46]; + A[6] = var_110 + 0.0001623376623376623375215*var_7*var_79; + A[60] = A[6]; + const double var_181 = 0.2000000000000000111022302*var_53; + const double var_182 = var_166 + var_18 + var_161 + var_181 + 0.7800000000000000266453526*var_13 + 0.2600000000000000088817842*var_85 + var_21 + 1.5000000000000000000000000*var_14 + 0.2000000000000000111022302*var_15; + A[77] = var_81 + 0.0024350649350649354422937*var_182*var_7; + const double var_183 = 0.7142857142857143015746146*var_59 + 0.0200000000000000004163336*var_23 + 0.1085714285714285687323155*var_60 + 0.0371428571428571441259692*var_61 + 0.1200000000000000094368957*var_34; + A[34] = var_176 + -0.0042613636363636369155938*var_183*var_7; + A[43] = A[34]; + const double var_184 = 7.2500000000000000000000000*var_77; + const double var_185 = 0.2500000000000000000000000*var_108 + var_84 + 0.2250000000000000055511151*var_20 + 0.7500000000000000000000000*var_127 + 0.7250000000000000888178420*var_11 + var_121 + var_184 + 0.6000000000000000888178420*var_9 + var_73; + A[14] = var_110 + 0.0001623376623376623375215*var_185*var_7; + A[41] = A[14]; + const double var_186 = var_16 + 0.2600000000000000088817842*var_88 + var_181 + var_91 + 1.5000000000000000000000000*var_20 + 0.7800000000000000266453526*var_11 + var_55 + 0.2000000000000000111022302*var_9 + var_119; + A[55] = 0.0024350649350649354422937*var_186*var_7 + var_81; + A[66] = var_81 + 0.0024350649350649354422937*var_143*var_7; + A[27] = 0.0005681818181818181542203*var_148*var_7 + var_132; + A[72] = A[27]; + const double var_187 = 1.5500000000000000444089210*var_40 + var_18 + 0.3000000000000000444089210*var_42 + 3.1000000000000000888178420*var_41 + var_96 + -0.5000000000000000000000000*var_43; + A[19] = 0.0001623376623376623375215*var_187*var_7; + A[91] = A[19]; + const double var_188 = 0.0107142857142857143848413*var_169 + var_117 + -0.0142857142857142852682140*var_63 + var_126 + var_150; + A[39] = var_102 + 0.0409090909090909088385857*var_188*var_7; + A[93] = A[39]; + const double var_189 = 0.3785714285714285587403083*var_13 + 0.0142857142857142852682140*var_74 + var_163 + var_103 + 0.1071428571428571369095195*var_14 + var_174 + var_147 + 0.2071428571428571285828468*var_15; + A[28] = 0.0005681818181818181542203*var_189*var_7 + var_132; + A[5] = var_26 + 0.0001623376623376623375215*var_7*var_92; + A[94] = A[49]; + const double var_190 = 0.7500000000000000000000000*var_108 + var_161 + var_111 + 0.2250000000000000055511151*var_11 + 0.2500000000000000000000000*var_127 + 0.7250000000000000888178420*var_20 + var_184 + 0.6000000000000000888178420*var_14 + var_155; + A[17] = var_110 + 0.0001623376623376623375215*var_190*var_7; + A[82] = A[28]; + const double var_191 = 0.0200000000000000004163336*var_16 + 0.7142857142857143015746146*var_68 + 0.1085714285714285687323155*var_97 + 0.1200000000000000094368957*var_69 + 0.0371428571428571441259692*var_98; + A[78] = var_176 + -0.0042613636363636369155938*var_191*var_7; + const double var_192 = 0.2500000000000000000000000*var_97 + 0.5000000000000000000000000*var_68 + 15.8750000000000000000000000*w[0][2]*w[1][2]*w[2][2] + var_44 + 0.1666666666666666574148081*var_69 + var_98; + A[22] = 0.0002164502164502164500287*var_192*var_7; + A[88] = 0.0024350649350649354422937*var_167*var_7 + var_81; + A[71] = A[17]; + A[47] = -0.0002922077922077922075388*var_42*var_7 + var_158 + 0.0008522727272727272313305*var_118*var_7; + A[74] = A[47]; + A[83] = A[38]; + A[48] = var_27 + -0.0034090909090909089253219*var_37*var_7; + A[3] = var_132 + 0.0005681818181818181542203*var_164*var_7; + A[21] = A[12]; + const double var_193 = -0.8857142857142856762209249*var_68 + -0.0285714285714285705364279*var_98 + -0.1857142857142857206298459*var_69 + var_16; + A[35] = 0.0008522727272727272313305*var_193*var_7 + var_158 + -0.0002922077922077922075388*var_7*var_97; + A[50] = A[5]; + const double var_194 = 0.3083333333333333481363070*w[0][2]*w[1][2]*w[2][2] + 0.0500000000000000027755576*var_97 + 1.5833333333333332593184650*var_68 + 0.2000000000000000111022302*var_69 + 0.0138888888888888881179007*var_98; + A[1] = 0.0001623376623376623375215*var_194*var_7 + var_100; + A[10] = A[1]; + const double var_195 = var_173 + 0.0142857142857142852682140*var_108 + 0.2071428571428571285828468*var_11 + var_146 + var_123 + 0.3785714285714285587403083*var_9 + 0.1071428571428571369095195*var_15 + var_156; + A[57] = 0.0012175324675324677211469*var_178*var_7 + var_109 + 0.0004870129870129870125646*var_59*var_7; + A[53] = A[35]; + A[65] = A[56]; + A[95] = A[59]; + A[84] = A[48]; + A[75] = A[57]; + A[31] = A[13]; + A[62] = A[26]; + A[4] = var_132 + 0.0005681818181818181542203*var_195*var_7; + A[87] = A[78]; + A[30] = A[3]; + A[40] = A[4]; + A[86] = A[68]; + A[85] = A[58]; + const double var_196 = var_16 + var_88 + 0.2600000000000000088817842*var_91 + var_72 + 0.2000000000000000111022302*var_11 + var_82 + 0.7800000000000000266453526*var_9 + 1.5000000000000000000000000*var_15 + var_36; + A[81] = A[18]; + A[33] = var_81 + 0.0024350649350649354422937*var_196*var_7; + } + + 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/mass_matrix_2d/mass_matrix_f3_p1_q3_quadrature.h b/mass_matrix_2d/mass_matrix_f3_p1_q3_quadrature.h new file mode 100644 index 0000000..58d7669 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f3_p1_q3_quadrature.h @@ -0,0 +1,4617 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F3_P1_Q3_QUADRATURE_H +#define __MASS_MATRIX_F3_P1_Q3_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p1_q3_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p1_q3_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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 mass_matrix_f3_p1_q3_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p1_q3_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p1_q3_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p1_q3_quadrature_finite_element_1() + { + // 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f3_p1_q3_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p1_q3_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p1_q3_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_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 mass_matrix_f3_p1_q3_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p1_q3_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p1_q3_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_p1_q3_quadrature_dofmap_1() + { + // 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.0*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 mass_matrix_f3_p1_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 mass_matrix_f3_p1_q3_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f3_p1_q3_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // 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[25][3] = \ + {{0.915147549378728, 0.0450425935698037, 0.0398098570514687}, + {0.764365329781281, 0.0376212523451112, 0.198013417873608}, + {0.535660544808143, 0.026364644944471, 0.437974810247386}, + {0.290249932250793, 0.0142857943955714, 0.695464273353636}, + {0.09391279733378, 0.00462228846504648, 0.901464914201173}, + {0.738611533396152, 0.221578609552379, 0.0398098570514687}, + {0.616915871859002, 0.185070710267389, 0.198013417873608}, + {0.43232925297036, 0.129695936782254, 0.437974810247386}, + {0.234259434638082, 0.0702762920082818, 0.695464273353636}, + {0.0757966027350624, 0.0227384830637641, 0.901464914201173}, + {0.480095071474266, 0.480095071474266, 0.0398098570514687}, + {0.400993291063196, 0.400993291063196, 0.198013417873608}, + {0.281012594876307, 0.281012594876307, 0.437974810247386}, + {0.152267863323182, 0.152267863323182, 0.695464273353636}, + {0.0492675428994132, 0.0492675428994133, 0.901464914201173}, + {0.221578609552379, 0.738611533396152, 0.0398098570514687}, + {0.185070710267389, 0.616915871859002, 0.198013417873608}, + {0.129695936782254, 0.43232925297036, 0.437974810247386}, + {0.0702762920082818, 0.234259434638082, 0.695464273353636}, + {0.022738483063764, 0.0757966027350624, 0.901464914201173}, + {0.0450425935698037, 0.915147549378728, 0.0398098570514687}, + {0.0376212523451112, 0.764365329781281, 0.198013417873608}, + {0.0263646449444709, 0.535660544808143, 0.437974810247386}, + {0.0142857943955715, 0.290249932250793, 0.695464273353636}, + {0.00462228846504642, 0.0939127973337801, 0.901464914201173}}; + + static const double FE1[25][10] = \ + {{0.595361771100889, 0.0363240630142744, 0.0329620582231266, -0.00697876330105453, -0.00710543413900173, 0.286154010031837, -0.144363814874519, 0.323767019699913, -0.160427557536749, 0.0443066477812842}, + {0.144847707077251, 0.031491752557511, 0.056509372357196, -0.0297392974343587, -0.0136089104009562, 0.880722068301204, -0.276497422020097, 0.167331423967527, -0.114798724929776, 0.153742030524499}, + {-0.0638922318573471, 0.0233191863197456, -0.0471646056404562, -0.0478518692290425, 0.0163120554591614, 0.640806423249974, 0.331418250941681, 0.038574441798557, -0.0585247318831845, 0.167003080840912}, + {0.0211818331847306, 0.0133805365030047, 0.0326369349932555, -0.0427925717552784, 0.0485711762178746, -0.117406110387015, 0.98683910857276, -0.0024116832712123, -0.0178593517002863, 0.0778601276421673}, + {0.0579517721596659, 0.00452658789692546, 0.541134376806172, -0.0184907249626245, 0.0319586608616019, -0.273633189306433, 0.649316299328904, -0.0014030624094848, -0.00192632644777788, 0.010565606073051}, + {0.0969129145557495, 0.0495966310503562, 0.0329620582231266, -0.0133081629182569, -0.0349538534974921, 0.160876909651335, -0.116515395516028, 0.895428534283356, -0.246912783611135, 0.175913147778989}, + {-0.0391667888544834, 0.0594654509565622, 0.056509372357196, -0.0733496016702976, -0.0669464878724995, 0.467663868980969, -0.223159844548554, 0.437096058075966, -0.228522561505531, 0.610410534080673}, + {-0.0451321541833679, 0.0638185648099453, -0.0471646056404562, -0.15615892407532, 0.0802441041051714, 0.253054939278284, 0.267486202295671, 0.074936267198872, -0.154146013447678, 0.663061619658879}, + {0.045160818752146, 0.0496137334753148, 0.0326369349932555, -0.17356708239734, 0.238936811531546, -0.217903867034122, 0.796473473259088, -0.0220190689531468, -0.0584641485580772, 0.309132394931336}, + {0.0519031146003489, 0.0204647143413336, 0.541134376806172, -0.0859485068100627, 0.157214651192224, -0.23755901477889, 0.524060308998282, -0.00599217068695466, -0.00722668705539908, 0.0419492133929461}, + {-0.0591559090807405, -0.0591559090807405, 0.0329620582231266, 0.03786731225338, -0.0757346245067602, 0.03786731225338, -0.0757346245067601, 0.456668557219904, 0.456668557219904, 0.247747270005307}, + {-0.032436155693348, -0.032436155693348, 0.056509372357196, 0.0725265831052634, -0.145053166210527, 0.0725265831052632, -0.145053166210527, 0.146872235029605, 0.146872235029605, 0.859671635180817}, + {0.025515852626442, 0.0255158526264419, -0.0471646056404562, -0.0869325766002105, 0.173865153200421, -0.0869325766002107, 0.173865153200421, -0.0557775204375565, -0.0557775204375563, 0.933822788062264}, + {0.0638199343796498, 0.0638199343796498, 0.0326369349932555, -0.258852571197659, 0.517705142395317, -0.258852571197659, 0.517705142395317, -0.0566742670215316, -0.0566742670215314, 0.435366587895191}, + {0.0388828743119486, 0.0388828743119486, 0.541134376806172, -0.170318740047627, 0.340637480095253, -0.170318740047627, 0.340637480095253, -0.0093083887122843, -0.00930838871228411, 0.0590791718992466}, + {0.0495966310503563, 0.0969129145557494, 0.0329620582231266, 0.160876909651335, -0.116515395516028, -0.013308162918257, -0.034953853497492, -0.246912783611135, 0.895428534283356, 0.175913147778989}, + {0.0594654509565623, -0.0391667888544834, 0.056509372357196, 0.467663868980969, -0.223159844548554, -0.0733496016702976, -0.0669464878724995, -0.228522561505532, 0.437096058075966, 0.610410534080673}, + {0.0638185648099453, -0.0451321541833679, -0.0471646056404562, 0.253054939278284, 0.267486202295671, -0.15615892407532, 0.0802441041051715, -0.154146013447678, 0.0749362671988722, 0.663061619658879}, + {0.0496137334753148, 0.045160818752146, 0.0326369349932555, -0.217903867034122, 0.796473473259088, -0.17356708239734, 0.238936811531547, -0.0584641485580774, -0.0220190689531466, 0.309132394931336}, + {0.0204647143413336, 0.0519031146003489, 0.541134376806172, -0.23755901477889, 0.524060308998282, -0.0859485068100628, 0.157214651192223, -0.00722668705539924, -0.00599217068695446, 0.041949213392946}, + {0.0363240630142745, 0.595361771100889, 0.0329620582231266, 0.286154010031837, -0.144363814874519, -0.00697876330105458, -0.00710543413900171, -0.160427557536749, 0.323767019699913, 0.0443066477812842}, + {0.031491752557511, 0.144847707077251, 0.056509372357196, 0.880722068301204, -0.276497422020097, -0.0297392974343586, -0.0136089104009562, -0.114798724929776, 0.167331423967527, 0.153742030524498}, + {0.0233191863197457, -0.0638922318573471, -0.0471646056404562, 0.640806423249974, 0.331418250941681, -0.0478518692290426, 0.0163120554591614, -0.0585247318831847, 0.0385744417985573, 0.167003080840912}, + {0.0133805365030048, 0.0211818331847307, 0.0326369349932554, -0.117406110387015, 0.986839108572759, -0.0427925717552788, 0.0485711762178751, -0.0178593517002866, -0.00241168327121213, 0.0778601276421677}, + {0.00452658789692547, 0.057951772159666, 0.541134376806172, -0.273633189306433, 0.649316299328904, -0.0184907249626247, 0.0319586608616018, -0.00192632644777806, -0.0014030624094846, 0.0105656060730509}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 100; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 8050 + for (unsigned int ip = 0; ip < 25; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + + // Total number of operations to compute function values = 18 + for (unsigned int r = 0; r < 3; r++) + { + F0 += FE0[ip][r]*w[2][r]; + F1 += FE0[ip][r]*w[0][r]; + F2 += FE0[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 4 + double I[1]; + // Number of operations: 4 + I[0] = F0*F1*F2*W25[ip]*det; + + + // Number of operations for primary indices: 300 + for (unsigned int j = 0; j < 10; j++) + { + for (unsigned int k = 0; k < 10; k++) + { + // Number of operations to compute entry: 3 + A[j*10 + k] += FE1[ip][j]*FE1[ip][k]*I[0]; + }// 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 mass_matrix_f3_p1_q3_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f3_p1_q3_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p1_q3_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1)))), 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 3; + } + + /// 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 mass_matrix_f3_p1_q3_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f3_p1_q3_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f3_p1_q3_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p1_q3_quadrature_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p1_q3_quadrature_finite_element_0(); + 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 mass_matrix_f3_p1_q3_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f3_p1_q3_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f3_p1_q3_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p1_q3_quadrature_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p1_q3_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f3_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/mass_matrix_2d/mass_matrix_f3_p1_q3_tensor.h b/mass_matrix_2d/mass_matrix_f3_p1_q3_tensor.h new file mode 100644 index 0000000..01ea6cc --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f3_p1_q3_tensor.h @@ -0,0 +1,4645 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F3_P1_Q3_TENSOR_H +#define __MASS_MATRIX_F3_P1_Q3_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p1_q3_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p1_q3_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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 mass_matrix_f3_p1_q3_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p1_q3_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p1_q3_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p1_q3_tensor_finite_element_1() + { + // 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f3_p1_q3_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p1_q3_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p1_q3_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_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 mass_matrix_f3_p1_q3_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p1_q3_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p1_q3_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_p1_q3_tensor_dofmap_1() + { + // 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.0*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 mass_matrix_f3_p1_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 mass_matrix_f3_p1_q3_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f3_p1_q3_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 54 + // Number of operations (multiply-add pairs) for tensor contraction: 1257 + // Total number of operations (multiply-add pairs): 1320 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0 = det*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_0_0_1 = det*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_0_0_2 = det*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_0_1_0 = det*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_0_1_1 = det*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_0_1_2 = det*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_0_2_0 = det*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_0_2_1 = det*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_0_2_2 = det*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_1_0_0 = det*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_1_0_1 = det*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_1_0_2 = det*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_1_1_0 = det*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_1_1_1 = det*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_1_1_2 = det*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_1_2_0 = det*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_1_2_1 = det*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_1_2_2 = det*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_2_0_0 = det*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_2_0_1 = det*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_2_0_2 = det*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_2_1_0 = det*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_2_1_1 = det*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_2_1_2 = det*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_2_2_0 = det*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_2_2_1 = det*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_2_2_2 = det*w[2][2]*w[0][2]*w[1][2]*(1.0); + + // Compute element tensor + A[73] = -0.000462662337662337*G0_0_0_0 - 0.00018262987012987*G0_0_0_1 - 0.00015827922077922*G0_0_0_2 - 0.00018262987012987*G0_0_1_0 - 0.000462662337662336*G0_0_1_1 - 0.00015827922077922*G0_0_1_2 - 0.00015827922077922*G0_0_2_0 - 0.00015827922077922*G0_0_2_1 - 8.52272727272722e-05*G0_0_2_2 - 0.00018262987012987*G0_1_0_0 - 0.000462662337662336*G0_1_0_1 - 0.00015827922077922*G0_1_0_2 - 0.000462662337662336*G0_1_1_0 - 0.00280032467532467*G0_1_1_1 - 0.000754870129870128*G0_1_1_2 - 0.00015827922077922*G0_1_2_0 - 0.000754870129870128*G0_1_2_1 - 0.000292207792207791*G0_1_2_2 - 0.00015827922077922*G0_2_0_0 - 0.00015827922077922*G0_2_0_1 - 8.52272727272722e-05*G0_2_0_2 - 0.00015827922077922*G0_2_1_0 - 0.000754870129870128*G0_2_1_1 - 0.000292207792207791*G0_2_1_2 - 8.52272727272722e-05*G0_2_2_0 - 0.000292207792207791*G0_2_2_1 - 2.43506493506484e-05*G0_2_2_2; + A[37] = A[73]; + A[85] = A[73] - 0.00233766233766233*G0_0_0_0 - 0.000280032467532466*G0_0_0_1 - 0.000596590909090907*G0_0_0_2 - 0.000280032467532466*G0_0_1_0 + 0.000280032467532466*G0_0_1_1 - 0.000596590909090906*G0_0_2_0 - 0.000206980519480519*G0_0_2_2 - 0.000280032467532466*G0_1_0_0 + 0.000280032467532466*G0_1_0_1 + 0.000280032467532466*G0_1_1_0 + 0.00233766233766233*G0_1_1_1 + 0.000596590909090907*G0_1_1_2 + 0.000596590909090907*G0_1_2_1 + 0.000206980519480519*G0_1_2_2 - 0.000596590909090906*G0_2_0_0 - 0.000206980519480519*G0_2_0_2 + 0.000596590909090907*G0_2_1_1 + 0.000206980519480519*G0_2_1_2 - 0.000206980519480519*G0_2_2_0 + 0.000206980519480519*G0_2_2_1; + A[58] = A[85]; + A[67] = A[85] - 0.00029220779220779*G0_0_0_1 + 0.00029220779220779*G0_0_0_2 - 0.00029220779220779*G0_0_1_0 - 0.000109577922077921*G0_0_1_1 + 0.00029220779220779*G0_0_2_0 + 0.00010957792207792*G0_0_2_2 - 0.000292207792207791*G0_1_0_0 - 0.000109577922077921*G0_1_0_1 - 0.000109577922077921*G0_1_1_0 + 0.000438311688311688*G0_1_1_1 + 7.30519480519479e-05*G0_1_1_2 + 7.30519480519479e-05*G0_1_2_1 - 7.30519480519482e-05*G0_1_2_2 + 0.00029220779220779*G0_2_0_0 + 0.000109577922077921*G0_2_0_2 + 7.30519480519479e-05*G0_2_1_1 - 7.30519480519482e-05*G0_2_1_2 + 0.00010957792207792*G0_2_2_0 - 7.30519480519482e-05*G0_2_2_1 - 0.000438311688311689*G0_2_2_2; + A[76] = A[67]; + A[45] = A[73] + 2.43506493506496e-05*G0_0_0_1 - 2.43506493506493e-05*G0_0_0_2 + 2.43506493506496e-05*G0_0_1_0 + 0.000377435064935063*G0_0_1_1 - 2.43506493506493e-05*G0_0_2_0 - 0.000377435064935064*G0_0_2_2 + 2.43506493506496e-05*G0_1_0_0 + 0.000377435064935063*G0_1_0_1 + 0.000377435064935064*G0_1_1_0 + 0.00277597402597402*G0_1_1_1 + 0.000462662337662336*G0_1_1_2 + 0.000462662337662336*G0_1_2_1 - 0.000462662337662337*G0_1_2_2 - 2.43506493506493e-05*G0_2_0_0 - 0.000377435064935064*G0_2_0_2 + 0.000462662337662336*G0_2_1_1 - 0.000462662337662337*G0_2_1_2 - 0.000377435064935064*G0_2_2_0 - 0.000462662337662337*G0_2_2_1 - 0.00277597402597402*G0_2_2_2; + A[1] = 0.00025703463203463*G0_0_0_0 + 3.24675324675323e-05*G0_0_0_1 + 8.11688311688303e-06*G0_0_0_2 + 3.24675324675323e-05*G0_0_1_0 + 3.24675324675322e-05*G0_0_1_1 + 8.11688311688303e-06*G0_0_2_0 + 2.25468975468974e-06*G0_0_2_2 + 3.24675324675323e-05*G0_1_0_0 + 3.24675324675322e-05*G0_1_0_1 + 3.24675324675322e-05*G0_1_1_0 + 0.000257034632034631*G0_1_1_1 + 8.11688311688304e-06*G0_1_1_2 + 8.11688311688304e-06*G0_1_2_1 + 2.25468975468974e-06*G0_1_2_2 + 8.11688311688303e-06*G0_2_0_0 + 2.25468975468974e-06*G0_2_0_2 + 8.11688311688304e-06*G0_2_1_1 + 2.25468975468974e-06*G0_2_1_2 + 2.25468975468974e-06*G0_2_2_0 + 2.25468975468974e-06*G0_2_2_1 + 5.00541125541123e-05*G0_2_2_2; + A[99] = 0.00876623376623373*G0_0_0_0 + 0.00525974025974024*G0_0_0_1 + 0.00525974025974024*G0_0_0_2 + 0.00525974025974024*G0_0_1_0 + 0.00525974025974024*G0_0_1_1 + 0.00394480519480518*G0_0_1_2 + 0.00525974025974024*G0_0_2_0 + 0.00394480519480518*G0_0_2_1 + 0.00525974025974024*G0_0_2_2 + 0.00525974025974024*G0_1_0_0 + 0.00525974025974024*G0_1_0_1 + 0.00394480519480518*G0_1_0_2 + 0.00525974025974024*G0_1_1_0 + 0.00876623376623374*G0_1_1_1 + 0.00525974025974024*G0_1_1_2 + 0.00394480519480518*G0_1_2_0 + 0.00525974025974024*G0_1_2_1 + 0.00525974025974024*G0_1_2_2 + 0.00525974025974024*G0_2_0_0 + 0.00394480519480518*G0_2_0_1 + 0.00525974025974024*G0_2_0_2 + 0.00394480519480518*G0_2_1_0 + 0.00525974025974024*G0_2_1_1 + 0.00525974025974024*G0_2_1_2 + 0.00525974025974024*G0_2_2_0 + 0.00525974025974024*G0_2_2_1 + 0.00876623376623373*G0_2_2_2; + A[78] = A[67] - 0.000243506493506494*G0_0_0_0 + 0.000243506493506492*G0_0_0_1 + 0.000243506493506492*G0_0_1_0 - 0.000219155844155844*G0_0_1_1 - 2.43506493506493e-05*G0_0_1_2 - 2.43506493506492e-05*G0_0_2_1 + 2.43506493506503e-05*G0_0_2_2 + 0.000243506493506492*G0_1_0_0 - 0.000219155844155844*G0_1_0_1 - 2.43506493506492e-05*G0_1_0_2 - 0.000219155844155844*G0_1_1_0 - 0.00301948051948051*G0_1_1_1 - 0.000377435064935064*G0_1_1_2 - 2.43506493506492e-05*G0_1_2_0 - 0.000377435064935064*G0_1_2_1 - 2.43506493506492e-05*G0_2_0_1 + 2.43506493506503e-05*G0_2_0_2 - 2.43506493506492e-05*G0_2_1_0 - 0.000377435064935064*G0_2_1_1 + 2.43506493506503e-05*G0_2_2_0 + 0.000377435064935066*G0_2_2_2; + A[21] = 5.00541125541123e-05*G0_0_0_0 + 2.25468975468971e-06*G0_0_0_1 + 2.25468975468973e-06*G0_0_0_2 + 2.25468975468971e-06*G0_0_1_0 + 8.11688311688301e-06*G0_0_1_1 + 2.25468975468973e-06*G0_0_2_0 + 8.11688311688304e-06*G0_0_2_2 + 2.25468975468971e-06*G0_1_0_0 + 8.116883116883e-06*G0_1_0_1 + 8.116883116883e-06*G0_1_1_0 + 0.00025703463203463*G0_1_1_1 + 3.24675324675323e-05*G0_1_1_2 + 3.24675324675323e-05*G0_1_2_1 + 3.24675324675323e-05*G0_1_2_2 + 2.25468975468973e-06*G0_2_0_0 + 8.11688311688303e-06*G0_2_0_2 + 3.24675324675323e-05*G0_2_1_1 + 3.24675324675323e-05*G0_2_1_2 + 8.11688311688304e-06*G0_2_2_0 + 3.24675324675323e-05*G0_2_2_1 + 0.00025703463203463*G0_2_2_2; + A[36] = A[85] + 0.00277597402597402*G0_0_0_0 + 0.000377435064935064*G0_0_0_1 + 0.000462662337662336*G0_0_0_2 + 0.000377435064935063*G0_0_1_0 + 2.43506493506497e-05*G0_0_1_1 + 0.000462662337662336*G0_0_2_0 - 0.000462662337662336*G0_0_2_2 + 0.000377435064935063*G0_1_0_0 + 2.43506493506497e-05*G0_1_0_1 + 2.43506493506497e-05*G0_1_1_0 - 2.4350649350649e-05*G0_1_1_2 - 2.4350649350649e-05*G0_1_2_1 - 0.000377435064935064*G0_1_2_2 + 0.000462662337662336*G0_2_0_0 - 0.000462662337662336*G0_2_0_2 - 2.43506493506491e-05*G0_2_1_1 - 0.000377435064935064*G0_2_1_2 - 0.000462662337662336*G0_2_2_0 - 0.000377435064935064*G0_2_2_1 - 0.00277597402597401*G0_2_2_2; + A[86] = A[85] + 0.00365259740259739*G0_0_0_0 + 0.000438311688311687*G0_0_0_1 + 0.000730519480519478*G0_0_0_2 + 0.000438311688311687*G0_0_1_0 - 0.000109577922077921*G0_0_1_1 + 7.30519480519479e-05*G0_0_1_2 + 0.000730519480519478*G0_0_2_0 + 7.30519480519479e-05*G0_0_2_1 + 0.000438311688311687*G0_1_0_0 - 0.000109577922077921*G0_1_0_1 + 7.30519480519479e-05*G0_1_0_2 - 0.000109577922077921*G0_1_1_0 - 0.000292207792207789*G0_1_1_1 + 7.30519480519479e-05*G0_1_2_0 - 7.30519480519476e-05*G0_1_2_2 + 0.000730519480519478*G0_2_0_0 + 7.30519480519479e-05*G0_2_0_1 + 7.30519480519479e-05*G0_2_1_0 - 7.30519480519477e-05*G0_2_1_2 - 7.30519480519476e-05*G0_2_2_1 - 0.000730519480519476*G0_2_2_2; + A[54] = A[45]; + A[10] = A[1]; + A[35] = A[86] - 0.00160714285714285*G0_0_0_0 - 0.000133928571428571*G0_0_0_1 - 0.000267857142857143*G0_0_0_2 - 0.000133928571428571*G0_0_1_0 + 0.00013392857142857*G0_0_1_1 - 0.000267857142857142*G0_0_2_0 + 0.000267857142857142*G0_0_2_2 - 0.000133928571428571*G0_1_0_0 + 0.00013392857142857*G0_1_0_1 + 0.00013392857142857*G0_1_1_0 - 0.000133928571428571*G0_1_1_2 - 0.000133928571428571*G0_1_2_1 + 0.000133928571428571*G0_1_2_2 - 0.000267857142857142*G0_2_0_0 + 0.000267857142857141*G0_2_0_2 - 0.000133928571428571*G0_2_1_1 + 0.000133928571428571*G0_2_1_2 + 0.000267857142857141*G0_2_2_0 + 0.000133928571428571*G0_2_2_1 + 0.00160714285714285*G0_2_2_2; + A[74] = A[86] - 0.00160714285714285*G0_0_0_0 - 0.000267857142857142*G0_0_0_1 - 0.000133928571428571*G0_0_0_2 - 0.000267857142857142*G0_0_1_0 + 0.000267857142857141*G0_0_1_1 - 0.000133928571428571*G0_0_2_0 + 0.00013392857142857*G0_0_2_2 - 0.000267857142857142*G0_1_0_0 + 0.000267857142857142*G0_1_0_1 + 0.000267857142857141*G0_1_1_0 + 0.00160714285714285*G0_1_1_1 + 0.000133928571428571*G0_1_1_2 + 0.000133928571428571*G0_1_2_1 - 0.000133928571428572*G0_1_2_2 - 0.000133928571428571*G0_2_0_0 + 0.00013392857142857*G0_2_0_2 + 0.000133928571428571*G0_2_1_1 - 0.000133928571428571*G0_2_1_2 + 0.00013392857142857*G0_2_2_0 - 0.000133928571428571*G0_2_2_1; + A[16] = -A[74] - 0.000941558441558438*G0_0_0_0 - 0.000300324675324674*G0_0_0_1 - 9.74025974025971e-05*G0_0_0_2 - 0.000300324675324674*G0_0_1_0 - 8.11688311688304e-06*G0_0_1_1 - 4.87012987012985e-05*G0_0_1_2 - 9.74025974025971e-05*G0_0_2_0 - 4.87012987012985e-05*G0_0_2_1 + 5.68181818181813e-05*G0_0_2_2 - 0.000300324675324674*G0_1_0_0 - 8.11688311688293e-06*G0_1_0_1 - 4.87012987012985e-05*G0_1_0_2 - 8.11688311688296e-06*G0_1_1_0 + 0.000811688311688308*G0_1_1_1 - 4.87012987012985e-05*G0_1_2_0 - 0.000174512987012987*G0_1_2_2 - 9.74025974025971e-05*G0_2_0_0 - 4.87012987012985e-05*G0_2_0_1 + 5.68181818181813e-05*G0_2_0_2 - 4.87012987012985e-05*G0_2_1_0 - 0.000174512987012987*G0_2_1_2 + 5.68181818181813e-05*G0_2_2_0 - 0.000174512987012987*G0_2_2_1 - 1.6233766233768e-05*G0_2_2_2; + A[51] = A[16] + 0.000925324675324671*G0_0_0_0 + 0.000125811688311688*G0_0_0_1 + 0.000154220779220779*G0_0_0_2 + 0.000125811688311688*G0_0_1_0 + 8.11688311688298e-06*G0_0_1_1 + 0.000154220779220779*G0_0_2_0 - 0.000154220779220779*G0_0_2_2 + 0.000125811688311688*G0_1_0_0 + 8.11688311688299e-06*G0_1_0_1 + 8.11688311688299e-06*G0_1_1_0 - 8.11688311688316e-06*G0_1_1_2 - 8.11688311688316e-06*G0_1_2_1 - 0.000125811688311688*G0_1_2_2 + 0.000154220779220779*G0_2_0_0 - 0.000154220779220779*G0_2_0_2 - 8.11688311688316e-06*G0_2_1_1 - 0.000125811688311688*G0_2_1_2 - 0.000154220779220779*G0_2_2_0 - 0.000125811688311688*G0_2_2_1 - 0.000925324675324672*G0_2_2_2; + A[15] = A[51]; + A[22] = A[16] + 0.000294913419913418*G0_0_0_0 + 4.41919191919189e-05*G0_0_0_1 - 6.76406926406931e-06*G0_0_0_2 + 4.41919191919189e-05*G0_0_1_0 + 1.98412698412696e-05*G0_0_1_1 - 9.46969696969701e-06*G0_0_1_2 - 6.7640692640693e-06*G0_0_2_0 - 9.46969696969701e-06*G0_0_2_1 + 1.35281385281347e-06*G0_0_2_2 + 4.41919191919189e-05*G0_1_0_0 + 1.98412698412696e-05*G0_1_0_1 - 9.46969696969701e-06*G0_1_0_2 + 1.98412698412696e-05*G0_1_1_0 + 0.000148809523809523*G0_1_1_1 + 2.97619047619046e-05*G0_1_1_2 - 9.46969696969701e-06*G0_1_2_0 + 2.97619047619046e-05*G0_1_2_1 + 9.87554112554106e-05*G0_1_2_2 - 6.7640692640693e-06*G0_2_0_0 - 9.46969696969701e-06*G0_2_0_1 + 1.35281385281347e-06*G0_2_0_2 - 9.46969696969701e-06*G0_2_1_0 + 2.97619047619046e-05*G0_2_1_1 + 9.87554112554106e-05*G0_2_1_2 + 1.35281385281347e-06*G0_2_2_0 + 9.87554112554106e-05*G0_2_2_1 + 0.00269751082251081*G0_2_2_2; + A[25] = A[22] + 0.000614177489177487*G0_0_0_0 + 8.16197691197687e-05*G0_0_0_1 + 4.32900432900433e-05*G0_0_0_2 + 8.16197691197687e-05*G0_0_1_0 + 4.50937950937917e-07*G0_0_1_1 - 2.70562770562768e-06*G0_0_1_2 + 4.32900432900433e-05*G0_0_2_0 - 2.70562770562768e-06*G0_0_2_1 - 0.000338203463203461*G0_0_2_2 + 8.16197691197687e-05*G0_1_0_0 + 4.50937950937917e-07*G0_1_0_1 - 2.70562770562768e-06*G0_1_0_2 + 4.5093795093791e-07*G0_1_1_0 - 0.000116341991341991*G0_1_1_1 - 3.78787878787877e-05*G0_1_1_2 - 2.70562770562768e-06*G0_1_2_0 - 3.78787878787877e-05*G0_1_2_1 - 0.000257034632034631*G0_1_2_2 + 4.32900432900433e-05*G0_2_0_0 - 2.70562770562768e-06*G0_2_0_1 - 0.000338203463203461*G0_2_0_2 - 2.70562770562768e-06*G0_2_1_0 - 3.78787878787877e-05*G0_2_1_1 - 0.000257034632034631*G0_2_1_2 - 0.000338203463203461*G0_2_2_0 - 0.000257034632034631*G0_2_2_1 - 0.00461309523809521*G0_2_2_2; + A[40] = A[22] - 0.000148809523809523*G0_0_0_0 - 1.98412698412697e-05*G0_0_0_1 - 2.97619047619046e-05*G0_0_0_2 - 1.98412698412697e-05*G0_0_1_0 - 4.41919191919189e-05*G0_0_1_1 + 9.469696969697e-06*G0_0_1_2 - 2.97619047619046e-05*G0_0_2_0 + 9.469696969697e-06*G0_0_2_1 - 9.87554112554105e-05*G0_0_2_2 - 1.98412698412697e-05*G0_1_0_0 - 4.41919191919189e-05*G0_1_0_1 + 9.46969696969699e-06*G0_1_0_2 - 4.41919191919189e-05*G0_1_1_0 - 0.000294913419913418*G0_1_1_1 + 6.76406926406945e-06*G0_1_1_2 + 9.46969696969699e-06*G0_1_2_0 + 6.76406926406945e-06*G0_1_2_1 - 1.35281385281347e-06*G0_1_2_2 - 2.97619047619046e-05*G0_2_0_0 + 9.469696969697e-06*G0_2_0_1 - 9.87554112554105e-05*G0_2_0_2 + 9.469696969697e-06*G0_2_1_0 + 6.76406926406943e-06*G0_2_1_1 - 1.35281385281347e-06*G0_2_1_2 - 9.87554112554105e-05*G0_2_2_0 - 1.35281385281347e-06*G0_2_2_1 - 0.00269751082251081*G0_2_2_2; + A[4] = A[40]; + A[32] = A[22] - 0.000116341991341991*G0_0_0_0 + 4.50937950937924e-07*G0_0_0_1 - 3.78787878787877e-05*G0_0_0_2 + 4.50937950937937e-07*G0_0_1_0 + 8.16197691197687e-05*G0_0_1_1 - 2.70562770562768e-06*G0_0_1_2 - 3.78787878787877e-05*G0_0_2_0 - 2.70562770562768e-06*G0_0_2_1 - 0.000257034632034631*G0_0_2_2 + 4.50937950937931e-07*G0_1_0_0 + 8.16197691197687e-05*G0_1_0_1 - 2.70562770562769e-06*G0_1_0_2 + 8.16197691197687e-05*G0_1_1_0 + 0.000614177489177486*G0_1_1_1 + 4.32900432900432e-05*G0_1_1_2 - 2.70562770562769e-06*G0_1_2_0 + 4.32900432900432e-05*G0_1_2_1 - 0.000338203463203462*G0_1_2_2 - 3.78787878787877e-05*G0_2_0_0 - 2.70562770562769e-06*G0_2_0_1 - 0.000257034632034631*G0_2_0_2 - 2.70562770562768e-06*G0_2_1_0 + 4.32900432900432e-05*G0_2_1_1 - 0.000338203463203461*G0_2_1_2 - 0.000257034632034631*G0_2_2_0 - 0.000338203463203461*G0_2_2_1 - 0.00461309523809521*G0_2_2_2; + A[92] = A[22] + 0.000395021645021643*G0_0_0_0 + 0.00021554834054834*G0_0_0_1 - 5.41125541125528e-06*G0_0_0_2 + 0.00021554834054834*G0_0_1_0 + 0.00021554834054834*G0_0_1_1 + 5.41125541125542e-06*G0_0_1_2 - 5.41125541125528e-06*G0_0_2_0 + 5.41125541125542e-06*G0_0_2_1 - 0.000297619047619046*G0_0_2_2 + 0.00021554834054834*G0_1_0_0 + 0.00021554834054834*G0_1_0_1 + 5.41125541125541e-06*G0_1_0_2 + 0.00021554834054834*G0_1_1_0 + 0.000395021645021643*G0_1_1_1 - 5.41125541125535e-06*G0_1_1_2 + 5.41125541125543e-06*G0_1_2_0 - 5.41125541125535e-06*G0_1_2_1 - 0.000297619047619046*G0_1_2_2 - 5.4112554112553e-06*G0_2_0_0 + 5.41125541125542e-06*G0_2_0_1 - 0.000297619047619046*G0_2_0_2 + 5.41125541125541e-06*G0_2_1_0 - 5.4112554112554e-06*G0_2_1_1 - 0.000297619047619046*G0_2_1_2 - 0.000297619047619046*G0_2_2_0 - 0.000297619047619046*G0_2_2_1 - 0.00327380952380951*G0_2_2_2; + A[26] = -A[92] + 6.49350649350648e-05*G0_0_0_0 + 0.000142045454545454*G0_0_0_1 - 7.30519480519478e-05*G0_0_0_2 + 0.000142045454545454*G0_0_1_0 + 0.000178571428571428*G0_0_1_1 - 8.11688311688311e-06*G0_0_1_2 - 7.30519480519478e-05*G0_0_2_0 - 8.11688311688312e-06*G0_0_2_1 + 8.11688311688301e-05*G0_0_2_2 + 0.000142045454545454*G0_1_0_0 + 0.000178571428571428*G0_1_0_1 - 8.11688311688311e-06*G0_1_0_2 + 0.000178571428571428*G0_1_1_0 + 0.00039366883116883*G0_1_1_1 + 8.11688311688306e-06*G0_1_1_2 - 8.1168831168831e-06*G0_1_2_0 + 8.11688311688306e-06*G0_1_2_1 - 7.30519480519478e-05*G0_2_0_0 - 8.11688311688312e-06*G0_2_0_1 + 8.11688311688301e-05*G0_2_0_2 - 8.11688311688314e-06*G0_2_1_0 + 8.116883116883e-06*G0_2_1_1 + 8.11688311688301e-05*G0_2_2_0 + 0.00259740259740258*G0_2_2_2; + A[61] = A[16]; + A[2] = 0.00025703463203463*G0_0_0_0 + 8.11688311688304e-06*G0_0_0_1 + 3.24675324675323e-05*G0_0_0_2 + 8.11688311688304e-06*G0_0_1_0 + 2.25468975468973e-06*G0_0_1_1 + 3.24675324675323e-05*G0_0_2_0 + 3.24675324675323e-05*G0_0_2_2 + 8.11688311688304e-06*G0_1_0_0 + 2.25468975468973e-06*G0_1_0_1 + 2.25468975468973e-06*G0_1_1_0 + 5.00541125541123e-05*G0_1_1_1 + 2.25468975468973e-06*G0_1_1_2 + 2.25468975468973e-06*G0_1_2_1 + 8.11688311688304e-06*G0_1_2_2 + 3.24675324675323e-05*G0_2_0_0 + 3.24675324675323e-05*G0_2_0_2 + 2.25468975468973e-06*G0_2_1_1 + 8.11688311688304e-06*G0_2_1_2 + 3.24675324675323e-05*G0_2_2_0 + 8.11688311688304e-06*G0_2_2_1 + 0.00025703463203463*G0_2_2_2; + A[48] = A[73] + 0.000438311688311688*G0_0_0_0 - 0.000109577922077921*G0_0_0_1 + 7.3051948051948e-05*G0_0_0_2 - 0.000109577922077921*G0_0_1_0 - 0.00029220779220779*G0_0_1_1 + 7.3051948051948e-05*G0_0_2_0 - 7.30519480519478e-05*G0_0_2_2 - 0.000109577922077921*G0_1_0_0 - 0.00029220779220779*G0_1_0_1 - 0.00029220779220779*G0_1_1_0 + 0.000292207792207792*G0_1_1_2 + 0.000292207792207792*G0_1_2_1 + 0.000109577922077922*G0_1_2_2 + 7.3051948051948e-05*G0_2_0_0 - 7.30519480519478e-05*G0_2_0_2 + 0.000292207792207792*G0_2_1_1 + 0.000109577922077922*G0_2_1_2 - 7.30519480519478e-05*G0_2_2_0 + 0.000109577922077922*G0_2_2_1 - 0.000438311688311686*G0_2_2_2; + A[30] = A[40] + 8.11688311688308e-06*G0_0_0_1 - 8.11688311688311e-06*G0_0_0_2 + 8.11688311688309e-06*G0_0_1_0 + 0.000125811688311688*G0_0_1_1 - 8.11688311688311e-06*G0_0_2_0 - 0.000125811688311688*G0_0_2_2 + 8.11688311688309e-06*G0_1_0_0 + 0.000125811688311688*G0_1_0_1 + 0.000125811688311688*G0_1_1_0 + 0.000925324675324671*G0_1_1_1 + 0.000154220779220779*G0_1_1_2 + 0.000154220779220779*G0_1_2_1 - 0.000154220779220779*G0_1_2_2 - 8.11688311688311e-06*G0_2_0_0 - 0.000125811688311688*G0_2_0_2 + 0.000154220779220779*G0_2_1_1 - 0.000154220779220779*G0_2_1_2 - 0.000125811688311688*G0_2_2_0 - 0.000154220779220779*G0_2_2_1 - 0.000925324675324672*G0_2_2_2; + A[69] = A[30] - 0.00142045454545454*G0_0_0_0 - 0.000608766233766231*G0_0_0_1 + 0.00042207792207792*G0_0_0_2 - 0.000608766233766231*G0_0_1_0 - 0.000556006493506491*G0_0_1_1 + 0.00018262987012987*G0_0_1_2 + 0.00042207792207792*G0_0_2_0 + 0.00018262987012987*G0_0_2_1 + 0.00176136363636363*G0_0_2_2 - 0.000608766233766232*G0_1_0_0 - 0.000556006493506491*G0_1_0_1 + 0.00018262987012987*G0_1_0_2 - 0.000556006493506491*G0_1_1_0 - 0.00132305194805194*G0_1_1_1 + 4.05844155844167e-06*G0_1_1_2 + 0.00018262987012987*G0_1_2_0 + 4.05844155844175e-06*G0_1_2_1 + 0.00110795454545454*G0_1_2_2 + 0.00042207792207792*G0_2_0_0 + 0.00018262987012987*G0_2_0_1 + 0.00176136363636363*G0_2_0_2 + 0.00018262987012987*G0_2_1_0 + 4.05844155844167e-06*G0_2_1_1 + 0.00110795454545454*G0_2_1_2 + 0.00176136363636363*G0_2_2_0 + 0.00110795454545454*G0_2_2_1 + 0.00530032467532466*G0_2_2_2; + A[11] = A[30] + 0.000148809523809523*G0_0_0_0 + 2.97619047619046e-05*G0_0_0_1 + 1.98412698412698e-05*G0_0_0_2 + 2.97619047619046e-05*G0_0_1_0 + 9.87554112554105e-05*G0_0_1_1 - 9.46969696969693e-06*G0_0_1_2 + 1.98412698412698e-05*G0_0_2_0 - 9.46969696969694e-06*G0_0_2_1 + 4.41919191919191e-05*G0_0_2_2 + 2.97619047619046e-05*G0_1_0_0 + 9.87554112554105e-05*G0_1_0_1 - 9.46969696969693e-06*G0_1_0_2 + 9.87554112554105e-05*G0_1_1_0 + 0.00269751082251081*G0_1_1_1 + 1.35281385281336e-06*G0_1_1_2 - 9.46969696969694e-06*G0_1_2_0 + 1.35281385281339e-06*G0_1_2_1 - 6.76406926406929e-06*G0_1_2_2 + 1.98412698412698e-05*G0_2_0_0 - 9.46969696969694e-06*G0_2_0_1 + 4.41919191919191e-05*G0_2_0_2 - 9.46969696969694e-06*G0_2_1_0 + 1.35281385281336e-06*G0_2_1_1 - 6.76406926406928e-06*G0_2_1_2 + 4.41919191919191e-05*G0_2_2_0 - 6.76406926406927e-06*G0_2_2_1 + 0.000294913419913419*G0_2_2_2; + A[82] = A[11] - 0.000294913419913419*G0_0_0_0 + 6.76406926406916e-06*G0_0_0_1 - 4.41919191919191e-05*G0_0_0_2 + 6.76406926406916e-06*G0_0_1_0 - 1.35281385281374e-06*G0_0_1_1 + 9.46969696969692e-06*G0_0_1_2 - 4.41919191919191e-05*G0_0_2_0 + 9.46969696969693e-06*G0_0_2_1 - 1.98412698412697e-05*G0_0_2_2 + 6.76406926406916e-06*G0_1_0_0 - 1.35281385281374e-06*G0_1_0_1 + 9.46969696969693e-06*G0_1_0_2 - 1.35281385281371e-06*G0_1_1_0 - 0.00269751082251081*G0_1_1_1 - 9.87554112554105e-05*G0_1_1_2 + 9.46969696969693e-06*G0_1_2_0 - 9.87554112554105e-05*G0_1_2_1 - 2.97619047619046e-05*G0_1_2_2 - 4.41919191919191e-05*G0_2_0_0 + 9.46969696969693e-06*G0_2_0_1 - 1.98412698412697e-05*G0_2_0_2 + 9.46969696969693e-06*G0_2_1_0 - 9.87554112554105e-05*G0_2_1_1 - 2.97619047619046e-05*G0_2_1_2 - 1.98412698412697e-05*G0_2_2_0 - 2.97619047619046e-05*G0_2_2_1 - 0.000148809523809522*G0_2_2_2; + A[89] = A[69] + 0.00102272727272727*G0_0_0_1 - 0.00102272727272727*G0_0_0_2 + 0.00102272727272727*G0_0_1_0 + 0.00219155844155843*G0_0_1_1 - 0.00102272727272727*G0_0_2_0 - 0.00219155844155843*G0_0_2_2 + 0.00102272727272727*G0_1_0_0 + 0.00219155844155843*G0_1_0_1 + 0.00219155844155843*G0_1_1_0 + 0.00569805194805193*G0_1_1_1 + 0.000949675324675322*G0_1_1_2 + 0.000949675324675322*G0_1_2_1 - 0.000949675324675321*G0_1_2_2 - 0.00102272727272727*G0_2_0_0 - 0.00219155844155843*G0_2_0_2 + 0.000949675324675322*G0_2_1_1 - 0.000949675324675321*G0_2_1_2 - 0.00219155844155843*G0_2_2_0 - 0.000949675324675321*G0_2_2_1 - 0.00569805194805193*G0_2_2_2; + A[93] = A[89] + 0.000876623376623373*G0_0_0_0 - 0.000219155844155844*G0_0_0_1 + 0.000146103896103895*G0_0_0_2 - 0.000219155844155844*G0_0_1_0 - 0.000584415584415583*G0_0_1_1 + 0.000146103896103895*G0_0_2_0 - 0.000146103896103897*G0_0_2_2 - 0.000219155844155844*G0_1_0_0 - 0.000584415584415583*G0_1_0_1 - 0.000584415584415583*G0_1_1_0 + 0.000584415584415581*G0_1_1_2 + 0.000584415584415581*G0_1_2_1 + 0.000219155844155842*G0_1_2_2 + 0.000146103896103895*G0_2_0_0 - 0.000146103896103897*G0_2_0_2 + 0.000584415584415581*G0_2_1_1 + 0.000219155844155842*G0_2_1_2 - 0.000146103896103897*G0_2_2_0 + 0.000219155844155842*G0_2_2_1 - 0.000876623376623376*G0_2_2_2; + A[94] = A[69] + 0.000876623376623374*G0_0_0_0 + 0.000146103896103895*G0_0_0_1 - 0.000219155844155843*G0_0_0_2 + 0.000146103896103895*G0_0_1_0 - 0.000146103896103896*G0_0_1_1 - 0.000219155844155843*G0_0_2_0 - 0.000584415584415582*G0_0_2_2 + 0.000146103896103896*G0_1_0_0 - 0.000146103896103895*G0_1_0_1 - 0.000146103896103895*G0_1_1_0 - 0.000876623376623372*G0_1_1_1 + 0.000219155844155844*G0_1_1_2 + 0.000219155844155843*G0_1_2_1 + 0.000584415584415582*G0_1_2_2 - 0.000219155844155843*G0_2_0_0 - 0.000584415584415582*G0_2_0_2 + 0.000219155844155843*G0_2_1_1 + 0.000584415584415582*G0_2_1_2 - 0.000584415584415582*G0_2_2_0 + 0.000584415584415582*G0_2_2_1; + A[72] = A[82] + 0.000925324675324671*G0_0_0_0 + 0.000154220779220778*G0_0_0_1 + 0.000125811688311688*G0_0_0_2 + 0.000154220779220778*G0_0_1_0 - 0.000154220779220778*G0_0_1_1 + 0.000125811688311688*G0_0_2_0 + 8.11688311688307e-06*G0_0_2_2 + 0.000154220779220778*G0_1_0_0 - 0.000154220779220778*G0_1_0_1 - 0.000154220779220778*G0_1_1_0 - 0.000925324675324671*G0_1_1_1 - 0.000125811688311688*G0_1_1_2 - 0.000125811688311688*G0_1_2_1 - 8.11688311688314e-06*G0_1_2_2 + 0.000125811688311688*G0_2_0_0 + 8.11688311688307e-06*G0_2_0_2 - 0.000125811688311688*G0_2_1_1 - 8.11688311688313e-06*G0_2_1_2 + 8.11688311688307e-06*G0_2_2_0 - 8.11688311688313e-06*G0_2_2_1; + A[41] = A[11] - 0.000116341991341991*G0_0_0_0 - 3.78787878787876e-05*G0_0_0_1 + 4.50937950937978e-07*G0_0_0_2 - 3.78787878787876e-05*G0_0_1_0 - 0.00025703463203463*G0_0_1_1 - 2.70562770562759e-06*G0_0_1_2 + 4.50937950937992e-07*G0_0_2_0 - 2.70562770562759e-06*G0_0_2_1 + 8.16197691197688e-05*G0_0_2_2 - 3.78787878787876e-05*G0_1_0_0 - 0.00025703463203463*G0_1_0_1 - 2.70562770562759e-06*G0_1_0_2 - 0.00025703463203463*G0_1_1_0 - 0.00461309523809521*G0_1_1_1 - 0.000338203463203461*G0_1_1_2 - 2.70562770562759e-06*G0_1_2_0 - 0.000338203463203461*G0_1_2_1 + 4.32900432900433e-05*G0_1_2_2 + 4.50937950937992e-07*G0_2_0_0 - 2.70562770562759e-06*G0_2_0_1 + 8.16197691197688e-05*G0_2_0_2 - 2.70562770562759e-06*G0_2_1_0 - 0.000338203463203461*G0_2_1_1 + 4.32900432900433e-05*G0_2_1_2 + 8.16197691197688e-05*G0_2_2_0 + 4.32900432900433e-05*G0_2_2_1 + 0.000614177489177486*G0_2_2_2; + A[97] = A[89] + 0.0065746753246753*G0_0_0_0 + 0.00131493506493506*G0_0_0_1 + 0.00175324675324675*G0_0_0_2 + 0.00131493506493506*G0_0_1_0 - 0.00131493506493506*G0_0_1_1 + 0.00175324675324675*G0_0_2_0 + 0.000657467532467529*G0_0_2_2 + 0.00131493506493506*G0_1_0_0 - 0.00131493506493506*G0_1_0_1 - 0.00131493506493506*G0_1_1_0 - 0.0065746753246753*G0_1_1_1 - 0.00175324675324675*G0_1_1_2 - 0.00175324675324675*G0_1_2_1 - 0.000657467532467531*G0_1_2_2 + 0.00175324675324675*G0_2_0_0 + 0.000657467532467529*G0_2_0_2 - 0.00175324675324675*G0_2_1_1 - 0.000657467532467531*G0_2_1_2 + 0.000657467532467529*G0_2_2_0 - 0.000657467532467531*G0_2_2_1; + A[71] = A[11] + 0.000614177489177485*G0_0_0_0 + 4.32900432900429e-05*G0_0_0_1 + 8.16197691197687e-05*G0_0_0_2 + 4.32900432900429e-05*G0_0_1_0 - 0.000338203463203461*G0_0_1_1 - 2.70562770562769e-06*G0_0_1_2 + 8.16197691197687e-05*G0_0_2_0 - 2.70562770562768e-06*G0_0_2_1 + 4.50937950937876e-07*G0_0_2_2 + 4.32900432900429e-05*G0_1_0_0 - 0.000338203463203461*G0_1_0_1 - 2.7056277056277e-06*G0_1_0_2 - 0.000338203463203461*G0_1_1_0 - 0.00461309523809521*G0_1_1_1 - 0.000257034632034631*G0_1_1_2 - 2.70562770562769e-06*G0_1_2_0 - 0.000257034632034631*G0_1_2_1 - 3.78787878787877e-05*G0_1_2_2 + 8.16197691197687e-05*G0_2_0_0 - 2.70562770562768e-06*G0_2_0_1 + 4.50937950937863e-07*G0_2_0_2 - 2.70562770562769e-06*G0_2_1_0 - 0.000257034632034631*G0_2_1_1 - 3.78787878787877e-05*G0_2_1_2 + 4.5093795093787e-07*G0_2_2_0 - 3.78787878787878e-05*G0_2_2_1 - 0.000116341991341991*G0_2_2_2; + A[27] = A[72]; + A[28] = A[82]; + A[98] = A[89]; + A[62] = A[26]; + A[14] = A[41]; + A[39] = A[93]; + A[23] = A[32]; + A[19] = A[11] + 0.000395021645021643*G0_0_0_0 - 5.41125541125563e-06*G0_0_0_1 + 0.00021554834054834*G0_0_0_2 - 5.41125541125563e-06*G0_0_1_0 - 0.000297619047619046*G0_0_1_1 + 5.41125541125527e-06*G0_0_1_2 + 0.00021554834054834*G0_0_2_0 + 5.41125541125528e-06*G0_0_2_1 + 0.00021554834054834*G0_0_2_2 - 5.41125541125565e-06*G0_1_0_0 - 0.000297619047619046*G0_1_0_1 + 5.41125541125527e-06*G0_1_0_2 - 0.000297619047619046*G0_1_1_0 - 0.00327380952380951*G0_1_1_1 - 0.000297619047619046*G0_1_1_2 + 5.41125541125526e-06*G0_1_2_0 - 0.000297619047619046*G0_1_2_1 - 5.41125541125535e-06*G0_1_2_2 + 0.00021554834054834*G0_2_0_0 + 5.41125541125528e-06*G0_2_0_1 + 0.00021554834054834*G0_2_0_2 + 5.41125541125528e-06*G0_2_1_0 - 0.000297619047619046*G0_2_1_1 - 5.41125541125532e-06*G0_2_1_2 + 0.00021554834054834*G0_2_2_0 - 5.41125541125536e-06*G0_2_2_1 + 0.000395021645021644*G0_2_2_2; + A[31] = -A[19] + 0.000393668831168829*G0_0_0_0 + 8.11688311688269e-06*G0_0_0_1 + 0.000178571428571428*G0_0_0_2 + 8.11688311688269e-06*G0_0_1_0 - 8.11688311688329e-06*G0_0_1_2 + 0.000178571428571428*G0_0_2_0 - 8.11688311688329e-06*G0_0_2_1 + 0.000142045454545454*G0_0_2_2 + 8.11688311688268e-06*G0_1_0_0 - 8.1168831168833e-06*G0_1_0_2 + 0.00259740259740258*G0_1_1_1 + 8.11688311688301e-05*G0_1_1_2 - 8.11688311688331e-06*G0_1_2_0 + 8.11688311688301e-05*G0_1_2_1 - 7.30519480519478e-05*G0_1_2_2 + 0.000178571428571428*G0_2_0_0 - 8.11688311688329e-06*G0_2_0_1 + 0.000142045454545454*G0_2_0_2 - 8.1168831168833e-06*G0_2_1_0 + 8.11688311688301e-05*G0_2_1_1 - 7.30519480519478e-05*G0_2_1_2 + 0.000142045454545454*G0_2_2_0 - 7.30519480519478e-05*G0_2_2_1 + 6.4935064935065e-05*G0_2_2_2; + A[13] = A[31]; + A[87] = A[78]; + A[42] = -A[92] + 0.00039366883116883*G0_0_0_0 + 0.000178571428571428*G0_0_0_1 + 8.11688311688311e-06*G0_0_0_2 + 0.000178571428571428*G0_0_1_0 + 0.000142045454545454*G0_0_1_1 - 8.11688311688311e-06*G0_0_1_2 + 8.11688311688311e-06*G0_0_2_0 - 8.11688311688311e-06*G0_0_2_1 + 0.000178571428571428*G0_1_0_0 + 0.000142045454545454*G0_1_0_1 - 8.11688311688311e-06*G0_1_0_2 + 0.000142045454545454*G0_1_1_0 + 6.49350649350649e-05*G0_1_1_1 - 7.30519480519479e-05*G0_1_1_2 - 8.11688311688309e-06*G0_1_2_0 - 7.30519480519479e-05*G0_1_2_1 + 8.11688311688299e-05*G0_1_2_2 + 8.11688311688308e-06*G0_2_0_0 - 8.11688311688311e-06*G0_2_0_1 - 8.11688311688312e-06*G0_2_1_0 - 7.3051948051948e-05*G0_2_1_1 + 8.11688311688299e-05*G0_2_1_2 + 8.11688311688299e-05*G0_2_2_1 + 0.00259740259740258*G0_2_2_2; + A[96] = A[69]; + A[65] = A[78] + 4.87012987012989e-05*G0_0_0_1 - 4.87012987012996e-05*G0_0_0_2 + 4.87012987012989e-05*G0_0_1_0 + 0.000353084415584415*G0_0_1_1 - 4.87012987012996e-05*G0_0_2_0 - 0.000353084415584415*G0_0_2_2 + 4.87012987012988e-05*G0_1_0_0 + 0.000353084415584414*G0_1_0_1 + 0.000353084415584414*G0_1_1_0 + 0.00295860389610388*G0_1_1_1 + 0.000304383116883116*G0_1_1_2 + 0.000304383116883116*G0_1_2_1 - 0.000304383116883116*G0_1_2_2 - 4.87012987012995e-05*G0_2_0_0 - 0.000353084415584415*G0_2_0_2 + 0.000304383116883116*G0_2_1_1 - 0.000304383116883116*G0_2_1_2 - 0.000353084415584415*G0_2_2_0 - 0.000304383116883116*G0_2_2_1 - 0.00295860389610388*G0_2_2_2; + A[53] = A[35]; + A[68] = A[86]; + A[17] = A[71]; + A[34] = A[78] + 0.00295860389610388*G0_0_0_0 + 0.000353084415584414*G0_0_0_1 + 0.000304383116883116*G0_0_0_2 + 0.000353084415584414*G0_0_1_0 + 4.87012987012993e-05*G0_0_1_1 + 0.000304383116883116*G0_0_2_0 - 0.000304383116883116*G0_0_2_2 + 0.000353084415584414*G0_1_0_0 + 4.87012987012991e-05*G0_1_0_1 + 4.87012987012991e-05*G0_1_1_0 - 4.87012987012987e-05*G0_1_1_2 - 4.87012987012987e-05*G0_1_2_1 - 0.000353084415584415*G0_1_2_2 + 0.000304383116883116*G0_2_0_0 - 0.000304383116883116*G0_2_0_2 - 4.87012987012987e-05*G0_2_1_1 - 0.000353084415584415*G0_2_1_2 - 0.000304383116883116*G0_2_2_0 - 0.000353084415584415*G0_2_2_1 - 0.00295860389610388*G0_2_2_2; + A[24] = A[42]; + A[84] = A[48]; + A[59] = A[69] + 0.0065746753246753*G0_0_0_0 + 0.00175324675324675*G0_0_0_1 + 0.00131493506493506*G0_0_0_2 + 0.00175324675324675*G0_0_1_0 + 0.000657467532467529*G0_0_1_1 + 0.00131493506493506*G0_0_2_0 - 0.00131493506493506*G0_0_2_2 + 0.00175324675324675*G0_1_0_0 + 0.000657467532467529*G0_1_0_1 + 0.000657467532467529*G0_1_1_0 - 0.000657467532467531*G0_1_1_2 - 0.000657467532467531*G0_1_2_1 - 0.00175324675324675*G0_1_2_2 + 0.00131493506493506*G0_2_0_0 - 0.00131493506493506*G0_2_0_2 - 0.000657467532467531*G0_2_1_1 - 0.00175324675324675*G0_2_1_2 - 0.00131493506493506*G0_2_2_0 - 0.00175324675324675*G0_2_2_1 - 0.0065746753246753*G0_2_2_2; + A[47] = A[74]; + A[91] = A[19]; + A[56] = A[65]; + A[3] = A[30]; + A[12] = A[21]; + A[49] = A[94]; + A[29] = A[92]; + A[81] = -A[19] + 6.49350649350647e-05*G0_0_0_0 - 7.30519480519482e-05*G0_0_0_1 + 0.000142045454545454*G0_0_0_2 - 7.30519480519482e-05*G0_0_1_0 + 8.11688311688296e-05*G0_0_1_1 - 8.11688311688329e-06*G0_0_1_2 + 0.000142045454545454*G0_0_2_0 - 8.11688311688329e-06*G0_0_2_1 + 0.000178571428571428*G0_0_2_2 - 7.30519480519482e-05*G0_1_0_0 + 8.11688311688295e-05*G0_1_0_1 - 8.11688311688331e-06*G0_1_0_2 + 8.11688311688296e-05*G0_1_1_0 + 0.00259740259740258*G0_1_1_1 - 8.11688311688331e-06*G0_1_2_0 + 8.11688311688306e-06*G0_1_2_2 + 0.000142045454545454*G0_2_0_0 - 8.11688311688329e-06*G0_2_0_1 + 0.000178571428571428*G0_2_0_2 - 8.1168831168833e-06*G0_2_1_0 + 8.11688311688308e-06*G0_2_1_2 + 0.000178571428571428*G0_2_2_0 + 8.11688311688306e-06*G0_2_2_1 + 0.00039366883116883*G0_2_2_2; + A[63] = A[36]; + A[0] = A[51] + 0.00269751082251081*G0_0_0_0 + 9.87554112554107e-05*G0_0_0_1 + 1.35281385281352e-06*G0_0_0_2 + 9.87554112554107e-05*G0_0_1_0 + 2.97619047619046e-05*G0_0_1_1 - 9.46969696969692e-06*G0_0_1_2 + 1.35281385281352e-06*G0_0_2_0 - 9.46969696969692e-06*G0_0_2_1 - 6.76406926406928e-06*G0_0_2_2 + 9.87554112554107e-05*G0_1_0_0 + 2.97619047619046e-05*G0_1_0_1 - 9.46969696969692e-06*G0_1_0_2 + 2.97619047619046e-05*G0_1_1_0 + 0.000148809523809523*G0_1_1_1 + 1.98412698412698e-05*G0_1_1_2 - 9.46969696969692e-06*G0_1_2_0 + 1.98412698412698e-05*G0_1_2_1 + 4.41919191919192e-05*G0_1_2_2 + 1.35281385281349e-06*G0_2_0_0 - 9.46969696969692e-06*G0_2_0_1 - 6.76406926406927e-06*G0_2_0_2 - 9.46969696969692e-06*G0_2_1_0 + 1.98412698412698e-05*G0_2_1_1 + 4.41919191919191e-05*G0_2_1_2 - 6.76406926406927e-06*G0_2_2_0 + 4.41919191919191e-05*G0_2_2_1 + 0.000294913419913419*G0_2_2_2; + A[90] = A[0] - 0.00327380952380951*G0_0_0_0 - 0.000297619047619046*G0_0_0_1 - 0.000297619047619046*G0_0_0_2 - 0.000297619047619046*G0_0_1_0 - 5.41125541125528e-06*G0_0_1_1 + 5.41125541125546e-06*G0_0_1_2 - 0.000297619047619046*G0_0_2_0 + 5.41125541125548e-06*G0_0_2_1 - 5.41125541125526e-06*G0_0_2_2 - 0.000297619047619046*G0_1_0_0 - 5.41125541125529e-06*G0_1_0_1 + 5.41125541125545e-06*G0_1_0_2 - 5.4112554112553e-06*G0_1_1_0 + 0.000395021645021644*G0_1_1_1 + 0.00021554834054834*G0_1_1_2 + 5.41125541125546e-06*G0_1_2_0 + 0.00021554834054834*G0_1_2_1 + 0.00021554834054834*G0_1_2_2 - 0.000297619047619046*G0_2_0_0 + 5.41125541125546e-06*G0_2_0_1 - 5.41125541125527e-06*G0_2_0_2 + 5.41125541125548e-06*G0_2_1_0 + 0.00021554834054834*G0_2_1_1 + 0.00021554834054834*G0_2_1_2 - 5.41125541125526e-06*G0_2_2_0 + 0.00021554834054834*G0_2_2_1 + 0.000395021645021644*G0_2_2_2; + A[7] = -A[90] + 0.00259740259740258*G0_0_0_0 + 8.11688311688303e-05*G0_0_0_1 + 8.11688311688303e-05*G0_0_1_0 - 7.30519480519477e-05*G0_0_1_1 - 8.1168831168831e-06*G0_0_1_2 - 8.11688311688306e-06*G0_0_2_1 + 8.1168831168831e-06*G0_0_2_2 + 8.11688311688304e-05*G0_1_0_0 - 7.30519480519477e-05*G0_1_0_1 - 8.1168831168831e-06*G0_1_0_2 - 7.30519480519477e-05*G0_1_1_0 + 6.49350649350652e-05*G0_1_1_1 + 0.000142045454545454*G0_1_1_2 - 8.11688311688308e-06*G0_1_2_0 + 0.000142045454545454*G0_1_2_1 + 0.000178571428571428*G0_1_2_2 - 8.11688311688309e-06*G0_2_0_1 + 8.1168831168831e-06*G0_2_0_2 - 8.11688311688308e-06*G0_2_1_0 + 0.000142045454545454*G0_2_1_1 + 0.000178571428571428*G0_2_1_2 + 8.11688311688311e-06*G0_2_2_0 + 0.000178571428571428*G0_2_2_1 + 0.00039366883116883*G0_2_2_2; + A[60] = A[0] - 0.00461309523809521*G0_0_0_0 - 0.000257034632034631*G0_0_0_1 - 0.000338203463203461*G0_0_0_2 - 0.000257034632034631*G0_0_1_0 - 3.78787878787876e-05*G0_0_1_1 - 2.70562770562761e-06*G0_0_1_2 - 0.000338203463203461*G0_0_2_0 - 2.70562770562761e-06*G0_0_2_1 + 4.32900432900433e-05*G0_0_2_2 - 0.000257034632034631*G0_1_0_0 - 3.78787878787876e-05*G0_1_0_1 - 2.70562770562761e-06*G0_1_0_2 - 3.78787878787876e-05*G0_1_1_0 - 0.000116341991341991*G0_1_1_1 + 4.50937950937985e-07*G0_1_1_2 - 2.70562770562761e-06*G0_1_2_0 + 4.50937950937985e-07*G0_1_2_1 + 8.16197691197689e-05*G0_1_2_2 - 0.000338203463203461*G0_2_0_0 - 2.70562770562761e-06*G0_2_0_1 + 4.32900432900433e-05*G0_2_0_2 - 2.70562770562761e-06*G0_2_1_0 + 4.50937950937992e-07*G0_2_1_1 + 8.16197691197689e-05*G0_2_1_2 + 4.32900432900433e-05*G0_2_2_0 + 8.16197691197689e-05*G0_2_2_1 + 0.000614177489177487*G0_2_2_2; + A[75] = A[90] + 0.00543831168831166*G0_0_0_0 + 0.00129870129870129*G0_0_0_1 + 0.00129870129870129*G0_0_0_2 + 0.00129870129870129*G0_0_1_0 + 0.000426136363636361*G0_0_1_1 + 0.000284090909090908*G0_0_1_2 + 0.00129870129870129*G0_0_2_0 + 0.000284090909090908*G0_0_2_1 + 0.000426136363636362*G0_0_2_2 + 0.00129870129870129*G0_1_0_0 + 0.000426136363636361*G0_1_0_1 + 0.000284090909090908*G0_1_0_2 + 0.000426136363636361*G0_1_1_0 - 1.62337662337663e-05*G0_1_1_1 - 8.11688311688316e-06*G0_1_1_2 + 0.000284090909090908*G0_1_2_0 - 8.11688311688321e-06*G0_1_2_1 - 8.11688311688305e-06*G0_1_2_2 + 0.00129870129870129*G0_2_0_0 + 0.000284090909090908*G0_2_0_1 + 0.000426136363636362*G0_2_0_2 + 0.000284090909090908*G0_2_1_0 - 8.11688311688321e-06*G0_2_1_1 - 8.11688311688305e-06*G0_2_1_2 + 0.000426136363636362*G0_2_2_0 - 8.11688311688305e-06*G0_2_2_1 - 1.62337662337658e-05*G0_2_2_2; + A[55] = A[75] + 0.00560064935064932*G0_0_0_0 + 0.00243506493506492*G0_0_0_2 - 0.00015827922077922*G0_0_1_1 + 0.00015827922077922*G0_0_1_2 + 0.00243506493506492*G0_0_2_0 + 0.00015827922077922*G0_0_2_1 + 0.00142451298701298*G0_0_2_2 - 0.00015827922077922*G0_1_0_1 + 0.00015827922077922*G0_1_0_2 - 0.00015827922077922*G0_1_1_0 - 0.000243506493506493*G0_1_1_1 + 0.00015827922077922*G0_1_2_0 + 0.000243506493506493*G0_1_2_2 + 0.00243506493506492*G0_2_0_0 + 0.00015827922077922*G0_2_0_1 + 0.00142451298701298*G0_2_0_2 + 0.00015827922077922*G0_2_1_0 + 0.000243506493506493*G0_2_1_2 + 0.00142451298701298*G0_2_2_0 + 0.000243506493506493*G0_2_2_1 + 0.00194805194805194*G0_2_2_2; + A[64] = A[75] - 0.00511363636363634*G0_0_0_0 - 0.000974025974025969*G0_0_0_1 - 0.000742694805194801*G0_0_0_2 - 0.000974025974025969*G0_0_1_0 - 0.000231331168831167*G0_0_1_1 - 0.000742694805194801*G0_0_2_0 + 0.000742694805194803*G0_0_2_2 - 0.000974025974025969*G0_1_0_0 - 0.000231331168831167*G0_1_0_1 - 0.000231331168831167*G0_1_1_0 + 0.000231331168831169*G0_1_1_2 + 0.000231331168831169*G0_1_2_1 + 0.000974025974025971*G0_1_2_2 - 0.000742694805194801*G0_2_0_0 + 0.000742694805194802*G0_2_0_2 + 0.000231331168831169*G0_2_1_1 + 0.000974025974025971*G0_2_1_2 + 0.000742694805194803*G0_2_2_0 + 0.000974025974025971*G0_2_2_1 + 0.00511363636363634*G0_2_2_2; + A[5] = -A[90] + 0.00259740259740258*G0_0_0_0 + 8.11688311688301e-05*G0_0_0_2 + 8.11688311688309e-06*G0_0_1_1 - 8.11688311688313e-06*G0_0_1_2 + 8.11688311688301e-05*G0_0_2_0 - 8.1168831168831e-06*G0_0_2_1 - 7.30519480519478e-05*G0_0_2_2 + 8.11688311688309e-06*G0_1_0_1 - 8.11688311688314e-06*G0_1_0_2 + 8.11688311688308e-06*G0_1_1_0 + 0.00039366883116883*G0_1_1_1 + 0.000178571428571428*G0_1_1_2 - 8.11688311688312e-06*G0_1_2_0 + 0.000178571428571428*G0_1_2_1 + 0.000142045454545454*G0_1_2_2 + 8.11688311688301e-05*G0_2_0_0 - 8.11688311688312e-06*G0_2_0_1 - 7.30519480519478e-05*G0_2_0_2 - 8.11688311688311e-06*G0_2_1_0 + 0.000178571428571428*G0_2_1_1 + 0.000142045454545454*G0_2_1_2 - 7.30519480519478e-05*G0_2_2_0 + 0.000142045454545454*G0_2_2_1 + 6.4935064935065e-05*G0_2_2_2; + A[8] = A[0] - 0.00461309523809521*G0_0_0_0 - 0.000338203463203461*G0_0_0_1 - 0.00025703463203463*G0_0_0_2 - 0.000338203463203461*G0_0_1_0 + 4.32900432900431e-05*G0_0_1_1 - 2.70562770562765e-06*G0_0_1_2 - 0.00025703463203463*G0_0_2_0 - 2.70562770562765e-06*G0_0_2_1 - 3.78787878787877e-05*G0_0_2_2 - 0.000338203463203461*G0_1_0_0 + 4.32900432900431e-05*G0_1_0_1 - 2.70562770562765e-06*G0_1_0_2 + 4.32900432900431e-05*G0_1_1_0 + 0.000614177489177486*G0_1_1_1 + 8.16197691197688e-05*G0_1_1_2 - 2.70562770562765e-06*G0_1_2_0 + 8.16197691197688e-05*G0_1_2_1 + 4.50937950937958e-07*G0_1_2_2 - 0.00025703463203463*G0_2_0_0 - 2.70562770562765e-06*G0_2_0_1 - 3.78787878787877e-05*G0_2_0_2 - 2.70562770562765e-06*G0_2_1_0 + 8.16197691197688e-05*G0_2_1_1 + 4.50937950937958e-07*G0_2_1_2 - 3.78787878787877e-05*G0_2_2_0 + 4.50937950937958e-07*G0_2_2_1 - 0.000116341991341991*G0_2_2_2; + A[83] = A[75] - 0.00511363636363634*G0_0_0_0 - 0.000742694805194801*G0_0_0_1 - 0.000974025974025969*G0_0_0_2 - 0.000742694805194801*G0_0_1_0 + 0.000742694805194801*G0_0_1_1 - 0.000974025974025969*G0_0_2_0 - 0.000231331168831168*G0_0_2_2 - 0.000742694805194801*G0_1_0_0 + 0.000742694805194801*G0_1_0_1 + 0.000742694805194801*G0_1_1_0 + 0.00511363636363634*G0_1_1_1 + 0.00097402597402597*G0_1_1_2 + 0.00097402597402597*G0_1_2_1 + 0.000231331168831168*G0_1_2_2 - 0.000974025974025969*G0_2_0_0 - 0.000231331168831168*G0_2_0_2 + 0.00097402597402597*G0_2_1_1 + 0.000231331168831168*G0_2_1_2 - 0.000231331168831168*G0_2_2_0 + 0.000231331168831168*G0_2_2_1; + A[46] = A[64]; + A[57] = A[75]; + A[80] = A[8]; + A[50] = A[5]; + A[70] = A[7]; + A[6] = A[60]; + A[9] = A[90]; + A[66] = A[55] - 0.00876623376623372*G0_0_0_0 - 0.000730519480519476*G0_0_0_1 - 0.00175324675324674*G0_0_0_2 - 0.000730519480519477*G0_0_1_0 - 7.30519480519474e-05*G0_0_1_1 - 0.00175324675324674*G0_0_2_0 + 0.00175324675324675*G0_0_2_2 - 0.000730519480519477*G0_1_0_0 - 7.30519480519475e-05*G0_1_0_1 - 7.30519480519475e-05*G0_1_1_0 + 7.3051948051948e-05*G0_1_1_2 + 7.3051948051948e-05*G0_1_2_1 + 0.000730519480519479*G0_1_2_2 - 0.00175324675324674*G0_2_0_0 + 0.00175324675324675*G0_2_0_2 + 7.30519480519481e-05*G0_2_1_1 + 0.000730519480519479*G0_2_1_2 + 0.00175324675324675*G0_2_2_0 + 0.000730519480519479*G0_2_2_1 + 0.00876623376623373*G0_2_2_2; + A[77] = A[55] + 0.00243506493506492*G0_0_0_1 - 0.00243506493506492*G0_0_0_2 + 0.00243506493506492*G0_0_1_0 + 0.0015827922077922*G0_0_1_1 - 0.00243506493506492*G0_0_2_0 - 0.0015827922077922*G0_0_2_2 + 0.00243506493506492*G0_1_0_0 + 0.0015827922077922*G0_1_0_1 + 0.0015827922077922*G0_1_1_0 + 0.00219155844155843*G0_1_1_1 + 0.000243506493506493*G0_1_1_2 + 0.000243506493506492*G0_1_2_1 - 0.000243506493506493*G0_1_2_2 - 0.00243506493506492*G0_2_0_0 - 0.0015827922077922*G0_2_0_2 + 0.000243506493506492*G0_2_1_1 - 0.000243506493506493*G0_2_1_2 - 0.0015827922077922*G0_2_2_0 - 0.000243506493506493*G0_2_2_1 - 0.00219155844155843*G0_2_2_2; + A[33] = A[55] - 0.0109577922077922*G0_0_0_0 - 0.000900974025974022*G0_0_0_1 - 0.00340909090909089*G0_0_0_2 - 0.000900974025974022*G0_0_1_0 + 0.000900974025974021*G0_0_1_1 - 0.00340909090909089*G0_0_2_0 - 0.00141233766233766*G0_0_2_2 - 0.000900974025974022*G0_1_0_0 + 0.000900974025974021*G0_1_0_1 + 0.000900974025974021*G0_1_1_0 + 0.0109577922077922*G0_1_1_1 + 0.00340909090909089*G0_1_1_2 + 0.00340909090909089*G0_1_2_1 + 0.00141233766233765*G0_1_2_2 - 0.00340909090909089*G0_2_0_0 - 0.00141233766233766*G0_2_0_2 + 0.00340909090909089*G0_2_1_1 + 0.00141233766233765*G0_2_1_2 - 0.00141233766233766*G0_2_2_0 + 0.00141233766233765*G0_2_2_1; + A[44] = A[66] - 0.00219155844155843*G0_0_0_0 - 0.000243506493506493*G0_0_0_1 - 0.0015827922077922*G0_0_0_2 - 0.000243506493506493*G0_0_1_0 + 0.000243506493506492*G0_0_1_1 - 0.0015827922077922*G0_0_2_0 - 0.00243506493506493*G0_0_2_2 - 0.000243506493506493*G0_1_0_0 + 0.000243506493506492*G0_1_0_1 + 0.000243506493506492*G0_1_1_0 + 0.00219155844155843*G0_1_1_1 + 0.0015827922077922*G0_1_1_2 + 0.0015827922077922*G0_1_2_1 + 0.00243506493506492*G0_1_2_2 - 0.0015827922077922*G0_2_0_0 - 0.00243506493506493*G0_2_0_2 + 0.0015827922077922*G0_2_1_1 + 0.00243506493506492*G0_2_1_2 - 0.00243506493506493*G0_2_2_0 + 0.00243506493506492*G0_2_2_1; + A[79] = A[97]; + A[38] = A[83]; + A[20] = A[2]; + A[18] = A[81]; + A[88] = A[66] + 0.00141233766233765*G0_0_0_1 - 0.00141233766233766*G0_0_0_2 + 0.00141233766233765*G0_0_1_0 + 0.00340909090909089*G0_0_1_1 - 0.00141233766233766*G0_0_2_0 - 0.0034090909090909*G0_0_2_2 + 0.00141233766233765*G0_1_0_0 + 0.00340909090909089*G0_1_0_1 + 0.00340909090909089*G0_1_1_0 + 0.0109577922077922*G0_1_1_1 + 0.000900974025974021*G0_1_1_2 + 0.000900974025974021*G0_1_2_1 - 0.000900974025974024*G0_1_2_2 - 0.00141233766233766*G0_2_0_0 - 0.0034090909090909*G0_2_0_2 + 0.000900974025974021*G0_2_1_1 - 0.000900974025974024*G0_2_1_2 - 0.0034090909090909*G0_2_2_0 - 0.000900974025974024*G0_2_2_1 - 0.0109577922077922*G0_2_2_2; + A[43] = A[34]; + A[95] = A[59]; + A[52] = A[25]; + } + + /// 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 mass_matrix_f3_p1_q3_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f3_p1_q3_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p1_q3_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1)))), 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 3; + } + + /// 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 mass_matrix_f3_p1_q3_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f3_p1_q3_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f3_p1_q3_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p1_q3_tensor_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p1_q3_tensor_finite_element_0(); + 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 mass_matrix_f3_p1_q3_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f3_p1_q3_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f3_p1_q3_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p1_q3_tensor_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p1_q3_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f3_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/mass_matrix_2d/mass_matrix_f3_p1_q4_excafe.h b/mass_matrix_2d/mass_matrix_f3_p1_q4_excafe.h new file mode 100644 index 0000000..ef3914b --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f3_p1_q4_excafe.h @@ -0,0 +1,619 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 1 minute and 20.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 = w[0][1]*w[1][1]*w[2][1]; + const double var_1 = -1.0000000000000000000000000*var_0; + const double var_2 = 0.0056437389770723107862427*var_1; + const double var_3 = -1.0000000000000000000000000*x[0][0]; + const double var_4 = x[1][0] + var_3; + const double var_5 = -1.0000000000000000000000000*x[0][1]; + const double var_6 = var_5 + x[2][1]; + const double var_7 = x[2][0] + var_3; + const double var_8 = var_5 + x[1][1]; + const double var_9 = var_4*var_6 + -1.0000000000000000000000000*var_7*var_8; + const double var_10 = std::abs(var_9); + const double var_11 = w[0][0]*w[1][2] + w[0][2]*w[1][0]; + const double var_12 = w[0][1]*w[1][0] + w[0][0]*w[1][1]; + const double var_13 = w[0][1]*w[1][2] + w[0][2]*w[1][1]; + const double var_14 = var_11*w[2][1] + var_13*w[2][0] + var_12*w[2][2]; + const double var_15 = 0.0000115316781983448651898*var_10*var_14; + const double var_16 = w[0][2]*w[1][2]*w[2][0] + var_11*w[2][2]; + const double var_17 = var_11*w[2][0] + w[0][0]*w[1][0]*w[2][2]; + const double var_18 = w[0][0]*w[1][0]*w[2][1] + var_12*w[2][0]; + const double var_19 = var_13*w[2][2] + w[0][2]*w[1][2]*w[2][1]; + const double var_20 = var_12*w[2][1] + w[0][1]*w[1][1]*w[2][0]; + const double var_21 = -1.0000000000000000000000000*var_20; + const double var_22 = w[0][1]*w[1][1]*w[2][2] + var_13*w[2][1]; + const double var_23 = -1.0000000000000000000000000*var_22; + const double var_24 = -0.2777777777777777901135892*w[0][1]*w[1][1]*w[2][1]; + const double var_25 = 0.0019769119769119771271026*w[0][0]*w[1][0]*w[2][0]; + const double var_26 = 0.0771717171717171690481507*w[0][2]*w[1][2]*w[2][2]; + const double var_27 = 0.0079365079365079360673718*var_21 + 0.0014862914862914862901971*var_18 + 0.0051659451659451663743661*var_17 + var_24 + 0.0181818181818181809350499*var_23 + 0.0117316017316017318083965*var_19 + 0.0135209235209235202612721*var_16 + var_26 + var_25; + A[19] = var_15 + 0.0042735042735042739342477*var_10*var_27; + const double var_28 = -0.0000251600251600251622621*var_10*var_14; + const double var_29 = -0.0000848534181867515124821*var_10*var_14; + const double var_30 = 1.4628571428571428558740308*w[0][2]*w[1][2]*w[2][2]; + const double var_31 = w[0][0]*w[1][0]*w[2][0]; + const double var_32 = 0.2285714285714285642914234*var_31; + const double var_33 = 71.0000000000000000000000000*w[0][1]*w[1][1]*w[2][1]; + const double var_34 = 0.2857142857142856984253854*var_33; + const double var_35 = 3.2857142857142855874030829*var_16 + 14.0000000000000000000000000*var_22; + const double var_36 = 3.4742857142857141994340964*var_20 + var_30 + 0.8628571428571428780784913*var_18 + 0.3200000000000000066613381*var_17 + 0.1600000000000000033306691*var_35 + var_34 + 0.6114285714285714323779075*var_19 + var_32; + A[71] = -0.0001726668393335059939996*var_10*var_36 + var_29; + const double var_37 = var_18 + var_0; + const double var_38 = var_20 + var_14; + const double var_39 = 0.0000184177961955739723319*var_10*var_14; + const double var_40 = -0.0000167733501066834381199*var_10*var_14; + const double var_41 = -1.0000000000000000000000000*var_16; + const double var_42 = -1.0000000000000000000000000*var_18; + const double var_43 = -1.0000000000000000000000000*var_19; + const double var_44 = 0.6666666666666666296592325*var_20; + const double var_45 = var_44 + var_22; + const double var_46 = -0.0010902677569344235760512*var_0; + const double var_47 = w[0][2]*w[1][2]*w[2][2]; + const double var_48 = -1.0000000000000000000000000*var_47; + const double var_49 = 0.0056437389770723107862427*var_48; + const double var_50 = -1.0000000000000000000000000*var_31; + const double var_51 = 0.0002565335898669231879873*var_50; + const double var_52 = 0.0005194805194805194800689*var_43 + -0.0010261343594676927519493*var_17 + var_51 + var_46 + var_49 + 0.0001346801346801346709828*var_42 + 0.0001539201539201539290554*var_45 + 0.0019240019240019240725353*var_41; + A[29] = 0.0769230769230769273470116*var_10*var_52 + var_40; + const double var_53 = 0.0000072972295194517415421*var_10*var_14; + const double var_54 = 0.0000236800236800236811325*var_10*var_14; + const double var_55 = 0.0398268398268398285400060*w[0][0]*w[1][0]*w[2][0]; + const double var_56 = 0.0034632034632034632004594*var_0; + const double var_57 = 0.0051948051948051948006890*var_41; + const double var_58 = 0.0259740259740259757381686*var_48; + const double var_59 = 0.1428571428571428492126927*var_20 + 0.1212121212121212154855243*var_43; + const double var_60 = 0.0024242424242424242403215*var_17 + var_55 + 0.0117748917748917748815618*var_18 + 0.0400000000000000008326673*var_59 + var_58 + 0.0001731601731601731600230*var_23 + var_56 + var_57; + A[132] = 0.0455840455840455863190108*var_10*var_60 + var_54; + A[188] = A[132]; + const double var_61 = 0.0398268398268398285400060*w[0][1]*w[1][1]*w[2][1]; + const double var_62 = 0.0051948051948051948006890*var_42; + const double var_63 = 0.0034632034632034632004594*var_47; + const double var_64 = 0.0259740259740259757381686*var_50; + const double var_65 = -1.0000000000000000000000000*var_17; + const double var_66 = 0.1428571428571428492126927*var_19 + 0.1212121212121212154855243*var_65; + const double var_67 = 0.0024242424242424242403215*var_20 + var_62 + var_64 + var_61 + 0.0400000000000000008326673*var_66 + var_63 + 0.0117748917748917748815618*var_22 + 0.0001731601731601731600230*var_41; + A[148] = var_54 + 0.0455840455840455863190108*var_10*var_67; + const double var_68 = var_20 + var_22; + const double var_69 = var_17 + var_16; + const double var_70 = var_18 + var_19; + const double var_71 = var_47 + var_31; + const double var_72 = 2.0000000000000000000000000*var_71; + const double var_73 = -1.0000000000000000000000000*var_70 + -1.0000000000000000000000000*var_72 + -0.8000000000000000444089210*var_68 + var_1 + 0.4000000000000000222044605*var_69; + const double var_74 = 0.0001124801124801124845324*var_10*var_14; + const double var_75 = -0.0413660413660413700531748*w[0][2]*w[1][2]*w[2][2]; + const double var_76 = 0.0317460317460317442694873*var_31; + const double var_77 = 0.8000000000000000444089210*w[0][1]*w[1][1]*w[2][1]; + const double var_78 = -0.0014430014430014430001914*var_77; + const double var_79 = 0.6666666666666666296592325*var_16; + const double var_80 = 0.0025974025974025974003445*var_20 + 0.0101010101010101018687015*var_79 + 0.0151996151996151990237749*var_17 + 0.0080808080808080808010718*var_18 + var_75 + var_76 + -0.0103896103896103896013781*var_19 + var_78 + -0.0039442039442039436222820*var_22; + A[119] = var_74 + 0.0615384615384615418776093*var_10*var_80; + A[217] = A[119]; + const double var_81 = 4.9333333333333335701809119*var_0; + const double var_82 = var_17 + var_47; + const double var_83 = var_14 + var_19; + const double var_84 = 0.6666666666666666296592325*var_22; + const double var_85 = var_20 + var_84; + const double var_86 = -0.0028860028860028860003828*var_31; + const double var_87 = 0.0246913580246913566540456*var_0; + const double var_88 = 0.0003527336860670194241402*var_83 + var_86 + 0.0007054673721340388482803*var_18 + -0.0011544011544011544001531*var_82 + 0.0051948051948051948006890*var_85 + var_87 + 0.0008658008658008658001148*var_41; + A[178] = 0.2461538461538461675104372*var_10*var_88; + A[206] = A[178]; + const double var_89 = var_0 + var_31; + const double var_90 = var_16 + var_19; + const double var_91 = var_20 + var_18; + const double var_92 = var_17 + var_22; + const double var_93 = 6.0158730158730158166235924*w[0][2]*w[1][2]*w[2][2] + -3.1785714285714283811046243*var_91 + -38.1984126984126959314380656*var_89 + -1.0277777777777776790912867*var_92 + 0.5515873015873015150489778*var_90; + const double var_94 = 2.0000000000000000000000000*var_89; + const double var_95 = var_91 + var_94; + const double var_96 = -0.0028860028860028860003828*var_47; + const double var_97 = 2.2121212121212123768998481*w[0][2]*w[1][2]*w[2][2] + -0.0222222222222222230703093*var_91 + -0.2383838383838383923052362*var_89 + -0.1727272727272727292913146*var_92 + 0.0363636363636363618700997*var_90; + const double var_98 = 0.1428571428571428492126927*var_17 + 0.1212121212121212154855243*var_21; + const double var_99 = -0.0001055734389067722415198*var_10*var_14; + const double var_100 = 0.7099567099567100081358717*w[0][0]*w[1][0]*w[2][0]; + const double var_101 = 1.7402597402597403952739796*w[0][2]*w[1][2]*w[2][2]; + const double var_102 = 0.0242424242424242424032155*var_0; + const double var_103 = 3.2857142857142855874030829*var_20 + 14.0000000000000000000000000*var_19; + const double var_104 = var_101 + 0.0121212121212121212016077*var_103 + var_100 + 0.1471861471861471981625868*var_17 + 0.1108225108225108224146993*var_18 + var_102 + 0.2285714285714285642914234*var_16 + 0.0372294372294372302722998*var_22; + A[113] = -0.0022792022792022790557420*var_10*var_104 + var_99; + const double var_105 = 1.3333333333333332593184650*var_71; + const double var_106 = var_14 + 1.3333333333333332593184650*var_70 + var_105 + 2.5777777777777779455448126*var_68 + 0.8000000000000000444089210*var_69 + 7.5555555555555553581825734*w[0][1]*w[1][1]*w[2][1]; + const double var_107 = -0.0000078933412266745598128*var_10*var_14; + const double var_108 = -0.0221260221260221254246936*w[0][0]*w[1][0]*w[2][0]; + const double var_109 = 0.0065416065416065410226265*w[0][1]*w[1][1]*w[2][1]; + const double var_110 = 0.0051948051948051948006890*var_65; + const double var_111 = 0.0009620009620009620362677*var_48; + const double var_112 = 0.1212121212121212154855243*var_42 + 0.1428571428571428492126927*var_22; + const double var_113 = var_111 + var_108 + 0.0002886002886002886000383*var_20 + 0.0222222222222222230703093*var_112 + 0.0019240019240019240725353*var_19 + var_109 + var_110 + 0.0009620009620009620362677*var_41; + A[103] = 0.0820512820512820512108831*var_10*var_113 + var_107; + const double var_114 = -0.0000087155642711198252247*var_10*var_14; + const double var_115 = 0.0359595959595959621668548*w[0][1]*w[1][1]*w[2][1]; + const double var_116 = -0.2040404040404040497680427*w[0][2]*w[1][2]*w[2][2]; + const double var_117 = -0.9676767676767676906735005*w[0][0]*w[1][0]*w[2][0]; + const double var_118 = 499.0000000000000000000000000*var_18 + 29.0000000000000000000000000*var_22; + const double var_119 = -0.0143434343434343438555834*var_20 + -0.1868686868686868784994459*var_17 + var_116 + -0.0002020202020202020200268*var_118 + -0.0200000000000000004163336*var_19 + var_117 + var_115 + -0.0595959595959595980763090*var_16; + A[21] = var_114 + 0.0004070004070004069819839*var_10*var_119; + A[91] = A[21]; + const double var_120 = 0.0398268398268398285400060*w[0][2]*w[1][2]*w[2][2]; + const double var_121 = 0.0034632034632034632004594*var_31; + const double var_122 = 0.0051948051948051948006890*var_23; + const double var_123 = 0.0259740259740259757381686*var_1; + const double var_124 = var_122 + 0.0400000000000000008326673*var_98 + var_120 + 0.0001731601731601731600230*var_42 + 0.0024242424242424242403215*var_19 + 0.0117748917748917748815618*var_16 + var_121 + var_123; + A[59] = var_54 + 0.0455840455840455863190108*var_10*var_124; + A[213] = A[59]; + const double var_125 = var_20 + var_31; + const double var_126 = var_17 + var_14; + const double var_127 = var_79 + var_19; + const double var_128 = 0.0246913580246913566540456*var_47; + const double var_129 = -0.0028860028860028860003828*var_0; + const double var_130 = 0.0051948051948051948006890*var_127 + -0.0011544011544011544001531*var_125 + var_128 + 0.0008658008658008658001148*var_42 + var_129 + 0.0003527336860670194241402*var_126 + 0.0007054673721340388482803*var_22; + const double var_131 = -0.1727272727272727292913146*var_70 + -0.2383838383838383923052362*var_71 + 0.0363636363636363618700997*var_68 + -0.0222222222222222230703093*var_69 + 2.2121212121212123768998481*w[0][1]*w[1][1]*w[2][1]; + A[70] = 0.0007326007326007326000972*var_10*var_131 + var_28; + const double var_132 = -1.5070707070707070052151266*w[0][0]*w[1][0]*w[2][0]; + const double var_133 = 2.1515151515151513805790273*var_47; + const double var_134 = -0.0333333333333333328707404*var_0; + const double var_135 = -0.0356902356902356887591310*var_20 + var_132 + -0.1545454545454545414173708*var_17 + var_134 + -0.0003367003367003367181147*var_118 + 0.0599326599326599346317934*var_19 + 0.1521885521885522063456619*var_16 + var_133; + const double var_136 = -1.3018181818181817632762431*w[0][0]*w[1][0]*w[2][0]; + const double var_137 = 12.2363636363636363313389666*w[0][1]*w[1][1]*w[2][1]; + const double var_138 = -0.0878787878787878756758900*var_83 + -0.2636363636363636131498822*var_18 + -0.3254545454545454408190608*var_82 + var_136 + var_137 + var_44 + -0.2169696969696969790497576*var_16 + 0.3333333333333333148296163*var_22; + const double var_139 = 14.0000000000000000000000000*var_16 + 3.2857142857142855874030829*var_18; + const double var_140 = 4.4126984126984121203918221*w[0][1]*w[1][1]*w[2][1]; + const double var_141 = 0.1269841269841269770779490*var_47; + const double var_142 = 0.4698412698412698373928720*var_125 + 0.1301587301587301681582431*var_18 + var_140 + 0.2000000000000000111022302*var_19 + 0.0444444444444444461406185*var_16 + var_141 + 0.1015873015873015872134744*var_126 + 0.8126984126984126977077949*var_22; + const double var_143 = 0.7099567099567100081358717*w[0][1]*w[1][1]*w[2][1]; + const double var_144 = -0.0413660413660413700531748*w[0][1]*w[1][1]*w[2][1]; + const double var_145 = 0.0001131378909156686833094*var_10*var_14; + const double var_146 = var_69 + var_72; + const double var_147 = 1.4799999999999999822364316*var_146 + 10.0000000000000000000000000*var_68 + var_33; + A[56] = var_145 + 0.0000657778435556213278207*var_10*var_147 + 0.0001697068363735030249641*var_10*var_70; + const double var_148 = var_47 + var_0; + const double var_149 = var_20 + var_16; + const double var_150 = var_22 + var_19; + const double var_151 = var_17 + var_18; + const double var_152 = 0.1269841269841269770779490*var_151 + 0.1015873015873015872134744*var_150 + 0.8126984126984126977077949*var_148 + 0.9841269841269840723541051*w[0][0]*w[1][0]*w[2][0] + 0.2000000000000000111022302*var_149; + const double var_153 = var_14 + var_22; + const double var_154 = 0.6666666666666666296592325*var_19; + const double var_155 = var_154 + var_16; + const double var_156 = 0.0008658008658008658001148*var_21 + 0.0007054673721340388482803*var_17 + var_86 + var_128 + 0.0051948051948051948006890*var_155 + 0.0003527336860670194241402*var_153 + -0.0011544011544011544001531*var_37; + const double var_157 = 0.0771717171717171690481507*w[0][0]*w[1][0]*w[2][0]; + const double var_158 = 0.0002849002849002848819678*var_10*var_14; + const double var_159 = 0.9841269841269840723541051*w[0][2]*w[1][2]*w[2][2] + 0.1015873015873015872134744*var_91 + 0.8126984126984126977077949*var_89 + 0.2000000000000000111022302*var_92 + 0.1269841269841269770779490*var_90; + A[51] = 0.0004144004144004144181250*var_10*var_159 + var_39; + A[93] = A[51]; + const double var_160 = -0.0221260221260221254246936*w[0][1]*w[1][1]*w[2][1]; + const double var_161 = 0.0065416065416065410226265*w[0][2]*w[1][2]*w[2][2]; + const double var_162 = 0.0051948051948051948006890*var_21; + const double var_163 = 0.0009620009620009620362677*var_50; + const double var_164 = 0.1212121212121212154855243*var_23 + 0.1428571428571428492126927*var_16; + const double var_165 = var_160 + 0.0019240019240019240725353*var_17 + var_162 + var_163 + var_161 + 0.0002886002886002886000383*var_19 + 0.0009620009620009620362677*var_42 + 0.0222222222222222230703093*var_164; + A[179] = 0.0820512820512820512108831*var_10*var_165 + var_107; + A[168] = A[56]; + const double var_166 = -0.2040404040404040497680427*w[0][0]*w[1][0]*w[2][0]; + const double var_167 = 0.0359595959595959621668548*w[0][2]*w[1][2]*w[2][2]; + const double var_168 = -0.9676767676767676906735005*w[0][1]*w[1][1]*w[2][1]; + const double var_169 = 29.0000000000000000000000000*var_16 + 499.0000000000000000000000000*var_22; + const double var_170 = -0.1868686868686868784994459*var_20 + var_166 + -0.0595959595959595980763090*var_18 + -0.0200000000000000004163336*var_17 + var_167 + var_168 + -0.0143434343434343438555834*var_19 + -0.0002020202020202020200268*var_169; + A[41] = 0.0004070004070004069819839*var_10*var_170 + var_114; + const double var_171 = var_0 + var_70; + const double var_172 = 0.0001731601731601731600230*var_21 + 0.0400000000000000008326673*var_112 + var_120 + var_56 + 0.0117748917748917748815618*var_19 + var_64 + 0.0024242424242424242403215*var_16 + var_110; + A[104] = var_54 + 0.0455840455840455863190108*var_10*var_172; + const double var_173 = 0.0009620009620009620362677*var_1; + const double var_174 = var_108 + 0.0009620009620009620362677*var_21 + var_161 + var_62 + 0.0002886002886002886000383*var_16 + 0.0222222222222222230703093*var_66 + var_173 + 0.0019240019240019240725353*var_22; + const double var_175 = 2.0000000000000000000000000*var_148; + const double var_176 = -0.8000000000000000444089210*var_151 + 0.4000000000000000222044605*var_150 + var_50 + -1.0000000000000000000000000*var_149 + -1.0000000000000000000000000*var_175; + const double var_177 = -0.0001420801420801420800188*var_10*var_14; + A[209] = var_177 + 0.0009472009472009471639856*var_10*var_176; + A[223] = A[209]; + const double var_178 = var_0 + var_19; + const double var_179 = 71.0000000000000000000000000*w[0][2]*w[1][2]*w[2][2]; + const double var_180 = -0.0005772005772005772000766*var_179; + const double var_181 = 0.8000000000000000444089210*w[0][0]*w[1][0]*w[2][0]; + const double var_182 = 0.0069264069264069264009187*var_181; + const double var_183 = 0.0016161616161616161602144*var_38 + 0.0012698412698412698401684*var_18 + 0.0014430014430014430001914*var_17 + var_182 + var_180 + -0.0023088023088023088003062*var_16 + 0.0057720057720057720007656*var_178 + 0.0098701298701298709886709*var_22; + A[66] = 0.0170940170940170957369908*var_10*var_183; + const double var_184 = 0.6666666666666666296592325*var_17; + const double var_185 = var_18 + var_184; + const double var_186 = -0.0010902677569344235760512*var_31; + const double var_187 = 0.0002565335898669231879873*var_48; + const double var_188 = 0.0005194805194805194800689*var_21 + 0.0001539201539201539290554*var_185 + var_2 + -0.0010261343594676927519493*var_19 + 0.0019240019240019240725353*var_23 + var_186 + var_187 + 0.0001346801346801346709828*var_41; + A[13] = 0.0769230769230769273470116*var_10*var_188 + var_40; + A[195] = A[13]; + const double var_189 = -0.0010902677569344235760512*var_47; + const double var_190 = 0.0056437389770723107862427*var_50; + const double var_191 = 0.0002565335898669231879873*var_1; + const double var_192 = -0.0010261343594676927519493*var_20 + 0.0005194805194805194800689*var_65 + var_191 + 0.0001346801346801346709828*var_23 + 0.0019240019240019240725353*var_42 + var_190 + var_189 + 0.0001539201539201539290554*var_155; + A[42] = 0.0769230769230769273470116*var_10*var_192 + var_40; + A[182] = A[42]; + const double var_193 = var_149 + var_31; + const double var_194 = -0.2040404040404040497680427*w[0][1]*w[1][1]*w[2][1]; + const double var_195 = -0.2777777777777777901135892*w[0][2]*w[1][2]*w[2][2]; + const double var_196 = 71.0000000000000000000000000*w[0][0]*w[1][0]*w[2][0]; + const double var_197 = -0.0005772005772005772000766*var_196; + const double var_198 = 0.8000000000000000444089210*w[0][2]*w[1][2]*w[2][2]; + const double var_199 = 0.0069264069264069264009187*var_198; + const double var_200 = 0.0098701298701298709886709*var_20 + -0.0023088023088023088003062*var_17 + 0.0012698412698412698401684*var_19 + var_197 + var_199 + 0.0014430014430014430001914*var_16 + 0.0016161616161616161602144*var_153 + 0.0057720057720057720007656*var_37; + A[130] = 0.0170940170940170957369908*var_10*var_200; + const double var_201 = var_14 + var_16; + const double var_202 = -0.0005772005772005772000766*var_33; + const double var_203 = 0.0000539378317156094923366*var_10*var_14; + const double var_204 = 1.3333333333333332593184650*var_148; + const double var_205 = 0.0304761904761904761640423*var_151 + 0.1600000000000000033306691*var_150 + 0.0133333333333333341891302*var_31 + var_204 + 0.1409523809523809401156313*var_149; + A[50] = 0.0013813347146680479519965*var_10*var_205 + var_203; + const double var_206 = -0.0014430014430014430001914*var_198; + const double var_207 = 0.0080808080808080808010718*var_17 + 0.0151996151996151990237749*var_18 + var_76 + -0.0039442039442039436222820*var_19 + 0.0101010101010101018687015*var_44 + 0.0025974025974025974003445*var_16 + var_144 + var_206 + -0.0103896103896103896013781*var_22; + const double var_208 = -0.9676767676767676906735005*w[0][2]*w[1][2]*w[2][2]; + const double var_209 = 29.0000000000000000000000000*var_20 + 499.0000000000000000000000000*var_19; + const double var_210 = -0.0200000000000000004163336*var_18 + -0.0595959595959595980763090*var_17 + var_166 + -0.1868686868686868784994459*var_16 + var_115 + var_208 + -0.0002020202020202020200268*var_209 + -0.0143434343434343438555834*var_22; + A[23] = 0.0004070004070004069819839*var_10*var_210 + var_114; + A[121] = A[23]; + const double var_211 = 1.7402597402597403952739796*w[0][1]*w[1][1]*w[2][1]; + A[89] = 0.2461538461538461675104372*var_10*var_130; + A[215] = A[89]; + const double var_212 = 0.0242424242424242424032155*var_31; + const double var_213 = 0.0019769119769119771271026*w[0][2]*w[1][2]*w[2][2]; + const double var_214 = -0.0000058377836155613928949*var_10*var_14; + const double var_215 = -1.5070707070707070052151266*w[0][1]*w[1][1]*w[2][1]; + const double var_216 = -0.0333333333333333328707404*var_31; + const double var_217 = 29.0000000000000000000000000*var_17 + 499.0000000000000000000000000*var_20; + const double var_218 = -0.0356902356902356887591310*var_18 + var_216 + 0.1521885521885522063456619*var_19 + 0.0599326599326599346317934*var_16 + var_133 + -0.0003367003367003367181147*var_217 + var_215 + -0.1545454545454545414173708*var_22; + A[33] = 0.0002442002442002442000324*var_10*var_218 + var_214; + const double var_219 = 1.7402597402597403952739796*w[0][0]*w[1][0]*w[2][0]; + const double var_220 = 0.0000001644446088890533206*var_10*var_14; + A[1] = var_220 + 0.0000025900025900025898592*var_10*var_93; + const double var_221 = 0.0001697068363735030249641*var_10*var_14; + const double var_222 = 4.9333333333333335701809119*var_31; + const double var_223 = 0.4933333333333333459158609*var_0; + const double var_224 = 0.6666666666666666296592325*var_179; + const double var_225 = 0.4933333333333333459158609*var_20 + 3.4399999999999999467092948*var_17 + 0.9866666666666666918317219*var_18 + 3.3333333333333330372738601*var_19 + var_223 + var_224 + 10.0000000000000000000000000*var_16 + 0.5733333333333333614589833*var_22 + var_222; + A[128] = var_221 + 0.0001973335306668639970145*var_10*var_225; + A[204] = A[148]; + const double var_226 = 0.6666666666666666296592325*var_18; + const double var_227 = var_226 + var_17; + const double var_228 = 0.0001346801346801346709828*var_21 + var_191 + 0.0019240019240019240725353*var_43 + var_49 + var_186 + 0.0001539201539201539290554*var_227 + -0.0010261343594676927519493*var_22 + 0.0005194805194805194800689*var_41; + const double var_229 = 0.7099567099567100081358717*w[0][2]*w[1][2]*w[2][2]; + const double var_230 = 3.2857142857142855874030829*var_17 + 14.0000000000000000000000000*var_20; + const double var_231 = var_212 + var_211 + 0.0372294372294372302722998*var_18 + var_229 + 0.1471861471861471981625868*var_19 + 0.1108225108225108224146993*var_16 + 0.0121212121212121212016077*var_230 + 0.2285714285714285642914234*var_22; + A[49] = var_99 + -0.0022792022792022790557420*var_10*var_231; + const double var_232 = 0.0019769119769119771271026*w[0][1]*w[1][1]*w[2][1]; + const double var_233 = 0.0051659451659451663743661*var_20 + var_157 + var_195 + 0.0079365079365079360673718*var_43 + 0.0117316017316017318083965*var_17 + 0.0135209235209235202612721*var_18 + var_232 + 0.0014862914862914862901971*var_22 + 0.0181818181818181809350499*var_41; + A[37] = 0.0042735042735042739342477*var_10*var_233 + var_15; + A[107] = A[37]; + const double var_234 = var_47 + var_22; + const double var_235 = 0.1269841269841269770779490*var_31; + const double var_236 = 0.8126984126984126977077949*var_20 + 0.0444444444444444461406185*var_17 + 0.1015873015873015872134744*var_201 + 0.2000000000000000111022302*var_18 + var_140 + 0.1301587301587301681582431*var_19 + 0.4698412698412698373928720*var_234 + var_235; + A[86] = 0.0004144004144004144181250*var_10*var_236; + const double var_237 = -0.0413660413660413700531748*w[0][0]*w[1][0]*w[2][0]; + const double var_238 = 0.0317460317460317442694873*var_47; + const double var_239 = -0.0039442039442039436222820*var_20 + var_237 + -0.0103896103896103896013781*var_18 + var_238 + 0.0080808080808080808010718*var_19 + var_78 + 0.0101010101010101018687015*var_184 + 0.0151996151996151990237749*var_16 + 0.0025974025974025974003445*var_22; + A[117] = var_74 + 0.0615384615384615418776093*var_10*var_239; + A[187] = A[117]; + const double var_240 = 4.9333333333333335701809119*var_47; + const double var_241 = 0.6666666666666666296592325*var_196; + const double var_242 = 0.5733333333333333614589833*var_20 + 3.3333333333333330372738601*var_18 + 10.0000000000000000000000000*var_17 + var_241 + 0.9866666666666666918317219*var_19 + var_223 + 3.4399999999999999467092948*var_16 + 0.4933333333333333459158609*var_22 + var_240; + A[14] = 0.0769230769230769273470116*var_10*var_228 + var_40; + const double var_243 = 1.4628571428571428558740308*w[0][1]*w[1][1]*w[2][1]; + const double var_244 = 0.2857142857142856984253854*var_179; + const double var_245 = 0.1600000000000000033306691*var_103 + var_244 + 0.8628571428571428780784913*var_17 + 0.3200000000000000066613381*var_18 + var_243 + var_32 + 3.4742857142857141994340964*var_16 + 0.6114285714285714323779075*var_22; + const double var_246 = var_92 + var_47; + const double var_247 = 0.1866666666666666751783765*var_91 + 0.0571428571428571410728559*var_89 + 0.0476190476190476164042309*var_90 + 0.0533333333333333367565210*var_246; + const double var_248 = var_16 + var_31; + const double var_249 = var_14 + var_18; + const double var_250 = 4.4126984126984121203918221*w[0][2]*w[1][2]*w[2][2]; + const double var_251 = 0.1269841269841269770779490*var_0; + const double var_252 = var_250 + 0.1015873015873015872134744*var_249 + 0.0444444444444444461406185*var_20 + 0.1301587301587301681582431*var_17 + var_251 + 0.8126984126984126977077949*var_19 + 0.4698412698412698373928720*var_248 + 0.2000000000000000111022302*var_22; + A[81] = 0.0004144004144004144181250*var_10*var_252; + A[95] = A[81]; + const double var_253 = 0.0019240019240019240725353*var_65 + 0.0001346801346801346709828*var_43 + 0.0001539201539201539290554*var_85 + var_46 + var_190 + 0.0005194805194805194800689*var_42 + -0.0010261343594676927519493*var_16 + var_187; + A[27] = 0.0769230769230769273470116*var_10*var_253 + var_40; + A[181] = A[27]; + const double var_254 = 0.0003527336860670194241402*var_249 + 0.0008658008658008658001148*var_65 + 0.0051948051948051948006890*var_45 + 0.0007054673721340388482803*var_19 + -0.0011544011544011544001531*var_248 + var_87 + var_96; + const double var_255 = 0.2285714285714285642914234*var_47; + const double var_256 = 0.2857142857142856984253854*var_196; + const double var_257 = 14.0000000000000000000000000*var_18 + 3.2857142857142855874030829*var_22; + const double var_258 = 0.6114285714285714323779075*var_20 + 0.1600000000000000033306691*var_257 + 3.4742857142857141994340964*var_17 + var_243 + 0.3200000000000000066613381*var_19 + var_256 + 0.8628571428571428780784913*var_16 + var_255; + A[100] = -0.0001726668393335059939996*var_10*var_258 + var_29; + A[156] = A[100]; + A[54] = 0.0004144004144004144181250*var_10*var_142; + const double var_259 = -1.0277777777777776790912867*var_70 + -38.1984126984126959314380656*var_71 + 0.5515873015873015150489778*var_68 + -3.1785714285714283811046243*var_69 + 6.0158730158730158166235924*w[0][1]*w[1][1]*w[2][1]; + A[2] = var_220 + 0.0000025900025900025898592*var_10*var_259; + A[30] = A[2]; + const double var_260 = 0.0372294372294372302722998*var_20 + 0.0121212121212121212016077*var_257 + 0.2285714285714285642914234*var_17 + var_229 + var_102 + 0.1108225108225108224146993*var_19 + 0.1471861471861471981625868*var_16 + var_219; + A[97] = -0.0022792022792022790557420*var_10*var_260 + var_99; + A[111] = A[97]; + const double var_261 = -0.2777777777777777901135892*w[0][0]*w[1][0]*w[2][0]; + const double var_262 = var_261 + 0.0014862914862914862901971*var_20 + 0.0181818181818181809350499*var_65 + 0.0079365079365079360673718*var_42 + 0.0135209235209235202612721*var_19 + var_232 + 0.0117316017316017318083965*var_16 + var_26 + 0.0051659451659451663743661*var_22; + A[7] = 0.0042735042735042739342477*var_10*var_262 + var_15; + const double var_263 = 4.4126984126984121203918221*w[0][0]*w[1][0]*w[2][0]; + const double var_264 = 0.1301587301587301681582431*var_20 + 0.8126984126984126977077949*var_17 + var_263 + 0.0444444444444444461406185*var_19 + 0.2000000000000000111022302*var_16 + var_141 + 0.4698412698412698373928720*var_37 + 0.1015873015873015872134744*var_153; + const double var_265 = -0.0221260221260221254246936*w[0][2]*w[1][2]*w[2][2]; + const double var_266 = 0.0065416065416065410226265*w[0][0]*w[1][0]*w[2][0]; + const double var_267 = 0.0051948051948051948006890*var_43; + const double var_268 = 0.1212121212121212154855243*var_41 + 0.1428571428571428492126927*var_18; + const double var_269 = 0.0019240019240019240725353*var_20 + 0.0002886002886002886000383*var_17 + 0.0009620009620009620362677*var_23 + 0.0222222222222222230703093*var_268 + var_267 + var_265 + var_266 + var_173; + const double var_270 = var_157 + 0.0181818181818181809350499*var_21 + 0.0117316017316017318083965*var_18 + 0.0135209235209235202612721*var_17 + var_24 + var_213 + 0.0079365079365079360673718*var_23 + 0.0014862914862914862901971*var_19 + 0.0051659451659451663743661*var_16; + const double var_271 = 0.4933333333333333459158609*var_31; + A[170] = A[86]; + const double var_272 = 2.1515151515151513805790273*var_31; + const double var_273 = -0.0333333333333333328707404*var_47; + const double var_274 = -0.1545454545454545414173708*var_20 + var_273 + 0.1521885521885522063456619*var_18 + 0.0599326599326599346317934*var_17 + var_272 + -0.0356902356902356887591310*var_19 + -0.0003367003367003367181147*var_169 + var_215; + A[11] = 0.0002442002442002442000324*var_10*var_274 + var_214; + const double var_275 = 0.0771717171717171690481507*w[0][1]*w[1][1]*w[2][1]; + const double var_276 = var_261 + 0.0117316017316017318083965*var_20 + 0.0079365079365079360673718*var_65 + var_275 + var_213 + 0.0181818181818181809350499*var_42 + 0.0051659451659451663743661*var_19 + 0.0014862914862914862901971*var_16 + 0.0135209235209235202612721*var_22; + A[10] = 0.0042735042735042739342477*var_10*var_276 + var_15; + A[150] = A[10]; + const double var_277 = -0.0001480001480001479909846*var_10*var_14; + const double var_278 = 0.1866666666666666751783765*var_150 + 0.0571428571428571410728559*var_148 + 0.0533333333333333367565210*var_193 + 0.0476190476190476164042309*var_151; + A[72] = -0.0031080031080031080004122*var_10*var_278 + var_277; + A[184] = A[72]; + const double var_279 = -1.3018181818181817632762431*w[0][1]*w[1][1]*w[2][1]; + const double var_280 = 12.2363636363636363313389666*w[0][0]*w[1][0]*w[2][0]; + const double var_281 = -0.2636363636363636131498822*var_20 + -0.0878787878787878756758900*var_201 + 0.3333333333333333148296163*var_17 + var_226 + -0.2169696969696969790497576*var_19 + var_279 + -0.3254545454545454408190608*var_234 + var_280; + const double var_282 = 0.0242424242424242424032155*var_47; + const double var_283 = 14.0000000000000000000000000*var_17 + 3.2857142857142855874030829*var_19; + const double var_284 = 0.1471861471861471981625868*var_20 + 0.2285714285714285642914234*var_18 + 0.0372294372294372302722998*var_16 + var_282 + var_219 + var_143 + 0.0121212121212121212016077*var_283 + 0.1108225108225108224146993*var_22; + const double var_285 = -0.0014430014430014430001914*var_181; + const double var_286 = -0.0103896103896103896013781*var_20 + 0.0101010101010101018687015*var_84 + 0.0025974025974025974003445*var_17 + -0.0039442039442039436222820*var_18 + 0.0151996151996151990237749*var_19 + var_238 + 0.0080808080808080808010718*var_16 + var_144 + var_285; + const double var_287 = 12.2363636363636363313389666*w[0][2]*w[1][2]*w[2][2]; + const double var_288 = var_154 + -0.3254545454545454408190608*var_125 + -0.2169696969696969790497576*var_18 + var_279 + 0.3333333333333333148296163*var_16 + var_287 + -0.0878787878787878756758900*var_126 + -0.2636363636363636131498822*var_22; + A[35] = 0.0001356668023334690030297*var_10*var_288; + const double var_289 = -0.0023088023088023088003062*var_20 + var_202 + 0.0016161616161616161602144*var_201 + 0.0012698412698412698401684*var_17 + 0.0014430014430014430001914*var_18 + var_182 + 0.0098701298701298709886709*var_19 + 0.0057720057720057720007656*var_234; + const double var_290 = 499.0000000000000000000000000*var_17 + 29.0000000000000000000000000*var_19; + const double var_291 = -0.0595959595959595980763090*var_20 + -0.1868686868686868784994459*var_18 + var_167 + -0.0002020202020202020200268*var_290 + var_194 + var_117 + -0.0143434343434343438555834*var_16 + -0.0200000000000000004163336*var_22; + A[39] = 0.0004070004070004069819839*var_10*var_291 + var_114; + const double var_292 = 0.0359595959595959621668548*w[0][0]*w[1][0]*w[2][0]; + const double var_293 = 499.0000000000000000000000000*var_16 + 29.0000000000000000000000000*var_18; + const double var_294 = -0.0200000000000000004163336*var_20 + -0.0143434343434343438555834*var_17 + -0.1868686868686868784994459*var_19 + var_194 + var_292 + -0.0002020202020202020200268*var_293 + var_208 + -0.0595959595959595980763090*var_22; + A[5] = 0.0004070004070004069819839*var_10*var_294 + var_114; + A[75] = A[5]; + const double var_295 = 0.4933333333333333459158609*var_47; + const double var_296 = -0.2169696969696969790497576*var_20 + var_79 + -0.2636363636363636131498822*var_17 + var_136 + 0.3333333333333333148296163*var_19 + var_287 + -0.0878787878787878756758900*var_153 + -0.3254545454545454408190608*var_37; + const double var_297 = -1.5070707070707070052151266*w[0][2]*w[1][2]*w[2][2]; + const double var_298 = 2.1515151515151513805790273*var_0; + const double var_299 = 0.0599326599326599346317934*var_20 + var_216 + -0.0356902356902356887591310*var_17 + var_297 + -0.1545454545454545414173708*var_19 + var_298 + -0.0003367003367003367181147*var_293 + 0.1521885521885522063456619*var_22; + A[20] = 0.0002442002442002442000324*var_10*var_299 + var_214; + A[76] = A[20]; + const double var_300 = 0.0135209235209235202612721*var_20 + var_195 + 0.0051659451659451663743661*var_18 + 0.0014862914862914862901971*var_17 + 0.0181818181818181809350499*var_43 + var_275 + 0.0117316017316017318083965*var_22 + 0.0079365079365079360673718*var_41 + var_25; + const double var_301 = 0.0001539201539201539290554*var_127 + 0.0001346801346801346709828*var_65 + 0.0019240019240019240725353*var_21 + -0.0010261343594676927519493*var_18 + var_51 + var_2 + 0.0005194805194805194800689*var_23 + var_189; + A[43] = var_40 + 0.0769230769230769273470116*var_10*var_301; + A[197] = A[43]; + A[216] = A[104]; + const double var_302 = -0.0253968253968253968033686*var_90 + 0.0400000000000000008326673*var_92 + 0.2984126984126984072354105*w[0][2]*w[1][2]*w[2][2] + 0.1269841269841269770779490*var_95; + const double var_303 = 0.2285714285714285642914234*var_20 + var_100 + var_211 + 0.1108225108225108224146993*var_17 + 0.1471861471861471981625868*var_18 + 0.0121212121212121212016077*var_35 + 0.0372294372294372302722998*var_19 + var_282; + A[161] = -0.0022792022792022790557420*var_10*var_303 + var_99; + const double var_304 = 1.4628571428571428558740308*w[0][0]*w[1][0]*w[2][0]; + const double var_305 = 0.6114285714285714323779075*var_18 + var_34 + 0.8628571428571428780784913*var_19 + var_255 + 0.3200000000000000066613381*var_16 + 0.1600000000000000033306691*var_230 + var_304 + 3.4742857142857141994340964*var_22; + A[55] = -0.0001726668393335059939996*var_10*var_305 + var_29; + A[154] = A[70]; + const double var_306 = 0.0363636363636363618700997*var_151 + -0.0222222222222222230703093*var_150 + -0.2383838383838383923052362*var_148 + 2.2121212121212123768998481*w[0][0]*w[1][0]*w[2][0] + -0.1727272727272727292913146*var_149; + A[134] = 0.2461538461538461675104372*var_10*var_156; + A[218] = A[134]; + A[69] = 0.0170940170940170957369908*var_10*var_289; + const double var_307 = 0.0246913580246913566540456*var_31; + const double var_308 = 0.0003527336860670194241402*var_38 + var_307 + 0.0008658008658008658001148*var_23 + var_96 + 0.0007054673721340388482803*var_16 + -0.0011544011544011544001531*var_178 + 0.0051948051948051948006890*var_227; + A[102] = 0.2461538461538461675104372*var_10*var_308; + const double var_309 = 1459.0000000000000000000000000*w[0][2]*w[1][2]*w[2][2] + 10.5833333333333321490954404*var_91 + 31.7500000000000000000000000*var_89 + 11.8333333333333321490954404*var_92 + 63.5000000000000000000000000*var_90; + const double var_310 = 0.1409523809523809401156313*var_70 + var_105 + 0.0304761904761904761640423*var_68 + 0.0133333333333333341891302*var_0 + 0.1600000000000000033306691*var_69; + A[98] = var_203 + 0.0013813347146680479519965*var_10*var_310; + A[126] = A[98]; + const double var_311 = 0.0117748917748917748815618*var_20 + 0.0001731601731601731600230*var_65 + var_58 + var_61 + 0.0400000000000000008326673*var_268 + var_267 + var_121 + 0.0024242424242424242403215*var_22; + A[88] = var_54 + 0.0455840455840455863190108*var_10*var_311; + const double var_312 = 0.1866666666666666751783765*var_69 + 0.0571428571428571410728559*var_71 + 0.0533333333333333367565210*var_171 + 0.0476190476190476164042309*var_68; + A[118] = -0.0031080031080031080004122*var_10*var_312 + var_277; + A[194] = 0.0009472009472009471639856*var_10*var_73 + var_177; + A[222] = A[194]; + const double var_313 = 0.0069264069264069264009187*var_77; + const double var_314 = 0.0012698412698412698401684*var_20 + 0.0016161616161616161602144*var_249 + 0.0098701298701298709886709*var_17 + var_180 + -0.0023088023088023088003062*var_19 + 0.0057720057720057720007656*var_248 + var_313 + 0.0014430014430014430001914*var_22; + A[52] = 0.0170940170940170957369908*var_10*var_314; + A[108] = A[52]; + A[67] = 0.0007326007326007326000972*var_10*var_97 + var_28; + A[109] = A[67]; + A[58] = 0.2461538461538461675104372*var_10*var_254; + A[198] = A[58]; + A[36] = 0.0002442002442002442000324*var_10*var_135 + var_214; + A[92] = A[36]; + const double var_315 = 1.8727272727272725738600911*var_151 + 25.4909090909090885190835252*var_150 + 58.0000000000000000000000000*var_148 + 1.2181818181818180324427203*w[0][0]*w[1][0]*w[2][0] + 6.8000000000000007105427358*var_149; + const double var_316 = var_202 + 0.0057720057720057720007656*var_125 + 0.0098701298701298709886709*var_18 + 0.0014430014430014430001914*var_19 + var_199 + 0.0012698412698412698401684*var_16 + 0.0016161616161616161602144*var_126 + -0.0023088023088023088003062*var_22; + const double var_317 = var_150 + var_175; + const double var_318 = 0.0000207200207200207188734*var_10*var_14; + const double var_319 = 0.2984126984126984072354105*w[0][1]*w[1][1]*w[2][1] + 0.1269841269841269770779490*var_146 + 0.0400000000000000008326673*var_70 + -0.0253968253968253968033686*var_68; + A[28] = 0.0007770007770007770001031*var_10*var_319 + var_318; + A[196] = A[28]; + const double var_320 = 10.5833333333333321490954404*var_150 + 63.5000000000000000000000000*var_151 + 31.7500000000000000000000000*var_148 + 1459.0000000000000000000000000*w[0][0]*w[1][0]*w[2][0] + 11.8333333333333321490954404*var_149; + const double var_321 = 0.0400000000000000008326673*var_149 + 0.1269841269841269770779490*var_317 + 0.2984126984126984072354105*w[0][0]*w[1][0]*w[2][0] + -0.0253968253968253968033686*var_151; + A[12] = var_318 + 0.0007770007770007770001031*var_10*var_321; + const double var_322 = var_212 + 0.1108225108225108224146993*var_20 + var_101 + 0.0372294372294372302722998*var_17 + 0.2285714285714285642914234*var_19 + 0.0121212121212121212016077*var_139 + var_143 + 0.1471861471861471981625868*var_22; + A[65] = var_99 + -0.0022792022792022790557420*var_10*var_322; + A[163] = 0.0615384615384615418776093*var_10*var_207 + var_74; + A[115] = var_28 + 0.0007326007326007326000972*var_10*var_306; + A[157] = A[115]; + const double var_323 = -0.5000000000000000000000000*var_151 + -8.7222222222222214327302936*var_150 + 19.8888888888888892836348532*var_148 + 2.1555555555555554470004154*w[0][0]*w[1][0]*w[2][0] + 0.6777777777777778123180497*var_149; + A[44] = var_318 + 0.0007770007770007770001031*var_10*var_302; + A[212] = A[44]; + A[145] = -0.0022792022792022790557420*var_10*var_284 + var_99; + const double var_324 = 0.0007054673721340388482803*var_20 + var_307 + 0.0003527336860670194241402*var_201 + 0.0008658008658008658001148*var_43 + 0.0051948051948051948006890*var_185 + var_129 + -0.0011544011544011544001531*var_234; + A[147] = 0.2461538461538461675104372*var_10*var_324; + A[202] = A[118]; + A[9] = 0.0001356668023334690030297*var_10*var_281; + const double var_325 = var_48 + 0.4000000000000000222044605*var_91 + -1.0000000000000000000000000*var_94 + -1.0000000000000000000000000*var_92 + -0.8000000000000000444089210*var_90; + A[193] = var_177 + 0.0009472009472009471639856*var_10*var_325; + A[207] = A[193]; + A[87] = var_107 + 0.0820512820512820512108831*var_10*var_269; + A[185] = A[87]; + A[34] = 0.0042735042735042739342477*var_10*var_300 + var_15; + const double var_326 = 0.2285714285714285642914234*var_0; + const double var_327 = 0.3200000000000000066613381*var_20 + var_326 + 0.6114285714285714323779075*var_17 + var_244 + 3.4742857142857141994340964*var_19 + 0.1600000000000000033306691*var_139 + var_304 + 0.8628571428571428780784913*var_22; + A[82] = -0.0001726668393335059939996*var_10*var_327 + var_29; + const double var_328 = var_250 + 0.1015873015873015872134744*var_38 + 0.2000000000000000111022302*var_17 + 0.0444444444444444461406185*var_18 + 0.8126984126984126977077949*var_16 + 0.4698412698412698373928720*var_178 + var_235 + 0.1301587301587301681582431*var_22; + A[53] = 0.0004144004144004144181250*var_10*var_328; + const double var_329 = 0.6666666666666666296592325*var_33; + const double var_330 = 10.0000000000000000000000000*var_20 + 0.9866666666666666918317219*var_17 + 3.4399999999999999467092948*var_18 + var_329 + 0.5733333333333333614589833*var_19 + 0.4933333333333333459158609*var_16 + var_295 + 3.3333333333333330372738601*var_22 + var_222; + A[176] = var_221 + 0.0001973335306668639970145*var_10*var_330; + A[164] = -0.0031080031080031080004122*var_10*var_247 + var_277; + A[220] = A[164]; + A[78] = A[50]; + const double var_331 = -0.0000090033423366756698130*var_10*var_14; + const double var_332 = 0.6777777777777778123180497*var_70 + 19.8888888888888892836348532*var_71 + -0.5000000000000000000000000*var_68 + -8.7222222222222214327302936*var_69 + 2.1555555555555554470004154*w[0][1]*w[1][1]*w[2][1]; + A[22] = 0.0000055500055500055500007*var_10*var_332 + var_331; + A[106] = A[22]; + const double var_333 = 0.0317460317460317442694873*var_0; + const double var_334 = 0.0080808080808080808010718*var_20 + 0.0101010101010101018687015*var_154 + -0.0039442039442039436222820*var_17 + 0.0025974025974025974003445*var_18 + var_75 + -0.0103896103896103896013781*var_16 + var_333 + var_285 + 0.0151996151996151990237749*var_22; + A[74] = var_74 + 0.0615384615384615418776093*var_10*var_334; + const double var_335 = 1.3333333333333332593184650*var_89; + const double var_336 = var_14 + 7.5555555555555553581825734*w[0][2]*w[1][2]*w[2][2] + 0.8000000000000000444089210*var_91 + var_335 + 1.3333333333333332593184650*var_92 + 2.5777777777777779455448126*var_90; + A[224] = 0.0021312021312021312002827*var_10*var_336; + A[73] = 0.0615384615384615418776093*var_10*var_286 + var_74; + A[199] = A[73]; + const double var_337 = var_14 + 0.8000000000000000444089210*var_150 + 2.5777777777777779455448126*var_151 + 7.5555555555555553581825734*w[0][0]*w[1][0]*w[2][0] + var_204 + 1.3333333333333332593184650*var_149; + A[192] = 0.0021312021312021312002827*var_10*var_337; + const double var_338 = 0.5515873015873015150489778*var_151 + -3.1785714285714283811046243*var_150 + -38.1984126984126959314380656*var_148 + 6.0158730158730158166235924*w[0][0]*w[1][0]*w[2][0] + -1.0277777777777776790912867*var_149; + A[17] = var_220 + 0.0000025900025900025898592*var_10*var_338; + A[31] = A[17]; + A[26] = 0.0001356668023334690030297*var_10*var_138; + A[214] = A[74]; + A[165] = A[11]; + const double var_339 = 0.1600000000000000033306691*var_91 + var_335 + 0.1409523809523809401156313*var_92 + 0.0133333333333333341891302*var_47 + 0.0304761904761904761640423*var_90; + A[146] = var_203 + 0.0013813347146680479519965*var_10*var_339; + const double var_340 = 31.7500000000000000000000000*var_71 + 11.8333333333333321490954404*var_70 + 63.5000000000000000000000000*var_68 + 10.5833333333333321490954404*var_69 + 1459.0000000000000000000000000*w[0][1]*w[1][1]*w[2][1]; + A[105] = A[7]; + A[68] = -0.0001726668393335059939996*var_10*var_245 + var_29; + A[124] = A[68]; + A[63] = A[49]; + const double var_341 = 0.0014430014430014430001914*var_20 + 0.0016161616161616161602144*var_83 + -0.0023088023088023088003062*var_18 + 0.0057720057720057720007656*var_82 + var_197 + var_313 + 0.0098701298701298709886709*var_16 + 0.0012698412698412698401684*var_22; + A[116] = 0.0170940170940170957369908*var_10*var_341; + const double var_342 = var_111 + var_160 + var_122 + 0.0002886002886002886000383*var_18 + 0.0009620009620009620362677*var_43 + 0.0222222222222222230703093*var_98 + 0.0019240019240019240725353*var_16 + var_266; + A[57] = 0.0820512820512820512108831*var_10*var_342 + var_107; + A[183] = A[57]; + A[61] = A[19]; + A[25] = 0.0042735042735042739342477*var_10*var_270 + var_15; + const double var_343 = 1.2181818181818180324427203*w[0][2]*w[1][2]*w[2][2] + 25.4909090909090885190835252*var_91 + 58.0000000000000000000000000*var_89 + 6.8000000000000007105427358*var_92 + 1.8727272727272725738600911*var_90; + const double var_344 = var_179 + 10.0000000000000000000000000*var_90 + 1.4799999999999999822364316*var_95; + A[83] = 0.0000657778435556213278207*var_10*var_344 + var_145 + 0.0001697068363735030249641*var_10*var_92; + A[125] = A[83]; + const double var_345 = -1.3018181818181817632762431*w[0][2]*w[1][2]*w[2][2]; + const double var_346 = -0.0878787878787878756758900*var_38 + 0.3333333333333333148296163*var_18 + var_345 + var_184 + -0.2636363636363636131498822*var_16 + -0.3254545454545454408190608*var_178 + -0.2169696969696969790497576*var_22 + var_280; + const double var_347 = var_134 + var_297 + 0.1521885521885522063456619*var_17 + 0.0599326599326599346317934*var_18 + var_272 + -0.1545454545454545414173708*var_16 + -0.0003367003367003367181147*var_209 + -0.0356902356902356887591310*var_22; + A[8] = 0.0002442002442002442000324*var_10*var_347 + var_214; + A[96] = var_221 + 0.0001973335306668639970145*var_10*var_242; + A[205] = A[163]; + A[120] = A[8]; + A[149] = 0.0820512820512820512108831*var_10*var_174 + var_107; + const double var_348 = 0.1521885521885522063456619*var_20 + var_273 + -0.1545454545454545414173708*var_18 + var_132 + -0.0003367003367003367181147*var_290 + var_298 + -0.0356902356902356887591310*var_16 + 0.0599326599326599346317934*var_22; + A[24] = var_214 + 0.0002442002442002442000324*var_10*var_348; + A[136] = A[24]; + const double var_349 = 3.4399999999999999467092948*var_20 + 10.0000000000000000000000000*var_18 + 3.3333333333333330372738601*var_17 + 0.4933333333333333459158609*var_19 + var_241 + 0.5733333333333333614589833*var_16 + var_295 + var_81 + 0.9866666666666666918317219*var_22; + A[144] = var_221 + 0.0001973335306668639970145*var_10*var_349; + A[79] = A[65]; + const double var_350 = 6.8000000000000007105427358*var_70 + 58.0000000000000000000000000*var_71 + 1.8727272727272725738600911*var_68 + 25.4909090909090885190835252*var_69 + 1.2181818181818180324427203*w[0][1]*w[1][1]*w[2][1]; + A[112] = var_158 + 0.0000814000814000814045283*var_10*var_350; + const double var_351 = 0.0009620009620009620362677*var_65 + 0.0019240019240019240725353*var_18 + 0.0222222222222222230703093*var_59 + var_163 + var_109 + var_265 + 0.0002886002886002886000383*var_22 + var_57; + A[131] = 0.0004144004144004144181250*var_10*var_152 + var_39; + A[173] = A[131]; + A[153] = A[55]; + A[166] = A[26]; + const double var_352 = 0.9866666666666666918317219*var_20 + 0.4933333333333333459158609*var_18 + 0.5733333333333333614589833*var_17 + var_271 + 10.0000000000000000000000000*var_19 + var_224 + 3.3333333333333330372738601*var_16 + var_81 + 3.4399999999999999467092948*var_22; + A[80] = var_221 + 0.0001973335306668639970145*var_10*var_352; + const double var_353 = 2.1555555555555554470004154*w[0][2]*w[1][2]*w[2][2] + -8.7222222222222214327302936*var_91 + 19.8888888888888892836348532*var_89 + 0.6777777777777778123180497*var_92 + -0.5000000000000000000000000*var_90; + A[40] = 0.0000055500055500055500007*var_10*var_353 + var_331; + A[152] = A[40]; + A[85] = 0.0170940170940170957369908*var_10*var_316; + A[155] = A[85]; + A[127] = A[113]; + A[201] = A[103]; + const double var_354 = 3.3333333333333330372738601*var_20 + 0.5733333333333333614589833*var_18 + 0.4933333333333333459158609*var_17 + var_271 + var_329 + 3.4399999999999999467092948*var_19 + 0.9866666666666666918317219*var_16 + 10.0000000000000000000000000*var_22 + var_240; + const double var_355 = 0.2000000000000000111022302*var_20 + 0.1015873015873015872134744*var_83 + 0.8126984126984126977077949*var_18 + var_251 + var_263 + 0.4698412698412698373928720*var_82 + 0.1301587301587301681582431*var_16 + 0.0444444444444444461406185*var_22; + A[129] = 0.0004144004144004144181250*var_10*var_355; + A[143] = A[129]; + const double var_356 = -0.0143434343434343438555834*var_18 + var_116 + var_168 + -0.0595959595959595980763090*var_19 + -0.0200000000000000004163336*var_16 + var_292 + -0.0002020202020202020200268*var_217 + -0.1868686868686868784994459*var_22; + A[139] = A[69]; + const double var_357 = 0.2000000000000000111022302*var_70 + 0.8126984126984126977077949*var_71 + 0.1269841269841269770779490*var_68 + 0.1015873015873015872134744*var_69 + 0.9841269841269840723541051*w[0][1]*w[1][1]*w[2][1]; + A[211] = A[29]; + A[133] = 0.0820512820512820512108831*var_10*var_351 + var_107; + A[203] = A[133]; + const double var_358 = 0.0151996151996151990237749*var_20 + var_237 + -0.0103896103896103896013781*var_17 + 0.0101010101010101018687015*var_226 + 0.0025974025974025974003445*var_19 + -0.0039442039442039436222820*var_16 + var_333 + var_206 + 0.0080808080808080808010718*var_22; + A[162] = 0.0615384615384615418776093*var_10*var_358 + var_74; + A[190] = A[162]; + const double var_359 = -0.0878787878787878756758900*var_249 + 0.3333333333333333148296163*var_20 + var_84 + -0.2169696969696969790497576*var_17 + -0.2636363636363636131498822*var_19 + -0.3254545454545454408190608*var_248 + var_345 + var_137; + A[137] = A[39]; + A[84] = var_39 + 0.0004144004144004144181250*var_10*var_357; + A[64] = 0.0000814000814000814045283*var_10*var_315 + var_158; + A[3] = 0.0004070004070004069819839*var_10*var_356 + var_114; + A[45] = A[3]; + A[140] = A[84]; + A[174] = A[146]; + const double var_360 = 0.8628571428571428780784913*var_20 + var_30 + 3.4742857142857141994340964*var_18 + var_326 + var_256 + 0.6114285714285714323779075*var_16 + 0.1600000000000000033306691*var_283 + 0.3200000000000000066613381*var_22; + A[114] = var_29 + -0.0001726668393335059939996*var_10*var_360; + A[221] = A[179]; + A[94] = A[66]; + A[16] = 0.0000012333345666679000237*var_10*var_340 + var_53; + A[4] = 0.0000055500055500055500007*var_10*var_323 + var_331; + const double var_361 = 0.0024242424242424242403215*var_18 + var_55 + 0.0117748917748917748815618*var_17 + 0.0001731601731601731600230*var_43 + var_162 + 0.0400000000000000008326673*var_164 + var_63 + var_123; + A[77] = A[35]; + A[177] = var_54 + 0.0455840455840455863190108*var_10*var_361; + A[172] = A[116]; + A[135] = A[9]; + A[6] = 0.0001356668023334690030297*var_10*var_346; + A[90] = A[6]; + A[189] = A[147]; + A[48] = var_221 + 0.0001973335306668639970145*var_10*var_354; + A[60] = A[4]; + A[151] = A[25]; + A[18] = 0.0001356668023334690030297*var_10*var_359; + A[46] = A[18]; + A[210] = A[14]; + A[208] = 0.0021312021312021312002827*var_10*var_106; + A[101] = 0.0004144004144004144181250*var_10*var_264; + A[171] = A[101]; + A[138] = A[54]; + const double var_362 = 1.4799999999999999822364316*var_317 + var_196 + 10.0000000000000000000000000*var_151; + A[191] = A[177]; + A[0] = var_53 + 0.0000012333345666679000237*var_10*var_320; + A[99] = var_145 + 0.0001697068363735030249641*var_10*var_149 + 0.0000657778435556213278207*var_10*var_362; + A[175] = A[161]; + A[219] = A[149]; + A[180] = A[12]; + A[169] = A[71]; + A[38] = 0.0001356668023334690030297*var_10*var_296; + A[200] = A[88]; + A[159] = A[145]; + A[110] = A[82]; + A[122] = A[38]; + A[142] = A[114]; + A[15] = A[1]; + A[32] = var_53 + 0.0000012333345666679000237*var_10*var_309; + A[186] = A[102]; + A[47] = A[33]; + A[167] = A[41]; + A[123] = A[53]; + A[62] = A[34]; + A[158] = A[130]; + A[160] = var_158 + 0.0000814000814000814045283*var_10*var_343; + A[141] = A[99]; + } + + 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/mass_matrix_2d/mass_matrix_f3_p1_q4_quadrature.h b/mass_matrix_2d/mass_matrix_f3_p1_q4_quadrature.h new file mode 100644 index 0000000..f369892 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f3_p1_q4_quadrature.h @@ -0,0 +1,6492 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F3_P1_Q4_QUADRATURE_H +#define __MASS_MATRIX_F3_P1_Q4_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p1_q4_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p1_q4_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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 mass_matrix_f3_p1_q4_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p1_q4_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p1_q4_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p1_q4_quadrature_finite_element_1() + { + // 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.0224478343233824, 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.0412393049421162, -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.0388807895679869, 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.0439885919382571, 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.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 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.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.00927360943924092, 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.0535412090610519}; + + // 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.0622092633087791, -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.251415744421884, 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.0224478343233824, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0412393049421162, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0388807895679869, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0439885919382571, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.00927360943924092, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0622092633087791, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.251415744421884, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f3_p1_q4_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p1_q4_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p1_q4_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_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 mass_matrix_f3_p1_q4_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p1_q4_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p1_q4_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_p1_q4_quadrature_dofmap_1() + { + // 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.0*m.num_entities[1] + 3.0*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 mass_matrix_f3_p1_q4_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 mass_matrix_f3_p1_q4_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f3_p1_q4_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Array of quadrature weights. + static const double W36[36] = {0.00619426535265906, 0.0116108747669979, 0.0120606064042655, 0.0084515357969434, 0.0037652982126918, 0.000748542561236343, 0.0130433943300833, 0.0244492622580587, 0.0253962715890485, 0.0177965759970269, 0.00792866733379675, 0.00157622175402364, 0.0169175056800133, 0.0317111115907051, 0.0329393989007878, 0.023082463651359, 0.0102836172287667, 0.00204438659154493, 0.0169175056800133, 0.0317111115907051, 0.0329393989007878, 0.023082463651359, 0.0102836172287667, 0.00204438659154493, 0.0130433943300833, 0.0244492622580587, 0.0253962715890485, 0.0177965759970269, 0.00792866733379675, 0.00157622175402364, 0.00619426535265908, 0.0116108747669979, 0.0120606064042655, 0.00845153579694342, 0.00376529821269181, 0.000748542561236345}; + // Quadrature points on the UFC reference element: (0.0327753666144599, 0.0293164271597849), (0.0287653330125591, 0.148078599668484), (0.0223868729780306, 0.336984690281154), (0.0149015633666711, 0.55867151877155), (0.00779187470128645, 0.769233862030055), (0.00246669715267023, 0.926945671319741), (0.164429241594827, 0.0293164271597849), (0.144311486950417, 0.148078599668484), (0.112311681780954, 0.336984690281154), (0.0747589734626491, 0.55867151877155), (0.0390907007328242, 0.769233862030055), (0.01237506041744, 0.926945671319741), (0.369529924372377, 0.0293164271597849), (0.324318304588776, 0.148078599668484), (0.252403568076518, 0.336984690281154), (0.168009519121192, 0.55867151877155), (0.0878504549759972, 0.769233862030055), (0.0278110821153606, 0.926945671319741), (0.601153648467838, 0.0293164271597849), (0.52760309574274, 0.148078599668484), (0.410611741642328, 0.336984690281154), (0.273318962107258, 0.55867151877155), (0.142915682993948, 0.769233862030055), (0.0452432465648983, 0.926945671319741), (0.806254331245388, 0.0293164271597849), (0.707609913381099, 0.148078599668484), (0.550703627937892, 0.336984690281154), (0.366569507765801, 0.55867151877155), (0.191675437237121, 0.769233862030055), (0.0606792682628189, 0.926945671319741), (0.937908206225755, 0.0293164271597849), (0.823156067318956, 0.148078599668484), (0.640628436740815, 0.336984690281154), (0.426426917861779, 0.55867151877155), (0.222974263268659, 0.769233862030055), (0.0705876315275886, 0.926945671319741) + + // Value of basis functions at quadrature points. + static const double FE0[36][3] = \ + {{0.937908206225755, 0.03277536661446, 0.0293164271597848}, + {0.823156067318957, 0.0287653330125592, 0.148078599668484}, + {0.640628436740815, 0.0223868729780305, 0.336984690281154}, + {0.426426917861779, 0.0149015633666711, 0.55867151877155}, + {0.222974263268659, 0.00779187470128651, 0.769233862030055}, + {0.0705876315275887, 0.00246669715267028, 0.926945671319741}, + {0.806254331245388, 0.164429241594827, 0.0293164271597848}, + {0.707609913381099, 0.144311486950417, 0.148078599668484}, + {0.550703627937892, 0.112311681780954, 0.336984690281154}, + {0.366569507765801, 0.0747589734626491, 0.55867151877155}, + {0.191675437237121, 0.0390907007328243, 0.769233862030055}, + {0.0606792682628189, 0.0123750604174401, 0.926945671319741}, + {0.601153648467838, 0.369529924372377, 0.0293164271597848}, + {0.52760309574274, 0.324318304588776, 0.148078599668484}, + {0.410611741642328, 0.252403568076518, 0.336984690281154}, + {0.273318962107258, 0.168009519121192, 0.55867151877155}, + {0.142915682993948, 0.0878504549759972, 0.769233862030055}, + {0.0452432465648984, 0.0278110821153607, 0.926945671319741}, + {0.369529924372377, 0.601153648467839, 0.0293164271597848}, + {0.324318304588776, 0.52760309574274, 0.148078599668484}, + {0.252403568076518, 0.410611741642328, 0.336984690281154}, + {0.168009519121192, 0.273318962107258, 0.55867151877155}, + {0.0878504549759972, 0.142915682993948, 0.769233862030055}, + {0.0278110821153607, 0.0452432465648984, 0.926945671319741}, + {0.164429241594827, 0.806254331245388, 0.0293164271597848}, + {0.144311486950417, 0.707609913381099, 0.148078599668484}, + {0.112311681780954, 0.550703627937892, 0.336984690281154}, + {0.0747589734626489, 0.366569507765801, 0.55867151877155}, + {0.0390907007328242, 0.191675437237121, 0.769233862030055}, + {0.0123750604174401, 0.0606792682628189, 0.926945671319741}, + {0.03277536661446, 0.937908206225755, 0.0293164271597848}, + {0.0287653330125592, 0.823156067318957, 0.148078599668484}, + {0.0223868729780305, 0.640628436740815, 0.336984690281154}, + {0.0149015633666711, 0.426426917861779, 0.55867151877155}, + {0.00779187470128645, 0.222974263268659, 0.769233862030055}, + {0.00246669715267034, 0.0705876315275887, 0.926945671319741}}; + + static const double FE1[36][15] = \ + {{0.56630237132032, -0.025448739951231, -0.02340903093109, 0.00416085056960128, 0.00294793329848728, 0.00425839910756952, 0.353405794301071, -0.267147951008896, 0.121859429227921, 0.395102868735011, -0.293986529335415, 0.133116353941705, 0.0793522773075458, -0.0250575137648273, -0.0254565128177721}, + {0.118972466830072, -0.0230709318617449, -0.0341013730463095, 0.018947016495499, 0.00614695794455526, 0.00651870726857255, 0.963270822664205, -0.455714379551745, 0.186540981008593, 0.18712228544335, -0.192157632298739, 0.105324818176152, 0.257233041221556, -0.099290349448832, -0.045742430845185}, + {-0.0410559740731875, -0.0188884466735285, 0.0210511710271628, 0.0349917675522029, -0.00955924750821981, -0.00456418811345946, 0.505990196901837, 0.469464799398205, -0.130609964999847, 0.0336144002765209, -0.0816095123137331, 0.0665214829999042, 0.241648244025793, -0.140804681095384, 0.0538099525957325}, + {0.0191042291114048, -0.0133255662493701, -0.0206485123834592, 0.0405094826163528, -0.0386646995111557, 0.00643281363514752, -0.131939141811172, 0.830314310030356, 0.184083027003091, -0.00351924058446104, -0.0168682880103284, 0.0309203767076776, 0.080169244991654, -0.106829866961562, 0.140261831415824}, + {-0.00938453904605184, -0.00735417356108037, 0.0220620722354296, 0.0304878329277379, -0.0482427486128633, 0.0357504701324324, 0.0547897737103965, -0.154040051327386, 1.02304452328671, 0.000554987335758502, 0.000727851735427045, 0.00883736717957267, -0.00462319916590223, -0.0414337049897014, 0.0888235381595224}, + {-0.039411023284595, -0.00242231653722821, 0.505649261589883, 0.0120147467421047, -0.0245209639812787, 0.0281958543435565, 0.215079260438399, -0.508591455559504, 0.806859721248732, 0.000572347890212842, 0.000494891999080295, 0.000914932279387579, -0.00370647497562177, -0.0051137834055052, 0.0139850012123767}, + {0.0824161637725179, -0.0294914855256902, -0.02340903093109, 0.00590593006797314, 0.00582593260452294, 0.0213637682196615, 0.171801701915994, -0.185697684231962, 0.104754060115829, 0.963597078074327, -0.40385910184121, 0.162423670230445, 0.276723174191905, -0.0425693977624813, -0.109784778900741}, + {-0.0303969806920391, -0.0350490773722188, -0.0341013730463095, 0.0342751641157549, 0.0147321571899481, 0.0327034051200263, 0.424735375088394, -0.312771366460782, 0.160356283157139, 0.413930126815579, -0.316080712840952, 0.163787650378721, 0.885711947101502, -0.204561955373223, -0.19727064318154}, + {-0.0178494055445301, -0.0407795027424123, 0.0210511710271628, 0.0861992776649916, -0.0290104851672837, -0.0228978671335801, 0.120724252767667, 0.310663028371925, -0.112276285979726, 0.040235489181343, -0.163892320828179, 0.140867690149755, 0.802235130592271, -0.36733313364048, 0.232062961281076}, + {0.0233190985494116, -0.0401256259898051, -0.0206485123834592, 0.132794326958115, -0.144587977270839, 0.032272489268862, -0.135906939764466, 0.47160061549191, 0.158243351369376, -0.0181864708721552, -0.0358278205906738, 0.0871323298781454, 0.228439462369848, -0.343417130728224, 0.604898803713954}, + {-0.0205277588289655, -0.0288155938118291, 0.0220620722354296, 0.124718754065599, -0.21075144429941, 0.179354902713459, 0.113128801818687, -0.285771773170361, 0.879440090705682, 0.00574894626256647, 0.0058988467391181, 0.031077053282736, -0.0430288533926338, -0.155598000009121, 0.383063955689044}, + {-0.0371082327213856, -0.0112820903294173, 0.505649261589883, 0.0567111236787091, -0.118093887044145, 0.141454495394839, 0.199601225425082, -0.461345808814886, 0.69360108019745, 0.00266474864758105, 0.00216201065863758, 0.00371239609144181, -0.0168674754837758, -0.0211711248206387, 0.0603122775306251}, + {-0.0339024544799458, 0.023387640004351, -0.02340903093109, -0.00720836763307398, -0.0182888871179095, 0.0480118473937476, 0.0267093906452789, -0.0874064926762268, 0.0781059809417426, 0.336668552801051, 0.596745158445697, -0.147812572060763, 0.292720606365088, 0.0996397790360984, -0.183961150734045}, + {-0.0095906246236551, 0.0192268203241027, -0.0341013730463094, -0.0267531412354512, -0.0232811757502806, 0.0734959712974962, 0.0255429142588088, -0.141471609601455, 0.119563716979669, 0.0559434966647409, 0.225932583629769, -0.0953212697058672, 0.900337562556068, 0.241033195353002, -0.330557067100639}, + {0.0213409951908707, 0.000797264231187582, 0.0210511710271628, -0.00215970873408773, 0.00113811168767276, -0.0514595033589619, -0.0847594279128907, 0.123720487246374, -0.0837146497543445, -0.0634853233702957, 0.00256059295790888, -0.00263157879369526, 0.717999738211763, 0.0107449258196653, 0.388856905551671}, + {0.00734599742741782, -0.02839014160368, -0.0206485123834592, 0.109010467002261, -0.152030381966887, 0.0725275529045928, -0.0344381186867421, 0.0703415678092674, 0.117988287733645, -0.0103565898127769, -0.00561896434021046, 0.0533312093041724, 0.0765736536295873, -0.269236283109832, 1.01360025609264}, + {-0.0353878578540361, -0.0414666912205211, 0.0220620722354296, 0.192691111987477, -0.364133910121009, 0.403073096930251, 0.179359194783873, -0.391207466820726, 0.65572189648889, 0.0204837405679316, 0.0139522896496609, 0.0358000125005907, -0.132378708183015, -0.200450896105804, 0.641882115161008}, + {-0.031669348089454, -0.0224768586657739, 0.505649261589883, 0.115398208580281, -0.248158040619958, 0.317897646905111, 0.166615019902697, -0.372031802654953, 0.517157928687178, 0.00499893806458903, 0.00366363544055174, 0.00563246559694469, -0.0305685004026728, -0.0331709792809288, 0.101062424946505}, + {0.023387640004351, -0.0339024544799458, -0.02340903093109, 0.0267093906452788, -0.0874064926762267, 0.0781059809417426, -0.00720836763307393, -0.0182888871179095, 0.0480118473937476, -0.147812572060763, 0.596745158445697, 0.336668552801051, 0.0996397790360983, 0.292720606365088, -0.183961150734045}, + {0.0192268203241027, -0.00959062462365504, -0.0341013730463094, 0.0255429142588087, -0.141471609601455, 0.119563716979669, -0.0267531412354512, -0.0232811757502805, 0.0734959712974963, -0.0953212697058673, 0.22593258362977, 0.0559434966647408, 0.241033195353002, 0.900337562556068, -0.330557067100639}, + {0.000797264231187593, 0.0213409951908707, 0.0210511710271628, -0.0847594279128908, 0.123720487246374, -0.0837146497543445, -0.00215970873408771, 0.00113811168767294, -0.0514595033589619, -0.00263157879369533, 0.00256059295790887, -0.0634853233702957, 0.0107449258196652, 0.717999738211763, 0.388856905551671}, + {-0.0283901416036801, 0.00734599742741785, -0.0206485123834592, -0.0344381186867421, 0.0703415678092673, 0.117988287733645, 0.109010467002261, -0.152030381966887, 0.0725275529045927, 0.0533312093041724, -0.00561896434021046, -0.0103565898127769, -0.269236283109833, 0.0765736536295877, 1.01360025609264}, + {-0.0414666912205212, -0.035387857854036, 0.0220620722354296, 0.179359194783873, -0.391207466820727, 0.65572189648889, 0.192691111987477, -0.364133910121008, 0.403073096930251, 0.0358000125005907, 0.0139522896496609, 0.0204837405679316, -0.200450896105804, -0.132378708183015, 0.641882115161008}, + {-0.0224768586657739, -0.031669348089454, 0.505649261589883, 0.166615019902697, -0.372031802654953, 0.517157928687178, 0.115398208580281, -0.248158040619958, 0.317897646905111, 0.00563246559694458, 0.00366363544055176, 0.00499893806458915, -0.0331709792809289, -0.0305685004026726, 0.101062424946505}, + {-0.0294914855256903, 0.0824161637725182, -0.02340903093109, 0.171801701915994, -0.185697684231962, 0.104754060115829, 0.00590593006797323, 0.00582593260452294, 0.0213637682196615, 0.162423670230446, -0.40385910184121, 0.963597078074327, -0.0425693977624813, 0.276723174191904, -0.109784778900741}, + {-0.0350490773722189, -0.030396980692039, -0.0341013730463095, 0.424735375088395, -0.312771366460783, 0.160356283157139, 0.034275164115755, 0.0147321571899484, 0.0327034051200263, 0.163787650378721, -0.316080712840952, 0.41393012681558, -0.204561955373223, 0.885711947101502, -0.19727064318154}, + {-0.0407795027424123, -0.0178494055445301, 0.0210511710271628, 0.120724252767667, 0.310663028371925, -0.112276285979726, 0.0861992776649916, -0.0290104851672834, -0.0228978671335801, 0.140867690149755, -0.163892320828179, 0.040235489181343, -0.36733313364048, 0.802235130592271, 0.232062961281076}, + {-0.0401256259898051, 0.0233190985494116, -0.0206485123834592, -0.135906939764466, 0.471600615491911, 0.158243351369376, 0.132794326958115, -0.144587977270839, 0.0322724892688619, 0.0871323298781453, -0.0358278205906738, -0.0181864708721552, -0.343417130728224, 0.228439462369848, 0.604898803713953}, + {-0.0288155938118291, -0.0205277588289655, 0.0220620722354296, 0.113128801818687, -0.285771773170361, 0.879440090705682, 0.124718754065599, -0.21075144429941, 0.179354902713459, 0.0310770532827359, 0.00589884673911823, 0.00574894626256647, -0.155598000009122, -0.0430288533926335, 0.383063955689044}, + {-0.0112820903294174, -0.0371082327213855, 0.505649261589883, 0.199601225425082, -0.461345808814886, 0.693601080197449, 0.0567111236787092, -0.118093887044145, 0.141454495394839, 0.0037123960914417, 0.00216201065863769, 0.00266474864758115, -0.021171124820639, -0.0168674754837758, 0.0603122775306252}, + {-0.0254487399512311, 0.566302371320319, -0.02340903093109, 0.35340579430107, -0.267147951008896, 0.121859429227921, 0.00416085056960128, 0.00294793329848743, 0.00425839910756955, 0.133116353941706, -0.293986529335416, 0.395102868735012, -0.0250575137648273, 0.0793522773075462, -0.0254565128177724}, + {-0.0230709318617449, 0.118972466830072, -0.0341013730463095, 0.963270822664205, -0.455714379551745, 0.186540981008593, 0.018947016495499, 0.00614695794455568, 0.00651870726857255, 0.105324818176152, -0.192157632298739, 0.18712228544335, -0.0992903494488324, 0.257233041221557, -0.045742430845185}, + {-0.0188884466735285, -0.0410559740731874, 0.0210511710271628, 0.505990196901837, 0.469464799398205, -0.130609964999847, 0.034991767552203, -0.00955924750821949, -0.00456418811345951, 0.0665214829999044, -0.0816095123137332, 0.0336144002765209, -0.140804681095384, 0.241648244025794, 0.0538099525957328}, + {-0.0133255662493701, 0.0191042291114048, -0.0206485123834592, -0.131939141811172, 0.830314310030356, 0.184083027003091, 0.0405094826163529, -0.0386646995111555, 0.00643281363514756, 0.0309203767076776, -0.0168682880103284, -0.00351924058446107, -0.106829866961562, 0.0801692449916541, 0.140261831415824}, + {-0.00735417356108038, -0.00938453904605184, 0.0220620722354296, 0.0547897737103965, -0.154040051327387, 1.02304452328671, 0.0304878329277378, -0.0482427486128629, 0.0357504701324325, 0.00883736717957254, 0.000727851735427243, 0.000554987335758443, -0.0414337049897016, -0.00462319916590201, 0.0888235381595222}, + {-0.00242231653722834, -0.0394110232845949, 0.505649261589883, 0.215079260438399, -0.508591455559504, 0.806859721248731, 0.0120147467421051, -0.0245209639812793, 0.0281958543435579, 0.000914932279387486, 0.000494891999080461, 0.000572347890212904, -0.00511378340550558, -0.00370647497562168, 0.0139850012123772}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 225; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 25092 + for (unsigned int ip = 0; ip < 36; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + + // Total number of operations to compute function values = 18 + for (unsigned int r = 0; r < 3; r++) + { + F0 += FE0[ip][r]*w[2][r]; + F1 += FE0[ip][r]*w[0][r]; + F2 += FE0[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 4 + double I[1]; + // Number of operations: 4 + I[0] = F0*F1*F2*W36[ip]*det; + + + // Number of operations for primary indices: 675 + for (unsigned int j = 0; j < 15; j++) + { + for (unsigned int k = 0; k < 15; k++) + { + // Number of operations to compute entry: 3 + A[j*15 + k] += FE1[ip][j]*FE1[ip][k]*I[0]; + }// 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 mass_matrix_f3_p1_q4_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f3_p1_q4_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p1_q4_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1)))), 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 3; + } + + /// 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 mass_matrix_f3_p1_q4_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f3_p1_q4_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f3_p1_q4_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p1_q4_quadrature_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p1_q4_quadrature_finite_element_0(); + 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 mass_matrix_f3_p1_q4_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f3_p1_q4_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f3_p1_q4_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p1_q4_quadrature_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p1_q4_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f3_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/mass_matrix_2d/mass_matrix_f3_p1_q4_tensor.h b/mass_matrix_2d/mass_matrix_f3_p1_q4_tensor.h new file mode 100644 index 0000000..eb41f43 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f3_p1_q4_tensor.h @@ -0,0 +1,6623 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F3_P1_Q4_TENSOR_H +#define __MASS_MATRIX_F3_P1_Q4_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p1_q4_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p1_q4_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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 mass_matrix_f3_p1_q4_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p1_q4_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p1_q4_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p1_q4_tensor_finite_element_1() + { + // 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.0224478343233824, 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.0412393049421162, -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.0388807895679869, 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.0439885919382571, 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.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 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.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.00927360943924092, 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.0535412090610519}; + + // 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.0622092633087791, -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.251415744421884, 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.0224478343233824, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0412393049421162, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0388807895679869, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0439885919382571, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.00927360943924092, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0622092633087791, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.251415744421884, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f3_p1_q4_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p1_q4_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p1_q4_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_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 mass_matrix_f3_p1_q4_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p1_q4_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p1_q4_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_p1_q4_tensor_dofmap_1() + { + // 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.0*m.num_entities[1] + 3.0*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 mass_matrix_f3_p1_q4_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 mass_matrix_f3_p1_q4_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f3_p1_q4_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 54 + // Number of operations (multiply-add pairs) for tensor contraction: 2624 + // Total number of operations (multiply-add pairs): 2687 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0 = det*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_0_0_1 = det*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_0_0_2 = det*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_0_1_0 = det*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_0_1_1 = det*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_0_1_2 = det*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_0_2_0 = det*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_0_2_1 = det*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_0_2_2 = det*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_1_0_0 = det*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_1_0_1 = det*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_1_0_2 = det*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_1_1_0 = det*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_1_1_1 = det*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_1_1_2 = det*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_1_2_0 = det*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_1_2_1 = det*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_1_2_2 = det*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_2_0_0 = det*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_2_0_1 = det*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_2_0_2 = det*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_2_1_0 = det*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_2_1_1 = det*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_2_1_2 = det*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_2_2_0 = det*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_2_2_1 = det*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_2_2_2 = det*w[2][2]*w[0][2]*w[1][2]*(1.0); + + // Compute element tensor + A[108] = 9.86667653334351e-05*G0_0_0_0 + 2.7626694293362e-05*G0_0_0_1 + 0.000168720168720174*G0_0_0_2 + 2.7626694293362e-05*G0_0_1_0 + 2.17066883733561e-05*G0_0_1_1 + 2.76266942933619e-05*G0_0_1_2 + 0.000168720168720174*G0_0_2_0 + 2.76266942933619e-05*G0_0_2_1 + 9.8666765333435e-05*G0_0_2_2 + 2.7626694293362e-05*G0_1_0_0 + 2.17066883733561e-05*G0_1_0_1 + 2.76266942933619e-05*G0_1_0_2 + 2.17066883733561e-05*G0_1_1_0 + 9.4720094720101e-05*G0_1_1_1 + 2.46666913333594e-05*G0_1_1_2 + 2.76266942933619e-05*G0_1_2_0 + 2.46666913333594e-05*G0_1_2_1 - 3.9466706133374e-05*G0_1_2_2 + 0.000168720168720174*G0_2_0_0 + 2.76266942933619e-05*G0_2_0_1 + 9.8666765333435e-05*G0_2_0_2 + 2.76266942933619e-05*G0_2_1_0 + 2.46666913333594e-05*G0_2_1_1 - 3.9466706133374e-05*G0_2_1_2 + 9.8666765333435e-05*G0_2_2_0 - 3.9466706133374e-05*G0_2_2_1 - 0.000700534033867391*G0_2_2_2; + A[192] = 0.0161024161024167*G0_0_0_0 + 0.00549376549376568*G0_0_0_1 + 0.00549376549376568*G0_0_0_2 + 0.00549376549376568*G0_0_1_0 + 0.00284160284160294*G0_0_1_1 + 0.0021312021312022*G0_0_1_2 + 0.00549376549376568*G0_0_2_0 + 0.0021312021312022*G0_0_2_1 + 0.00284160284160294*G0_0_2_2 + 0.00549376549376568*G0_1_0_0 + 0.00284160284160294*G0_1_0_1 + 0.0021312021312022*G0_1_0_2 + 0.00284160284160294*G0_1_1_0 + 0.00284160284160294*G0_1_1_1 + 0.00170496170496176*G0_1_1_2 + 0.0021312021312022*G0_1_2_0 + 0.00170496170496176*G0_1_2_1 + 0.00170496170496176*G0_1_2_2 + 0.00549376549376568*G0_2_0_0 + 0.0021312021312022*G0_2_0_1 + 0.00284160284160294*G0_2_0_2 + 0.0021312021312022*G0_2_1_0 + 0.00170496170496176*G0_2_1_1 + 0.00170496170496176*G0_2_1_2 + 0.00284160284160294*G0_2_2_0 + 0.00170496170496176*G0_2_2_1 + 0.00284160284160294*G0_2_2_2; + A[21] = -0.000393844838289297*G0_0_0_0 - 4.10289299178203e-05*G0_0_0_1 - 7.60556316111898e-05*G0_0_0_2 - 4.10289299178203e-05*G0_0_1_0 - 5.83778361556158e-06*G0_0_1_1 - 8.71556427112013e-06*G0_0_1_2 - 7.60556316111898e-05*G0_0_2_0 - 8.71556427112013e-06*G0_0_2_1 - 2.42555798111362e-05*G0_0_2_2 - 4.10289299178203e-05*G0_1_0_0 - 5.83778361556158e-06*G0_1_0_1 - 8.71556427112013e-06*G0_1_0_2 - 5.83778361556158e-06*G0_1_1_0 + 1.46355701911264e-05*G0_1_1_1 - 2.38444682889133e-06*G0_1_1_2 - 8.71556427112013e-06*G0_1_2_0 - 2.38444682889133e-06*G0_1_2_1 - 8.1400081400084e-06*G0_1_2_2 - 7.60556316111898e-05*G0_2_0_0 - 8.71556427112013e-06*G0_2_0_1 - 2.42555798111362e-05*G0_2_0_2 - 8.71556427112013e-06*G0_2_1_0 - 2.38444682889133e-06*G0_2_1_1 - 8.14000814000841e-06*G0_2_1_2 - 2.42555798111362e-05*G0_2_2_0 - 8.14000814000841e-06*G0_2_2_1 - 8.30445274889748e-05*G0_2_2_2; + A[52] = A[108]; + A[36] = A[21] + 2.58178035955828e-05*G0_0_0_0 + 3.83155938711508e-05*G0_0_0_2 + 3.83155938711508e-05*G0_0_2_0 + 6.14200614200636e-05*G0_0_2_2 - 2.27755783311348e-05*G0_1_1_1 + 2.27755783311347e-05*G0_1_2_2 + 3.83155938711508e-05*G0_2_0_0 + 6.14200614200636e-05*G0_2_0_2 + 2.27755783311347e-05*G0_2_1_2 + 6.14200614200636e-05*G0_2_2_0 + 2.27755783311347e-05*G0_2_2_1 + 0.000608445052889518*G0_2_2_2; + A[149] = -A[21] - 0.00220931332042451*G0_0_0_0 - 0.000467269356158262*G0_0_0_1 - 0.000297069185958085*G0_0_0_2 - 0.000467269356158262*G0_0_1_0 - 8.47711958823102e-05*G0_0_1_1 - 0.000297069185958085*G0_0_2_0 - 5.7555613111172e-07*G0_0_2_2 - 0.000467269356158262*G0_1_0_0 - 8.47711958823103e-05*G0_1_0_1 - 8.47711958823103e-05*G0_1_1_0 - 6.4297842075623e-05*G0_1_1_1 + 0.000155482377704605*G0_1_1_2 + 0.000155482377704605*G0_1_2_1 + 0.000252340252340261*G0_1_2_2 - 0.000297069185958085*G0_2_0_0 - 5.7555613111172e-07*G0_2_0_2 + 0.000155482377704605*G0_2_1_1 + 0.000252340252340261*G0_2_1_2 - 5.7555613111172e-07*G0_2_2_0 + 0.000252340252340261*G0_2_2_1 + 0.000453702675924913*G0_2_2_2; + A[208] = A[192] - 0.0132608132608137*G0_0_0_0 - 0.00265216265216275*G0_0_0_1 - 0.00378880378880392*G0_0_0_2 - 0.00265216265216275*G0_0_1_0 + 0.00265216265216274*G0_0_1_1 - 0.00378880378880392*G0_0_2_0 - 0.00113664113664118*G0_0_2_2 - 0.00265216265216275*G0_1_0_0 + 0.00265216265216274*G0_1_0_1 + 0.00265216265216274*G0_1_1_0 + 0.0132608132608137*G0_1_1_1 + 0.00378880378880392*G0_1_1_2 + 0.00378880378880392*G0_1_2_1 + 0.00113664113664117*G0_1_2_2 - 0.00378880378880392*G0_2_0_0 - 0.00113664113664118*G0_2_0_2 + 0.00378880378880392*G0_2_1_1 + 0.00113664113664117*G0_2_1_2 - 0.00113664113664118*G0_2_2_0 + 0.00113664113664117*G0_2_2_1; + A[94] = A[108] - 3.94667061333867e-06*G0_0_0_0 - 5.92000592000628e-06*G0_0_0_1 - 0.000144053477386816*G0_0_0_2 - 5.92000592000628e-06*G0_0_1_0 + 5.92000592000581e-06*G0_0_1_1 - 0.000144053477386816*G0_0_2_0 - 0.000138133471466809*G0_0_2_2 - 5.92000592000628e-06*G0_1_0_0 + 5.92000592000582e-06*G0_1_0_1 + 5.92000592000582e-06*G0_1_1_0 + 3.94667061333432e-06*G0_1_1_1 + 0.000144053477386815*G0_1_1_2 + 0.000144053477386815*G0_1_2_1 + 0.000138133471466809*G0_1_2_2 - 0.000144053477386816*G0_2_0_0 - 0.000138133471466809*G0_2_0_2 + 0.000144053477386815*G0_2_1_1 + 0.000138133471466809*G0_2_1_2 - 0.000138133471466809*G0_2_2_0 + 0.000138133471466809*G0_2_2_1; + A[139] = A[94] + 2.96000296000312e-06*G0_0_0_1 - 2.96000296000282e-06*G0_0_0_2 + 2.96000296000313e-06*G0_0_1_0 - 6.70934004267363e-05*G0_0_1_1 - 2.96000296000281e-06*G0_0_2_0 + 6.70934004267362e-05*G0_0_2_2 + 2.96000296000312e-06*G0_1_0_0 - 6.70934004267363e-05*G0_1_0_1 - 6.70934004267363e-05*G0_1_1_0 - 0.000799200799200829*G0_1_1_1 - 7.00534033867392e-05*G0_1_1_2 - 7.00534033867392e-05*G0_1_2_1 + 7.00534033867393e-05*G0_1_2_2 - 2.96000296000282e-06*G0_2_0_0 + 6.70934004267362e-05*G0_2_0_2 - 7.00534033867392e-05*G0_2_1_1 + 7.00534033867392e-05*G0_2_1_2 + 6.70934004267362e-05*G0_2_2_0 + 7.00534033867392e-05*G0_2_2_1 + 0.000799200799200827*G0_2_2_2; + A[106] = 0.000110383443716781*G0_0_0_0 + 3.76167042833725e-06*G0_0_0_1 - 4.84083817417167e-05*G0_0_0_2 + 3.76167042833725e-06*G0_0_1_0 - 2.77500277500286e-06*G0_0_1_1 - 9.00334233667597e-06*G0_0_1_2 - 4.84083817417167e-05*G0_0_2_0 - 9.00334233667597e-06*G0_0_2_1 - 4.84083817417167e-05*G0_0_2_2 + 3.76167042833725e-06*G0_1_0_0 - 2.77500277500286e-06*G0_1_0_1 - 9.00334233667597e-06*G0_1_0_2 - 2.77500277500286e-06*G0_1_1_0 + 1.19633452966794e-05*G0_1_1_1 - 2.77500277500286e-06*G0_1_1_2 - 9.00334233667597e-06*G0_1_2_0 - 2.77500277500286e-06*G0_1_2_1 + 3.76167042833721e-06*G0_1_2_2 - 4.84083817417167e-05*G0_2_0_0 - 9.00334233667597e-06*G0_2_0_1 - 4.84083817417167e-05*G0_2_0_2 - 9.00334233667597e-06*G0_2_1_0 - 2.77500277500286e-06*G0_2_1_1 + 3.76167042833721e-06*G0_2_1_2 - 4.84083817417167e-05*G0_2_2_0 + 3.76167042833721e-06*G0_2_2_1 + 0.000110383443716781*G0_2_2_2; + A[8] = -A[36] + 0.000157373490706828*G0_0_0_0 - 2.6393359726694e-05*G0_0_0_1 - 5.75556131111825e-07*G0_0_0_2 - 2.6393359726694e-05*G0_0_1_0 - 5.75556131111818e-07*G0_0_2_0 - 5.75556131111743e-07*G0_0_2_2 - 2.6393359726694e-05*G0_1_0_0 - 2.6393359726694e-05*G0_1_2_2 - 5.75556131111811e-07*G0_2_0_0 - 5.75556131111743e-07*G0_2_0_2 - 2.6393359726694e-05*G0_2_1_2 - 5.75556131111743e-07*G0_2_2_0 - 2.6393359726694e-05*G0_2_2_1 + 0.000157373490706829*G0_2_2_2; + A[85] = A[139] + 3.94667061333783e-06*G0_0_0_0 + 0.000144053477386816*G0_0_0_1 + 5.92000592000625e-06*G0_0_0_2 + 0.000144053477386816*G0_0_1_0 + 0.000138133471466809*G0_0_1_1 + 5.92000592000624e-06*G0_0_2_0 - 5.92000592000592e-06*G0_0_2_2 + 0.000144053477386816*G0_1_0_0 + 0.00013813347146681*G0_1_0_1 + 0.000138133471466809*G0_1_1_0 - 0.00013813347146681*G0_1_1_2 - 0.00013813347146681*G0_1_2_1 - 0.000144053477386815*G0_1_2_2 + 5.92000592000625e-06*G0_2_0_0 - 5.92000592000591e-06*G0_2_0_2 - 0.00013813347146681*G0_2_1_1 - 0.000144053477386815*G0_2_1_2 - 5.92000592000592e-06*G0_2_2_0 - 0.000144053477386815*G0_2_2_1 - 3.94667061333638e-06*G0_2_2_2; + A[158] = A[85] - 0.000799200799200825*G0_0_0_0 - 7.0053403386739e-05*G0_0_0_1 - 6.70934004267358e-05*G0_0_0_2 - 7.00534033867391e-05*G0_0_1_0 + 7.00534033867392e-05*G0_0_1_1 - 6.70934004267358e-05*G0_0_2_0 + 2.96000296000308e-06*G0_0_2_2 - 7.00534033867391e-05*G0_1_0_0 + 7.00534033867392e-05*G0_1_0_1 + 7.00534033867392e-05*G0_1_1_0 + 0.000799200799200828*G0_1_1_1 + 6.70934004267361e-05*G0_1_1_2 + 6.70934004267361e-05*G0_1_2_1 - 2.96000296000323e-06*G0_1_2_2 - 6.70934004267358e-05*G0_2_0_0 + 2.96000296000307e-06*G0_2_0_2 + 6.70934004267362e-05*G0_2_1_1 - 2.96000296000322e-06*G0_2_1_2 + 2.96000296000308e-06*G0_2_2_0 - 2.96000296000322e-06*G0_2_2_1; + A[212] = A[85] + 9.86667653334352e-05*G0_0_0_0 - 7.0053403386739e-05*G0_0_0_1 + 3.45333678667025e-06*G0_0_0_2 - 7.0053403386739e-05*G0_0_1_0 - 6.90667357334042e-06*G0_0_1_2 + 3.45333678667026e-06*G0_0_2_0 - 6.90667357334041e-06*G0_0_2_1 - 4.14400414400429e-05*G0_0_2_2 - 7.0053403386739e-05*G0_1_0_0 - 6.90667357334042e-06*G0_1_0_2 + 0.000897867564534264*G0_1_1_1 + 7.05467372134065e-05*G0_1_1_2 - 6.90667357334043e-06*G0_1_2_0 + 7.05467372134064e-05*G0_1_2_1 - 4.44000444000461e-05*G0_1_2_2 + 3.45333678667026e-06*G0_2_0_0 - 6.90667357334042e-06*G0_2_0_1 - 4.14400414400429e-05*G0_2_0_2 - 6.90667357334042e-06*G0_2_1_0 + 7.05467372134065e-05*G0_2_1_1 - 4.44000444000461e-05*G0_2_1_2 - 4.14400414400429e-05*G0_2_2_0 - 4.44000444000461e-05*G0_2_2_1 + 0.000137146803813473*G0_2_2_2; + A[7] = A[212] - 0.00138441805108476*G0_0_0_0 - 0.000132583465916804*G0_0_0_1 - 0.000108780108780112*G0_0_0_2 - 0.000132583465916804*G0_0_1_0 - 9.23150923150955e-05*G0_0_1_1 - 9.18834252167617e-06*G0_0_1_2 - 0.000108780108780112*G0_0_2_0 - 9.18834252167617e-06*G0_0_2_1 + 6.98684032017389e-05*G0_0_2_2 - 0.000132583465916804*G0_1_0_0 - 9.23150923150955e-05*G0_1_0_1 - 9.18834252167617e-06*G0_1_0_2 - 9.23150923150955e-05*G0_1_1_0 - 0.000188885188885196*G0_1_1_1 - 9.00334233667606e-06*G0_1_1_2 - 9.18834252167617e-06*G0_1_2_0 - 9.00334233667606e-06*G0_1_2_1 + 7.75150775150801e-05*G0_1_2_2 - 0.000108780108780112*G0_2_0_0 - 9.18834252167616e-06*G0_2_0_1 + 6.98684032017389e-05*G0_2_0_2 - 9.18834252167616e-06*G0_2_1_0 - 9.00334233667605e-06*G0_2_1_1 + 7.75150775150801e-05*G0_2_1_2 + 6.98684032017389e-05*G0_2_2_0 + 7.75150775150801e-05*G0_2_2_1 + 9.7926764593435e-05*G0_2_2_2; + A[42] = -A[212] - 0.000236800236800245*G0_0_0_0 - 4.93333826667177e-05*G0_0_0_1 - 8.88000888000915e-06*G0_0_0_2 - 4.93333826667177e-05*G0_0_1_0 + 1.97333530666871e-05*G0_0_1_1 + 3.94667061333746e-06*G0_0_1_2 - 8.88000888000915e-06*G0_0_2_0 + 3.94667061333745e-06*G0_0_2_1 - 7.89334122667479e-06*G0_0_2_2 - 4.93333826667177e-05*G0_1_0_0 + 1.97333530666871e-05*G0_1_0_1 + 3.94667061333746e-06*G0_1_0_2 + 1.97333530666871e-05*G0_1_1_0 + 0.000177600177600184*G0_1_1_1 + 2.07200207200215e-05*G0_1_1_2 + 3.94667061333745e-06*G0_1_2_0 + 2.07200207200215e-05*G0_1_2_1 - 1.18400118400122e-05*G0_1_2_2 - 8.88000888000915e-06*G0_2_0_0 + 3.94667061333744e-06*G0_2_0_1 - 7.89334122667479e-06*G0_2_0_2 + 3.94667061333744e-06*G0_2_1_0 + 2.07200207200215e-05*G0_2_1_1 - 1.18400118400122e-05*G0_2_1_2 - 7.89334122667479e-06*G0_2_2_0 - 1.18400118400122e-05*G0_2_2_1 + 0.000148000148000153*G0_2_2_2; + A[122] = A[42] + 0.000257520257520267*G0_0_0_0 + 0.000103846770513441*G0_0_0_1 + 4.193337526671e-06*G0_0_0_2 + 0.000103846770513441*G0_0_1_0 + 4.94978272756067e-05*G0_0_1_1 + 4.85111596222721e-06*G0_0_1_2 + 4.193337526671e-06*G0_0_2_0 + 4.85111596222722e-06*G0_0_2_1 + 7.86045230489702e-05*G0_0_2_2 + 0.000103846770513441*G0_1_0_0 + 4.94978272756067e-05*G0_1_0_1 + 4.85111596222722e-06*G0_1_0_2 + 4.94978272756067e-05*G0_1_1_0 - 2.44200244200255e-05*G0_1_1_1 - 1.56222378444611e-06*G0_1_1_2 + 4.85111596222722e-06*G0_1_2_0 - 1.56222378444611e-06*G0_1_2_1 + 3.73289262178165e-05*G0_1_2_2 + 4.193337526671e-06*G0_2_0_0 + 4.85111596222723e-06*G0_2_0_1 + 7.86045230489703e-05*G0_2_0_2 + 4.85111596222722e-06*G0_2_1_0 - 1.56222378444611e-06*G0_2_1_1 + 3.73289262178165e-05*G0_2_1_2 + 7.86045230489702e-05*G0_2_2_0 + 3.73289262178165e-05*G0_2_2_1 + 0.00174393507726847*G0_2_2_2; + A[26] = A[122] + 8.38667505334201e-06*G0_0_0_1 - 8.38667505334205e-06*G0_0_0_2 + 8.38667505334201e-06*G0_0_1_0 + 0.000119880119880125*G0_0_1_1 - 8.38667505334205e-06*G0_0_2_0 - 0.000119880119880124*G0_0_2_2 + 8.38667505334201e-06*G0_1_0_0 + 0.000119880119880125*G0_1_0_1 + 0.000119880119880125*G0_1_1_0 + 0.00170422170422177*G0_1_1_1 + 5.71445015889482e-05*G0_1_1_2 + 5.71445015889482e-05*G0_1_2_1 - 5.71445015889481e-05*G0_1_2_2 - 8.38667505334206e-06*G0_2_0_0 - 0.000119880119880124*G0_2_0_2 + 5.71445015889482e-05*G0_2_1_1 - 5.71445015889481e-05*G0_2_1_2 - 0.000119880119880124*G0_2_2_0 - 5.71445015889481e-05*G0_2_2_1 - 0.00170422170422176*G0_2_2_2; + A[181] = A[26] - 0.000257520257520267*G0_0_0_0 - 4.19333752667121e-06*G0_0_0_1 - 0.000103846770513441*G0_0_0_2 - 4.19333752667118e-06*G0_0_1_0 - 7.86045230489711e-05*G0_0_1_1 - 4.85111596222734e-06*G0_0_1_2 - 0.000103846770513441*G0_0_2_0 - 4.85111596222734e-06*G0_0_2_1 - 4.94978272756068e-05*G0_0_2_2 - 4.19333752667119e-06*G0_1_0_0 - 7.86045230489711e-05*G0_1_0_1 - 4.85111596222734e-06*G0_1_0_2 - 7.86045230489711e-05*G0_1_1_0 - 0.00174393507726848*G0_1_1_1 - 3.73289262178168e-05*G0_1_1_2 - 4.85111596222734e-06*G0_1_2_0 - 3.73289262178168e-05*G0_1_2_1 + 1.56222378444597e-06*G0_1_2_2 - 0.000103846770513441*G0_2_0_0 - 4.85111596222734e-06*G0_2_0_1 - 4.94978272756067e-05*G0_2_0_2 - 4.85111596222733e-06*G0_2_1_0 - 3.73289262178168e-05*G0_2_1_1 + 1.56222378444597e-06*G0_2_1_2 - 4.94978272756067e-05*G0_2_2_0 + 1.56222378444597e-06*G0_2_2_1 + 2.44200244200254e-05*G0_2_2_2; + A[191] = -A[42] + 0.0013813347146681*G0_0_0_0 - 3.74933708267052e-05*G0_0_0_1 + 0.000496787163453847*G0_0_0_2 - 3.74933708267051e-05*G0_0_1_0 - 0.000315733649066993*G0_0_1_1 + 6.90667357334057e-06*G0_0_1_2 + 0.000496787163453847*G0_0_2_0 + 6.9066735733406e-06*G0_0_2_1 + 0.000272320272320282*G0_0_2_2 - 3.74933708267051e-05*G0_1_0_0 - 0.000315733649066993*G0_1_0_1 + 6.90667357334056e-06*G0_1_0_2 - 0.000315733649066993*G0_1_1_0 - 0.00120373453706791*G0_1_1_1 - 0.000231373564706906*G0_1_1_2 + 6.90667357334056e-06*G0_1_2_0 - 0.000231373564706906*G0_1_2_1 + 0.000496787163453847*G0_2_0_0 + 6.90667357334057e-06*G0_2_0_1 + 0.000272320272320282*G0_2_0_2 + 6.90667357334058e-06*G0_2_1_0 - 0.000231373564706906*G0_2_1_1 + 0.000272320272320282*G0_2_2_0 + 7.4000074000076e-05*G0_2_2_2; + A[27] = A[181]; + A[132] = -A[181] + 0.00138133471466809*G0_0_0_0 + 0.000496787163453846*G0_0_0_1 - 3.74933708267064e-05*G0_0_0_2 + 0.000496787163453846*G0_0_1_0 + 0.000272320272320281*G0_0_1_1 + 6.90667357334012e-06*G0_0_1_2 - 3.74933708267065e-05*G0_0_2_0 + 6.90667357334015e-06*G0_0_2_1 - 0.000315733649066994*G0_0_2_2 + 0.000496787163453846*G0_1_0_0 + 0.000272320272320281*G0_1_0_1 + 6.90667357334012e-06*G0_1_0_2 + 0.000272320272320281*G0_1_1_0 + 7.40000740000748e-05*G0_1_1_1 + 6.90667357334016e-06*G0_1_2_0 - 0.000231373564706906*G0_1_2_2 - 3.74933708267065e-05*G0_2_0_0 + 6.90667357334015e-06*G0_2_0_1 - 0.000315733649066994*G0_2_0_2 + 6.90667357334017e-06*G0_2_1_0 - 0.000231373564706906*G0_2_1_2 - 0.000315733649066994*G0_2_2_0 - 0.000231373564706906*G0_2_2_1 - 0.00120373453706791*G0_2_2_2; + A[188] = A[132]; + A[182] = A[42]; + A[51] = A[7] + 0.00152386707942268*G0_0_0_0 + 7.60145204589674e-05*G0_0_0_1 + 0.000160580160580166*G0_0_0_2 + 7.60145204589674e-05*G0_0_1_0 + 3.57461468572592e-05*G0_0_1_1 + 6.88611799722936e-06*G0_0_1_2 + 0.000160580160580166*G0_0_2_0 + 6.88611799722935e-06*G0_0_2_1 + 2.48722470944701e-06*G0_0_2_2 + 7.60145204589674e-05*G0_1_0_0 + 3.57461468572592e-05*G0_1_0_1 + 6.88611799722935e-06*G0_1_0_2 + 3.57461468572592e-05*G0_1_1_0 + 0.000328334217223118*G0_1_1_1 + 6.08033941367298e-05*G0_1_1_2 + 6.88611799722935e-06*G0_1_2_0 + 6.08033941367297e-05*G0_1_2_1 - 5.15944960389407e-06*G0_1_2_2 + 0.000160580160580166*G0_2_0_0 + 6.88611799722935e-06*G0_2_0_1 + 2.487224709447e-06*G0_2_0_2 + 6.88611799722935e-06*G0_2_1_0 + 6.08033941367297e-05*G0_2_1_1 - 5.1594496038941e-06*G0_2_1_2 + 2.48722470944701e-06*G0_2_2_0 - 5.15944960389408e-06*G0_2_2_1 + 7.80289669178587e-05*G0_2_2_2; + A[10] = A[51] - 0.00152386707942269*G0_0_0_0 - 0.00011979789757568*G0_0_0_1 - 0.000116796783463454*G0_0_0_2 - 0.00011979789757568*G0_0_1_0 + 8.03723025945285e-06*G0_0_1_1 - 6.88611799722936e-06*G0_0_1_2 - 0.000116796783463454*G0_0_2_0 - 6.88611799722936e-06*G0_0_2_1 - 4.6270601826159e-05*G0_0_2_2 - 0.00011979789757568*G0_1_0_0 + 8.03723025945285e-06*G0_1_0_1 - 6.88611799722936e-06*G0_1_0_2 + 8.03723025945285e-06*G0_1_1_0 - 6.98889587778421e-06*G0_1_1_1 - 2.50983584316926e-05*G0_1_1_2 - 6.88611799722936e-06*G0_1_2_0 - 2.50983584316926e-05*G0_1_2_1 - 3.05455861011428e-05*G0_1_2_2 - 0.000116796783463454*G0_2_0_0 - 6.88611799722936e-06*G0_2_0_1 - 4.6270601826159e-05*G0_2_0_2 - 6.88611799722936e-06*G0_2_1_0 - 2.50983584316926e-05*G0_2_1_1 - 3.05455861011428e-05*G0_2_1_2 - 4.6270601826159e-05*G0_2_2_0 - 3.05455861011428e-05*G0_2_2_1 - 0.000399374288263191*G0_2_2_2; + A[100] = -A[51] - 0.00316588761033216*G0_0_0_0 - 0.000344675900231468*G0_0_0_1 - 0.000517013850347201*G0_0_0_2 - 0.000344675900231468*G0_0_1_0 - 6.3475619031177e-05*G0_0_1_1 - 6.64356219911798e-05*G0_0_1_2 - 0.000517013850347201*G0_0_2_0 - 6.64356219911798e-05*G0_0_2_1 - 9.63645408089883e-05*G0_0_2_2 - 0.000344675900231468*G0_1_0_0 - 6.3475619031177e-05*G0_1_0_1 - 6.64356219911798e-05*G0_1_0_2 - 6.3475619031177e-05*G0_1_1_0 + 8.41956397511981e-05*G0_1_1_1 - 7.89334122667471e-06*G0_1_1_2 - 6.64356219911798e-05*G0_1_2_0 - 7.89334122667472e-06*G0_1_2_1 - 2.63111374222477e-06*G0_1_2_2 - 0.000517013850347201*G0_2_0_0 - 6.64356219911798e-05*G0_2_0_1 - 9.63645408089883e-05*G0_2_0_2 - 6.64356219911798e-05*G0_2_1_0 - 7.89334122667472e-06*G0_2_1_1 - 2.63111374222479e-06*G0_2_1_2 - 9.63645408089883e-05*G0_2_2_0 - 2.63111374222478e-06*G0_2_2_1 + 0.000368355923911493*G0_2_2_2; + A[218] = -A[100] - 0.00421307087973769*G0_0_0_0 - 0.000670934004267361*G0_0_0_1 - 0.00042624042624044*G0_0_0_2 - 0.000670934004267361*G0_0_1_0 - 0.000318693652026996*G0_0_1_1 + 1.97333530666873e-06*G0_0_1_2 - 0.00042624042624044*G0_0_2_0 + 1.97333530666872e-06*G0_0_2_1 + 0.00112973446306784*G0_0_2_2 - 0.000670934004267361*G0_1_0_0 - 0.000318693652026996*G0_1_0_1 + 1.97333530666876e-06*G0_1_0_2 - 0.000318693652026996*G0_1_1_0 - 0.000536747203413889*G0_1_1_1 - 3.94667061333745e-06*G0_1_1_2 + 1.97333530666873e-06*G0_1_2_0 - 3.94667061333746e-06*G0_1_2_1 + 0.000797227463894158*G0_1_2_2 - 0.00042624042624044*G0_2_0_0 + 1.97333530666873e-06*G0_2_0_1 + 0.00112973446306784*G0_2_0_2 + 1.97333530666876e-06*G0_2_1_0 - 3.94667061333744e-06*G0_2_1_1 + 0.000797227463894158*G0_2_1_2 + 0.00112973446306784*G0_2_2_0 + 0.000797227463894158*G0_2_2_1 + 0.00603840603840625*G0_2_2_2; + A[186] = A[218] + 0.00678827345494036*G0_0_0_0 + 0.00113664113664118*G0_0_0_1 + 0.00110506777173448*G0_0_0_2 + 0.00113664113664118*G0_0_1_0 + 0.000299946966613644*G0_0_1_1 + 0.00110506777173448*G0_0_2_0 - 0.00110506777173448*G0_0_2_2 + 0.00113664113664118*G0_1_0_0 + 0.000299946966613644*G0_1_0_1 + 0.000299946966613644*G0_1_1_0 - 0.000299946966613643*G0_1_1_2 - 0.000299946966613643*G0_1_2_1 - 0.00113664113664118*G0_1_2_2 + 0.00110506777173448*G0_2_0_0 - 0.00110506777173448*G0_2_0_2 - 0.000299946966613643*G0_2_1_1 - 0.00113664113664118*G0_2_1_2 - 0.00110506777173448*G0_2_2_0 - 0.00113664113664118*G0_2_2_1 - 0.00678827345494035*G0_2_2_2; + A[89] = A[218] + 0.00042624042624044*G0_0_0_0 + 7.10400710400735e-05*G0_0_0_1 - 8.68267534934232e-05*G0_0_0_2 + 7.10400710400735e-05*G0_0_1_0 - 7.10400710400733e-05*G0_0_1_1 - 8.68267534934232e-05*G0_0_2_0 - 0.000426240426240441*G0_0_2_2 + 7.10400710400736e-05*G0_1_0_0 - 7.10400710400733e-05*G0_1_0_1 - 7.10400710400733e-05*G0_1_1_0 - 0.000426240426240441*G0_1_1_1 + 8.68267534934234e-05*G0_1_1_2 + 8.68267534934234e-05*G0_1_2_1 + 0.000426240426240442*G0_1_2_2 - 8.68267534934232e-05*G0_2_0_0 - 0.000426240426240441*G0_2_0_2 + 8.68267534934234e-05*G0_2_1_1 + 0.000426240426240442*G0_2_1_2 - 0.000426240426240441*G0_2_2_0 + 0.000426240426240442*G0_2_2_1; + A[153] = -A[89] - 0.000536747203413888*G0_0_0_0 - 0.000318693652026996*G0_0_0_1 - 3.94667061333737e-06*G0_0_0_2 - 0.000318693652026996*G0_0_1_0 - 0.000670934004267361*G0_0_1_1 + 1.9733353066687e-06*G0_0_1_2 - 3.94667061333737e-06*G0_0_2_0 + 1.97333530666869e-06*G0_0_2_1 + 0.000797227463894158*G0_0_2_2 - 0.000318693652026996*G0_1_0_0 - 0.000670934004267361*G0_1_0_1 + 1.9733353066687e-06*G0_1_0_2 - 0.000670934004267361*G0_1_1_0 - 0.0042130708797377*G0_1_1_1 - 0.000426240426240442*G0_1_1_2 + 1.97333530666869e-06*G0_1_2_0 - 0.000426240426240442*G0_1_2_1 + 0.00112973446306784*G0_1_2_2 - 3.94667061333737e-06*G0_2_0_0 + 1.9733353066687e-06*G0_2_0_1 + 0.000797227463894158*G0_2_0_2 + 1.97333530666869e-06*G0_2_1_0 - 0.000426240426240442*G0_2_1_1 + 0.00112973446306784*G0_2_1_2 + 0.000797227463894158*G0_2_2_0 + 0.00112973446306784*G0_2_2_1 + 0.00603840603840624*G0_2_2_2; + A[215] = A[89]; + A[61] = A[7] + 0.00119553286219957*G0_0_0_0 + 4.02683736017083e-05*G0_0_0_1 + 9.97767664434362e-05*G0_0_0_2 + 4.02683736017083e-05*G0_0_1_0 - 4.02683736017085e-05*G0_0_1_1 + 9.97767664434362e-05*G0_0_2_0 + 7.64667431334119e-06*G0_0_2_2 + 4.02683736017083e-05*G0_1_0_0 - 4.02683736017085e-05*G0_1_0_1 - 4.02683736017085e-05*G0_1_1_0 - 0.00119553286219957*G0_1_1_1 - 9.97767664434362e-05*G0_1_1_2 - 9.97767664434362e-05*G0_1_2_1 - 7.64667431334103e-06*G0_1_2_2 + 9.97767664434362e-05*G0_2_0_0 + 7.64667431334117e-06*G0_2_0_2 - 9.97767664434362e-05*G0_2_1_1 - 7.64667431334103e-06*G0_2_1_2 + 7.64667431334118e-06*G0_2_2_0 - 7.64667431334104e-06*G0_2_2_1; + A[142] = A[100] - 0.00021312021312022*G0_0_0_1 + 0.00021312021312022*G0_0_0_2 - 0.00021312021312022*G0_0_1_0 - 4.34133767467113e-05*G0_0_1_1 + 0.00021312021312022*G0_0_2_0 + 4.34133767467118e-05*G0_0_2_2 - 0.00021312021312022*G0_1_0_0 - 4.34133767467113e-05*G0_1_0_1 - 4.34133767467113e-05*G0_1_1_0 + 0.000213120213120222*G0_1_1_1 + 3.5520035520037e-05*G0_1_1_2 + 3.5520035520037e-05*G0_1_2_1 - 3.55200355200365e-05*G0_1_2_2 + 0.00021312021312022*G0_2_0_0 + 4.34133767467118e-05*G0_2_0_2 + 3.5520035520037e-05*G0_2_1_1 - 3.55200355200365e-05*G0_2_1_2 + 4.34133767467118e-05*G0_2_2_0 - 3.55200355200365e-05*G0_2_2_1 - 0.00021312021312022*G0_2_2_2; + A[66] = A[94]; + A[91] = A[21]; + A[109] = -A[212] + 2.26933560266907e-05*G0_0_0_0 + 8.23867490534185e-05*G0_0_0_1 - 9.54600954600984e-05*G0_0_0_2 + 8.23867490534184e-05*G0_0_1_0 + 8.23867490534184e-05*G0_0_1_1 - 4.44000444000447e-06*G0_0_1_2 - 9.54600954600984e-05*G0_0_2_0 - 4.44000444000446e-06*G0_0_2_1 + 6.90667357334059e-06*G0_0_2_2 + 8.23867490534185e-05*G0_1_0_0 + 8.23867490534184e-05*G0_1_0_1 - 4.44000444000446e-06*G0_1_0_2 + 8.23867490534184e-05*G0_1_1_0 + 2.26933560266894e-05*G0_1_1_1 - 9.54600954600983e-05*G0_1_1_2 - 4.44000444000447e-06*G0_1_2_0 - 9.54600954600983e-05*G0_1_2_1 + 6.90667357334096e-06*G0_1_2_2 - 9.54600954600984e-05*G0_2_0_0 - 4.44000444000448e-06*G0_2_0_1 + 6.90667357334053e-06*G0_2_0_2 - 4.44000444000448e-06*G0_2_1_0 - 9.54600954600983e-05*G0_2_1_1 + 6.90667357334093e-06*G0_2_1_2 + 6.90667357334055e-06*G0_2_2_0 + 6.90667357334093e-06*G0_2_2_1 + 0.00185246851913525*G0_2_2_2; + A[2] = -9.893398782288e-05*G0_0_0_0 - 2.66194710639163e-06*G0_0_0_1 - 8.2325082325085e-06*G0_0_0_2 - 2.66194710639163e-06*G0_0_1_0 + 1.42861253972371e-06*G0_0_1_1 - 8.2325082325085e-06*G0_0_2_0 - 8.23250823250852e-06*G0_0_2_2 - 2.66194710639163e-06*G0_1_0_0 + 1.42861253972371e-06*G0_1_0_1 + 1.42861253972371e-06*G0_1_1_0 + 1.55811266922384e-05*G0_1_1_1 + 1.42861253972371e-06*G0_1_1_2 + 1.42861253972371e-06*G0_1_2_1 - 2.66194710639165e-06*G0_1_2_2 - 8.2325082325085e-06*G0_2_0_0 - 8.23250823250852e-06*G0_2_0_2 + 1.42861253972371e-06*G0_2_1_1 - 2.66194710639165e-06*G0_2_1_2 - 8.23250823250852e-06*G0_2_2_0 - 2.66194710639165e-06*G0_2_2_1 - 9.89339878228802e-05*G0_2_2_2; + A[1] = A[2] - 0.000114515114515119*G0_1_1_1 + 0.000114515114515119*G0_2_2_2; + A[41] = A[1] + 1.58894603339054e-05*G0_0_0_0 - 1.60230715786277e-05*G0_0_0_1 - 1.60230715786277e-05*G0_0_1_0 - 6.78231233786812e-05*G0_0_1_1 - 1.60230715786277e-05*G0_1_0_0 - 6.78231233786812e-05*G0_1_0_1 - 6.78231233786812e-05*G0_1_1_0 - 0.000294910850466416*G0_1_1_1 - 3.83669828114286e-05*G0_1_1_2 - 3.83669828114286e-05*G0_1_2_1 - 3.83669828114286e-05*G0_2_1_1 - 9.45556501112013e-07*G0_2_2_2; + A[16] = -A[41] - 4.38861549972675e-05*G0_0_0_0 - 9.66112077223219e-06*G0_0_0_1 + 4.91278269056065e-06*G0_0_0_2 - 9.66112077223219e-06*G0_0_1_0 + 2.26111337222479e-06*G0_0_1_1 + 4.91278269056065e-06*G0_0_2_0 + 1.06683440016777e-05*G0_0_2_2 - 9.66112077223219e-06*G0_1_0_0 + 2.26111337222479e-06*G0_1_0_1 + 2.2611133722248e-06*G0_1_1_0 + 0.00140559029447923*G0_1_1_1 + 3.7287815065594e-05*G0_1_1_2 + 3.7287815065594e-05*G0_1_2_1 + 8.75667542334238e-06*G0_1_2_2 + 4.91278269056065e-06*G0_2_0_0 + 1.06683440016777e-05*G0_2_0_2 + 3.7287815065594e-05*G0_2_1_1 + 8.75667542334237e-06*G0_2_1_2 + 1.06683440016777e-05*G0_2_2_0 + 8.75667542334237e-06*G0_2_2_1 + 5.37939426828335e-05*G0_2_2_2; + A[165] = A[41] + 0.000608445052889518*G0_0_0_0 + 6.14200614200636e-05*G0_0_0_1 + 2.27755783311346e-05*G0_0_0_2 + 6.14200614200636e-05*G0_0_1_0 + 3.83155938711507e-05*G0_0_1_1 + 2.27755783311346e-05*G0_0_2_0 + 6.14200614200636e-05*G0_1_0_0 + 3.83155938711507e-05*G0_1_0_1 + 3.83155938711507e-05*G0_1_1_0 + 2.58178035955813e-05*G0_1_1_1 + 2.27755783311346e-05*G0_2_0_0 - 2.27755783311348e-05*G0_2_2_2; + A[57] = -A[41] + 0.000453702675924911*G0_0_0_0 - 5.75556131112452e-07*G0_0_0_1 + 0.00025234025234026*G0_0_0_2 - 5.75556131112428e-07*G0_0_1_0 - 0.000297069185958086*G0_0_1_1 + 0.00025234025234026*G0_0_2_0 + 0.000155482377704605*G0_0_2_2 - 5.75556131112448e-07*G0_1_0_0 - 0.000297069185958086*G0_1_0_1 - 0.000297069185958086*G0_1_1_0 - 0.00220931332042451*G0_1_1_1 - 0.000467269356158262*G0_1_1_2 - 0.000467269356158262*G0_1_2_1 - 8.47711958823104e-05*G0_1_2_2 + 0.00025234025234026*G0_2_0_0 + 0.000155482377704605*G0_2_0_2 - 0.000467269356158262*G0_2_1_1 - 8.47711958823105e-05*G0_2_1_2 + 0.000155482377704605*G0_2_2_0 - 8.47711958823104e-05*G0_2_2_1 - 6.42978420756231e-05*G0_2_2_2; + A[31] = A[2] + 0.000114515114515118*G0_0_0_0 - 0.000114515114515119*G0_1_1_1; + A[60] = A[31] - 3.61778139555962e-06*G0_0_0_0 + 0.000209317431539662*G0_1_1_1 - 4.01758735092082e-05*G0_1_1_2 - 4.01758735092082e-05*G0_1_2_1 - 4.01758735092082e-05*G0_1_2_2 - 4.01758735092082e-05*G0_2_1_1 - 4.01758735092082e-05*G0_2_1_2 - 4.01758735092082e-05*G0_2_2_1 + 0.000209317431539661*G0_2_2_2; + A[4] = A[60]; + A[11] = A[165]; + A[32] = A[16] - 1.54166820833497e-06*G0_0_0_1 + 1.54166820833492e-06*G0_0_0_2 - 1.54166820833497e-06*G0_0_1_0 - 6.52639541528456e-05*G0_0_1_1 + 1.54166820833493e-06*G0_0_2_0 + 6.52639541528453e-05*G0_0_2_2 - 1.54166820833497e-06*G0_1_0_0 - 6.52639541528456e-05*G0_1_0_1 - 6.52639541528456e-05*G0_1_1_0 - 0.00176027676027682*G0_1_1_1 - 6.37222859445102e-05*G0_1_1_2 - 6.37222859445102e-05*G0_1_2_1 + 6.37222859445104e-05*G0_1_2_2 + 1.54166820833493e-06*G0_2_0_0 + 6.52639541528453e-05*G0_2_0_2 - 6.37222859445102e-05*G0_2_1_1 + 6.37222859445104e-05*G0_2_1_2 + 6.52639541528453e-05*G0_2_2_0 + 6.37222859445104e-05*G0_2_2_1 + 0.00176027676027682*G0_2_2_2; + A[5] = A[31] - 9.45556501112296e-07*G0_0_0_0 - 3.83669828114286e-05*G0_0_2_2 + 1.5889460333905e-05*G0_1_1_1 - 1.60230715786278e-05*G0_1_1_2 - 1.60230715786278e-05*G0_1_2_1 - 6.78231233786814e-05*G0_1_2_2 - 3.83669828114286e-05*G0_2_0_2 - 1.60230715786278e-05*G0_2_1_1 - 6.78231233786814e-05*G0_2_1_2 - 3.83669828114286e-05*G0_2_2_0 - 6.78231233786814e-05*G0_2_2_1 - 0.000294910850466417*G0_2_2_2; + A[15] = A[1]; + A[137] = A[1] - 0.000294910850466416*G0_0_0_0 - 6.78231233786813e-05*G0_0_0_1 - 3.83669828114285e-05*G0_0_0_2 - 6.78231233786813e-05*G0_0_1_0 - 1.60230715786277e-05*G0_0_1_1 - 3.83669828114285e-05*G0_0_2_0 - 6.78231233786813e-05*G0_1_0_0 - 1.60230715786277e-05*G0_1_0_1 - 1.60230715786277e-05*G0_1_1_0 + 1.58894603339055e-05*G0_1_1_1 - 3.83669828114285e-05*G0_2_0_0 - 9.45556501112391e-07*G0_2_2_2; + A[103] = -A[137] - 0.00220931332042451*G0_0_0_0 - 0.000297069185958085*G0_0_0_1 - 0.000467269356158261*G0_0_0_2 - 0.000297069185958085*G0_0_1_0 - 5.75556131112204e-07*G0_0_1_1 - 0.000467269356158261*G0_0_2_0 - 8.47711958823099e-05*G0_0_2_2 - 0.000297069185958085*G0_1_0_0 - 5.75556131112214e-07*G0_1_0_1 - 5.75556131112228e-07*G0_1_1_0 + 0.000453702675924913*G0_1_1_1 + 0.000252340252340261*G0_1_1_2 + 0.000252340252340261*G0_1_2_1 + 0.000155482377704605*G0_1_2_2 - 0.000467269356158261*G0_2_0_0 - 8.47711958823099e-05*G0_2_0_2 + 0.000252340252340261*G0_2_1_1 + 0.000155482377704605*G0_2_1_2 - 8.47711958823099e-05*G0_2_2_0 + 0.000155482377704605*G0_2_2_1 - 6.42978420756222e-05*G0_2_2_2; + A[201] = A[103]; + A[133] = A[21] + 0.000314911426022549*G0_0_0_0 + 0.000198895754451317*G0_0_0_1 - 2.87778065555835e-06*G0_0_0_2 + 0.000198895754451317*G0_0_1_0 + 0.000266318044095831*G0_0_1_1 - 2.87778065555838e-06*G0_0_2_0 - 0.000401984846429304*G0_0_2_2 + 0.000198895754451317*G0_1_0_0 + 0.000266318044095831*G0_1_0_1 + 0.000266318044095831*G0_1_1_0 + 0.000522111633222762*G0_1_1_1 + 2.60644705089158e-05*G0_1_1_2 + 2.60644705089158e-05*G0_1_2_1 - 0.000212873546206887*G0_1_2_2 - 2.87778065555838e-06*G0_2_0_0 - 0.000401984846429304*G0_2_0_2 + 2.60644705089158e-05*G0_2_1_1 - 0.000212873546206887*G0_2_1_2 - 0.000401984846429304*G0_2_2_0 - 0.000212873546206887*G0_2_2_1 - 0.00173242395464623*G0_2_2_2; + A[68] = -A[186] + 0.00603840603840625*G0_0_0_0 + 0.000797227463894159*G0_0_0_1 + 0.00112973446306784*G0_0_0_2 + 0.000797227463894159*G0_0_1_0 - 3.94667061333711e-06*G0_0_1_1 + 1.97333530666891e-06*G0_0_1_2 + 0.00112973446306783*G0_0_2_0 + 1.97333530666885e-06*G0_0_2_1 - 0.000426240426240441*G0_0_2_2 + 0.000797227463894159*G0_1_0_0 - 3.94667061333711e-06*G0_1_0_1 + 1.97333530666892e-06*G0_1_0_2 - 3.94667061333711e-06*G0_1_1_0 - 0.000536747203413889*G0_1_1_1 - 0.000318693652026996*G0_1_1_2 + 1.97333530666889e-06*G0_1_2_0 - 0.000318693652026996*G0_1_2_1 - 0.000670934004267361*G0_1_2_2 + 0.00112973446306784*G0_2_0_0 + 1.97333530666892e-06*G0_2_0_1 - 0.000426240426240441*G0_2_0_2 + 1.97333530666891e-06*G0_2_1_0 - 0.000318693652026996*G0_2_1_1 - 0.00067093400426736*G0_2_1_2 - 0.000426240426240441*G0_2_2_0 - 0.000670934004267361*G0_2_2_1 - 0.00421307087973769*G0_2_2_2; + A[110] = A[68] - 0.00021312021312022*G0_0_0_0 - 3.55200355200366e-05*G0_0_0_1 + 4.34133767467117e-05*G0_0_0_2 - 3.55200355200366e-05*G0_0_1_0 + 3.55200355200368e-05*G0_0_1_1 + 4.34133767467117e-05*G0_0_2_0 + 0.000213120213120221*G0_0_2_2 - 3.55200355200366e-05*G0_1_0_0 + 3.55200355200368e-05*G0_1_0_1 + 3.55200355200368e-05*G0_1_1_0 + 0.000213120213120221*G0_1_1_1 - 4.34133767467114e-05*G0_1_1_2 - 4.34133767467114e-05*G0_1_2_1 - 0.00021312021312022*G0_1_2_2 + 4.34133767467117e-05*G0_2_0_0 + 0.000213120213120221*G0_2_0_2 - 4.34133767467114e-05*G0_2_1_1 - 0.00021312021312022*G0_2_1_2 + 0.000213120213120221*G0_2_2_0 - 0.00021312021312022*G0_2_2_1; + A[198] = -A[110] - 0.000536747203413888*G0_0_0_0 - 3.94667061333742e-06*G0_0_0_1 - 0.000318693652026996*G0_0_0_2 - 3.94667061333744e-06*G0_0_1_0 + 0.000797227463894159*G0_0_1_1 + 1.97333530666895e-06*G0_0_1_2 - 0.000318693652026996*G0_0_2_0 + 1.97333530666898e-06*G0_0_2_1 - 0.000670934004267359*G0_0_2_2 - 3.94667061333745e-06*G0_1_0_0 + 0.000797227463894159*G0_1_0_1 + 1.97333530666895e-06*G0_1_0_2 + 0.000797227463894159*G0_1_1_0 + 0.00603840603840626*G0_1_1_1 + 0.00112973446306784*G0_1_1_2 + 1.97333530666892e-06*G0_1_2_0 + 0.00112973446306784*G0_1_2_1 - 0.000426240426240439*G0_1_2_2 - 0.000318693652026996*G0_2_0_0 + 1.97333530666896e-06*G0_2_0_1 - 0.000670934004267359*G0_2_0_2 + 1.97333530666894e-06*G0_2_1_0 + 0.00112973446306784*G0_2_1_1 - 0.000426240426240439*G0_2_1_2 - 0.000670934004267359*G0_2_2_0 - 0.000426240426240439*G0_2_2_1 - 0.00421307087973768*G0_2_2_2; + A[169] = A[68] - 9.37334270667636e-05*G0_0_0_1 + 9.37334270667636e-05*G0_0_0_2 - 9.37334270667636e-05*G0_0_1_0 - 0.000509120509120526*G0_0_1_1 + 9.37334270667636e-05*G0_0_2_0 + 0.000509120509120527*G0_0_2_2 - 9.37334270667636e-05*G0_1_0_0 - 0.000509120509120526*G0_1_0_1 - 0.000509120509120527*G0_1_1_0 - 0.00325008325008336*G0_1_1_1 - 0.000281200281200291*G0_1_1_2 - 0.000281200281200291*G0_1_2_1 + 0.000281200281200291*G0_1_2_2 + 9.37334270667636e-05*G0_2_0_0 + 0.000509120509120527*G0_2_0_2 - 0.000281200281200291*G0_2_1_1 + 0.000281200281200291*G0_2_1_2 + 0.000509120509120527*G0_2_2_0 + 0.000281200281200291*G0_2_2_1 + 0.00325008325008336*G0_2_2_2; + A[71] = A[169]; + A[82] = A[110]; + A[45] = A[31] - 9.45556501112026e-07*G0_0_0_0 - 3.83669828114287e-05*G0_0_1_1 - 3.83669828114287e-05*G0_1_0_1 - 3.83669828114287e-05*G0_1_1_0 - 0.000294910850466418*G0_1_1_1 - 6.78231233786816e-05*G0_1_1_2 - 6.78231233786816e-05*G0_1_2_1 - 1.60230715786278e-05*G0_1_2_2 - 6.78231233786816e-05*G0_2_1_1 - 1.60230715786278e-05*G0_2_1_2 - 1.60230715786278e-05*G0_2_2_1 + 1.58894603339051e-05*G0_2_2_2; + A[47] = A[45] - 2.27755783311347e-05*G0_0_0_0 + 2.27755783311347e-05*G0_0_2_2 + 2.58178035955838e-05*G0_1_1_1 + 3.83155938711511e-05*G0_1_1_2 + 3.8315593871151e-05*G0_1_2_1 + 6.14200614200637e-05*G0_1_2_2 + 2.27755783311347e-05*G0_2_0_2 + 3.8315593871151e-05*G0_2_1_1 + 6.14200614200637e-05*G0_2_1_2 + 2.27755783311347e-05*G0_2_2_0 + 6.14200614200637e-05*G0_2_2_1 + 0.000608445052889518*G0_2_2_2; + A[76] = -A[47] - 2.63933597266939e-05*G0_0_1_1 - 2.63933597266939e-05*G0_0_2_2 - 2.63933597266939e-05*G0_1_0_1 - 2.63933597266939e-05*G0_1_1_0 + 0.000157373490706829*G0_1_1_1 - 5.7555613111175e-07*G0_1_1_2 - 5.7555613111175e-07*G0_1_2_1 - 5.75556131111649e-07*G0_1_2_2 - 2.63933597266939e-05*G0_2_0_2 - 5.7555613111175e-07*G0_2_1_1 - 5.75556131111662e-07*G0_2_1_2 - 2.63933597266939e-05*G0_2_2_0 - 5.75556131111662e-07*G0_2_2_1 + 0.000157373490706829*G0_2_2_2; + A[20] = A[76]; + A[38] = A[122]; + A[120] = A[8]; + A[92] = A[36]; + A[179] = A[137] + 0.000314911426022548*G0_0_0_0 - 2.87778065555847e-06*G0_0_0_1 + 0.000198895754451317*G0_0_0_2 - 2.87778065555845e-06*G0_0_1_0 - 0.000401984846429305*G0_0_1_1 + 0.000198895754451317*G0_0_2_0 + 0.000266318044095831*G0_0_2_2 - 2.87778065555846e-06*G0_1_0_0 - 0.000401984846429305*G0_1_0_1 - 0.000401984846429305*G0_1_1_0 - 0.00173242395464624*G0_1_1_1 - 0.000212873546206887*G0_1_1_2 - 0.000212873546206887*G0_1_2_1 + 2.60644705089162e-05*G0_1_2_2 + 0.000198895754451317*G0_2_0_0 + 0.000266318044095831*G0_2_0_2 - 0.000212873546206887*G0_2_1_1 + 2.60644705089163e-05*G0_2_1_2 + 0.000266318044095831*G0_2_2_0 + 2.60644705089162e-05*G0_2_2_1 + 0.000522111633222763*G0_2_2_2; + A[116] = A[158] - 0.000138133471466809*G0_0_0_1 + 0.000138133471466809*G0_0_0_2 - 0.000138133471466809*G0_0_1_0 - 0.000144053477386815*G0_0_1_1 + 0.000138133471466809*G0_0_2_0 + 0.000144053477386815*G0_0_2_2 - 0.000138133471466809*G0_1_0_0 - 0.000144053477386815*G0_1_0_1 - 0.000144053477386815*G0_1_1_0 - 3.94667061333527e-06*G0_1_1_1 - 5.92000592000583e-06*G0_1_1_2 - 5.92000592000583e-06*G0_1_2_1 + 5.92000592000603e-06*G0_1_2_2 + 0.000138133471466809*G0_2_0_0 + 0.000144053477386815*G0_2_0_2 - 5.92000592000582e-06*G0_2_1_1 + 5.92000592000604e-06*G0_2_1_2 + 0.000144053477386815*G0_2_2_0 + 5.92000592000603e-06*G0_2_2_1 + 3.94667061333675e-06*G0_2_2_2; + A[219] = A[149]; + A[189] = -A[169] + 0.00603840603840625*G0_0_0_0 + 0.00112973446306784*G0_0_0_1 + 0.000797227463894158*G0_0_0_2 + 0.00112973446306784*G0_0_1_0 - 0.00042624042624044*G0_0_1_1 + 1.973335306669e-06*G0_0_1_2 + 0.000797227463894158*G0_0_2_0 + 1.973335306669e-06*G0_0_2_1 - 3.94667061333706e-06*G0_0_2_2 + 0.00112973446306784*G0_1_0_0 - 0.00042624042624044*G0_1_0_1 + 1.973335306669e-06*G0_1_0_2 - 0.00042624042624044*G0_1_1_0 - 0.0042130708797377*G0_1_1_1 - 0.000670934004267361*G0_1_1_2 + 1.973335306669e-06*G0_1_2_0 - 0.000670934004267361*G0_1_2_1 - 0.000318693652026996*G0_1_2_2 + 0.000797227463894158*G0_2_0_0 + 1.97333530666895e-06*G0_2_0_1 - 3.94667061333712e-06*G0_2_0_2 + 1.97333530666902e-06*G0_2_1_0 - 0.000670934004267361*G0_2_1_1 - 0.000318693652026996*G0_2_1_2 - 3.94667061333711e-06*G0_2_2_0 - 0.000318693652026996*G0_2_2_1 - 0.000536747203413888*G0_2_2_2; + A[55] = A[153]; + A[130] = A[158]; + A[43] = -A[212] + 0.000177600177600184*G0_0_0_0 + 1.97333530666871e-05*G0_0_0_1 + 2.07200207200215e-05*G0_0_0_2 + 1.97333530666871e-05*G0_0_1_0 - 4.93333826667177e-05*G0_0_1_1 + 3.94667061333744e-06*G0_0_1_2 + 2.07200207200215e-05*G0_0_2_0 + 3.94667061333744e-06*G0_0_2_1 - 1.18400118400122e-05*G0_0_2_2 + 1.97333530666871e-05*G0_1_0_0 - 4.93333826667177e-05*G0_1_0_1 + 3.94667061333745e-06*G0_1_0_2 - 4.93333826667177e-05*G0_1_1_0 - 0.000236800236800245*G0_1_1_1 - 8.88000888000923e-06*G0_1_1_2 + 3.94667061333745e-06*G0_1_2_0 - 8.88000888000925e-06*G0_1_2_1 - 7.89334122667478e-06*G0_1_2_2 + 2.07200207200215e-05*G0_2_0_0 + 3.94667061333744e-06*G0_2_0_1 - 1.18400118400122e-05*G0_2_0_2 + 3.94667061333743e-06*G0_2_1_0 - 8.88000888000925e-06*G0_2_1_1 - 7.89334122667479e-06*G0_2_1_2 - 1.18400118400122e-05*G0_2_2_0 - 7.89334122667478e-06*G0_2_2_1 + 0.000148000148000153*G0_2_2_2; + A[35] = A[43] - 2.44200244200252e-05*G0_0_0_0 + 4.94978272756067e-05*G0_0_0_1 - 1.56222378444608e-06*G0_0_0_2 + 4.94978272756067e-05*G0_0_1_0 + 0.000103846770513441*G0_0_1_1 + 4.85111596222722e-06*G0_0_1_2 - 1.56222378444608e-06*G0_0_2_0 + 4.85111596222722e-06*G0_0_2_1 + 3.73289262178164e-05*G0_0_2_2 + 4.94978272756067e-05*G0_1_0_0 + 0.000103846770513441*G0_1_0_1 + 4.85111596222722e-06*G0_1_0_2 + 0.000103846770513441*G0_1_1_0 + 0.000257520257520267*G0_1_1_1 + 4.19333752667103e-06*G0_1_1_2 + 4.85111596222722e-06*G0_1_2_0 + 4.19333752667105e-06*G0_1_2_1 + 7.86045230489702e-05*G0_1_2_2 - 1.56222378444608e-06*G0_2_0_0 + 4.85111596222722e-06*G0_2_0_1 + 3.73289262178164e-05*G0_2_0_2 + 4.85111596222722e-06*G0_2_1_0 + 4.19333752667105e-06*G0_2_1_1 + 7.86045230489702e-05*G0_2_1_2 + 3.73289262178164e-05*G0_2_2_0 + 7.86045230489702e-05*G0_2_2_1 + 0.00174393507726847*G0_2_2_2; + A[135] = A[35] + 0.00170422170422176*G0_0_0_0 + 0.000119880119880124*G0_0_0_1 + 5.71445015889478e-05*G0_0_0_2 + 0.000119880119880124*G0_0_1_0 + 8.3866750533419e-06*G0_0_1_1 + 5.71445015889478e-05*G0_0_2_0 - 5.7144501588948e-05*G0_0_2_2 + 0.000119880119880124*G0_1_0_0 + 8.38667505334189e-06*G0_1_0_1 + 8.38667505334189e-06*G0_1_1_0 - 8.38667505334208e-06*G0_1_1_2 - 8.38667505334209e-06*G0_1_2_1 - 0.000119880119880124*G0_1_2_2 + 5.71445015889478e-05*G0_2_0_0 - 5.7144501588948e-05*G0_2_0_2 - 8.38667505334208e-06*G0_2_1_1 - 0.000119880119880124*G0_2_1_2 - 5.7144501588948e-05*G0_2_2_0 - 0.000119880119880124*G0_2_2_1 - 0.00170422170422176*G0_2_2_2; + A[170] = -A[43] + 3.28889217778117e-05*G0_0_0_0 + 3.94667061333742e-06*G0_0_0_1 + 8.0577858355639e-06*G0_0_0_2 + 3.94667061333742e-06*G0_0_1_0 + 0.00018878241100464*G0_0_1_1 + 2.53244697689151e-05*G0_0_1_2 + 8.0577858355639e-06*G0_0_2_0 + 2.53244697689151e-05*G0_0_2_1 + 4.99911611022739e-05*G0_0_2_2 + 3.94667061333744e-06*G0_1_0_0 + 0.00018878241100464*G0_1_0_1 + 2.53244697689151e-05*G0_1_0_2 + 0.00018878241100464*G0_1_1_0 + 0.00139449028337922*G0_1_1_1 + 0.000154742376964605*G0_1_1_2 + 2.53244697689151e-05*G0_1_2_0 + 0.000154742376964605*G0_1_2_1 + 6.57778435556236e-05*G0_1_2_2 + 8.05778583556391e-06*G0_2_0_0 + 2.53244697689151e-05*G0_2_0_1 + 4.9991161102274e-05*G0_2_0_2 + 2.53244697689151e-05*G0_2_1_0 + 0.000154742376964605*G0_2_1_1 + 6.57778435556236e-05*G0_2_1_2 + 4.9991161102274e-05*G0_2_2_0 + 6.57778435556236e-05*G0_2_2_1 + 0.000110835666391226*G0_2_2_2; + A[86] = A[170]; + A[138] = A[170] + 0.000142080142080146*G0_0_0_0 - 2.89422511644746e-05*G0_0_0_1 + 2.36800236800244e-05*G0_0_0_2 - 2.89422511644746e-05*G0_0_1_0 - 0.000142080142080147*G0_0_1_1 + 2.36800236800244e-05*G0_0_2_0 - 2.36800236800244e-05*G0_0_2_2 - 2.89422511644746e-05*G0_1_0_0 - 0.000142080142080147*G0_1_0_1 - 0.000142080142080147*G0_1_1_0 + 0.000142080142080148*G0_1_1_2 + 0.000142080142080148*G0_1_2_1 + 2.89422511644746e-05*G0_1_2_2 + 2.36800236800244e-05*G0_2_0_0 - 2.36800236800245e-05*G0_2_0_2 + 0.000142080142080148*G0_2_1_1 + 2.89422511644746e-05*G0_2_1_2 - 2.36800236800244e-05*G0_2_2_0 + 2.89422511644746e-05*G0_2_2_1 - 0.000142080142080147*G0_2_2_2; + A[195] = A[135] - 0.00174393507726847*G0_0_0_0 - 7.86045230489704e-05*G0_0_0_1 - 3.73289262178162e-05*G0_0_0_2 - 7.86045230489704e-05*G0_0_1_0 - 4.19333752667111e-06*G0_0_1_1 - 4.85111596222728e-06*G0_0_1_2 - 3.73289262178162e-05*G0_0_2_0 - 4.85111596222728e-06*G0_0_2_1 + 1.56222378444606e-06*G0_0_2_2 - 7.86045230489704e-05*G0_1_0_0 - 4.19333752667108e-06*G0_1_0_1 - 4.85111596222728e-06*G0_1_0_2 - 4.19333752667109e-06*G0_1_1_0 - 0.000257520257520267*G0_1_1_1 - 0.000103846770513441*G0_1_1_2 - 4.85111596222728e-06*G0_1_2_0 - 0.000103846770513441*G0_1_2_1 - 4.94978272756069e-05*G0_1_2_2 - 3.73289262178162e-05*G0_2_0_0 - 4.85111596222728e-06*G0_2_0_1 + 1.56222378444606e-06*G0_2_0_2 - 4.85111596222728e-06*G0_2_1_0 - 0.000103846770513441*G0_2_1_1 - 4.94978272756068e-05*G0_2_1_2 + 1.56222378444606e-06*G0_2_2_0 - 4.94978272756068e-05*G0_2_2_1 + 2.44200244200252e-05*G0_2_2_2; + A[129] = A[170] + 0.00177600177600183*G0_0_0_0 + 0.000253902476124707*G0_0_0_1 + 0.000176284620729071*G0_0_0_2 + 0.000253902476124707*G0_0_1_0 - 0.000253902476124707*G0_0_1_1 + 0.000176284620729071*G0_0_2_0 + 1.18400118400122e-05*G0_0_2_2 + 0.000253902476124707*G0_1_0_0 - 0.000253902476124707*G0_1_0_1 - 0.000253902476124707*G0_1_1_0 - 0.00177600177600184*G0_1_1_1 - 0.000176284620729071*G0_1_1_2 - 0.000176284620729071*G0_1_2_1 - 1.18400118400123e-05*G0_1_2_2 + 0.000176284620729071*G0_2_0_0 + 1.18400118400122e-05*G0_2_0_2 - 0.000176284620729071*G0_2_1_1 - 1.18400118400123e-05*G0_2_1_2 + 1.18400118400122e-05*G0_2_2_0 - 1.18400118400123e-05*G0_2_2_1; + A[126] = -A[35] + 0.00179762624207074*G0_0_0_0 + 0.000165266831933504*G0_0_0_1 + 0.000209091320202438*G0_0_0_2 + 0.000165266831933504*G0_0_1_0 - 2.05555761111325e-06*G0_0_1_1 + 4.20155975711546e-05*G0_0_1_2 + 0.000209091320202438*G0_0_2_0 + 4.20155975711546e-05*G0_0_2_1 + 0.000266235821791386*G0_0_2_2 + 0.000165266831933504*G0_1_0_0 - 2.05555761111326e-06*G0_1_0_1 + 4.20155975711546e-05*G0_1_0_2 - 2.05555761111326e-06*G0_1_1_0 - 0.000158195713751275*G0_1_1_1 + 6.33111744222874e-06*G0_1_1_2 + 4.20155975711545e-05*G0_1_2_0 + 6.33111744222874e-06*G0_1_2_1 + 0.000285146951813628*G0_1_2_2 + 0.000209091320202438*G0_2_0_0 + 4.20155975711546e-05*G0_2_0_1 + 0.000266235821791386*G0_2_0_2 + 4.20155975711546e-05*G0_2_1_0 + 6.33111744222874e-06*G0_2_1_1 + 0.000285146951813628*G0_2_1_2 + 0.000266235821791386*G0_2_2_0 + 0.000285146951813628*G0_2_2_1 + 0.00350184794629251*G0_2_2_2; + A[101] = A[138] + 0.00163392163392169*G0_0_0_0 + 0.000140764585209035*G0_0_0_1 + 0.000294684739129193*G0_0_0_2 + 0.000140764585209035*G0_0_1_0 - 0.000140764585209035*G0_0_1_1 + 0.000294684739129193*G0_0_2_0 + 6.4462286684511e-05*G0_0_2_2 + 0.000140764585209035*G0_1_0_0 - 0.000140764585209035*G0_1_0_1 - 0.000140764585209035*G0_1_1_0 - 0.0016339216339217*G0_1_1_1 - 0.000294684739129194*G0_1_1_2 - 0.000294684739129195*G0_1_2_1 - 6.44622866845113e-05*G0_1_2_2 + 0.000294684739129193*G0_2_0_0 + 6.4462286684511e-05*G0_2_0_2 - 0.000294684739129194*G0_2_1_1 - 6.44622866845113e-05*G0_2_1_2 + 6.4462286684511e-05*G0_2_2_0 - 6.44622866845113e-05*G0_2_2_1; + A[174] = A[126] + 2.63111374222496e-05*G0_0_0_1 - 2.63111374222488e-05*G0_0_0_2 + 2.63111374222496e-05*G0_0_1_0 + 0.000178915734471297*G0_0_1_1 - 2.63111374222488e-05*G0_0_2_0 - 0.000178915734471296*G0_0_2_2 + 2.63111374222496e-05*G0_1_0_0 + 0.000178915734471297*G0_1_0_1 + 0.000178915734471297*G0_1_1_0 + 0.00182336182336189*G0_1_1_1 + 0.000152604597049047*G0_1_1_2 + 0.000152604597049047*G0_1_2_1 - 0.000152604597049047*G0_1_2_2 - 2.63111374222488e-05*G0_2_0_0 - 0.000178915734471296*G0_2_0_2 + 0.000152604597049047*G0_2_1_1 - 0.000152604597049047*G0_2_1_2 - 0.000178915734471296*G0_2_2_0 - 0.000152604597049047*G0_2_2_1 - 0.00182336182336188*G0_2_2_2; + A[50] = A[126] - 0.00182336182336188*G0_0_0_0 - 0.000152604597049047*G0_0_0_1 - 0.000178915734471295*G0_0_0_2 - 0.000152604597049047*G0_0_1_0 + 0.000152604597049047*G0_0_1_1 - 0.000178915734471295*G0_0_2_0 - 2.63111374222492e-05*G0_0_2_2 - 0.000152604597049047*G0_1_0_0 + 0.000152604597049047*G0_1_0_1 + 0.000152604597049047*G0_1_1_0 + 0.00182336182336189*G0_1_1_1 + 0.000178915734471296*G0_1_1_2 + 0.000178915734471296*G0_1_2_1 + 2.63111374222493e-05*G0_1_2_2 - 0.000178915734471295*G0_2_0_0 - 2.63111374222492e-05*G0_2_0_2 + 0.000178915734471296*G0_2_1_1 + 2.63111374222493e-05*G0_2_1_2 - 2.63111374222492e-05*G0_2_2_0 + 2.63111374222493e-05*G0_2_2_1; + A[148] = -A[43] - 0.00120373453706791*G0_0_0_0 - 0.000315733649066993*G0_0_0_1 - 0.000231373564706906*G0_0_0_2 - 0.000315733649066993*G0_0_1_0 - 3.74933708267049e-05*G0_0_1_1 + 6.90667357334055e-06*G0_0_1_2 - 0.000231373564706906*G0_0_2_0 + 6.90667357334056e-06*G0_0_2_1 - 0.000315733649066993*G0_1_0_0 - 3.7493370826705e-05*G0_1_0_1 + 6.90667357334054e-06*G0_1_0_2 - 3.7493370826705e-05*G0_1_1_0 + 0.0013813347146681*G0_1_1_1 + 0.000496787163453848*G0_1_1_2 + 6.90667357334056e-06*G0_1_2_0 + 0.000496787163453848*G0_1_2_1 + 0.000272320272320282*G0_1_2_2 - 0.000231373564706906*G0_2_0_0 + 6.90667357334054e-06*G0_2_0_1 + 6.90667357334056e-06*G0_2_1_0 + 0.000496787163453848*G0_2_1_1 + 0.000272320272320282*G0_2_1_2 + 0.000272320272320282*G0_2_2_1 + 7.4000074000077e-05*G0_2_2_2; + A[123] = A[170] - 6.44622866845112e-05*G0_0_0_1 + 6.44622866845111e-05*G0_0_0_2 - 6.44622866845112e-05*G0_0_1_0 - 0.000294684739129194*G0_0_1_1 + 6.44622866845111e-05*G0_0_2_0 + 0.000294684739129194*G0_0_2_2 - 6.44622866845112e-05*G0_1_0_0 - 0.000294684739129194*G0_1_0_1 - 0.000294684739129194*G0_1_1_0 - 0.00163392163392169*G0_1_1_1 - 0.000140764585209034*G0_1_1_2 - 0.000140764585209034*G0_1_2_1 + 0.000140764585209035*G0_1_2_2 + 6.44622866845111e-05*G0_2_0_0 + 0.000294684739129194*G0_2_0_2 - 0.000140764585209034*G0_2_1_1 + 0.000140764585209035*G0_2_1_2 + 0.000294684739129194*G0_2_2_0 + 0.000140764585209035*G0_2_2_1 + 0.00163392163392169*G0_2_2_2; + A[204] = A[148]; + A[143] = A[129]; + A[88] = -A[195] + 7.40000740000758e-05*G0_0_0_0 + 0.000272320272320281*G0_0_0_1 + 0.000272320272320281*G0_0_1_0 + 0.000496787163453847*G0_0_1_1 + 6.90667357334044e-06*G0_0_1_2 + 6.90667357334044e-06*G0_0_2_1 - 0.000231373564706906*G0_0_2_2 + 0.000272320272320281*G0_1_0_0 + 0.000496787163453847*G0_1_0_1 + 6.90667357334042e-06*G0_1_0_2 + 0.000496787163453847*G0_1_1_0 + 0.0013813347146681*G0_1_1_1 - 3.74933708267054e-05*G0_1_1_2 + 6.90667357334041e-06*G0_1_2_0 - 3.74933708267054e-05*G0_1_2_1 - 0.000315733649066993*G0_1_2_2 + 6.90667357334044e-06*G0_2_0_1 - 0.000231373564706906*G0_2_0_2 + 6.90667357334043e-06*G0_2_1_0 - 3.74933708267053e-05*G0_2_1_1 - 0.000315733649066993*G0_2_1_2 - 0.000231373564706906*G0_2_2_0 - 0.000315733649066993*G0_2_2_1 - 0.00120373453706791*G0_2_2_2; + A[146] = A[174]; + A[75] = A[5]; + A[150] = A[10]; + A[183] = A[57]; + A[178] = -A[142] - 0.00421307087973768*G0_0_0_0 - 0.000426240426240441*G0_0_0_1 - 0.000670934004267359*G0_0_0_2 - 0.00042624042624044*G0_0_1_0 + 0.00112973446306784*G0_0_1_1 + 1.97333530666892e-06*G0_0_1_2 - 0.00067093400426736*G0_0_2_0 + 1.97333530666889e-06*G0_0_2_1 - 0.000318693652026996*G0_0_2_2 - 0.00042624042624044*G0_1_0_0 + 0.00112973446306784*G0_1_0_1 + 1.97333530666892e-06*G0_1_0_2 + 0.00112973446306784*G0_1_1_0 + 0.00603840603840626*G0_1_1_1 + 0.000797227463894159*G0_1_1_2 + 1.97333530666891e-06*G0_1_2_0 + 0.000797227463894159*G0_1_2_1 - 3.94667061333677e-06*G0_1_2_2 - 0.000670934004267359*G0_2_0_0 + 1.97333530666889e-06*G0_2_0_1 - 0.000318693652026996*G0_2_0_2 + 1.97333530666891e-06*G0_2_1_0 + 0.000797227463894159*G0_2_1_1 - 3.9466706133368e-06*G0_2_1_2 - 0.000318693652026996*G0_2_2_0 - 3.94667061333677e-06*G0_2_2_1 - 0.000536747203413887*G0_2_2_2; + A[197] = A[43]; + A[19] = A[61]; + A[12] = A[94] + 0.000137146803813477*G0_0_0_0 - 4.14400414400429e-05*G0_0_0_1 - 4.44000444000456e-05*G0_0_0_2 - 4.14400414400429e-05*G0_0_1_0 + 3.45333678667019e-06*G0_0_1_1 - 6.90667357334041e-06*G0_0_1_2 - 4.44000444000456e-05*G0_0_2_0 - 6.9066735733404e-06*G0_0_2_1 + 7.05467372134065e-05*G0_0_2_2 - 4.14400414400429e-05*G0_1_0_0 + 3.45333678667019e-06*G0_1_0_1 - 6.90667357334041e-06*G0_1_0_2 + 3.45333678667019e-06*G0_1_1_0 + 9.8666765333436e-05*G0_1_1_1 - 7.0053403386739e-05*G0_1_1_2 - 6.9066735733404e-06*G0_1_2_0 - 7.0053403386739e-05*G0_1_2_1 - 4.44000444000456e-05*G0_2_0_0 - 6.9066735733404e-06*G0_2_0_1 + 7.05467372134065e-05*G0_2_0_2 - 6.9066735733404e-06*G0_2_1_0 - 7.0053403386739e-05*G0_2_1_1 + 7.05467372134065e-05*G0_2_2_0 + 0.000897867564534262*G0_2_2_2; + A[99] = A[12] + 0.0044383599939157*G0_0_0_0 + 0.000677511788622923*G0_0_0_1 + 0.000677511788622923*G0_0_0_2 + 0.000677511788622923*G0_0_1_0 + 0.000138626805293477*G0_0_1_1 + 9.24178701956511e-05*G0_0_1_2 + 0.000677511788622923*G0_0_2_0 + 9.24178701956511e-05*G0_0_2_1 + 0.000138626805293476*G0_0_2_2 + 0.000677511788622923*G0_1_0_0 + 0.000138626805293477*G0_1_0_1 + 9.24178701956511e-05*G0_1_0_2 + 0.000138626805293477*G0_1_1_0 - 2.6311137422252e-06*G0_1_1_1 - 1.31555687111259e-06*G0_1_1_2 + 9.24178701956511e-05*G0_1_2_0 - 1.3155568711126e-06*G0_1_2_1 - 1.31555687111266e-06*G0_1_2_2 + 0.000677511788622923*G0_2_0_0 + 9.24178701956511e-05*G0_2_0_1 + 0.000138626805293476*G0_2_0_2 + 9.24178701956511e-05*G0_2_1_0 - 1.31555687111259e-06*G0_2_1_1 - 1.31555687111263e-06*G0_2_1_2 + 0.000138626805293476*G0_2_2_0 - 1.31555687111263e-06*G0_2_2_1 - 2.63111374222545e-06*G0_2_2_2; + A[97] = -A[99] + 0.00070382292604518*G0_0_0_0 + 0.00027100471544917*G0_0_0_1 + 0.000136817914595698*G0_0_0_2 + 0.00027100471544917*G0_0_1_0 + 8.48534181867546e-05*G0_0_1_1 + 7.56445200889679e-06*G0_0_1_2 + 0.000136817914595698*G0_0_2_0 + 7.56445200889679e-06*G0_0_2_1 - 0.000165760165760171*G0_0_2_2 + 0.00027100471544917*G0_1_0_0 + 8.48534181867546e-05*G0_1_0_1 + 7.56445200889675e-06*G0_1_0_2 + 8.48534181867546e-05*G0_1_1_0 + 0.000139449028337923*G0_1_1_1 + 6.57778435556258e-06*G0_1_1_2 + 7.56445200889677e-06*G0_1_2_0 + 6.57778435556257e-06*G0_1_2_1 - 0.000155235710791271*G0_1_2_2 + 0.000136817914595698*G0_2_0_0 + 7.56445200889679e-06*G0_2_0_1 - 0.000165760165760171*G0_2_0_2 + 7.56445200889679e-06*G0_2_1_0 + 6.57778435556258e-06*G0_2_1_1 - 0.000155235710791271*G0_2_1_2 - 0.000165760165760171*G0_2_2_0 - 0.000155235710791271*G0_2_2_1 - 0.00142343253454369*G0_2_2_2; + A[157] = -A[12] + 0.00185246851913525*G0_0_0_0 + 6.90667357334083e-06*G0_0_0_1 + 6.90667357334023e-06*G0_0_0_2 + 6.90667357334089e-06*G0_0_1_0 - 9.54600954600984e-05*G0_0_1_1 - 4.44000444000459e-06*G0_0_1_2 + 6.9066735733402e-06*G0_0_2_0 - 4.44000444000459e-06*G0_0_2_1 - 9.54600954600986e-05*G0_0_2_2 + 6.90667357334088e-06*G0_1_0_0 - 9.54600954600984e-05*G0_1_0_1 - 4.44000444000459e-06*G0_1_0_2 - 9.54600954600984e-05*G0_1_1_0 + 2.26933560266901e-05*G0_1_1_1 + 8.23867490534184e-05*G0_1_1_2 - 4.44000444000458e-06*G0_1_2_0 + 8.23867490534184e-05*G0_1_2_1 + 8.23867490534184e-05*G0_1_2_2 + 6.90667357334022e-06*G0_2_0_0 - 4.44000444000459e-06*G0_2_0_1 - 9.54600954600986e-05*G0_2_0_2 - 4.44000444000459e-06*G0_2_1_0 + 8.23867490534184e-05*G0_2_1_1 + 8.23867490534184e-05*G0_2_1_2 - 9.54600954600986e-05*G0_2_2_0 + 8.23867490534184e-05*G0_2_2_1 + 2.26933560266899e-05*G0_2_2_2; + A[111] = A[97]; + A[163] = A[99] - 0.00271662493884726*G0_0_0_0 + 0.000277582499804731*G0_0_0_1 - 0.000160497938275721*G0_0_0_2 + 0.000277582499804731*G0_0_1_0 + 0.000244693578026919*G0_0_1_1 - 6.57778435556402e-07*G0_0_1_2 - 0.000160497938275721*G0_0_2_0 - 6.57778435556389e-07*G0_0_2_1 - 9.86667653334359e-06*G0_0_2_2 + 0.000277582499804731*G0_1_0_0 + 0.000244693578026919*G0_1_0_1 - 6.57778435556375e-07*G0_1_0_2 + 0.000244693578026919*G0_1_1_0 - 0.00274030496252729*G0_1_1_1 - 0.000736711847822986*G0_1_1_2 - 6.57778435556456e-07*G0_1_2_0 - 0.000736711847822986*G0_1_2_1 - 0.000340071451182574*G0_1_2_2 - 0.000160497938275721*G0_2_0_0 - 6.57778435556389e-07*G0_2_0_1 - 9.86667653334359e-06*G0_2_0_2 - 6.57778435556375e-07*G0_2_1_0 - 0.000736711847822986*G0_2_1_1 - 0.000340071451182574*G0_2_1_2 - 9.86667653334367e-06*G0_2_2_0 - 0.000340071451182574*G0_2_2_1 - 0.000265742487964719*G0_2_2_2; + A[205] = A[163]; + A[113] = A[97] + 0.00234826901493576*G0_0_0_0 + 0.000134186800853473*G0_0_0_1 + 0.000185493518826858*G0_0_0_2 + 0.000134186800853473*G0_0_1_0 - 5.92000592000602e-06*G0_0_1_1 + 0.000185493518826858*G0_0_2_0 - 0.000185493518826858*G0_0_2_2 + 0.000134186800853473*G0_1_0_0 - 5.92000592000605e-06*G0_1_0_1 - 5.92000592000605e-06*G0_1_1_0 + 5.92000592000602e-06*G0_1_1_2 + 5.92000592000602e-06*G0_1_2_1 - 0.000134186800853472*G0_1_2_2 + 0.000185493518826858*G0_2_0_0 - 0.000185493518826858*G0_2_0_2 + 5.92000592000602e-06*G0_2_1_1 - 0.000134186800853472*G0_2_1_2 - 0.000185493518826858*G0_2_2_0 - 0.000134186800853472*G0_2_2_1 - 0.00234826901493576*G0_2_2_2; + A[125] = -A[113] - 0.00142343253454369*G0_0_0_0 - 0.000155235710791271*G0_0_0_1 - 0.000165760165760171*G0_0_0_2 - 0.000155235710791271*G0_0_1_0 + 6.57778435556241e-06*G0_0_1_1 + 7.56445200889683e-06*G0_0_1_2 - 0.000165760165760171*G0_0_2_0 + 7.56445200889682e-06*G0_0_2_1 + 0.000136817914595698*G0_0_2_2 - 0.000155235710791271*G0_1_0_0 + 6.57778435556241e-06*G0_1_0_1 + 7.56445200889682e-06*G0_1_0_2 + 6.57778435556241e-06*G0_1_1_0 + 0.000139449028337922*G0_1_1_1 + 8.48534181867545e-05*G0_1_1_2 + 7.56445200889682e-06*G0_1_2_0 + 8.48534181867545e-05*G0_1_2_1 + 0.00027100471544917*G0_1_2_2 - 0.000165760165760171*G0_2_0_0 + 7.56445200889682e-06*G0_2_0_1 + 0.000136817914595698*G0_2_0_2 + 7.56445200889681e-06*G0_2_1_0 + 8.48534181867546e-05*G0_2_1_1 + 0.00027100471544917*G0_2_1_2 + 0.000136817914595698*G0_2_2_0 + 0.00027100471544917*G0_2_2_1 + 0.000703822926045173*G0_2_2_2; + A[117] = A[125] - 0.00274030496252728*G0_0_0_0 - 0.000736711847822983*G0_0_0_1 + 0.00024469357802692*G0_0_0_2 - 0.000736711847822983*G0_0_1_0 - 0.000340071451182573*G0_0_1_1 - 6.57778435556131e-07*G0_0_1_2 + 0.00024469357802692*G0_0_2_0 - 6.57778435556131e-07*G0_0_2_1 + 0.000277582499804731*G0_0_2_2 - 0.000736711847822983*G0_1_0_0 - 0.000340071451182573*G0_1_0_1 - 6.57778435556131e-07*G0_1_0_2 - 0.000340071451182573*G0_1_1_0 - 0.00026574248796472*G0_1_1_1 - 9.866676533344e-06*G0_1_1_2 - 6.57778435556145e-07*G0_1_2_0 - 9.866676533344e-06*G0_1_2_1 - 0.000160497938275722*G0_1_2_2 + 0.00024469357802692*G0_2_0_0 - 6.57778435556117e-07*G0_2_0_1 + 0.000277582499804731*G0_2_0_2 - 6.57778435556117e-07*G0_2_1_0 - 9.866676533344e-06*G0_2_1_1 - 0.000160497938275722*G0_2_1_2 + 0.000277582499804731*G0_2_2_0 - 0.000160497938275722*G0_2_2_1 - 0.00271662493884725*G0_2_2_2; + A[199] = A[125] - 0.000265742487964718*G0_0_0_0 - 0.000340071451182573*G0_0_0_1 - 9.86667653334343e-06*G0_0_0_2 - 0.000340071451182573*G0_0_1_0 - 0.000736711847822984*G0_0_1_1 - 6.5777843555628e-07*G0_0_1_2 - 9.8666765333434e-06*G0_0_2_0 - 6.57778435556267e-07*G0_0_2_1 - 0.000160497938275722*G0_0_2_2 - 0.000340071451182573*G0_1_0_0 - 0.000736711847822984*G0_1_0_1 - 6.5777843555628e-07*G0_1_0_2 - 0.000736711847822984*G0_1_1_0 - 0.00274030496252728*G0_1_1_1 + 0.00024469357802692*G0_1_1_2 - 6.5777843555628e-07*G0_1_2_0 + 0.00024469357802692*G0_1_2_1 + 0.000277582499804732*G0_1_2_2 - 9.86667653334346e-06*G0_2_0_0 - 6.57778435556267e-07*G0_2_0_1 - 0.000160497938275721*G0_2_0_2 - 6.57778435556267e-07*G0_2_1_0 + 0.00024469357802692*G0_2_1_1 + 0.000277582499804732*G0_2_1_2 - 0.000160497938275722*G0_2_2_0 + 0.000277582499804732*G0_2_2_1 - 0.00271662493884725*G0_2_2_2; + A[83] = A[125]; + A[65] = -A[125] + 0.000139449028337922*G0_0_0_0 + 6.57778435556241e-06*G0_0_0_1 + 8.48534181867543e-05*G0_0_0_2 + 6.57778435556241e-06*G0_0_1_0 - 0.000155235710791272*G0_0_1_1 + 7.56445200889675e-06*G0_0_1_2 + 8.48534181867543e-05*G0_0_2_0 + 7.56445200889678e-06*G0_0_2_1 + 0.000271004715449169*G0_0_2_2 + 6.57778435556239e-06*G0_1_0_0 - 0.000155235710791272*G0_1_0_1 + 7.56445200889681e-06*G0_1_0_2 - 0.000155235710791272*G0_1_1_0 - 0.00142343253454369*G0_1_1_1 - 0.000165760165760171*G0_1_1_2 + 7.56445200889678e-06*G0_1_2_0 - 0.000165760165760171*G0_1_2_1 + 0.000136817914595698*G0_1_2_2 + 8.48534181867543e-05*G0_2_0_0 + 7.56445200889677e-06*G0_2_0_1 + 0.000271004715449169*G0_2_0_2 + 7.56445200889677e-06*G0_2_1_0 - 0.000165760165760171*G0_2_1_1 + 0.000136817914595698*G0_2_1_2 + 0.000271004715449169*G0_2_2_0 + 0.000136817914595698*G0_2_2_1 + 0.000703822926045173*G0_2_2_2; + A[14] = -A[12] + 0.000148000148000154*G0_0_0_0 - 1.18400118400123e-05*G0_0_0_1 - 7.89334122667483e-06*G0_0_0_2 - 1.18400118400123e-05*G0_0_1_0 + 2.07200207200214e-05*G0_0_1_1 + 3.94667061333741e-06*G0_0_1_2 - 7.89334122667485e-06*G0_0_2_0 + 3.94667061333741e-06*G0_0_2_1 - 8.88000888000919e-06*G0_0_2_2 - 1.18400118400123e-05*G0_1_0_0 + 2.07200207200214e-05*G0_1_0_1 + 3.94667061333741e-06*G0_1_0_2 + 2.07200207200214e-05*G0_1_1_0 + 0.000177600177600184*G0_1_1_1 + 1.97333530666872e-05*G0_1_1_2 + 3.94667061333741e-06*G0_1_2_0 + 1.97333530666872e-05*G0_1_2_1 - 4.93333826667177e-05*G0_1_2_2 - 7.89334122667482e-06*G0_2_0_0 + 3.94667061333741e-06*G0_2_0_1 - 8.88000888000919e-06*G0_2_0_2 + 3.94667061333741e-06*G0_2_1_0 + 1.97333530666872e-05*G0_2_1_1 - 4.93333826667177e-05*G0_2_1_2 - 8.8800088800092e-06*G0_2_2_0 - 4.93333826667177e-05*G0_2_2_1 - 0.000236800236800245*G0_2_2_2; + A[90] = A[14] + 0.00174393507726847*G0_0_0_0 + 3.73289262178163e-05*G0_0_0_1 + 7.86045230489697e-05*G0_0_0_2 + 3.73289262178163e-05*G0_0_1_0 - 1.56222378444614e-06*G0_0_1_1 + 4.85111596222722e-06*G0_0_1_2 + 7.86045230489697e-05*G0_0_2_0 + 4.85111596222722e-06*G0_0_2_1 + 4.19333752667097e-06*G0_0_2_2 + 3.73289262178163e-05*G0_1_0_0 - 1.56222378444614e-06*G0_1_0_1 + 4.85111596222722e-06*G0_1_0_2 - 1.56222378444614e-06*G0_1_1_0 - 2.44200244200256e-05*G0_1_1_1 + 4.94978272756067e-05*G0_1_1_2 + 4.85111596222722e-06*G0_1_2_0 + 4.94978272756067e-05*G0_1_2_1 + 0.000103846770513441*G0_1_2_2 + 7.86045230489697e-05*G0_2_0_0 + 4.85111596222722e-06*G0_2_0_1 + 4.19333752667098e-06*G0_2_0_2 + 4.85111596222721e-06*G0_2_1_0 + 4.94978272756067e-05*G0_2_1_1 + 0.000103846770513441*G0_2_1_2 + 4.19333752667098e-06*G0_2_2_0 + 0.000103846770513441*G0_2_2_1 + 0.000257520257520267*G0_2_2_2; + A[46] = A[90] - 0.00170422170422176*G0_0_0_0 - 5.7144501588948e-05*G0_0_0_1 - 0.000119880119880124*G0_0_0_2 - 5.7144501588948e-05*G0_0_1_0 + 5.71445015889483e-05*G0_0_1_1 - 0.000119880119880124*G0_0_2_0 - 8.38667505334192e-06*G0_0_2_2 - 5.7144501588948e-05*G0_1_0_0 + 5.71445015889483e-05*G0_1_0_1 + 5.71445015889483e-05*G0_1_1_0 + 0.00170422170422176*G0_1_1_1 + 0.000119880119880124*G0_1_1_2 + 0.000119880119880124*G0_1_2_1 + 8.38667505334199e-06*G0_1_2_2 - 0.000119880119880124*G0_2_0_0 - 8.38667505334191e-06*G0_2_0_2 + 0.000119880119880124*G0_2_1_1 + 8.38667505334199e-06*G0_2_1_2 - 8.38667505334191e-06*G0_2_2_0 + 8.38667505334199e-06*G0_2_2_1; + A[211] = A[46] + 2.44200244200254e-05*G0_0_0_0 + 1.56222378444602e-06*G0_0_0_1 - 4.94978272756067e-05*G0_0_0_2 + 1.56222378444602e-06*G0_0_1_0 - 3.73289262178168e-05*G0_0_1_1 - 4.85111596222729e-06*G0_0_1_2 - 4.94978272756067e-05*G0_0_2_0 - 4.85111596222728e-06*G0_0_2_1 - 0.000103846770513441*G0_0_2_2 + 1.56222378444602e-06*G0_1_0_0 - 3.73289262178168e-05*G0_1_0_1 - 4.85111596222728e-06*G0_1_0_2 - 3.73289262178168e-05*G0_1_1_0 - 0.00174393507726847*G0_1_1_1 - 7.86045230489701e-05*G0_1_1_2 - 4.85111596222728e-06*G0_1_2_0 - 7.86045230489701e-05*G0_1_2_1 - 4.19333752667098e-06*G0_1_2_2 - 4.94978272756067e-05*G0_2_0_0 - 4.85111596222729e-06*G0_2_0_1 - 0.000103846770513441*G0_2_0_2 - 4.85111596222729e-06*G0_2_1_0 - 7.86045230489701e-05*G0_2_1_1 - 4.19333752667098e-06*G0_2_1_2 - 0.000103846770513441*G0_2_2_0 - 4.19333752667097e-06*G0_2_2_1 - 0.000257520257520266*G0_2_2_2; + A[104] = -A[211] - 0.00120373453706791*G0_0_0_0 - 0.000231373564706906*G0_0_0_1 - 0.000315733649066993*G0_0_0_2 - 0.000231373564706906*G0_0_1_0 + 6.90667357334031e-06*G0_0_1_2 - 0.000315733649066993*G0_0_2_0 + 6.90667357334034e-06*G0_0_2_1 - 3.74933708267056e-05*G0_0_2_2 - 0.000231373564706906*G0_1_0_0 + 6.90667357334035e-06*G0_1_0_2 + 7.40000740000756e-05*G0_1_1_1 + 0.000272320272320281*G0_1_1_2 + 6.90667357334033e-06*G0_1_2_0 + 0.000272320272320281*G0_1_2_1 + 0.000496787163453847*G0_1_2_2 - 0.000315733649066993*G0_2_0_0 + 6.9066735733403e-06*G0_2_0_1 - 3.74933708267055e-05*G0_2_0_2 + 6.9066735733403e-06*G0_2_1_0 + 0.000272320272320281*G0_2_1_1 + 0.000496787163453847*G0_2_1_2 - 3.74933708267055e-05*G0_2_2_0 + 0.000496787163453847*G0_2_2_1 + 0.00138133471466809*G0_2_2_2; + A[79] = A[65]; + A[187] = A[117]; + A[216] = A[104]; + A[213] = -A[14] + 7.40000740000771e-05*G0_0_0_0 + 0.000272320272320281*G0_0_0_2 - 0.000231373564706906*G0_0_1_1 + 6.90667357334062e-06*G0_0_1_2 + 0.000272320272320281*G0_0_2_0 + 6.90667357334062e-06*G0_0_2_1 + 0.000496787163453847*G0_0_2_2 - 0.000231373564706906*G0_1_0_1 + 6.90667357334061e-06*G0_1_0_2 - 0.000231373564706906*G0_1_1_0 - 0.00120373453706791*G0_1_1_1 - 0.000315733649066993*G0_1_1_2 + 6.90667357334062e-06*G0_1_2_0 - 0.000315733649066993*G0_1_2_1 - 3.74933708267052e-05*G0_1_2_2 + 0.000272320272320281*G0_2_0_0 + 6.90667357334061e-06*G0_2_0_1 + 0.000496787163453847*G0_2_0_2 + 6.90667357334062e-06*G0_2_1_0 - 0.000315733649066993*G0_2_1_1 - 3.74933708267051e-05*G0_2_1_2 + 0.000496787163453847*G0_2_2_0 - 3.74933708267051e-05*G0_2_2_1 + 0.0013813347146681*G0_2_2_2; + A[18] = A[46]; + A[29] = A[211]; + A[73] = A[199]; + A[119] = A[99] - 0.00271662493884726*G0_0_0_0 - 0.000160497938275722*G0_0_0_1 + 0.000277582499804731*G0_0_0_2 - 0.000160497938275722*G0_0_1_0 - 9.86667653334359e-06*G0_0_1_1 - 6.5777843555567e-07*G0_0_1_2 + 0.000277582499804731*G0_0_2_0 - 6.57778435555697e-07*G0_0_2_1 + 0.00024469357802692*G0_0_2_2 - 0.000160497938275722*G0_1_0_0 - 9.86667653334359e-06*G0_1_0_1 - 6.57778435555697e-07*G0_1_0_2 - 9.86667653334359e-06*G0_1_1_0 - 0.000265742487964719*G0_1_1_1 - 0.000340071451182573*G0_1_1_2 - 6.57778435555697e-07*G0_1_2_0 - 0.000340071451182573*G0_1_2_1 - 0.000736711847822982*G0_1_2_2 + 0.000277582499804731*G0_2_0_0 - 6.57778435555697e-07*G0_2_0_1 + 0.00024469357802692*G0_2_0_2 - 6.57778435555697e-07*G0_2_1_0 - 0.000340071451182573*G0_2_1_1 - 0.000736711847822982*G0_2_1_2 + 0.00024469357802692*G0_2_2_0 - 0.000736711847822982*G0_2_2_1 - 0.00274030496252727*G0_2_2_2; + A[54] = A[138]; + A[33] = A[47]; + A[24] = -A[165] + 0.000157373490706829*G0_0_0_0 - 5.75556131111601e-07*G0_0_0_1 - 2.6393359726694e-05*G0_0_0_2 - 5.75556131111628e-07*G0_0_1_0 - 5.7555613111154e-07*G0_0_1_1 - 2.6393359726694e-05*G0_0_2_0 - 5.75556131111615e-07*G0_1_0_0 - 5.75556131111533e-07*G0_1_0_1 - 5.75556131111533e-07*G0_1_1_0 + 0.000157373490706831*G0_1_1_1 - 2.6393359726694e-05*G0_1_1_2 - 2.6393359726694e-05*G0_1_2_1 - 2.6393359726694e-05*G0_2_0_0 - 2.6393359726694e-05*G0_2_1_1; + A[127] = A[113]; + A[62] = A[10] + 0.00119553286219957*G0_0_0_0 + 9.97767664434367e-05*G0_0_0_1 + 4.02683736017082e-05*G0_0_0_2 + 9.97767664434367e-05*G0_0_1_0 + 7.64667431334111e-06*G0_0_1_1 + 4.02683736017082e-05*G0_0_2_0 - 4.02683736017083e-05*G0_0_2_2 + 9.97767664434367e-05*G0_1_0_0 + 7.64667431334111e-06*G0_1_0_1 + 7.64667431334111e-06*G0_1_1_0 - 7.64667431334138e-06*G0_1_1_2 - 7.64667431334138e-06*G0_1_2_1 - 9.97767664434366e-05*G0_1_2_2 + 4.02683736017082e-05*G0_2_0_0 - 4.02683736017083e-05*G0_2_0_2 - 7.64667431334139e-06*G0_2_1_1 - 9.97767664434366e-05*G0_2_1_2 - 4.02683736017083e-05*G0_2_2_0 - 9.97767664434366e-05*G0_2_2_1 - 0.00119553286219957*G0_2_2_2; + A[44] = A[212]; + A[141] = A[99]; + A[95] = A[138] - 1.18400118400121e-05*G0_0_0_1 + 1.18400118400124e-05*G0_0_0_2 - 1.18400118400121e-05*G0_0_1_0 - 0.000176284620729072*G0_0_1_1 + 1.18400118400123e-05*G0_0_2_0 + 0.000176284620729071*G0_0_2_2 - 1.18400118400121e-05*G0_1_0_0 - 0.000176284620729072*G0_1_0_1 - 0.000176284620729072*G0_1_1_0 - 0.00177600177600184*G0_1_1_1 - 0.000253902476124708*G0_1_1_2 - 0.000253902476124708*G0_1_2_1 + 0.000253902476124707*G0_1_2_2 + 1.18400118400123e-05*G0_2_0_0 + 0.000176284620729071*G0_2_0_2 - 0.000253902476124708*G0_2_1_1 + 0.000253902476124707*G0_2_1_2 + 0.000176284620729071*G0_2_2_0 + 0.000253902476124707*G0_2_2_1 + 0.00177600177600184*G0_2_2_2; + A[78] = A[50]; + A[172] = A[116]; + A[155] = A[85]; + A[105] = A[7]; + A[98] = A[126]; + A[180] = A[12]; + A[217] = A[119]; + A[200] = A[88]; + A[6] = A[90]; + A[22] = A[106]; + A[9] = A[135]; + A[49] = A[65] + 5.92000592000603e-06*G0_0_0_1 - 5.92000592000611e-06*G0_0_0_2 + 5.92000592000603e-06*G0_0_1_0 - 0.000134186800853473*G0_0_1_1 - 5.92000592000611e-06*G0_0_2_0 + 0.000134186800853472*G0_0_2_2 + 5.92000592000603e-06*G0_1_0_0 - 0.000134186800853473*G0_1_0_1 - 0.000134186800853473*G0_1_1_0 - 0.00234826901493576*G0_1_1_1 - 0.000185493518826858*G0_1_1_2 - 0.000185493518826858*G0_1_2_1 + 0.000185493518826858*G0_1_2_2 - 5.92000592000611e-06*G0_2_0_0 + 0.000134186800853472*G0_2_0_2 - 0.000185493518826858*G0_2_1_1 + 0.000185493518826858*G0_2_1_2 + 0.000134186800853472*G0_2_2_0 + 0.000185493518826858*G0_2_2_1 + 0.00234826901493576*G0_2_2_2; + A[56] = -A[49] + 0.000139449028337922*G0_0_0_0 + 8.48534181867545e-05*G0_0_0_1 + 6.57778435556235e-06*G0_0_0_2 + 8.48534181867545e-05*G0_0_1_0 + 0.00027100471544917*G0_0_1_1 + 7.56445200889675e-06*G0_0_1_2 + 6.57778435556235e-06*G0_0_2_0 + 7.56445200889675e-06*G0_0_2_1 - 0.000155235710791272*G0_0_2_2 + 8.48534181867545e-05*G0_1_0_0 + 0.00027100471544917*G0_1_0_1 + 7.56445200889675e-06*G0_1_0_2 + 0.00027100471544917*G0_1_1_0 + 0.000703822926045186*G0_1_1_1 + 0.000136817914595699*G0_1_1_2 + 7.56445200889675e-06*G0_1_2_0 + 0.000136817914595699*G0_1_2_1 - 0.000165760165760171*G0_1_2_2 + 6.57778435556235e-06*G0_2_0_0 + 7.56445200889675e-06*G0_2_0_1 - 0.000155235710791271*G0_2_0_2 + 7.56445200889675e-06*G0_2_1_0 + 0.000136817914595699*G0_2_1_1 - 0.000165760165760171*G0_2_1_2 - 0.000155235710791271*G0_2_2_0 - 0.000165760165760171*G0_2_2_1 - 0.00142343253454369*G0_2_2_2; + A[176] = A[56] + 0.000778809667698584*G0_0_0_0 + 0.000509120509120526*G0_0_0_1 + 9.73512084623228e-05*G0_0_0_2 + 0.000509120509120526*G0_0_1_0 + 0.00131555687111247*G0_0_1_1 + 5.65689454578362e-05*G0_0_1_2 + 9.73512084623228e-05*G0_0_2_0 + 5.65689454578362e-05*G0_0_2_1 + 0.000509120509120526*G0_1_0_0 + 0.00131555687111247*G0_1_0_1 + 5.65689454578362e-05*G0_1_0_2 + 0.00131555687111247*G0_1_1_0 + 0.00467022689244929*G0_1_1_1 + 5.65689454578362e-05*G0_1_2_0 - 5.65689454578364e-05*G0_1_2_2 + 9.73512084623228e-05*G0_2_0_0 + 5.65689454578362e-05*G0_2_0_1 + 5.65689454578362e-05*G0_2_1_0 - 5.65689454578364e-05*G0_2_1_2 - 5.65689454578364e-05*G0_2_2_1 - 9.73512084623229e-05*G0_2_2_2; + A[214] = A[56] - 0.000265742487964719*G0_0_0_0 - 9.86667653334397e-06*G0_0_0_1 - 0.000340071451182574*G0_0_0_2 - 9.86667653334397e-06*G0_0_1_0 - 0.000160497938275723*G0_0_1_1 - 6.57778435556727e-07*G0_0_1_2 - 0.000340071451182574*G0_0_2_0 - 6.57778435556714e-07*G0_0_2_1 - 0.000736711847822984*G0_0_2_2 - 9.86667653334397e-06*G0_1_0_0 - 0.000160497938275723*G0_1_0_1 - 6.57778435556754e-07*G0_1_0_2 - 0.000160497938275723*G0_1_1_0 - 0.00271662493884727*G0_1_1_1 + 0.00027758249980473*G0_1_1_2 - 6.57778435556714e-07*G0_1_2_0 + 0.00027758249980473*G0_1_2_1 + 0.000244693578026919*G0_1_2_2 - 0.000340071451182574*G0_2_0_0 - 6.57778435556741e-07*G0_2_0_1 - 0.000736711847822984*G0_2_0_2 - 6.57778435556714e-07*G0_2_1_0 + 0.00027758249980473*G0_2_1_1 + 0.000244693578026919*G0_2_1_2 - 0.000736711847822984*G0_2_2_0 + 0.000244693578026919*G0_2_2_1 - 0.00274030496252728*G0_2_2_2; + A[202] = -A[56] + 1.71022393244627e-05*G0_0_0_0 + 3.94667061333828e-06*G0_0_0_1 - 0.000482809371698276*G0_0_0_2 + 3.94667061333828e-06*G0_0_1_0 + 0.000509778287556085*G0_0_1_1 - 3.48622570844798e-05*G0_0_1_2 - 0.000482809371698276*G0_0_2_0 - 3.48622570844798e-05*G0_0_2_1 - 0.000482809371698276*G0_0_2_2 + 3.94667061333828e-06*G0_1_0_0 + 0.000509778287556085*G0_1_0_1 - 3.48622570844798e-05*G0_1_0_2 + 0.000509778287556085*G0_1_1_0 + 0.00450446672668912*G0_1_1_1 + 0.000509778287556086*G0_1_1_2 - 3.48622570844798e-05*G0_1_2_0 + 0.000509778287556086*G0_1_2_1 + 3.94667061333847e-06*G0_1_2_2 - 0.000482809371698276*G0_2_0_0 - 3.48622570844798e-05*G0_2_0_1 - 0.000482809371698276*G0_2_0_2 - 3.48622570844798e-05*G0_2_1_0 + 0.000509778287556086*G0_2_1_1 + 3.94667061333841e-06*G0_2_1_2 - 0.000482809371698276*G0_2_2_0 + 3.94667061333841e-06*G0_2_2_1 + 1.71022393244619e-05*G0_2_2_2; + A[144] = A[176] + 0.00836694170027533*G0_0_0_0 + 0.00129450796117467*G0_0_0_1 + 0.00046307601863159*G0_0_0_2 + 0.00129450796117467*G0_0_1_0 - 0.00129450796117467*G0_0_1_1 + 0.00046307601863159*G0_0_2_0 + 1.57866824533496e-05*G0_0_2_2 + 0.00129450796117467*G0_1_0_0 - 0.00129450796117467*G0_1_0_1 - 0.00129450796117467*G0_1_1_0 - 0.00836694170027534*G0_1_1_1 - 0.00046307601863159*G0_1_1_2 - 0.00046307601863159*G0_1_2_1 - 1.57866824533497e-05*G0_1_2_2 + 0.00046307601863159*G0_2_0_0 + 1.57866824533496e-05*G0_2_0_2 - 0.00046307601863159*G0_2_1_1 - 1.57866824533497e-05*G0_2_1_2 + 1.57866824533496e-05*G0_2_2_0 - 1.57866824533497e-05*G0_2_2_1; + A[80] = A[144] - 0.00924310257643624*G0_0_0_0 - 0.00187598409820639*G0_0_0_1 - 0.000544640544640563*G0_0_0_2 - 0.00187598409820639*G0_0_1_0 - 0.000484124928569391*G0_0_1_1 - 0.000544640544640563*G0_0_2_0 + 0.000544640544640563*G0_0_2_2 - 0.00187598409820639*G0_1_0_0 - 0.000484124928569391*G0_1_0_1 - 0.000484124928569391*G0_1_1_0 + 0.00048412492856939*G0_1_1_2 + 0.00048412492856939*G0_1_2_1 + 0.00187598409820639*G0_1_2_2 - 0.000544640544640563*G0_2_0_0 + 0.000544640544640563*G0_2_0_2 + 0.00048412492856939*G0_2_1_1 + 0.00187598409820639*G0_2_1_2 + 0.000544640544640563*G0_2_2_0 + 0.00187598409820639*G0_2_2_1 + 0.00924310257643623*G0_2_2_2; + A[164] = A[202] - 0.00041440041440043*G0_0_0_1 + 0.000414400414400428*G0_0_0_2 - 0.00041440041440043*G0_0_1_0 - 0.000432160432160448*G0_0_1_1 + 0.000414400414400428*G0_0_2_0 + 0.000432160432160446*G0_0_2_2 - 0.00041440041440043*G0_1_0_0 - 0.000432160432160449*G0_1_0_1 - 0.000432160432160449*G0_1_1_0 - 1.18400118400155e-05*G0_1_1_1 - 1.77600177600195e-05*G0_1_1_2 - 1.77600177600195e-05*G0_1_2_1 + 1.77600177600181e-05*G0_1_2_2 + 0.000414400414400428*G0_2_0_0 + 0.000432160432160446*G0_2_0_2 - 1.77600177600195e-05*G0_2_1_1 + 1.77600177600181e-05*G0_2_1_2 + 0.000432160432160446*G0_2_2_0 + 1.77600177600182e-05*G0_2_2_1 + 1.18400118400142e-05*G0_2_2_2; + A[72] = A[202] + 1.18400118400115e-05*G0_0_0_0 + 1.77600177600179e-05*G0_0_0_1 + 0.000432160432160446*G0_0_0_2 + 1.77600177600179e-05*G0_0_1_0 - 1.77600177600193e-05*G0_0_1_1 + 0.000432160432160446*G0_0_2_0 + 0.000414400414400428*G0_0_2_2 + 1.77600177600179e-05*G0_1_0_0 - 1.77600177600193e-05*G0_1_0_1 - 1.77600177600193e-05*G0_1_1_0 - 1.18400118400149e-05*G0_1_1_1 - 0.000432160432160449*G0_1_1_2 - 0.000432160432160449*G0_1_2_1 - 0.000414400414400429*G0_1_2_2 + 0.000432160432160446*G0_2_0_0 + 0.000414400414400428*G0_2_0_2 - 0.000432160432160449*G0_2_1_1 - 0.000414400414400429*G0_2_1_2 + 0.000414400414400428*G0_2_2_0 - 0.000414400414400429*G0_2_2_1; + A[175] = -A[56] - 0.00142343253454369*G0_0_0_0 - 0.000165760165760171*G0_0_0_1 - 0.000155235710791272*G0_0_0_2 - 0.000165760165760171*G0_0_1_0 + 0.000136817914595697*G0_0_1_1 + 7.56445200889677e-06*G0_0_1_2 - 0.000155235710791272*G0_0_2_0 + 7.56445200889675e-06*G0_0_2_1 + 6.57778435556242e-06*G0_0_2_2 - 0.000165760165760171*G0_1_0_0 + 0.000136817914595697*G0_1_0_1 + 7.56445200889677e-06*G0_1_0_2 + 0.000136817914595697*G0_1_1_0 + 0.00070382292604517*G0_1_1_1 + 0.00027100471544917*G0_1_1_2 + 7.56445200889677e-06*G0_1_2_0 + 0.00027100471544917*G0_1_2_1 + 8.48534181867545e-05*G0_1_2_2 - 0.000155235710791272*G0_2_0_0 + 7.56445200889677e-06*G0_2_0_1 + 6.57778435556242e-06*G0_2_0_2 + 7.56445200889677e-06*G0_2_1_0 + 0.00027100471544917*G0_2_1_1 + 8.48534181867545e-05*G0_2_1_2 + 6.57778435556242e-06*G0_2_2_0 + 8.48534181867545e-05*G0_2_2_1 + 0.000139449028337922*G0_2_2_2; + A[193] = A[202] - 0.00171680171680178*G0_0_0_0 + 0.000544640544640563*G0_0_0_1 - 0.000367040367040379*G0_0_0_2 + 0.000544640544640563*G0_0_1_0 + 0.000526880526880543*G0_0_1_1 + 5.92000592000559e-06*G0_0_1_2 - 0.000367040367040379*G0_0_2_0 + 5.92000592000559e-06*G0_0_2_1 - 0.000177600177600184*G0_0_2_2 + 0.000544640544640563*G0_1_0_0 + 0.000526880526880544*G0_1_0_1 + 5.92000592000553e-06*G0_1_0_2 + 0.000526880526880544*G0_1_1_0 - 0.0017286417286418*G0_1_1_1 - 0.000799200799200829*G0_1_1_2 + 5.92000592000559e-06*G0_1_2_0 - 0.000799200799200829*G0_1_2_1 - 0.000592000592000613*G0_1_2_2 - 0.000367040367040379*G0_2_0_0 + 5.92000592000556e-06*G0_2_0_1 - 0.000177600177600184*G0_2_0_2 + 5.92000592000556e-06*G0_2_1_0 - 0.000799200799200829*G0_2_1_1 - 0.000592000592000613*G0_2_1_2 - 0.000177600177600184*G0_2_2_0 - 0.000592000592000613*G0_2_2_1 - 0.000769600769600794*G0_2_2_2; + A[159] = A[175] - 0.00234826901493576*G0_0_0_0 - 0.000185493518826858*G0_0_0_1 - 0.000134186800853472*G0_0_0_2 - 0.000185493518826858*G0_0_1_0 + 0.000185493518826859*G0_0_1_1 - 0.000134186800853472*G0_0_2_0 + 5.92000592000607e-06*G0_0_2_2 - 0.000185493518826859*G0_1_0_0 + 0.000185493518826859*G0_1_0_1 + 0.000185493518826859*G0_1_1_0 + 0.00234826901493577*G0_1_1_1 + 0.000134186800853472*G0_1_1_2 + 0.000134186800853472*G0_1_2_1 - 5.92000592000605e-06*G0_1_2_2 - 0.000134186800853472*G0_2_0_0 + 5.92000592000607e-06*G0_2_0_2 + 0.000134186800853472*G0_2_1_1 - 5.92000592000605e-06*G0_2_1_2 + 5.92000592000609e-06*G0_2_2_0 - 5.92000592000605e-06*G0_2_2_1; + A[160] = -A[164] + 0.0045436045436047*G0_0_0_0 + 0.00149480149480155*G0_0_0_1 + 0.000387760387760401*G0_0_0_2 + 0.00149480149480155*G0_0_1_0 + 0.00149480149480155*G0_0_1_1 + 0.000136900136900142*G0_0_1_2 + 0.000387760387760401*G0_0_2_0 + 0.000136900136900142*G0_0_2_1 + 4.44000444000504e-06*G0_0_2_2 + 0.00149480149480155*G0_1_0_0 + 0.00149480149480155*G0_1_0_1 + 0.000136900136900142*G0_1_0_2 + 0.00149480149480155*G0_1_1_0 + 0.00454360454360471*G0_1_1_1 + 0.000387760387760402*G0_1_1_2 + 0.000136900136900142*G0_1_2_0 + 0.000387760387760402*G0_1_2_1 + 4.44000444000523e-06*G0_1_2_2 + 0.000387760387760401*G0_2_0_0 + 0.000136900136900142*G0_2_0_1 + 4.44000444000504e-06*G0_2_0_2 + 0.000136900136900142*G0_2_1_0 + 0.000387760387760402*G0_2_1_1 + 4.44000444000523e-06*G0_2_1_2 + 4.44000444000504e-06*G0_2_2_0 + 4.44000444000523e-06*G0_2_2_1 - 6.66000666000672e-05*G0_2_2_2; + A[168] = A[56]; + A[222] = A[193] - 0.00132608132608137*G0_0_0_1 + 0.00132608132608137*G0_0_0_2 - 0.00132608132608137*G0_0_1_0 - 0.00113664113664118*G0_0_1_1 + 0.00132608132608137*G0_0_2_0 + 0.00113664113664117*G0_0_2_2 - 0.00132608132608137*G0_1_0_0 - 0.00113664113664118*G0_1_0_1 - 0.00113664113664118*G0_1_1_0 + 0.000947200947200985*G0_1_1_1 + 0.000189440189440197*G0_1_1_2 + 0.000189440189440197*G0_1_2_1 - 0.000189440189440195*G0_1_2_2 + 0.00132608132608137*G0_2_0_0 + 0.00113664113664117*G0_2_0_2 + 0.000189440189440198*G0_2_1_1 - 0.000189440189440195*G0_2_1_2 + 0.00113664113664117*G0_2_2_0 - 0.000189440189440196*G0_2_2_1 - 0.000947200947200982*G0_2_2_2; + A[184] = A[72]; + A[207] = A[193]; + A[220] = A[164]; + A[194] = A[222]; + A[118] = A[202]; + A[34] = A[62]; + A[147] = A[189]; + A[124] = A[68]; + A[84] = A[10] + 0.00152386707942269*G0_0_0_0 + 0.000160580160580166*G0_0_0_1 + 7.60145204589673e-05*G0_0_0_2 + 0.000160580160580166*G0_0_1_0 + 2.48722470944705e-06*G0_0_1_1 + 6.88611799722934e-06*G0_0_1_2 + 7.60145204589673e-05*G0_0_2_0 + 6.88611799722935e-06*G0_0_2_1 + 3.57461468572591e-05*G0_0_2_2 + 0.000160580160580166*G0_1_0_0 + 2.48722470944707e-06*G0_1_0_1 + 6.88611799722935e-06*G0_1_0_2 + 2.48722470944706e-06*G0_1_1_0 + 7.80289669178584e-05*G0_1_1_1 - 5.15944960389424e-06*G0_1_1_2 + 6.88611799722935e-06*G0_1_2_0 - 5.15944960389424e-06*G0_1_2_1 + 6.08033941367295e-05*G0_1_2_2 + 7.60145204589673e-05*G0_2_0_0 + 6.88611799722935e-06*G0_2_0_1 + 3.57461468572591e-05*G0_2_0_2 + 6.88611799722935e-06*G0_2_1_0 - 5.15944960389424e-06*G0_2_1_1 + 6.08033941367295e-05*G0_2_1_2 + 3.57461468572591e-05*G0_2_2_0 + 6.08033941367295e-05*G0_2_2_1 + 0.000328334217223117*G0_2_2_2; + A[107] = A[84] - 6.98889587778481e-06*G0_0_0_0 - 2.50983584316926e-05*G0_0_0_1 + 8.03723025945278e-06*G0_0_0_2 - 2.50983584316926e-05*G0_0_1_0 - 3.05455861011429e-05*G0_0_1_1 - 6.88611799722935e-06*G0_0_1_2 + 8.03723025945276e-06*G0_0_2_0 - 6.88611799722935e-06*G0_0_2_1 - 0.000119797897575679*G0_0_2_2 - 2.50983584316926e-05*G0_1_0_0 - 3.05455861011429e-05*G0_1_0_1 - 6.88611799722936e-06*G0_1_0_2 - 3.05455861011429e-05*G0_1_1_0 - 0.000399374288263192*G0_1_1_1 - 4.62706018261591e-05*G0_1_1_2 - 6.88611799722936e-06*G0_1_2_0 - 4.62706018261591e-05*G0_1_2_1 - 0.000116796783463454*G0_1_2_2 + 8.03723025945277e-06*G0_2_0_0 - 6.88611799722936e-06*G0_2_0_1 - 0.000119797897575679*G0_2_0_2 - 6.88611799722936e-06*G0_2_1_0 - 4.62706018261591e-05*G0_2_1_1 - 0.000116796783463454*G0_2_1_2 - 0.000119797897575679*G0_2_2_0 - 0.000116796783463454*G0_2_2_1 - 0.00152386707942268*G0_2_2_2; + A[25] = A[107] - 7.64667431334115e-06*G0_0_0_1 + 7.64667431334129e-06*G0_0_0_2 - 7.64667431334116e-06*G0_0_1_0 - 9.9776766443437e-05*G0_0_1_1 + 7.6466743133413e-06*G0_0_2_0 + 9.97767664434365e-05*G0_0_2_2 - 7.64667431334116e-06*G0_1_0_0 - 9.9776766443437e-05*G0_1_0_1 - 9.9776766443437e-05*G0_1_1_0 - 0.00119553286219957*G0_1_1_1 - 4.02683736017084e-05*G0_1_1_2 - 4.02683736017084e-05*G0_1_2_1 + 4.02683736017083e-05*G0_1_2_2 + 7.6466743133413e-06*G0_2_0_0 + 9.97767664434365e-05*G0_2_0_2 - 4.02683736017084e-05*G0_2_1_1 + 4.02683736017083e-05*G0_2_1_2 + 9.97767664434365e-05*G0_2_2_0 + 4.02683736017083e-05*G0_2_2_1 + 0.00119553286219957*G0_2_2_2; + A[37] = A[107]; + A[173] = A[107] + 7.80289669178581e-05*G0_0_0_0 - 5.15944960389423e-06*G0_0_0_1 + 2.48722470944694e-06*G0_0_0_2 - 5.15944960389424e-06*G0_0_1_0 + 6.08033941367296e-05*G0_0_1_1 + 6.88611799722936e-06*G0_0_1_2 + 2.48722470944695e-06*G0_0_2_0 + 6.88611799722936e-06*G0_0_2_1 + 0.000160580160580166*G0_0_2_2 - 5.15944960389424e-06*G0_1_0_0 + 6.08033941367296e-05*G0_1_0_1 + 6.88611799722936e-06*G0_1_0_2 + 6.08033941367296e-05*G0_1_1_0 + 0.000328334217223118*G0_1_1_1 + 3.57461468572592e-05*G0_1_1_2 + 6.88611799722936e-06*G0_1_2_0 + 3.57461468572592e-05*G0_1_2_1 + 7.60145204589676e-05*G0_1_2_2 + 2.48722470944696e-06*G0_2_0_0 + 6.88611799722936e-06*G0_2_0_1 + 0.000160580160580166*G0_2_0_2 + 6.88611799722936e-06*G0_2_1_0 + 3.57461468572592e-05*G0_2_1_1 + 7.60145204589676e-05*G0_2_1_2 + 0.000160580160580166*G0_2_2_0 + 7.60145204589676e-05*G0_2_2_1 + 0.00152386707942269*G0_2_2_2; + A[67] = A[109]; + A[161] = A[175]; + A[136] = A[24]; + A[96] = A[144] - 0.00131555687111247*G0_0_0_1 + 0.00131555687111247*G0_0_0_2 - 0.00131555687111247*G0_0_1_0 - 0.000565689454578364*G0_0_1_1 + 0.00131555687111247*G0_0_2_0 + 0.000565689454578363*G0_0_2_2 - 0.00131555687111247*G0_1_0_0 - 0.000565689454578364*G0_1_0_1 - 0.000565689454578364*G0_1_1_0 - 0.00087616087616091*G0_1_1_1 - 9.73512084623232e-05*G0_1_1_2 - 9.73512084623232e-05*G0_1_2_1 + 9.73512084623228e-05*G0_1_2_2 + 0.00131555687111247*G0_2_0_0 + 0.000565689454578363*G0_2_0_2 - 9.73512084623232e-05*G0_2_1_1 + 9.73512084623228e-05*G0_2_1_2 + 0.000565689454578363*G0_2_2_0 + 9.73512084623228e-05*G0_2_2_1 + 0.000876160876160906*G0_2_2_2; + A[81] = A[95]; + A[167] = A[41]; + A[156] = A[100]; + A[112] = A[160] - 0.00152144152144158*G0_0_0_1 + 0.00152144152144157*G0_0_0_2 - 0.00152144152144158*G0_0_1_0 - 0.00192252192252199*G0_0_1_1 + 0.00152144152144157*G0_0_2_0 + 0.00192252192252198*G0_0_2_2 - 0.00152144152144158*G0_1_0_0 - 0.00192252192252199*G0_1_0_1 - 0.00192252192252199*G0_1_1_0 - 0.00462204462204479*G0_1_1_1 - 0.000401080401080416*G0_1_1_2 - 0.000401080401080416*G0_1_2_1 + 0.000401080401080413*G0_1_2_2 + 0.00152144152144157*G0_2_0_0 + 0.00192252192252198*G0_2_0_2 - 0.000401080401080416*G0_2_1_1 + 0.000401080401080413*G0_2_1_2 + 0.00192252192252198*G0_2_2_0 + 0.000401080401080413*G0_2_2_1 + 0.00462204462204477*G0_2_2_2; + A[223] = A[193] + 0.00094720094720098*G0_0_0_0 - 0.00113664113664118*G0_0_0_1 + 0.000189440189440196*G0_0_0_2 - 0.00113664113664118*G0_0_1_0 - 0.00132608132608137*G0_0_1_1 + 0.000189440189440195*G0_0_2_0 - 0.000189440189440196*G0_0_2_2 - 0.00113664113664118*G0_1_0_0 - 0.00132608132608137*G0_1_0_1 - 0.00132608132608137*G0_1_1_0 + 0.00132608132608137*G0_1_1_2 + 0.00132608132608137*G0_1_2_1 + 0.00113664113664118*G0_1_2_2 + 0.000189440189440196*G0_2_0_0 - 0.000189440189440196*G0_2_0_2 + 0.00132608132608137*G0_2_1_1 + 0.00113664113664118*G0_2_1_2 - 0.000189440189440196*G0_2_2_0 + 0.00113664113664118*G0_2_2_1 - 0.00094720094720098*G0_2_2_2; + A[185] = A[45] + 0.000522111633222761*G0_0_0_0 + 0.00026631804409583*G0_0_0_1 + 2.60644705089155e-05*G0_0_0_2 + 0.00026631804409583*G0_0_1_0 + 0.000198895754451317*G0_0_1_1 + 2.60644705089155e-05*G0_0_2_0 - 0.000212873546206887*G0_0_2_2 + 0.000266318044095831*G0_1_0_0 + 0.000198895754451317*G0_1_0_1 + 0.000198895754451317*G0_1_1_0 + 0.000314911426022549*G0_1_1_1 - 2.87778065555861e-06*G0_1_1_2 - 2.87778065555862e-06*G0_1_2_1 - 0.000401984846429305*G0_1_2_2 + 2.60644705089155e-05*G0_2_0_0 - 0.000212873546206887*G0_2_0_2 - 2.87778065555861e-06*G0_2_1_1 - 0.000401984846429305*G0_2_1_2 - 0.000212873546206887*G0_2_2_0 - 0.000401984846429305*G0_2_2_1 - 0.00173242395464624*G0_2_2_2; + A[210] = A[14]; + A[203] = A[133]; + A[3] = A[45]; + A[59] = A[213]; + A[17] = A[31]; + A[134] = A[218]; + A[69] = A[139]; + A[48] = A[176] - 0.000876160876160906*G0_0_0_0 - 0.000565689454578363*G0_0_0_1 - 9.73512084623228e-05*G0_0_0_2 - 0.000565689454578363*G0_0_1_0 - 0.00131555687111247*G0_0_1_1 - 9.73512084623228e-05*G0_0_2_0 + 9.73512084623228e-05*G0_0_2_2 - 0.000565689454578363*G0_1_0_0 - 0.00131555687111247*G0_1_0_1 - 0.00131555687111247*G0_1_1_0 + 0.00131555687111247*G0_1_1_2 + 0.00131555687111247*G0_1_2_1 + 0.000565689454578363*G0_1_2_2 - 9.73512084623228e-05*G0_2_0_0 + 9.73512084623228e-05*G0_2_0_2 + 0.00131555687111247*G0_2_1_1 + 0.000565689454578363*G0_2_1_2 + 9.73512084623228e-05*G0_2_2_0 + 0.000565689454578363*G0_2_2_1 + 0.000876160876160906*G0_2_2_2; + A[39] = A[137]; + A[121] = A[106] - 0.000193427971205756*G0_0_0_0 + 2.41528019305805e-05*G0_0_0_2 + 2.41528019305805e-05*G0_0_2_0 - 2.76472498694731e-05*G0_0_2_2 + 2.67222489444688e-06*G0_1_1_1 - 4.47906003461574e-05*G0_1_2_2 + 2.41528019305805e-05*G0_2_0_0 - 2.76472498694731e-05*G0_2_0_2 - 4.47906003461574e-05*G0_2_1_2 - 2.76472498694731e-05*G0_2_2_0 - 4.47906003461574e-05*G0_2_2_1 - 0.000504228282006077*G0_2_2_2; + A[87] = A[185]; + A[64] = A[160] - 0.00462204462204478*G0_0_0_0 - 0.00192252192252199*G0_0_0_1 - 0.000401080401080414*G0_0_0_2 - 0.00192252192252199*G0_0_1_0 - 0.00152144152144158*G0_0_1_1 - 0.000401080401080414*G0_0_2_0 + 0.000401080401080414*G0_0_2_2 - 0.00192252192252199*G0_1_0_0 - 0.00152144152144158*G0_1_0_1 - 0.00152144152144158*G0_1_1_0 + 0.00152144152144157*G0_1_1_2 + 0.00152144152144157*G0_1_2_1 + 0.00192252192252199*G0_1_2_2 - 0.000401080401080414*G0_2_0_0 + 0.000401080401080414*G0_2_0_2 + 0.00152144152144157*G0_2_1_1 + 0.00192252192252199*G0_2_1_2 + 0.000401080401080414*G0_2_2_0 + 0.00192252192252199*G0_2_2_1 + 0.00462204462204478*G0_2_2_2; + A[162] = A[56] - 0.00274030496252728*G0_0_0_0 + 0.000244693578026919*G0_0_0_1 - 0.000736711847822984*G0_0_0_2 + 0.000244693578026919*G0_0_1_0 + 0.000277582499804731*G0_0_1_1 - 6.57778435556497e-07*G0_0_1_2 - 0.000736711847822984*G0_0_2_0 - 6.57778435556524e-07*G0_0_2_1 - 0.000340071451182574*G0_0_2_2 + 0.000244693578026919*G0_1_0_0 + 0.000277582499804731*G0_1_0_1 - 6.57778435556524e-07*G0_1_0_2 + 0.000277582499804731*G0_1_1_0 - 0.00271662493884726*G0_1_1_1 - 0.000160497938275722*G0_1_1_2 - 6.57778435556551e-07*G0_1_2_0 - 0.000160497938275722*G0_1_2_1 - 9.86667653334384e-06*G0_1_2_2 - 0.000736711847822984*G0_2_0_0 - 6.57778435556497e-07*G0_2_0_1 - 0.000340071451182574*G0_2_0_2 - 6.57778435556524e-07*G0_2_1_0 - 0.000160497938275722*G0_2_1_1 - 9.86667653334381e-06*G0_2_1_2 - 0.000340071451182574*G0_2_2_0 - 9.86667653334384e-06*G0_2_2_1 - 0.00026574248796472*G0_2_2_2; + A[93] = A[51]; + A[166] = A[26]; + A[115] = A[157]; + A[224] = A[192] - 0.0132608132608137*G0_0_0_0 - 0.00378880378880392*G0_0_0_1 - 0.00265216265216275*G0_0_0_2 - 0.00378880378880392*G0_0_1_0 - 0.00113664113664118*G0_0_1_1 - 0.00265216265216275*G0_0_2_0 + 0.00265216265216274*G0_0_2_2 - 0.00378880378880392*G0_1_0_0 - 0.00113664113664118*G0_1_0_1 - 0.00113664113664118*G0_1_1_0 + 0.00113664113664117*G0_1_1_2 + 0.00113664113664117*G0_1_2_1 + 0.00378880378880391*G0_1_2_2 - 0.00265216265216275*G0_2_0_0 + 0.00265216265216274*G0_2_0_2 + 0.00113664113664117*G0_2_1_1 + 0.00378880378880391*G0_2_1_2 + 0.00265216265216274*G0_2_2_0 + 0.00378880378880391*G0_2_2_1 + 0.0132608132608137*G0_2_2_2; + A[190] = A[162]; + A[206] = A[178]; + A[0] = A[16] + 0.00176027676027682*G0_0_0_0 + 6.37222859445104e-05*G0_0_0_1 + 6.52639541528451e-05*G0_0_0_2 + 6.37222859445104e-05*G0_0_1_0 - 6.37222859445106e-05*G0_0_1_1 + 6.52639541528451e-05*G0_0_2_0 + 1.54166820833492e-06*G0_0_2_2 + 6.37222859445104e-05*G0_1_0_0 - 6.37222859445106e-05*G0_1_0_1 - 6.37222859445106e-05*G0_1_1_0 - 0.00176027676027682*G0_1_1_1 - 6.52639541528451e-05*G0_1_1_2 - 6.52639541528451e-05*G0_1_2_1 - 1.5416682083349e-06*G0_1_2_2 + 6.52639541528451e-05*G0_2_0_0 + 1.54166820833492e-06*G0_2_0_2 - 6.52639541528451e-05*G0_2_1_1 - 1.5416682083349e-06*G0_2_1_2 + 1.54166820833492e-06*G0_2_2_0 - 1.5416682083349e-06*G0_2_2_1; + A[58] = A[198]; + A[28] = A[108] + 9.86667653334357e-05*G0_0_0_0 + 3.45333678667025e-06*G0_0_0_1 - 7.00534033867386e-05*G0_0_0_2 + 3.45333678667025e-06*G0_0_1_0 - 4.14400414400427e-05*G0_0_1_1 - 6.90667357334037e-06*G0_0_1_2 - 7.00534033867386e-05*G0_0_2_0 - 6.90667357334038e-06*G0_0_2_1 + 3.45333678667026e-06*G0_1_0_0 - 4.14400414400427e-05*G0_1_0_1 - 6.90667357334038e-06*G0_1_0_2 - 4.14400414400427e-05*G0_1_1_0 + 0.000137146803813476*G0_1_1_1 - 4.44000444000461e-05*G0_1_1_2 - 6.90667357334038e-06*G0_1_2_0 - 4.44000444000461e-05*G0_1_2_1 + 7.05467372134063e-05*G0_1_2_2 - 7.00534033867386e-05*G0_2_0_0 - 6.90667357334038e-06*G0_2_0_1 - 6.90667357334038e-06*G0_2_1_0 - 4.44000444000461e-05*G0_2_1_1 + 7.05467372134063e-05*G0_2_1_2 + 7.05467372134063e-05*G0_2_2_1 + 0.000897867564534261*G0_2_2_2; + A[70] = -A[28] + 2.26933560266912e-05*G0_0_0_0 - 9.54600954600981e-05*G0_0_0_1 + 8.23867490534187e-05*G0_0_0_2 - 9.54600954600981e-05*G0_0_1_0 + 6.90667357334166e-06*G0_0_1_1 - 4.44000444000437e-06*G0_0_1_2 + 8.23867490534187e-05*G0_0_2_0 - 4.44000444000438e-06*G0_0_2_1 + 8.23867490534185e-05*G0_0_2_2 - 9.54600954600981e-05*G0_1_0_0 + 6.9066735733417e-06*G0_1_0_1 - 4.44000444000435e-06*G0_1_0_2 + 6.90667357334171e-06*G0_1_1_0 + 0.00185246851913526*G0_1_1_1 + 6.90667357334115e-06*G0_1_1_2 - 4.44000444000436e-06*G0_1_2_0 + 6.90667357334116e-06*G0_1_2_1 - 9.54600954600987e-05*G0_1_2_2 + 8.23867490534187e-05*G0_2_0_0 - 4.44000444000436e-06*G0_2_0_1 + 8.23867490534185e-05*G0_2_0_2 - 4.44000444000437e-06*G0_2_1_0 + 6.90667357334116e-06*G0_2_1_1 - 9.54600954600987e-05*G0_2_1_2 + 8.23867490534185e-05*G0_2_2_0 - 9.54600954600987e-05*G0_2_2_1 + 2.26933560266895e-05*G0_2_2_2; + A[154] = A[70]; + A[131] = A[173]; + A[74] = A[214]; + A[40] = A[1] + 0.000209317431539661*G0_0_0_0 - 4.01758735092082e-05*G0_0_0_1 - 4.01758735092082e-05*G0_0_1_0 - 4.01758735092081e-05*G0_0_1_1 - 4.01758735092082e-05*G0_1_0_0 - 4.01758735092081e-05*G0_1_0_1 - 4.01758735092081e-05*G0_1_1_0 + 0.000209317431539662*G0_1_1_1 - 3.61778139555921e-06*G0_2_2_2; + A[145] = A[159]; + A[151] = A[25]; + A[102] = A[186]; + A[177] = A[191]; + A[114] = A[142]; + A[221] = A[179]; + A[196] = A[28]; + A[209] = A[223]; + A[13] = A[195]; + A[53] = A[123]; + A[30] = A[2]; + A[23] = A[121]; + A[128] = A[176] - 0.00048412492856939*G0_0_0_1 + 0.000484124928569389*G0_0_0_2 - 0.00048412492856939*G0_0_1_0 - 0.00187598409820639*G0_0_1_1 + 0.000484124928569389*G0_0_2_0 + 0.00187598409820638*G0_0_2_2 - 0.00048412492856939*G0_1_0_0 - 0.00187598409820639*G0_1_0_1 - 0.00187598409820639*G0_1_1_0 - 0.00924310257643625*G0_1_1_1 - 0.000544640544640564*G0_1_1_2 - 0.000544640544640564*G0_1_2_1 + 0.000544640544640564*G0_1_2_2 + 0.000484124928569389*G0_2_0_0 + 0.00187598409820638*G0_2_0_2 - 0.000544640544640564*G0_2_1_1 + 0.000544640544640564*G0_2_1_2 + 0.00187598409820638*G0_2_2_0 + 0.000544640544640564*G0_2_2_1 + 0.00924310257643622*G0_2_2_2; + A[63] = A[49]; + A[140] = A[84]; + A[77] = A[35]; + A[171] = A[101]; + A[152] = A[40]; + } + + /// 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 mass_matrix_f3_p1_q4_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f3_p1_q4_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p1_q4_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1)))), 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 3; + } + + /// 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 mass_matrix_f3_p1_q4_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f3_p1_q4_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f3_p1_q4_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p1_q4_tensor_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p1_q4_tensor_finite_element_0(); + 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 mass_matrix_f3_p1_q4_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f3_p1_q4_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f3_p1_q4_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p1_q4_tensor_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p1_q4_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f3_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/mass_matrix_2d/mass_matrix_f3_p2_q1_excafe.h b/mass_matrix_2d/mass_matrix_f3_p2_q1_excafe.h new file mode 100644 index 0000000..bf5079a --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f3_p2_q1_excafe.h @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 1 minute and 51.12 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[1][4]*w[2][0] + w[1][0]*w[2][4]; + const double var_1 = var_0*w[0][0] + w[0][4]*w[1][0]*w[2][0]; + const double var_2 = w[1][3]*w[2][2] + w[1][2]*w[2][3]; + const double var_3 = w[1][2]*w[2][1] + w[1][1]*w[2][2]; + const double var_4 = w[1][2]*w[2][4] + w[1][4]*w[2][2]; + const double var_5 = var_4*w[0][1] + var_3*w[0][4]; + const double var_6 = w[1][3]*w[2][0] + w[1][0]*w[2][3]; + const double var_7 = -0.1333333333333333314829616*var_6; + const double var_8 = -1.0000000000000000000000000*x[0][1]; + const double var_9 = x[2][1] + var_8; + const double var_10 = -1.0000000000000000000000000*x[0][0]; + const double var_11 = x[1][0] + var_10; + const double var_12 = x[1][1] + var_8; + const double var_13 = x[2][0] + var_10; + const double var_14 = var_11*var_9 + -1.0000000000000000000000000*var_12*var_13; + const double var_15 = std::abs(var_14); + const double var_16 = w[1][1]*w[2][0] + w[1][0]*w[2][1]; + const double var_17 = w[1][0]*w[2][2] + w[1][2]*w[2][0]; + const double var_18 = var_3*w[0][0] + var_17*w[0][1] + var_16*w[0][2]; + const double var_19 = 0.0027777777777777778837887*var_18; + const double var_20 = w[0][0] + w[0][1]; + const double var_21 = -0.1666666666666666574148081*var_20 + w[0][2]; + const double var_22 = 0.0416666666666666643537020*var_21*w[1][2]*w[2][2] + var_19; + const double var_23 = w[0][1] + w[0][2]; + const double var_24 = w[0][0] + -0.1666666666666666574148081*var_23; + const double var_25 = 0.0416666666666666643537020*var_24*w[1][0]*w[2][0]; + const double var_26 = w[0][3]*w[1][4] + w[0][4]*w[1][3]; + const double var_27 = 2.0000000000000000000000000*w[0][3]; + const double var_28 = w[0][5] + var_27; + const double var_29 = 0.0416666666666666643537020*w[0][0]; + const double var_30 = -0.0083333333333333332176851*w[0][2]; + const double var_31 = -1.0000000000000000000000000*w[0][4] + 0.1666666666666666574148081*w[0][1]; + const double var_32 = 0.1000000000000000055511151*var_31; + const double var_33 = -0.0666666666666666657414808*var_28 + var_30 + var_32 + var_29; + const double var_34 = -0.1333333333333333314829616*w[0][4] + 0.0416666666666666643537020*w[0][1]; + const double var_35 = 0.1666666666666666574148081*w[0][0] + -1.0000000000000000000000000*w[0][3]; + const double var_36 = 0.1000000000000000055511151*var_35; + const double var_37 = var_34 + -0.0666666666666666657414808*w[0][5] + var_30 + var_36; + const double var_38 = 0.6666666666666666296592325*w[0][0]; + const double var_39 = -0.5000000000000000000000000*w[0][1] + -1.0000000000000000000000000*var_38; + const double var_40 = w[0][0] + w[0][2]; + const double var_41 = w[0][1] + var_40; + const double var_42 = -0.2000000000000000111022302*w[0][5] + -0.0250000000000000013877788*var_20 + 0.2500000000000000000000000*w[0][2]; + const double var_43 = w[0][5]*w[1][3] + w[0][3]*w[1][5]; + const double var_44 = w[0][4]*w[1][4]; + const double var_45 = 0.8000000000000000444089210*var_44 + -0.1333333333333333314829616*w[0][1]*w[1][4] + 0.4000000000000000222044605*var_43; + const double var_46 = w[0][4]*w[1][5] + w[0][5]*w[1][4]; + const double var_47 = w[0][3]*w[1][3]; + const double var_48 = 0.8000000000000000444089210*var_47 + 0.4000000000000000222044605*var_46; + const double var_49 = w[0][5]*w[1][5]; + const double var_50 = var_48 + 0.4000000000000000222044605*var_49 + var_37*w[1][1] + 0.2000000000000000111022302*var_39*w[1][3] + 0.5333333333333333259318465*var_26 + -0.1000000000000000055511151*w[0][0]*w[1][4] + var_45 + 0.3333333333333333148296163*var_42*w[1][2] + -0.0666666666666666657414808*var_41*w[1][5] + var_33*w[1][0]; + const double var_51 = 2.0000000000000000000000000*w[0][5]; + const double var_52 = w[0][3] + var_51; + const double var_53 = 0.0416666666666666643537020*w[0][2]; + const double var_54 = -0.0083333333333333332176851*w[0][0]; + const double var_55 = var_32 + var_53 + -0.0666666666666666657414808*var_52 + var_54; + const double var_56 = -1.0000000000000000000000000*w[0][5] + 0.1666666666666666574148081*w[0][2]; + const double var_57 = 0.1000000000000000055511151*var_56; + const double var_58 = -0.0666666666666666657414808*w[0][3] + var_57 + var_34 + var_54; + const double var_59 = -0.2000000000000000111022302*w[0][3] + 0.2500000000000000000000000*w[0][0] + -0.0250000000000000013877788*var_23; + const double var_60 = var_51 + -0.3333333333333333148296163*w[0][2]; + const double var_61 = var_26 + var_60*w[1][5]; + const double var_62 = 0.4000000000000000222044605*var_61; + const double var_63 = w[0][1]*w[1][5] + w[0][2]*w[1][4]; + const double var_64 = var_55*w[1][2] + 0.5333333333333333259318465*var_46 + -0.0666666666666666657414808*var_41*w[1][3] + -0.1000000000000000055511151*var_63 + var_62 + 0.3333333333333333148296163*var_59*w[1][0] + var_58*w[1][1] + 0.4000000000000000222044605*var_47 + var_45; + const double var_65 = var_58*w[2][1] + var_55*w[2][2] + 0.3333333333333333148296163*var_59*w[2][0]; + const double var_66 = w[1][4]*w[2][1] + w[1][1]*w[2][4]; + const double var_67 = var_4*w[0][2] + w[0][4]*w[1][2]*w[2][2]; + const double var_68 = var_37*w[2][1] + 0.3333333333333333148296163*var_42*w[2][2] + var_33*w[2][0]; + const double var_69 = -0.1333333333333333314829616*w[0][1]*w[2][4]; + const double var_70 = var_68 + -0.1000000000000000055511151*w[0][0]*w[2][4] + var_69; + const double var_71 = w[1][1]*w[2][1]; + const double var_72 = 2.6666666666666665186369300*w[0][5] + -0.5000000000000000000000000*w[0][2]; + const double var_73 = 4.0000000000000000000000000*var_26 + var_72*w[1][5]; + const double var_74 = 16.0000000000000000000000000*w[0][4]*w[1][4] + 4.0000000000000000000000000*var_46 + 2.0000000000000000000000000*var_43 + 2.6666666666666665186369300*w[0][3]*w[1][3] + -0.6666666666666666296592325*w[0][1]*w[1][5] + var_73; + const double var_75 = w[0][3] + w[0][5]; + const double var_76 = var_3 + var_16; + const double var_77 = var_0 + var_4 + -0.5000000000000000000000000*var_76; + const double var_78 = var_76*w[0][4] + var_77*w[0][1] + var_40*var_66; + const double var_79 = var_4*w[0][5] + var_0*w[0][3]; + const double var_80 = var_17 + var_3; + const double var_81 = w[1][2]*w[2][2]; + const double var_82 = w[1][0]*w[2][0]; + const double var_83 = var_82 + var_71; + const double var_84 = var_81 + 0.5000000000000000000000000*var_83 + -0.1000000000000000055511151*var_80 + 0.2000000000000000111022302*var_16; + const double var_85 = var_17 + var_16; + const double var_86 = var_81 + var_71; + const double var_87 = var_82 + -0.1000000000000000055511151*var_85 + 0.2000000000000000111022302*var_3 + 0.5000000000000000000000000*var_86; + const double var_88 = var_17 + 0.2000000000000000111022302*w[1][1]*w[2][1]; + const double var_89 = var_40*var_88 + var_3*w[0][2] + var_16*w[0][0]; + const double var_90 = var_87*w[0][5] + var_84*w[0][3] + -0.2500000000000000000000000*var_89; + const double var_91 = 0.2000000000000000111022302*var_74*w[2][4] + -0.1333333333333333314829616*var_66*var_75 + 0.0083333333333333332176851*var_78 + var_50*w[2][3] + var_70*w[1][3] + var_65*w[1][5] + var_64*w[2][5] + 0.0833333333333333287074041*var_90 + -0.1000000000000000055511151*var_79 + 0.1666666666666666574148081*var_67 + 0.0500000000000000027755576*var_71*w[0][4]; + const double var_92 = var_0*w[0][2] + var_17*w[0][4] + var_4*w[0][0]; + const double var_93 = -1.0000000000000000000000000*w[0][1]*w[1][4]*w[2][4] + var_31*var_66 + -0.2500000000000000000000000*var_92; + const double var_94 = var_25 + var_22 + 0.3333333333333333148296163*var_91 + 0.1000000000000000055511151*var_93 + 0.0555555555555555524716027*var_1; + A[2] = 0.0095238095238095246686250*var_15*var_94; + const double var_95 = 0.0011904761904761905835781*w[1][0]*w[2][0] + 0.0317460317460317442694873*w[1][3]*w[2][3] + -0.0039682539682539680336859*var_6 + -0.0079365079365079360673718*var_3; + const double var_96 = w[1][1]*w[2][3] + w[1][3]*w[2][1]; + const double var_97 = var_96*w[0][1] + w[0][3]*w[1][1]*w[2][1]; + const double var_98 = w[0][1] + -0.1666666666666666574148081*var_40; + const double var_99 = 0.0416666666666666643537020*var_98*w[1][1]*w[2][1]; + const double var_100 = w[0][4] + var_27; + const double var_101 = -0.0083333333333333332176851*w[0][1]; + const double var_102 = var_57 + -0.0666666666666666657414808*var_100 + var_29 + var_101; + const double var_103 = w[0][4] + var_51; + const double var_104 = -0.0666666666666666657414808*var_103 + var_53 + var_36 + var_101; + const double var_105 = -0.2000000000000000111022302*w[0][4] + 0.2500000000000000000000000*w[0][1] + -0.0250000000000000013877788*var_40; + const double var_106 = var_38 + 0.5000000000000000000000000*w[0][2]; + const double var_107 = 0.3333333333333333148296163*var_105*w[1][1] + var_48 + -0.1000000000000000055511151*w[0][0]*w[1][5] + 0.4000000000000000222044605*var_44 + var_62 + -0.0666666666666666657414808*var_41*w[1][4] + 0.5333333333333333259318465*var_43 + -0.2000000000000000111022302*var_106*w[1][3] + var_104*w[1][2] + var_102*w[1][0]; + const double var_108 = var_104*w[2][2] + var_102*w[2][0] + 0.3333333333333333148296163*var_105*w[2][1]; + const double var_109 = var_2*w[0][2] + w[0][3]*w[1][2]*w[2][2]; + const double var_110 = var_7 + -0.1000000000000000055511151*var_96 + 0.0833333333333333287074041*var_84; + const double var_111 = 2.6666666666666665186369300*w[0][4] + var_39; + const double var_112 = -0.6666666666666666296592325*w[0][0]*w[1][5] + 2.0000000000000000000000000*var_46 + var_111*w[1][4] + 4.0000000000000000000000000*var_43 + 16.0000000000000000000000000*w[0][3]*w[1][3] + var_73; + const double var_113 = -0.1000000000000000055511151*var_2; + const double var_114 = var_81 + var_82; + const double var_115 = 0.2000000000000000111022302*var_17 + 0.5000000000000000000000000*var_114 + -0.1000000000000000055511151*var_76 + var_71; + const double var_116 = 0.0833333333333333287074041*var_115; + const double var_117 = var_116 + var_7 + var_113; + const double var_118 = var_17*w[0][2] + var_16*w[0][1] + var_23*var_3; + const double var_119 = var_96 + -0.5000000000000000000000000*var_85 + var_2; + const double var_120 = -0.5000000000000000000000000*w[1][0]*w[2][0] + var_6; + const double var_121 = var_85*w[0][3] + var_119*w[0][0] + var_120*var_23; + const double var_122 = var_108*w[1][5] + var_110*w[0][4] + var_68*w[1][4] + var_50*w[2][4] + -0.0208333333333333321768510*var_118 + 0.0500000000000000027755576*var_82*w[0][3] + var_107*w[2][5] + 0.0083333333333333332176851*var_121 + 0.2000000000000000111022302*var_112*w[2][3] + var_117*w[0][5] + 0.1666666666666666574148081*var_109; + const double var_123 = var_3*w[0][3] + var_2*w[0][1] + var_96*w[0][2]; + const double var_124 = -0.2500000000000000000000000*var_123 + var_35*var_6 + -1.0000000000000000000000000*w[0][0]*w[1][3]*w[2][3]; + const double var_125 = var_99 + var_22 + 0.1000000000000000055511151*var_124 + 0.0555555555555555524716027*var_97 + 0.3333333333333333148296163*var_122; + const double var_126 = -0.4000000000000000222044605*var_96 + 0.3333333333333333148296163*var_4 + -0.2666666666666666629659233*var_0; + const double var_127 = var_3*w[0][1] + var_17*w[0][0] + var_16*var_20; + const double var_128 = w[1][5]*w[2][1] + w[1][1]*w[2][5]; + const double var_129 = w[0][5]*w[1][1]*w[2][1] + var_128*w[0][1]; + const double var_130 = w[1][5]*w[2][0] + w[1][0]*w[2][5]; + const double var_131 = w[0][5]*w[1][0]*w[2][0] + var_130*w[0][0]; + const double var_132 = -0.1333333333333333314829616*w[0][2]*w[2][5]; + const double var_133 = var_132 + -0.1000000000000000055511151*w[0][0]*w[2][5] + var_108; + const double var_134 = var_132 + -0.1000000000000000055511151*w[0][1]*w[2][5] + var_65; + const double var_135 = w[1][2]*w[2][5] + w[1][5]*w[2][2]; + const double var_136 = -0.1333333333333333314829616*var_135; + const double var_137 = var_116 + var_136 + -0.1000000000000000055511151*var_130; + const double var_138 = var_136 + 0.0833333333333333287074041*var_87 + -0.1000000000000000055511151*var_128; + const double var_139 = -0.5000000000000000000000000*var_80 + var_130 + var_128; + const double var_140 = var_135 + -0.5000000000000000000000000*w[1][2]*w[2][2]; + const double var_141 = var_80*w[0][5] + var_140*var_20 + var_139*w[0][2]; + const double var_142 = var_44 + var_47; + const double var_143 = 4.0000000000000000000000000*w[0][5]*w[1][5] + var_43 + 0.6666666666666666296592325*var_142 + var_46; + const double var_144 = var_26 + 2.0000000000000000000000000*var_143; + const double var_145 = -0.0208333333333333321768510*var_127 + 0.0500000000000000027755576*var_81*w[0][5] + var_138*w[0][4] + var_107*w[2][3] + var_137*w[0][3] + var_133*w[1][3] + var_64*w[2][4] + 0.4000000000000000222044605*var_144*w[2][5] + 0.1666666666666666574148081*var_131 + 0.0083333333333333332176851*var_141 + var_134*w[1][4]; + const double var_146 = var_130*w[0][1] + var_128*w[0][0] + var_16*w[0][5]; + const double var_147 = var_135*var_56 + -1.0000000000000000000000000*w[0][2]*w[1][5]*w[2][5] + -0.2500000000000000000000000*var_146; + const double var_148 = var_25 + var_19 + var_99 + 0.1000000000000000055511151*var_147 + 0.0555555555555555524716027*var_129 + 0.3333333333333333148296163*var_145; + const double var_149 = var_67 + var_129; + const double var_150 = -0.0039682539682539680336859*var_66 + -0.0079365079365079360673718*var_17 + 0.0317460317460317442694873*w[1][4]*w[2][4] + 0.0011904761904761905835781*w[1][1]*w[2][1]; + const double var_151 = w[1][4]*w[2][3] + w[1][3]*w[2][4]; + const double var_152 = 0.0833333333333333287074041*var_81 + var_150 + 0.0158730158730158721347436*var_151 + 0.0011904761904761905835781*var_16 + var_95; + const double var_153 = 0.0011904761904761905835781*w[1][2]*w[2][2] + -0.0039682539682539680336859*var_135 + -0.0079365079365079360673718*var_16 + 0.0317460317460317442694873*w[1][5]*w[2][5]; + const double var_154 = w[1][4]*w[2][5] + w[1][5]*w[2][4]; + const double var_155 = 0.0011904761904761905835781*var_3 + 0.0833333333333333287074041*var_82 + var_150 + var_153 + 0.0158730158730158721347436*var_154; + const double var_156 = 0.4000000000000000222044605*w[1][4]*w[2][4]; + const double var_157 = var_110 + -0.1000000000000000055511151*var_0; + const double var_158 = var_3*w[0][5] + var_128*w[0][2]; + const double var_159 = var_5 + var_158; + const double var_160 = var_4*w[0][4]; + const double var_161 = w[2][5] + w[2][3]; + const double var_162 = var_135 + var_130; + const double var_163 = var_28*var_96 + var_128*var_52 + 4.0000000000000000000000000*var_161*var_43 + -0.8000000000000000444089210*var_162*w[0][3]; + const double var_164 = var_44 + 0.1333333333333333314829616*var_43; + A[1] = 0.0095238095238095246686250*var_148*var_15; + A[3] = A[1]; + const double var_165 = w[1][3]*w[2][5] + w[1][5]*w[2][3]; + const double var_166 = -0.4000000000000000222044605*w[1][5]*w[2][5]; + const double var_167 = -0.4000000000000000222044605*w[1][3]*w[2][3]; + const double var_168 = -0.2666666666666666629659233*var_165 + 0.0250000000000000013877788*var_76 + -0.1666666666666666574148081*var_71 + var_166 + -0.0166666666666666664353702*var_17 + var_167; + const double var_169 = var_47 + 0.1333333333333333314829616*var_46; + const double var_170 = var_6*w[0][0] + w[0][3]*w[1][0]*w[2][0]; + const double var_171 = -0.0190476190476190493372499*var_6*w[0][3] + -0.0079365079365079360673718*var_123 + 0.1904761904761904656169236*var_169*w[2][3] + 0.0035714285714285713170535*var_170; + const double var_172 = w[0][5]*w[1][2]*w[2][2] + var_135*w[0][2]; + const double var_173 = 0.1333333333333333314829616*var_26 + var_49; + const double var_174 = 0.0035714285714285713170535*var_172 + 0.1904761904761904656169236*var_173*w[2][5] + -0.0079365079365079360673718*var_146 + -0.0190476190476190493372499*var_135*w[0][5]; + const double var_175 = 0.1250000000000000000000000*var_135 + -0.0357142857142857123031732*w[1][2]*w[2][2]; + const double var_176 = -0.1428571428571428492126927*w[1][0]*w[2][0] + 0.5000000000000000000000000*var_6; + const double var_177 = 0.0158730158730158721347436*var_165 + 0.0833333333333333287074041*var_71 + var_153 + var_95 + 0.0011904761904761905835781*var_17; + const double var_178 = 0.3333333333333333148296163*var_47 + 0.2000000000000000111022302*var_46; + const double var_179 = w[0][3] + 0.6666666666666666296592325*w[0][5]; + const double var_180 = var_161*var_44 + -1.0000000000000000000000000*var_179*var_2 + -0.3333333333333333148296163*var_103*var_6 + -1.0000000000000000000000000*var_130*w[0][5]; + const double var_181 = var_96*w[0][0] + var_16*w[0][3]; + const double var_182 = var_181 + var_158; + const double var_183 = var_131 + var_109; + const double var_184 = 0.2000000000000000111022302*var_26 + 0.3333333333333333148296163*w[0][5]*w[1][5]; + const double var_185 = 4.0000000000000000000000000*var_184 + -0.2000000000000000111022302*var_106*w[1][4]; + const double var_186 = var_113 + var_137; + const double var_187 = var_168*var_40 + var_133*w[1][4] + 0.1250000000000000000000000*var_183 + 0.4000000000000000222044605*var_180 + -0.0833333333333333287074041*var_182 + var_185*w[2][3] + var_107*w[2][4] + var_186*w[0][4] + 0.3333333333333333148296163*var_163; + const double var_188 = var_17*w[0][3] + var_2*w[0][0]; + const double var_189 = var_17*w[0][5] + var_130*w[0][2]; + const double var_190 = var_189 + var_188; + const double var_191 = var_97 + var_129; + const double var_192 = 0.0027777777777777778837887*var_190 + var_171 + 0.0476190476190476164042309*var_187 + var_174 + 0.1904761904761904656169236*var_178*w[2][5] + var_177*w[0][1] + 0.0357142857142857123031732*var_191 + 0.0222222222222222230703093*var_175*w[0][0] + 0.0055555555555555557675773*var_176*w[0][2]; + const double var_193 = var_0*w[0][1] + var_16*w[0][4]; + const double var_194 = var_189 + var_193; + A[4] = 0.0666666666666666657414808*var_15*var_192; + const double var_195 = w[2][4] + w[2][5]; + const double var_196 = -1.0000000000000000000000000*var_156; + const double var_197 = -0.0166666666666666664353702*var_3 + var_196 + -0.1666666666666666574148081*var_82 + var_166 + -0.2666666666666666629659233*var_154 + 0.0250000000000000013877788*var_85; + const double var_198 = 0.3333333333333333148296163*var_0 + -0.2666666666666666629659233*var_4 + -0.4000000000000000222044605*var_128; + const double var_199 = -0.1000000000000000055511151*w[0][2]*w[2][4] + var_134 + var_69; + const double var_200 = var_138 + -0.1000000000000000055511151*var_4; + const double var_201 = var_0*w[0][4]; + const double var_202 = var_135 + var_128; + const double var_203 = -1.0000000000000000000000000*var_160 + var_195*var_47 + -0.3333333333333333148296163*var_52*var_66 + -0.6666666666666666296592325*var_202*w[0][4]; + const double var_204 = 0.6666666666666666296592325*var_201 + 0.4000000000000000222044605*var_203 + var_64*w[2][3] + 4.0000000000000000000000000*var_184*w[2][4] + var_198*w[0][5] + 1.3333333333333332593184650*var_195*var_46 + var_199*w[1][3] + -0.0833333333333333287074041*var_194 + 0.1250000000000000000000000*var_149 + var_197*var_23 + 0.3333333333333333148296163*var_103*var_130 + var_200*w[0][3]; + const double var_205 = w[0][4]*w[1][1]*w[2][1] + var_66*w[0][1]; + const double var_206 = 0.1904761904761904656169236*var_164*w[2][4] + -0.0190476190476190493372499*var_66*w[0][4] + 0.0035714285714285713170535*var_205 + -0.0079365079365079360673718*var_92; + const double var_207 = 0.3333333333333333148296163*var_44 + 0.2000000000000000111022302*var_43; + const double var_208 = var_131 + var_1; + const double var_209 = w[2][4] + w[2][3]; + const double var_210 = var_196 + 0.0250000000000000013877788*var_80 + -0.1666666666666666574148081*var_81 + -0.2666666666666666629659233*var_151 + -0.0166666666666666664353702*var_16 + var_167; + const double var_211 = var_96 + var_6; + const double var_212 = 0.2000000000000000111022302*var_39*w[2][3] + 0.4000000000000000222044605*var_209*w[0][5] + var_70; + const double var_213 = var_97 + var_1; + const double var_214 = var_5 + var_188; + const double var_215 = -0.4000000000000000222044605*var_201 + -0.0833333333333333287074041*var_214 + -0.1333333333333333314829616*var_28*var_66 + var_50*w[2][5] + 0.6666666666666666296592325*var_160 + 4.0000000000000000000000000*var_207*w[2][3] + 1.3333333333333332593184650*var_209*var_26 + var_20*var_210 + 0.1250000000000000000000000*var_213 + 0.3333333333333333148296163*var_100*var_2 + var_212*w[1][5] + var_126*w[0][3] + var_157*w[0][5] + -0.2666666666666666629659233*var_211*w[0][4]; + const double var_216 = var_67 + var_109; + const double var_217 = var_193 + var_181; + const double var_218 = 0.5000000000000000000000000*var_66 + -0.1428571428571428492126927*w[1][1]*w[2][1]; + const double var_219 = var_218*w[0][0] + var_176*w[0][1]; + const double var_220 = 0.0027777777777777778837887*var_217 + 0.1904761904761904656169236*var_178*w[2][4] + var_171 + var_206 + 0.0357142857142857123031732*var_216 + var_152*w[0][2] + 0.0476190476190476164042309*var_215 + 0.0055555555555555557675773*var_219; + A[8] = 0.0666666666666666657414808*var_15*var_220; + A[6] = A[2]; + const double var_221 = var_155*w[0][0] + 0.0027777777777777778837887*var_159 + 0.0055555555555555557675773*var_218*w[0][2] + 0.0357142857142857123031732*var_208 + 0.0222222222222222230703093*var_175*w[0][1] + var_206 + var_174 + 0.0476190476190476164042309*var_204 + 0.1904761904761904656169236*var_207*w[2][5]; + A[0] = 0.0666666666666666657414808*var_15*var_221; + A[5] = 0.0095238095238095246686250*var_125*var_15; + A[7] = A[5]; + } + + 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/mass_matrix_2d/mass_matrix_f3_p2_q1_quadrature.h b/mass_matrix_2d/mass_matrix_f3_p2_q1_quadrature.h new file mode 100644 index 0000000..91ed180 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f3_p2_q1_quadrature.h @@ -0,0 +1,3417 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F3_P2_Q1_QUADRATURE_H +#define __MASS_MATRIX_F3_P2_Q1_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p2_q1_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p2_q1_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f3_p2_q1_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p2_q1_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p2_q1_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p2_q1_quadrature_finite_element_1() + { + // 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 mass_matrix_f3_p2_q1_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p2_q1_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p2_q1_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_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 mass_matrix_f3_p2_q1_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p2_q1_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p2_q1_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_p2_q1_quadrature_dofmap_1() + { + // 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 mass_matrix_f3_p2_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 mass_matrix_f3_p2_q1_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f3_p2_q1_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // 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[25][3] = \ + {{0.915147549378728, 0.0450425935698037, 0.0398098570514687}, + {0.764365329781281, 0.0376212523451112, 0.198013417873608}, + {0.535660544808143, 0.026364644944471, 0.437974810247386}, + {0.290249932250793, 0.0142857943955714, 0.695464273353636}, + {0.09391279733378, 0.00462228846504648, 0.901464914201173}, + {0.738611533396152, 0.221578609552379, 0.0398098570514687}, + {0.616915871859002, 0.185070710267389, 0.198013417873608}, + {0.43232925297036, 0.129695936782254, 0.437974810247386}, + {0.234259434638082, 0.0702762920082818, 0.695464273353636}, + {0.0757966027350624, 0.0227384830637641, 0.901464914201173}, + {0.480095071474266, 0.480095071474266, 0.0398098570514687}, + {0.400993291063196, 0.400993291063196, 0.198013417873608}, + {0.281012594876307, 0.281012594876307, 0.437974810247386}, + {0.152267863323182, 0.152267863323182, 0.695464273353636}, + {0.0492675428994132, 0.0492675428994133, 0.901464914201173}, + {0.221578609552379, 0.738611533396152, 0.0398098570514687}, + {0.185070710267389, 0.616915871859002, 0.198013417873608}, + {0.129695936782254, 0.43232925297036, 0.437974810247386}, + {0.0702762920082818, 0.234259434638082, 0.695464273353636}, + {0.022738483063764, 0.0757966027350624, 0.901464914201173}, + {0.0450425935698037, 0.915147549378728, 0.0398098570514687}, + {0.0376212523451112, 0.764365329781281, 0.198013417873608}, + {0.0263646449444709, 0.535660544808143, 0.437974810247386}, + {0.0142857943955715, 0.290249932250793, 0.695464273353636}, + {0.00462228846504642, 0.0939127973337801, 0.901464914201173}}; + + static const double FE1[25][6] = \ + {{0.759842524889053, -0.0409849230988147, -0.036640207614552, 0.00717255684496526, 0.145727572487076, 0.164882476492272}, + {0.404143384962011, -0.0347905350890822, -0.119594790557632, 0.0297980510461641, 0.605418365816316, 0.115025523822223}, + {0.03820389372017, -0.0249744559383749, -0.0543309414249184, 0.0461882014671776, 0.938423301877432, 0.0564900002985143}, + {-0.121759885907613, -0.0138776265525463, 0.271876837668966, 0.0397410384743821, 0.807433832894958, 0.0165858034218534}, + {-0.0762735703276687, -0.00457955736373819, 0.723813068870285, 0.0166673234982246, 0.338636367163553, 0.00173636815934475}, + {0.352482461135478, -0.123384449130048, -0.036640207614552, 0.0352840510877738, 0.117616078244268, 0.65464206627708}, + {0.144254514044104, -0.116568374669637, -0.119594790557632, 0.146585935553368, 0.488630481309112, 0.456692234320686}, + {-0.0585120870225412, -0.0960538647466012, -0.0543309414249184, 0.227214213208259, 0.75739729013635, 0.224285389849452}, + {-0.124504469204174, -0.0603987775714151, 0.271876837668966, 0.19549860142211, 0.65167626994723, 0.0658515377372835}, + {-0.0643063527627087, -0.0217044058396818, 0.723813068870285, 0.0819917787365635, 0.273311911925214, 0.00689399907032831}, + {-0.0191125161665053, -0.0191125161665052, -0.036640207614552, 0.0764500646660208, 0.0764500646660208, 0.921965110615521}, + {-0.0794020521078101, -0.07940205210781, -0.119594790557632, 0.31760820843124, 0.31760820843124, 0.643182477910772}, + {-0.123076437918076, -0.123076437918076, -0.0543309414249183, 0.492305751672305, 0.492305751672305, 0.315872313916462}, + {-0.105896858921168, -0.105896858921168, 0.271876837668966, 0.42358743568467, 0.42358743568467, 0.092742008804029}, + {-0.0444129613327222, -0.0444129613327222, 0.723813068870285, 0.177651845330889, 0.177651845330889, 0.00970916313338213}, + {-0.123384449130048, 0.352482461135478, -0.036640207614552, 0.117616078244268, 0.0352840510877737, 0.65464206627708}, + {-0.116568374669637, 0.144254514044104, -0.119594790557632, 0.488630481309112, 0.146585935553368, 0.456692234320686}, + {-0.0960538647466012, -0.0585120870225412, -0.0543309414249183, 0.75739729013635, 0.227214213208259, 0.224285389849452}, + {-0.0603987775714152, -0.124504469204174, 0.271876837668966, 0.65167626994723, 0.195498601422111, 0.0658515377372835}, + {-0.0217044058396819, -0.0643063527627086, 0.723813068870285, 0.273311911925214, 0.0819917787365634, 0.00689399907032831}, + {-0.0409849230988147, 0.759842524889054, -0.036640207614552, 0.145727572487076, 0.00717255684496518, 0.164882476492272}, + {-0.0347905350890822, 0.404143384962011, -0.119594790557632, 0.605418365816316, 0.0297980510461639, 0.115025523822223}, + {-0.024974455938375, 0.03820389372017, -0.0543309414249183, 0.938423301877431, 0.0461882014671776, 0.0564900002985144}, + {-0.0138776265525464, -0.121759885907613, 0.271876837668966, 0.807433832894958, 0.0397410384743823, 0.0165858034218536}, + {-0.00457955736373822, -0.0762735703276687, 0.723813068870285, 0.338636367163553, 0.0166673234982245, 0.00173636815934475}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 9; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 1675 + for (unsigned int ip = 0; ip < 25; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + + // Total number of operations to compute function values = 36 + for (unsigned int r = 0; r < 6; r++) + { + F0 += FE1[ip][r]*w[2][r]; + F1 += FE1[ip][r]*w[0][r]; + F2 += FE1[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 4 + double I[1]; + // Number of operations: 4 + I[0] = F0*F1*F2*W25[ip]*det; + + + // Number of operations for primary indices: 27 + for (unsigned int j = 0; j < 3; j++) + { + for (unsigned int k = 0; k < 3; k++) + { + // Number of operations to compute entry: 3 + A[j*3 + k] += FE0[ip][j]*FE0[ip][k]*I[0]; + }// 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 mass_matrix_f3_p2_q1_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f3_p2_q1_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p2_q1_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1)))), 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 3; + } + + /// 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 mass_matrix_f3_p2_q1_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f3_p2_q1_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f3_p2_q1_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p2_q1_quadrature_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p2_q1_quadrature_finite_element_0(); + 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 mass_matrix_f3_p2_q1_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f3_p2_q1_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f3_p2_q1_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p2_q1_quadrature_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p2_q1_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f3_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/mass_matrix_2d/mass_matrix_f3_p2_q1_tensor.h b/mass_matrix_2d/mass_matrix_f3_p2_q1_tensor.h new file mode 100644 index 0000000..6c13ccb --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f3_p2_q1_tensor.h @@ -0,0 +1,3543 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F3_P2_Q1_TENSOR_H +#define __MASS_MATRIX_F3_P2_Q1_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p2_q1_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p2_q1_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f3_p2_q1_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p2_q1_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p2_q1_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p2_q1_tensor_finite_element_1() + { + // 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 mass_matrix_f3_p2_q1_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p2_q1_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p2_q1_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_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 mass_matrix_f3_p2_q1_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p2_q1_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p2_q1_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_p2_q1_tensor_dofmap_1() + { + // 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 mass_matrix_f3_p2_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 mass_matrix_f3_p2_q1_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f3_p2_q1_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 432 + // Number of operations (multiply-add pairs) for tensor contraction: 1096 + // Total number of operations (multiply-add pairs): 1537 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0 = det*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_0_0_1 = det*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_0_0_2 = det*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_0_0_3 = det*w[2][0]*w[0][0]*w[1][3]*(1.0); + const double G0_0_0_4 = det*w[2][0]*w[0][0]*w[1][4]*(1.0); + const double G0_0_0_5 = det*w[2][0]*w[0][0]*w[1][5]*(1.0); + const double G0_0_1_0 = det*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_0_1_1 = det*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_0_1_2 = det*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_0_1_3 = det*w[2][0]*w[0][1]*w[1][3]*(1.0); + const double G0_0_1_4 = det*w[2][0]*w[0][1]*w[1][4]*(1.0); + const double G0_0_1_5 = det*w[2][0]*w[0][1]*w[1][5]*(1.0); + const double G0_0_2_0 = det*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_0_2_1 = det*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_0_2_2 = det*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_0_2_3 = det*w[2][0]*w[0][2]*w[1][3]*(1.0); + const double G0_0_2_4 = det*w[2][0]*w[0][2]*w[1][4]*(1.0); + const double G0_0_2_5 = det*w[2][0]*w[0][2]*w[1][5]*(1.0); + const double G0_0_3_0 = det*w[2][0]*w[0][3]*w[1][0]*(1.0); + const double G0_0_3_1 = det*w[2][0]*w[0][3]*w[1][1]*(1.0); + const double G0_0_3_2 = det*w[2][0]*w[0][3]*w[1][2]*(1.0); + const double G0_0_3_3 = det*w[2][0]*w[0][3]*w[1][3]*(1.0); + const double G0_0_3_4 = det*w[2][0]*w[0][3]*w[1][4]*(1.0); + const double G0_0_3_5 = det*w[2][0]*w[0][3]*w[1][5]*(1.0); + const double G0_0_4_0 = det*w[2][0]*w[0][4]*w[1][0]*(1.0); + const double G0_0_4_1 = det*w[2][0]*w[0][4]*w[1][1]*(1.0); + const double G0_0_4_2 = det*w[2][0]*w[0][4]*w[1][2]*(1.0); + const double G0_0_4_3 = det*w[2][0]*w[0][4]*w[1][3]*(1.0); + const double G0_0_4_4 = det*w[2][0]*w[0][4]*w[1][4]*(1.0); + const double G0_0_4_5 = det*w[2][0]*w[0][4]*w[1][5]*(1.0); + const double G0_0_5_0 = det*w[2][0]*w[0][5]*w[1][0]*(1.0); + const double G0_0_5_1 = det*w[2][0]*w[0][5]*w[1][1]*(1.0); + const double G0_0_5_2 = det*w[2][0]*w[0][5]*w[1][2]*(1.0); + const double G0_0_5_3 = det*w[2][0]*w[0][5]*w[1][3]*(1.0); + const double G0_0_5_4 = det*w[2][0]*w[0][5]*w[1][4]*(1.0); + const double G0_0_5_5 = det*w[2][0]*w[0][5]*w[1][5]*(1.0); + const double G0_1_0_0 = det*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_1_0_1 = det*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_1_0_2 = det*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_1_0_3 = det*w[2][1]*w[0][0]*w[1][3]*(1.0); + const double G0_1_0_4 = det*w[2][1]*w[0][0]*w[1][4]*(1.0); + const double G0_1_0_5 = det*w[2][1]*w[0][0]*w[1][5]*(1.0); + const double G0_1_1_0 = det*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_1_1_1 = det*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_1_1_2 = det*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_1_1_3 = det*w[2][1]*w[0][1]*w[1][3]*(1.0); + const double G0_1_1_4 = det*w[2][1]*w[0][1]*w[1][4]*(1.0); + const double G0_1_1_5 = det*w[2][1]*w[0][1]*w[1][5]*(1.0); + const double G0_1_2_0 = det*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_1_2_1 = det*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_1_2_2 = det*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_1_2_3 = det*w[2][1]*w[0][2]*w[1][3]*(1.0); + const double G0_1_2_4 = det*w[2][1]*w[0][2]*w[1][4]*(1.0); + const double G0_1_2_5 = det*w[2][1]*w[0][2]*w[1][5]*(1.0); + const double G0_1_3_0 = det*w[2][1]*w[0][3]*w[1][0]*(1.0); + const double G0_1_3_1 = det*w[2][1]*w[0][3]*w[1][1]*(1.0); + const double G0_1_3_2 = det*w[2][1]*w[0][3]*w[1][2]*(1.0); + const double G0_1_3_3 = det*w[2][1]*w[0][3]*w[1][3]*(1.0); + const double G0_1_3_4 = det*w[2][1]*w[0][3]*w[1][4]*(1.0); + const double G0_1_3_5 = det*w[2][1]*w[0][3]*w[1][5]*(1.0); + const double G0_1_4_0 = det*w[2][1]*w[0][4]*w[1][0]*(1.0); + const double G0_1_4_1 = det*w[2][1]*w[0][4]*w[1][1]*(1.0); + const double G0_1_4_2 = det*w[2][1]*w[0][4]*w[1][2]*(1.0); + const double G0_1_4_3 = det*w[2][1]*w[0][4]*w[1][3]*(1.0); + const double G0_1_4_4 = det*w[2][1]*w[0][4]*w[1][4]*(1.0); + const double G0_1_4_5 = det*w[2][1]*w[0][4]*w[1][5]*(1.0); + const double G0_1_5_0 = det*w[2][1]*w[0][5]*w[1][0]*(1.0); + const double G0_1_5_1 = det*w[2][1]*w[0][5]*w[1][1]*(1.0); + const double G0_1_5_2 = det*w[2][1]*w[0][5]*w[1][2]*(1.0); + const double G0_1_5_3 = det*w[2][1]*w[0][5]*w[1][3]*(1.0); + const double G0_1_5_4 = det*w[2][1]*w[0][5]*w[1][4]*(1.0); + const double G0_1_5_5 = det*w[2][1]*w[0][5]*w[1][5]*(1.0); + const double G0_2_0_0 = det*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_2_0_1 = det*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_2_0_2 = det*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_2_0_3 = det*w[2][2]*w[0][0]*w[1][3]*(1.0); + const double G0_2_0_4 = det*w[2][2]*w[0][0]*w[1][4]*(1.0); + const double G0_2_0_5 = det*w[2][2]*w[0][0]*w[1][5]*(1.0); + const double G0_2_1_0 = det*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_2_1_1 = det*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_2_1_2 = det*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_2_1_3 = det*w[2][2]*w[0][1]*w[1][3]*(1.0); + const double G0_2_1_4 = det*w[2][2]*w[0][1]*w[1][4]*(1.0); + const double G0_2_1_5 = det*w[2][2]*w[0][1]*w[1][5]*(1.0); + const double G0_2_2_0 = det*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_2_2_1 = det*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_2_2_2 = det*w[2][2]*w[0][2]*w[1][2]*(1.0); + const double G0_2_2_3 = det*w[2][2]*w[0][2]*w[1][3]*(1.0); + const double G0_2_2_4 = det*w[2][2]*w[0][2]*w[1][4]*(1.0); + const double G0_2_2_5 = det*w[2][2]*w[0][2]*w[1][5]*(1.0); + const double G0_2_3_0 = det*w[2][2]*w[0][3]*w[1][0]*(1.0); + const double G0_2_3_1 = det*w[2][2]*w[0][3]*w[1][1]*(1.0); + const double G0_2_3_2 = det*w[2][2]*w[0][3]*w[1][2]*(1.0); + const double G0_2_3_3 = det*w[2][2]*w[0][3]*w[1][3]*(1.0); + const double G0_2_3_4 = det*w[2][2]*w[0][3]*w[1][4]*(1.0); + const double G0_2_3_5 = det*w[2][2]*w[0][3]*w[1][5]*(1.0); + const double G0_2_4_0 = det*w[2][2]*w[0][4]*w[1][0]*(1.0); + const double G0_2_4_1 = det*w[2][2]*w[0][4]*w[1][1]*(1.0); + const double G0_2_4_2 = det*w[2][2]*w[0][4]*w[1][2]*(1.0); + const double G0_2_4_3 = det*w[2][2]*w[0][4]*w[1][3]*(1.0); + const double G0_2_4_4 = det*w[2][2]*w[0][4]*w[1][4]*(1.0); + const double G0_2_4_5 = det*w[2][2]*w[0][4]*w[1][5]*(1.0); + const double G0_2_5_0 = det*w[2][2]*w[0][5]*w[1][0]*(1.0); + const double G0_2_5_1 = det*w[2][2]*w[0][5]*w[1][1]*(1.0); + const double G0_2_5_2 = det*w[2][2]*w[0][5]*w[1][2]*(1.0); + const double G0_2_5_3 = det*w[2][2]*w[0][5]*w[1][3]*(1.0); + const double G0_2_5_4 = det*w[2][2]*w[0][5]*w[1][4]*(1.0); + const double G0_2_5_5 = det*w[2][2]*w[0][5]*w[1][5]*(1.0); + const double G0_3_0_0 = det*w[2][3]*w[0][0]*w[1][0]*(1.0); + const double G0_3_0_1 = det*w[2][3]*w[0][0]*w[1][1]*(1.0); + const double G0_3_0_2 = det*w[2][3]*w[0][0]*w[1][2]*(1.0); + const double G0_3_0_3 = det*w[2][3]*w[0][0]*w[1][3]*(1.0); + const double G0_3_0_4 = det*w[2][3]*w[0][0]*w[1][4]*(1.0); + const double G0_3_0_5 = det*w[2][3]*w[0][0]*w[1][5]*(1.0); + const double G0_3_1_0 = det*w[2][3]*w[0][1]*w[1][0]*(1.0); + const double G0_3_1_1 = det*w[2][3]*w[0][1]*w[1][1]*(1.0); + const double G0_3_1_2 = det*w[2][3]*w[0][1]*w[1][2]*(1.0); + const double G0_3_1_3 = det*w[2][3]*w[0][1]*w[1][3]*(1.0); + const double G0_3_1_4 = det*w[2][3]*w[0][1]*w[1][4]*(1.0); + const double G0_3_1_5 = det*w[2][3]*w[0][1]*w[1][5]*(1.0); + const double G0_3_2_0 = det*w[2][3]*w[0][2]*w[1][0]*(1.0); + const double G0_3_2_1 = det*w[2][3]*w[0][2]*w[1][1]*(1.0); + const double G0_3_2_2 = det*w[2][3]*w[0][2]*w[1][2]*(1.0); + const double G0_3_2_3 = det*w[2][3]*w[0][2]*w[1][3]*(1.0); + const double G0_3_2_4 = det*w[2][3]*w[0][2]*w[1][4]*(1.0); + const double G0_3_2_5 = det*w[2][3]*w[0][2]*w[1][5]*(1.0); + const double G0_3_3_0 = det*w[2][3]*w[0][3]*w[1][0]*(1.0); + const double G0_3_3_1 = det*w[2][3]*w[0][3]*w[1][1]*(1.0); + const double G0_3_3_2 = det*w[2][3]*w[0][3]*w[1][2]*(1.0); + const double G0_3_3_3 = det*w[2][3]*w[0][3]*w[1][3]*(1.0); + const double G0_3_3_4 = det*w[2][3]*w[0][3]*w[1][4]*(1.0); + const double G0_3_3_5 = det*w[2][3]*w[0][3]*w[1][5]*(1.0); + const double G0_3_4_0 = det*w[2][3]*w[0][4]*w[1][0]*(1.0); + const double G0_3_4_1 = det*w[2][3]*w[0][4]*w[1][1]*(1.0); + const double G0_3_4_2 = det*w[2][3]*w[0][4]*w[1][2]*(1.0); + const double G0_3_4_3 = det*w[2][3]*w[0][4]*w[1][3]*(1.0); + const double G0_3_4_4 = det*w[2][3]*w[0][4]*w[1][4]*(1.0); + const double G0_3_4_5 = det*w[2][3]*w[0][4]*w[1][5]*(1.0); + const double G0_3_5_0 = det*w[2][3]*w[0][5]*w[1][0]*(1.0); + const double G0_3_5_1 = det*w[2][3]*w[0][5]*w[1][1]*(1.0); + const double G0_3_5_2 = det*w[2][3]*w[0][5]*w[1][2]*(1.0); + const double G0_3_5_3 = det*w[2][3]*w[0][5]*w[1][3]*(1.0); + const double G0_3_5_4 = det*w[2][3]*w[0][5]*w[1][4]*(1.0); + const double G0_3_5_5 = det*w[2][3]*w[0][5]*w[1][5]*(1.0); + const double G0_4_0_0 = det*w[2][4]*w[0][0]*w[1][0]*(1.0); + const double G0_4_0_1 = det*w[2][4]*w[0][0]*w[1][1]*(1.0); + const double G0_4_0_2 = det*w[2][4]*w[0][0]*w[1][2]*(1.0); + const double G0_4_0_3 = det*w[2][4]*w[0][0]*w[1][3]*(1.0); + const double G0_4_0_4 = det*w[2][4]*w[0][0]*w[1][4]*(1.0); + const double G0_4_0_5 = det*w[2][4]*w[0][0]*w[1][5]*(1.0); + const double G0_4_1_0 = det*w[2][4]*w[0][1]*w[1][0]*(1.0); + const double G0_4_1_1 = det*w[2][4]*w[0][1]*w[1][1]*(1.0); + const double G0_4_1_2 = det*w[2][4]*w[0][1]*w[1][2]*(1.0); + const double G0_4_1_3 = det*w[2][4]*w[0][1]*w[1][3]*(1.0); + const double G0_4_1_4 = det*w[2][4]*w[0][1]*w[1][4]*(1.0); + const double G0_4_1_5 = det*w[2][4]*w[0][1]*w[1][5]*(1.0); + const double G0_4_2_0 = det*w[2][4]*w[0][2]*w[1][0]*(1.0); + const double G0_4_2_1 = det*w[2][4]*w[0][2]*w[1][1]*(1.0); + const double G0_4_2_2 = det*w[2][4]*w[0][2]*w[1][2]*(1.0); + const double G0_4_2_3 = det*w[2][4]*w[0][2]*w[1][3]*(1.0); + const double G0_4_2_4 = det*w[2][4]*w[0][2]*w[1][4]*(1.0); + const double G0_4_2_5 = det*w[2][4]*w[0][2]*w[1][5]*(1.0); + const double G0_4_3_0 = det*w[2][4]*w[0][3]*w[1][0]*(1.0); + const double G0_4_3_1 = det*w[2][4]*w[0][3]*w[1][1]*(1.0); + const double G0_4_3_2 = det*w[2][4]*w[0][3]*w[1][2]*(1.0); + const double G0_4_3_3 = det*w[2][4]*w[0][3]*w[1][3]*(1.0); + const double G0_4_3_4 = det*w[2][4]*w[0][3]*w[1][4]*(1.0); + const double G0_4_3_5 = det*w[2][4]*w[0][3]*w[1][5]*(1.0); + const double G0_4_4_0 = det*w[2][4]*w[0][4]*w[1][0]*(1.0); + const double G0_4_4_1 = det*w[2][4]*w[0][4]*w[1][1]*(1.0); + const double G0_4_4_2 = det*w[2][4]*w[0][4]*w[1][2]*(1.0); + const double G0_4_4_3 = det*w[2][4]*w[0][4]*w[1][3]*(1.0); + const double G0_4_4_4 = det*w[2][4]*w[0][4]*w[1][4]*(1.0); + const double G0_4_4_5 = det*w[2][4]*w[0][4]*w[1][5]*(1.0); + const double G0_4_5_0 = det*w[2][4]*w[0][5]*w[1][0]*(1.0); + const double G0_4_5_1 = det*w[2][4]*w[0][5]*w[1][1]*(1.0); + const double G0_4_5_2 = det*w[2][4]*w[0][5]*w[1][2]*(1.0); + const double G0_4_5_3 = det*w[2][4]*w[0][5]*w[1][3]*(1.0); + const double G0_4_5_4 = det*w[2][4]*w[0][5]*w[1][4]*(1.0); + const double G0_4_5_5 = det*w[2][4]*w[0][5]*w[1][5]*(1.0); + const double G0_5_0_0 = det*w[2][5]*w[0][0]*w[1][0]*(1.0); + const double G0_5_0_1 = det*w[2][5]*w[0][0]*w[1][1]*(1.0); + const double G0_5_0_2 = det*w[2][5]*w[0][0]*w[1][2]*(1.0); + const double G0_5_0_3 = det*w[2][5]*w[0][0]*w[1][3]*(1.0); + const double G0_5_0_4 = det*w[2][5]*w[0][0]*w[1][4]*(1.0); + const double G0_5_0_5 = det*w[2][5]*w[0][0]*w[1][5]*(1.0); + const double G0_5_1_0 = det*w[2][5]*w[0][1]*w[1][0]*(1.0); + const double G0_5_1_1 = det*w[2][5]*w[0][1]*w[1][1]*(1.0); + const double G0_5_1_2 = det*w[2][5]*w[0][1]*w[1][2]*(1.0); + const double G0_5_1_3 = det*w[2][5]*w[0][1]*w[1][3]*(1.0); + const double G0_5_1_4 = det*w[2][5]*w[0][1]*w[1][4]*(1.0); + const double G0_5_1_5 = det*w[2][5]*w[0][1]*w[1][5]*(1.0); + const double G0_5_2_0 = det*w[2][5]*w[0][2]*w[1][0]*(1.0); + const double G0_5_2_1 = det*w[2][5]*w[0][2]*w[1][1]*(1.0); + const double G0_5_2_2 = det*w[2][5]*w[0][2]*w[1][2]*(1.0); + const double G0_5_2_3 = det*w[2][5]*w[0][2]*w[1][3]*(1.0); + const double G0_5_2_4 = det*w[2][5]*w[0][2]*w[1][4]*(1.0); + const double G0_5_2_5 = det*w[2][5]*w[0][2]*w[1][5]*(1.0); + const double G0_5_3_0 = det*w[2][5]*w[0][3]*w[1][0]*(1.0); + const double G0_5_3_1 = det*w[2][5]*w[0][3]*w[1][1]*(1.0); + const double G0_5_3_2 = det*w[2][5]*w[0][3]*w[1][2]*(1.0); + const double G0_5_3_3 = det*w[2][5]*w[0][3]*w[1][3]*(1.0); + const double G0_5_3_4 = det*w[2][5]*w[0][3]*w[1][4]*(1.0); + const double G0_5_3_5 = det*w[2][5]*w[0][3]*w[1][5]*(1.0); + const double G0_5_4_0 = det*w[2][5]*w[0][4]*w[1][0]*(1.0); + const double G0_5_4_1 = det*w[2][5]*w[0][4]*w[1][1]*(1.0); + const double G0_5_4_2 = det*w[2][5]*w[0][4]*w[1][2]*(1.0); + const double G0_5_4_3 = det*w[2][5]*w[0][4]*w[1][3]*(1.0); + const double G0_5_4_4 = det*w[2][5]*w[0][4]*w[1][4]*(1.0); + const double G0_5_4_5 = det*w[2][5]*w[0][4]*w[1][5]*(1.0); + const double G0_5_5_0 = det*w[2][5]*w[0][5]*w[1][0]*(1.0); + const double G0_5_5_1 = det*w[2][5]*w[0][5]*w[1][1]*(1.0); + const double G0_5_5_2 = det*w[2][5]*w[0][5]*w[1][2]*(1.0); + const double G0_5_5_3 = det*w[2][5]*w[0][5]*w[1][3]*(1.0); + const double G0_5_5_4 = det*w[2][5]*w[0][5]*w[1][4]*(1.0); + const double G0_5_5_5 = det*w[2][5]*w[0][5]*w[1][5]*(1.0); + + // Compute element tensor + A[1] = 0.000396825396825395*G0_0_0_0 - 6.61375661375658e-05*G0_0_0_1 - 6.61375661375659e-05*G0_0_0_2 + 0.000132275132275132*G0_0_0_3 + 0.000264550264550263*G0_0_0_4 + 0.000529100529100526*G0_0_0_5 - 6.61375661375658e-05*G0_0_1_0 - 6.61375661375658e-05*G0_0_1_1 + 2.64550264550264e-05*G0_0_1_2 - 2.64550264550263e-05*G0_0_1_3 - 2.64550264550263e-05*G0_0_1_4 - 0.000238095238095237*G0_0_1_5 - 6.61375661375659e-05*G0_0_2_0 + 2.64550264550263e-05*G0_0_2_1 - 1.32275132275132e-05*G0_0_2_2 + 5.29100529100527e-05*G0_0_2_3 - 2.64550264550263e-05*G0_0_2_4 + 2.64550264550265e-05*G0_0_2_5 + 0.000132275132275132*G0_0_3_0 - 2.64550264550263e-05*G0_0_3_1 + 5.29100529100527e-05*G0_0_3_2 - 0.000423280423280422*G0_0_3_3 - 0.000211640211640211*G0_0_3_4 - 0.000317460317460316*G0_0_3_5 + 0.000264550264550263*G0_0_4_0 - 2.64550264550263e-05*G0_0_4_1 - 2.64550264550263e-05*G0_0_4_2 - 0.000211640211640211*G0_0_4_3 + 0.000529100529100526*G0_0_5_0 - 0.000238095238095237*G0_0_5_1 + 2.64550264550265e-05*G0_0_5_2 - 0.000317460317460316*G0_0_5_3 - 6.61375661375658e-05*G0_1_0_0 - 6.61375661375658e-05*G0_1_0_1 + 2.64550264550264e-05*G0_1_0_2 - 2.64550264550263e-05*G0_1_0_3 - 2.64550264550263e-05*G0_1_0_4 - 0.000238095238095237*G0_1_0_5 - 6.61375661375658e-05*G0_1_1_0 + 0.000396825396825394*G0_1_1_1 - 6.61375661375658e-05*G0_1_1_2 + 0.000264550264550263*G0_1_1_3 + 0.000132275132275132*G0_1_1_4 + 0.000529100529100526*G0_1_1_5 + 2.64550264550264e-05*G0_1_2_0 - 6.61375661375658e-05*G0_1_2_1 - 1.32275132275132e-05*G0_1_2_2 - 2.64550264550263e-05*G0_1_2_3 + 5.29100529100528e-05*G0_1_2_4 + 2.64550264550265e-05*G0_1_2_5 - 2.64550264550263e-05*G0_1_3_0 + 0.000264550264550263*G0_1_3_1 - 2.64550264550263e-05*G0_1_3_2 - 0.000211640211640211*G0_1_3_4 - 2.64550264550263e-05*G0_1_4_0 + 0.000132275132275132*G0_1_4_1 + 5.29100529100528e-05*G0_1_4_2 - 0.000211640211640211*G0_1_4_3 - 0.000423280423280422*G0_1_4_4 - 0.000317460317460316*G0_1_4_5 - 0.000238095238095237*G0_1_5_0 + 0.000529100529100526*G0_1_5_1 + 2.64550264550264e-05*G0_1_5_2 - 0.000317460317460316*G0_1_5_4 - 6.61375661375659e-05*G0_2_0_0 + 2.64550264550263e-05*G0_2_0_1 - 1.32275132275132e-05*G0_2_0_2 + 5.29100529100527e-05*G0_2_0_3 - 2.64550264550263e-05*G0_2_0_4 + 2.64550264550265e-05*G0_2_0_5 + 2.64550264550264e-05*G0_2_1_0 - 6.61375661375658e-05*G0_2_1_1 - 1.32275132275132e-05*G0_2_1_2 - 2.64550264550263e-05*G0_2_1_3 + 5.29100529100528e-05*G0_2_1_4 + 2.64550264550265e-05*G0_2_1_5 - 1.32275132275132e-05*G0_2_2_0 - 1.32275132275132e-05*G0_2_2_1 + 0.000132275132275132*G0_2_2_3 + 0.000132275132275132*G0_2_2_4 + 0.000158730158730158*G0_2_2_5 + 5.29100529100527e-05*G0_2_3_0 - 2.64550264550263e-05*G0_2_3_1 + 0.000132275132275132*G0_2_3_2 - 0.000317460317460316*G0_2_3_3 - 0.000211640211640211*G0_2_3_4 - 0.000423280423280422*G0_2_3_5 - 2.64550264550263e-05*G0_2_4_0 + 5.29100529100528e-05*G0_2_4_1 + 0.000132275132275132*G0_2_4_2 - 0.000211640211640211*G0_2_4_3 - 0.000317460317460317*G0_2_4_4 - 0.000423280423280422*G0_2_4_5 + 2.64550264550265e-05*G0_2_5_0 + 2.64550264550265e-05*G0_2_5_1 + 0.000158730158730158*G0_2_5_2 - 0.000423280423280422*G0_2_5_3 - 0.000423280423280422*G0_2_5_4 - 0.000952380952380949*G0_2_5_5 + 0.000132275132275132*G0_3_0_0 - 2.64550264550263e-05*G0_3_0_1 + 5.29100529100527e-05*G0_3_0_2 - 0.000423280423280422*G0_3_0_3 - 0.000211640211640211*G0_3_0_4 - 0.000317460317460316*G0_3_0_5 - 2.64550264550263e-05*G0_3_1_0 + 0.000264550264550263*G0_3_1_1 - 2.64550264550263e-05*G0_3_1_2 - 0.000211640211640211*G0_3_1_4 + 5.29100529100527e-05*G0_3_2_0 - 2.64550264550263e-05*G0_3_2_1 + 0.000132275132275132*G0_3_2_2 - 0.000317460317460316*G0_3_2_3 - 0.000211640211640211*G0_3_2_4 - 0.000423280423280422*G0_3_2_5 - 0.000423280423280422*G0_3_3_0 - 0.000317460317460316*G0_3_3_2 + 0.00253968253968253*G0_3_3_3 + 0.00126984126984127*G0_3_3_4 + 0.00169312169312169*G0_3_3_5 - 0.000211640211640211*G0_3_4_0 - 0.000211640211640211*G0_3_4_1 - 0.000211640211640211*G0_3_4_2 + 0.00126984126984127*G0_3_4_3 + 0.00126984126984127*G0_3_4_4 + 0.00126984126984127*G0_3_4_5 - 0.000317460317460316*G0_3_5_0 - 0.000423280423280422*G0_3_5_2 + 0.00169312169312169*G0_3_5_3 + 0.00126984126984127*G0_3_5_4 + 0.00253968253968253*G0_3_5_5 + 0.000264550264550263*G0_4_0_0 - 2.64550264550263e-05*G0_4_0_1 - 2.64550264550263e-05*G0_4_0_2 - 0.000211640211640211*G0_4_0_3 - 2.64550264550263e-05*G0_4_1_0 + 0.000132275132275132*G0_4_1_1 + 5.29100529100528e-05*G0_4_1_2 - 0.000211640211640211*G0_4_1_3 - 0.000423280423280422*G0_4_1_4 - 0.000317460317460316*G0_4_1_5 - 2.64550264550263e-05*G0_4_2_0 + 5.29100529100528e-05*G0_4_2_1 + 0.000132275132275132*G0_4_2_2 - 0.000211640211640211*G0_4_2_3 - 0.000317460317460317*G0_4_2_4 - 0.000423280423280422*G0_4_2_5 - 0.000211640211640211*G0_4_3_0 - 0.000211640211640211*G0_4_3_1 - 0.000211640211640211*G0_4_3_2 + 0.00126984126984127*G0_4_3_3 + 0.00126984126984127*G0_4_3_4 + 0.00126984126984127*G0_4_3_5 - 0.000423280423280422*G0_4_4_1 - 0.000317460317460317*G0_4_4_2 + 0.00126984126984127*G0_4_4_3 + 0.00253968253968253*G0_4_4_4 + 0.00169312169312169*G0_4_4_5 - 0.000317460317460316*G0_4_5_1 - 0.000423280423280422*G0_4_5_2 + 0.00126984126984127*G0_4_5_3 + 0.00169312169312169*G0_4_5_4 + 0.00253968253968253*G0_4_5_5 + 0.000529100529100526*G0_5_0_0 - 0.000238095238095237*G0_5_0_1 + 2.64550264550265e-05*G0_5_0_2 - 0.000317460317460316*G0_5_0_3 - 0.000238095238095237*G0_5_1_0 + 0.000529100529100526*G0_5_1_1 + 2.64550264550264e-05*G0_5_1_2 - 0.000317460317460316*G0_5_1_4 + 2.64550264550265e-05*G0_5_2_0 + 2.64550264550265e-05*G0_5_2_1 + 0.000158730158730158*G0_5_2_2 - 0.000423280423280422*G0_5_2_3 - 0.000423280423280422*G0_5_2_4 - 0.000952380952380948*G0_5_2_5 - 0.000317460317460316*G0_5_3_0 - 0.000423280423280422*G0_5_3_2 + 0.00169312169312169*G0_5_3_3 + 0.00126984126984127*G0_5_3_4 + 0.00253968253968253*G0_5_3_5 - 0.000317460317460316*G0_5_4_1 - 0.000423280423280422*G0_5_4_2 + 0.00126984126984127*G0_5_4_3 + 0.00169312169312169*G0_5_4_4 + 0.00253968253968253*G0_5_4_5 - 0.000952380952380949*G0_5_5_2 + 0.00253968253968253*G0_5_5_3 + 0.00253968253968253*G0_5_5_4 + 0.0101587301587301*G0_5_5_5; + A[5] = A[1] - 0.000396825396825395*G0_0_0_0 + 5.29100529100526e-05*G0_0_0_1 + 5.29100529100527e-05*G0_0_0_2 + 2.64550264550263e-05*G0_0_0_3 - 0.000132275132275132*G0_0_0_4 - 0.000396825396825394*G0_0_0_5 + 5.29100529100526e-05*G0_0_1_0 + 5.29100529100526e-05*G0_0_1_3 + 7.9365079365079e-05*G0_0_1_4 + 0.000211640211640211*G0_0_1_5 + 5.29100529100527e-05*G0_0_2_0 - 5.29100529100527e-05*G0_0_2_2 - 2.64550264550263e-05*G0_0_2_3 + 2.64550264550263e-05*G0_0_2_5 + 2.64550264550263e-05*G0_0_3_0 + 5.29100529100526e-05*G0_0_3_1 - 2.64550264550263e-05*G0_0_3_2 - 0.000529100529100527*G0_0_3_3 - 0.000211640211640211*G0_0_3_4 - 0.000105820105820106*G0_0_3_5 - 0.000132275132275132*G0_0_4_0 + 7.9365079365079e-05*G0_0_4_1 - 0.000211640211640211*G0_0_4_3 - 0.000317460317460316*G0_0_4_4 - 0.000211640211640211*G0_0_4_5 - 0.000396825396825394*G0_0_5_0 + 0.000211640211640211*G0_0_5_1 + 2.64550264550263e-05*G0_0_5_2 - 0.000105820105820106*G0_0_5_3 - 0.000211640211640211*G0_0_5_4 - 0.000317460317460315*G0_0_5_5 + 5.29100529100526e-05*G0_1_0_0 + 5.29100529100526e-05*G0_1_0_3 + 7.9365079365079e-05*G0_1_0_4 + 0.00021164021164021*G0_1_0_5 + 0.000264550264550264*G0_1_1_3 - 0.000264550264550263*G0_1_1_5 - 5.29100529100525e-05*G0_1_2_2 - 0.000211640211640211*G0_1_2_3 - 7.93650793650791e-05*G0_1_2_4 - 5.29100529100528e-05*G0_1_2_5 + 5.29100529100526e-05*G0_1_3_0 + 0.000264550264550264*G0_1_3_1 - 0.000211640211640211*G0_1_3_2 - 0.000105820105820105*G0_1_3_4 + 7.9365079365079e-05*G0_1_4_0 - 7.93650793650791e-05*G0_1_4_2 - 0.000105820105820105*G0_1_4_3 + 0.000105820105820105*G0_1_4_5 + 0.00021164021164021*G0_1_5_0 - 0.000264550264550263*G0_1_5_1 - 5.29100529100528e-05*G0_1_5_2 + 0.000105820105820105*G0_1_5_4 + 5.29100529100527e-05*G0_2_0_0 - 5.29100529100527e-05*G0_2_0_2 - 2.64550264550263e-05*G0_2_0_3 + 2.64550264550263e-05*G0_2_0_5 - 5.29100529100525e-05*G0_2_1_2 - 0.000211640211640211*G0_2_1_3 - 7.93650793650791e-05*G0_2_1_4 - 5.29100529100528e-05*G0_2_1_5 - 5.29100529100527e-05*G0_2_2_0 - 5.29100529100525e-05*G0_2_2_1 + 0.000396825396825395*G0_2_2_2 + 0.000396825396825395*G0_2_2_3 + 0.000132275132275132*G0_2_2_4 - 2.64550264550263e-05*G0_2_2_5 - 2.64550264550263e-05*G0_2_3_0 - 0.000211640211640211*G0_2_3_1 + 0.000396825396825395*G0_2_3_2 + 0.000317460317460315*G0_2_3_3 + 0.000211640211640211*G0_2_3_4 + 0.000105820105820105*G0_2_3_5 - 7.93650793650791e-05*G0_2_4_1 + 0.000132275132275132*G0_2_4_2 + 0.000211640211640211*G0_2_4_3 + 0.000317460317460317*G0_2_4_4 + 0.000211640211640211*G0_2_4_5 + 2.64550264550263e-05*G0_2_5_0 - 5.29100529100528e-05*G0_2_5_1 - 2.64550264550263e-05*G0_2_5_2 + 0.000105820105820106*G0_2_5_3 + 0.000211640211640211*G0_2_5_4 + 0.000529100529100527*G0_2_5_5 + 2.64550264550263e-05*G0_3_0_0 + 5.29100529100526e-05*G0_3_0_1 - 2.64550264550263e-05*G0_3_0_2 - 0.000529100529100527*G0_3_0_3 - 0.000211640211640211*G0_3_0_4 - 0.000105820105820106*G0_3_0_5 + 5.29100529100526e-05*G0_3_1_0 + 0.000264550264550264*G0_3_1_1 - 0.000211640211640211*G0_3_1_2 - 0.000105820105820105*G0_3_1_4 - 2.64550264550263e-05*G0_3_2_0 - 0.000211640211640211*G0_3_2_1 + 0.000396825396825395*G0_3_2_2 + 0.000317460317460315*G0_3_2_3 + 0.000211640211640211*G0_3_2_4 + 0.000105820105820105*G0_3_2_5 - 0.000529100529100527*G0_3_3_0 + 0.000317460317460315*G0_3_3_2 + 0.00761904761904759*G0_3_3_3 + 0.00126984126984127*G0_3_3_4 + 0.000846560846560845*G0_3_3_5 - 0.000211640211640211*G0_3_4_0 - 0.000105820105820105*G0_3_4_1 + 0.000211640211640211*G0_3_4_2 + 0.00126984126984127*G0_3_4_3 + 0.000423280423280422*G0_3_4_4 - 0.000105820105820106*G0_3_5_0 + 0.000105820105820105*G0_3_5_2 + 0.000846560846560845*G0_3_5_3 - 0.000846560846560842*G0_3_5_5 - 0.000132275132275132*G0_4_0_0 + 7.9365079365079e-05*G0_4_0_1 - 0.000211640211640211*G0_4_0_3 - 0.000317460317460316*G0_4_0_4 - 0.000211640211640211*G0_4_0_5 + 7.9365079365079e-05*G0_4_1_0 - 7.93650793650791e-05*G0_4_1_2 - 0.000105820105820105*G0_4_1_3 + 0.000105820105820105*G0_4_1_5 - 7.93650793650791e-05*G0_4_2_1 + 0.000132275132275132*G0_4_2_2 + 0.000211640211640211*G0_4_2_3 + 0.000317460317460317*G0_4_2_4 + 0.000211640211640211*G0_4_2_5 - 0.000211640211640211*G0_4_3_0 - 0.000105820105820105*G0_4_3_1 + 0.000211640211640211*G0_4_3_2 + 0.00126984126984127*G0_4_3_3 + 0.000423280423280422*G0_4_3_4 - 0.000317460317460316*G0_4_4_0 + 0.000317460317460317*G0_4_4_2 + 0.000423280423280422*G0_4_4_3 - 0.000423280423280422*G0_4_4_5 - 0.000211640211640211*G0_4_5_0 + 0.000105820105820105*G0_4_5_1 + 0.000211640211640211*G0_4_5_2 - 0.000423280423280422*G0_4_5_4 - 0.00126984126984127*G0_4_5_5 - 0.000396825396825394*G0_5_0_0 + 0.000211640211640211*G0_5_0_1 + 2.64550264550263e-05*G0_5_0_2 - 0.000105820105820106*G0_5_0_3 - 0.000211640211640211*G0_5_0_4 - 0.000317460317460315*G0_5_0_5 + 0.000211640211640211*G0_5_1_0 - 0.000264550264550263*G0_5_1_1 - 5.29100529100528e-05*G0_5_1_2 + 0.000105820105820105*G0_5_1_4 + 2.64550264550263e-05*G0_5_2_0 - 5.29100529100528e-05*G0_5_2_1 - 2.64550264550263e-05*G0_5_2_2 + 0.000105820105820106*G0_5_2_3 + 0.000211640211640211*G0_5_2_4 + 0.000529100529100527*G0_5_2_5 - 0.000105820105820106*G0_5_3_0 + 0.000105820105820105*G0_5_3_2 + 0.000846560846560845*G0_5_3_3 - 0.000846560846560841*G0_5_3_5 - 0.000211640211640211*G0_5_4_0 + 0.000105820105820105*G0_5_4_1 + 0.000211640211640211*G0_5_4_2 - 0.000423280423280422*G0_5_4_4 - 0.00126984126984126*G0_5_4_5 - 0.000317460317460315*G0_5_5_0 + 0.000529100529100527*G0_5_5_2 - 0.000846560846560842*G0_5_5_3 - 0.00126984126984126*G0_5_5_4 - 0.00761904761904758*G0_5_5_5; + A[0] = A[1] + 0.00515873015873013*G0_0_0_0 - 0.000462962962962961*G0_0_0_1 - 0.000462962962962961*G0_0_0_2 + 0.000132275132275133*G0_0_0_3 + 0.00211640211640211*G0_0_0_4 + 0.00185185185185184*G0_0_0_5 - 0.000462962962962961*G0_0_1_0 + 0.000145502645502645*G0_0_1_1 + 5.29100529100528e-05*G0_0_1_2 - 0.000238095238095237*G0_0_1_4 - 0.00029100529100529*G0_0_1_5 - 0.000462962962962961*G0_0_2_0 + 5.29100529100528e-05*G0_0_2_1 + 9.25925925925923e-05*G0_0_2_2 - 7.93650793650792e-05*G0_0_2_3 - 0.000502645502645501*G0_0_2_4 - 0.00029100529100529*G0_0_2_5 + 0.000132275132275133*G0_0_3_0 - 7.93650793650792e-05*G0_0_3_2 + 0.000211640211640211*G0_0_3_3 + 0.000211640211640212*G0_0_3_4 + 0.000317460317460317*G0_0_3_5 + 0.00211640211640211*G0_0_4_0 - 0.000238095238095237*G0_0_4_1 - 0.000502645502645501*G0_0_4_2 + 0.000211640211640212*G0_0_4_3 + 0.00211640211640211*G0_0_4_4 + 0.00105820105820105*G0_0_4_5 + 0.00185185185185184*G0_0_5_0 - 0.00029100529100529*G0_0_5_1 - 0.00029100529100529*G0_0_5_2 + 0.000317460317460317*G0_0_5_3 + 0.00105820105820105*G0_0_5_4 + 0.00211640211640211*G0_0_5_5 - 0.000462962962962961*G0_1_0_0 + 0.000145502645502645*G0_1_0_1 + 5.29100529100528e-05*G0_1_0_2 - 0.000238095238095237*G0_1_0_4 - 0.00029100529100529*G0_1_0_5 + 0.000145502645502645*G0_1_1_0 - 0.000396825396825394*G0_1_1_1 + 1.32275132275131e-05*G0_1_1_2 - 0.000132275132275132*G0_1_1_3 + 0.000105820105820106*G0_1_1_4 - 0.000132275132275131*G0_1_1_5 + 5.29100529100528e-05*G0_1_2_0 + 1.32275132275131e-05*G0_1_2_1 - 3.96825396825396e-05*G0_1_2_2 + 7.93650793650791e-05*G0_1_2_3 + 0.000132275132275132*G0_1_2_4 + 0.000158730158730158*G0_1_2_5 - 0.000132275132275132*G0_1_3_1 + 7.93650793650791e-05*G0_1_3_2 - 0.000211640211640211*G0_1_3_3 - 0.000211640211640211*G0_1_3_4 - 0.000317460317460316*G0_1_3_5 - 0.000238095238095237*G0_1_4_0 + 0.000105820105820106*G0_1_4_1 + 0.000132275132275132*G0_1_4_2 - 0.000211640211640211*G0_1_4_3 - 0.000846560846560845*G0_1_4_4 - 0.000529100529100527*G0_1_4_5 - 0.00029100529100529*G0_1_5_0 - 0.000132275132275131*G0_1_5_1 + 0.000158730158730158*G0_1_5_2 - 0.000317460317460316*G0_1_5_3 - 0.000529100529100527*G0_1_5_4 - 0.00126984126984126*G0_1_5_5 - 0.000462962962962961*G0_2_0_0 + 5.29100529100528e-05*G0_2_0_1 + 9.25925925925923e-05*G0_2_0_2 - 7.93650793650792e-05*G0_2_0_3 - 0.000502645502645501*G0_2_0_4 - 0.00029100529100529*G0_2_0_5 + 5.29100529100528e-05*G0_2_1_0 + 1.32275132275131e-05*G0_2_1_1 - 3.96825396825395e-05*G0_2_1_2 + 7.93650793650791e-05*G0_2_1_3 + 0.000132275132275132*G0_2_1_4 + 0.000158730158730158*G0_2_1_5 + 9.25925925925923e-05*G0_2_2_0 - 3.96825396825396e-05*G0_2_2_1 + 0.000264550264550264*G0_2_2_4 + 7.93650793650791e-05*G0_2_2_5 - 7.93650793650792e-05*G0_2_3_0 + 7.93650793650791e-05*G0_2_3_1 + 0.000105820105820105*G0_2_3_3 - 0.000105820105820106*G0_2_3_4 - 0.000502645502645501*G0_2_4_0 + 0.000132275132275132*G0_2_4_1 + 0.000264550264550264*G0_2_4_2 - 0.000105820105820106*G0_2_4_3 - 0.000952380952380949*G0_2_4_4 - 0.000423280423280422*G0_2_4_5 - 0.00029100529100529*G0_2_5_0 + 0.000158730158730158*G0_2_5_1 + 7.9365079365079e-05*G0_2_5_2 - 0.000423280423280422*G0_2_5_4 - 0.000317460317460316*G0_2_5_5 + 0.000132275132275133*G0_3_0_0 - 7.93650793650792e-05*G0_3_0_2 + 0.000211640211640211*G0_3_0_3 + 0.000211640211640212*G0_3_0_4 + 0.000317460317460317*G0_3_0_5 - 0.000132275132275132*G0_3_1_1 + 7.93650793650791e-05*G0_3_1_2 - 0.000211640211640211*G0_3_1_3 - 0.000211640211640211*G0_3_1_4 - 0.000317460317460316*G0_3_1_5 - 7.93650793650792e-05*G0_3_2_0 + 7.93650793650791e-05*G0_3_2_1 + 0.000105820105820105*G0_3_2_3 - 0.000105820105820106*G0_3_2_4 + 0.000211640211640211*G0_3_3_0 - 0.000211640211640211*G0_3_3_1 + 0.000105820105820105*G0_3_3_2 - 0.00126984126984127*G0_3_3_3 - 0.000423280423280422*G0_3_3_5 + 0.000211640211640211*G0_3_4_0 - 0.000211640211640211*G0_3_4_1 - 0.000105820105820106*G0_3_4_2 + 0.00126984126984127*G0_3_4_4 + 0.000423280423280422*G0_3_4_5 + 0.000317460317460317*G0_3_5_0 - 0.000317460317460316*G0_3_5_1 - 0.000423280423280422*G0_3_5_3 + 0.000423280423280422*G0_3_5_4 + 0.00211640211640211*G0_4_0_0 - 0.000238095238095237*G0_4_0_1 - 0.000502645502645501*G0_4_0_2 + 0.000211640211640212*G0_4_0_3 + 0.00211640211640211*G0_4_0_4 + 0.00105820105820105*G0_4_0_5 - 0.000238095238095237*G0_4_1_0 + 0.000105820105820106*G0_4_1_1 + 0.000132275132275132*G0_4_1_2 - 0.000211640211640211*G0_4_1_3 - 0.000846560846560845*G0_4_1_4 - 0.000529100529100527*G0_4_1_5 - 0.000502645502645501*G0_4_2_0 + 0.000132275132275132*G0_4_2_1 + 0.000264550264550264*G0_4_2_2 - 0.000105820105820106*G0_4_2_3 - 0.000952380952380949*G0_4_2_4 - 0.000423280423280422*G0_4_2_5 + 0.000211640211640211*G0_4_3_0 - 0.000211640211640211*G0_4_3_1 - 0.000105820105820106*G0_4_3_2 + 0.00126984126984127*G0_4_3_4 + 0.000423280423280422*G0_4_3_5 + 0.00211640211640211*G0_4_4_0 - 0.000846560846560845*G0_4_4_1 - 0.000952380952380949*G0_4_4_2 + 0.00126984126984127*G0_4_4_3 + 0.0101587301587301*G0_4_4_4 + 0.00253968253968253*G0_4_4_5 + 0.00105820105820105*G0_4_5_0 - 0.000529100529100527*G0_4_5_1 - 0.000423280423280421*G0_4_5_2 + 0.000423280423280422*G0_4_5_3 + 0.00253968253968253*G0_4_5_4 + 0.00169312169312168*G0_4_5_5 + 0.00185185185185184*G0_5_0_0 - 0.00029100529100529*G0_5_0_1 - 0.00029100529100529*G0_5_0_2 + 0.000317460317460317*G0_5_0_3 + 0.00105820105820105*G0_5_0_4 + 0.00211640211640211*G0_5_0_5 - 0.00029100529100529*G0_5_1_0 - 0.000132275132275131*G0_5_1_1 + 0.000158730158730158*G0_5_1_2 - 0.000317460317460316*G0_5_1_3 - 0.000529100529100527*G0_5_1_4 - 0.00126984126984126*G0_5_1_5 - 0.00029100529100529*G0_5_2_0 + 0.000158730158730158*G0_5_2_1 + 7.93650793650791e-05*G0_5_2_2 - 0.000423280423280422*G0_5_2_4 - 0.000317460317460316*G0_5_2_5 + 0.000317460317460317*G0_5_3_0 - 0.000317460317460316*G0_5_3_1 - 0.000423280423280422*G0_5_3_3 + 0.000423280423280422*G0_5_3_4 + 0.00105820105820105*G0_5_4_0 - 0.000529100529100527*G0_5_4_1 - 0.000423280423280421*G0_5_4_2 + 0.000423280423280422*G0_5_4_3 + 0.00253968253968253*G0_5_4_4 + 0.00169312169312168*G0_5_4_5 + 0.00211640211640211*G0_5_5_0 - 0.00126984126984126*G0_5_5_1 - 0.000317460317460316*G0_5_5_2 + 0.00169312169312168*G0_5_5_4 + 0.00253968253968252*G0_5_5_5; + A[7] = A[5]; + A[6] = A[1] + 0.000264550264550264*G0_0_0_4 - 0.000264550264550263*G0_0_0_5 + 5.29100529100527e-05*G0_0_1_1 + 7.9365079365079e-05*G0_0_1_3 + 5.29100529100526e-05*G0_0_1_4 + 0.000211640211640211*G0_0_1_5 - 5.29100529100526e-05*G0_0_2_2 - 7.93650793650791e-05*G0_0_2_3 - 0.000211640211640211*G0_0_2_4 - 5.29100529100528e-05*G0_0_2_5 + 7.9365079365079e-05*G0_0_3_1 - 7.93650793650791e-05*G0_0_3_2 - 0.000105820105820105*G0_0_3_4 + 0.000105820105820105*G0_0_3_5 + 0.000264550264550263*G0_0_4_0 + 5.29100529100526e-05*G0_0_4_1 - 0.000211640211640211*G0_0_4_2 - 0.000105820105820105*G0_0_4_3 - 0.000264550264550263*G0_0_5_0 + 0.000211640211640211*G0_0_5_1 - 5.29100529100528e-05*G0_0_5_2 + 0.000105820105820105*G0_0_5_3 + 5.29100529100526e-05*G0_1_0_1 + 7.9365079365079e-05*G0_1_0_3 + 5.29100529100526e-05*G0_1_0_4 + 0.00021164021164021*G0_1_0_5 + 5.29100529100526e-05*G0_1_1_0 - 0.000396825396825394*G0_1_1_1 + 5.29100529100526e-05*G0_1_1_2 - 0.000132275132275131*G0_1_1_3 + 2.64550264550264e-05*G0_1_1_4 - 0.000396825396825395*G0_1_1_5 + 5.29100529100526e-05*G0_1_2_1 - 5.29100529100526e-05*G0_1_2_2 - 2.64550264550262e-05*G0_1_2_4 + 2.64550264550263e-05*G0_1_2_5 + 7.9365079365079e-05*G0_1_3_0 - 0.000132275132275132*G0_1_3_1 - 0.000317460317460316*G0_1_3_3 - 0.000211640211640211*G0_1_3_4 - 0.000211640211640211*G0_1_3_5 + 5.29100529100526e-05*G0_1_4_0 + 2.64550264550264e-05*G0_1_4_1 - 2.64550264550263e-05*G0_1_4_2 - 0.000211640211640211*G0_1_4_3 - 0.000529100529100527*G0_1_4_4 - 0.000105820105820106*G0_1_4_5 + 0.00021164021164021*G0_1_5_0 - 0.000396825396825395*G0_1_5_1 + 2.64550264550263e-05*G0_1_5_2 - 0.000211640211640211*G0_1_5_3 - 0.000105820105820106*G0_1_5_4 - 0.000317460317460316*G0_1_5_5 - 5.29100529100526e-05*G0_2_0_2 - 7.93650793650791e-05*G0_2_0_3 - 0.000211640211640211*G0_2_0_4 - 5.29100529100528e-05*G0_2_0_5 + 5.29100529100526e-05*G0_2_1_1 - 5.29100529100526e-05*G0_2_1_2 - 2.64550264550262e-05*G0_2_1_4 + 2.64550264550263e-05*G0_2_1_5 - 5.29100529100526e-05*G0_2_2_0 - 5.29100529100526e-05*G0_2_2_1 + 0.000396825396825394*G0_2_2_2 + 0.000132275132275131*G0_2_2_3 + 0.000396825396825395*G0_2_2_4 - 2.64550264550263e-05*G0_2_2_5 - 7.93650793650791e-05*G0_2_3_0 + 0.000132275132275131*G0_2_3_2 + 0.000317460317460316*G0_2_3_3 + 0.000211640211640211*G0_2_3_4 + 0.000211640211640211*G0_2_3_5 - 0.000211640211640211*G0_2_4_0 - 2.64550264550262e-05*G0_2_4_1 + 0.000396825396825395*G0_2_4_2 + 0.000211640211640211*G0_2_4_3 + 0.000317460317460316*G0_2_4_4 + 0.000105820105820105*G0_2_4_5 - 5.29100529100528e-05*G0_2_5_0 + 2.64550264550263e-05*G0_2_5_1 - 2.64550264550263e-05*G0_2_5_2 + 0.000211640211640211*G0_2_5_3 + 0.000105820105820105*G0_2_5_4 + 0.000529100529100527*G0_2_5_5 + 7.9365079365079e-05*G0_3_0_1 - 7.93650793650791e-05*G0_3_0_2 - 0.000105820105820105*G0_3_0_4 + 0.000105820105820105*G0_3_0_5 + 7.9365079365079e-05*G0_3_1_0 - 0.000132275132275131*G0_3_1_1 - 0.000317460317460316*G0_3_1_3 - 0.000211640211640211*G0_3_1_4 - 0.000211640211640211*G0_3_1_5 - 7.93650793650791e-05*G0_3_2_0 + 0.000132275132275131*G0_3_2_2 + 0.000317460317460316*G0_3_2_3 + 0.000211640211640211*G0_3_2_4 + 0.000211640211640211*G0_3_2_5 - 0.000317460317460316*G0_3_3_1 + 0.000317460317460316*G0_3_3_2 + 0.000423280423280422*G0_3_3_4 - 0.000423280423280422*G0_3_3_5 - 0.000105820105820105*G0_3_4_0 - 0.000211640211640211*G0_3_4_1 + 0.000211640211640211*G0_3_4_2 + 0.000423280423280422*G0_3_4_3 + 0.00126984126984127*G0_3_4_4 + 0.000105820105820105*G0_3_5_0 - 0.000211640211640211*G0_3_5_1 + 0.000211640211640211*G0_3_5_2 - 0.000423280423280422*G0_3_5_3 - 0.00126984126984126*G0_3_5_5 + 0.000264550264550263*G0_4_0_0 + 5.29100529100526e-05*G0_4_0_1 - 0.000211640211640211*G0_4_0_2 - 0.000105820105820105*G0_4_0_3 + 5.29100529100526e-05*G0_4_1_0 + 2.64550264550264e-05*G0_4_1_1 - 2.64550264550263e-05*G0_4_1_2 - 0.000211640211640211*G0_4_1_3 - 0.000529100529100527*G0_4_1_4 - 0.000105820105820106*G0_4_1_5 - 0.000211640211640211*G0_4_2_0 - 2.64550264550262e-05*G0_4_2_1 + 0.000396825396825395*G0_4_2_2 + 0.000211640211640211*G0_4_2_3 + 0.000317460317460316*G0_4_2_4 + 0.000105820105820105*G0_4_2_5 - 0.000105820105820105*G0_4_3_0 - 0.000211640211640211*G0_4_3_1 + 0.000211640211640211*G0_4_3_2 + 0.000423280423280422*G0_4_3_3 + 0.00126984126984127*G0_4_3_4 - 0.000529100529100527*G0_4_4_1 + 0.000317460317460316*G0_4_4_2 + 0.00126984126984127*G0_4_4_3 + 0.00761904761904759*G0_4_4_4 + 0.000846560846560844*G0_4_4_5 - 0.000105820105820106*G0_4_5_1 + 0.000105820105820105*G0_4_5_2 + 0.000846560846560844*G0_4_5_4 - 0.000846560846560843*G0_4_5_5 - 0.000264550264550263*G0_5_0_0 + 0.000211640211640211*G0_5_0_1 - 5.29100529100528e-05*G0_5_0_2 + 0.000105820105820105*G0_5_0_3 + 0.000211640211640211*G0_5_1_0 - 0.000396825396825395*G0_5_1_1 + 2.64550264550263e-05*G0_5_1_2 - 0.000211640211640211*G0_5_1_3 - 0.000105820105820106*G0_5_1_4 - 0.000317460317460316*G0_5_1_5 - 5.29100529100528e-05*G0_5_2_0 + 2.64550264550263e-05*G0_5_2_1 - 2.64550264550263e-05*G0_5_2_2 + 0.000211640211640211*G0_5_2_3 + 0.000105820105820105*G0_5_2_4 + 0.000529100529100527*G0_5_2_5 + 0.000105820105820105*G0_5_3_0 - 0.000211640211640211*G0_5_3_1 + 0.000211640211640211*G0_5_3_2 - 0.000423280423280422*G0_5_3_3 - 0.00126984126984126*G0_5_3_5 - 0.000105820105820106*G0_5_4_1 + 0.000105820105820105*G0_5_4_2 + 0.000846560846560844*G0_5_4_4 - 0.000846560846560843*G0_5_4_5 - 0.000317460317460316*G0_5_5_1 + 0.000529100529100527*G0_5_5_2 - 0.00126984126984126*G0_5_5_3 - 0.000846560846560843*G0_5_5_4 - 0.00761904761904758*G0_5_5_5; + A[2] = A[6]; + A[8] = A[0] - 0.00555555555555553*G0_0_0_0 + 0.000476190476190474*G0_0_0_1 + 0.000608465608465606*G0_0_0_2 - 2.64550264550271e-05*G0_0_0_3 - 0.00198412698412697*G0_0_0_4 - 0.00224867724867724*G0_0_0_5 + 0.000476190476190474*G0_0_1_0 - 0.000132275132275132*G0_0_1_1 + 0.000211640211640211*G0_0_1_3 + 0.000449735449735448*G0_0_1_4 + 0.000582010582010579*G0_0_1_5 + 0.000608465608465606*G0_0_2_0 - 0.000608465608465605*G0_0_2_2 - 0.000238095238095237*G0_0_2_3 + 0.000238095238095237*G0_0_2_5 - 2.64550264550271e-05*G0_0_3_0 + 0.000211640211640211*G0_0_3_1 - 0.000238095238095237*G0_0_3_2 - 0.00105820105820105*G0_0_3_3 - 0.000846560846560844*G0_0_3_4 - 0.000423280423280422*G0_0_3_5 - 0.00198412698412697*G0_0_4_0 + 0.000449735449735448*G0_0_4_1 - 0.000846560846560844*G0_0_4_3 - 0.00338624338624337*G0_0_4_4 - 0.00137566137566137*G0_0_4_5 - 0.00224867724867724*G0_0_5_0 + 0.000582010582010579*G0_0_5_1 + 0.000238095238095237*G0_0_5_2 - 0.000423280423280422*G0_0_5_3 - 0.00137566137566137*G0_0_5_4 - 0.00232804232804232*G0_0_5_5 + 0.000476190476190474*G0_1_0_0 - 0.000132275132275132*G0_1_0_1 + 0.000211640211640211*G0_1_0_3 + 0.000449735449735448*G0_1_0_4 + 0.000582010582010579*G0_1_0_5 - 0.000132275132275132*G0_1_1_0 + 0.000132275132275132*G0_1_1_2 + 0.000264550264550263*G0_1_1_3 - 0.000264550264550263*G0_1_1_5 + 0.000132275132275132*G0_1_2_1 - 0.000476190476190473*G0_1_2_2 - 0.000582010582010579*G0_1_2_3 - 0.000449735449735448*G0_1_2_4 - 0.000211640211640211*G0_1_2_5 + 0.000211640211640211*G0_1_3_0 + 0.000264550264550263*G0_1_3_1 - 0.000582010582010579*G0_1_3_2 - 0.00105820105820105*G0_1_3_3 - 0.000423280423280422*G0_1_3_4 + 0.000449735449735448*G0_1_4_0 - 0.000449735449735448*G0_1_4_2 - 0.000423280423280422*G0_1_4_3 + 0.000423280423280422*G0_1_4_5 + 0.000582010582010579*G0_1_5_0 - 0.000264550264550263*G0_1_5_1 - 0.000211640211640211*G0_1_5_2 + 0.000423280423280422*G0_1_5_4 + 0.00105820105820105*G0_1_5_5 + 0.000608465608465606*G0_2_0_0 - 0.000608465608465605*G0_2_0_2 - 0.000238095238095237*G0_2_0_3 + 0.000238095238095237*G0_2_0_5 + 0.000132275132275132*G0_2_1_1 - 0.000476190476190473*G0_2_1_2 - 0.000582010582010579*G0_2_1_3 - 0.000449735449735448*G0_2_1_4 - 0.000211640211640211*G0_2_1_5 - 0.000608465608465605*G0_2_2_0 - 0.000476190476190473*G0_2_2_1 + 0.00555555555555552*G0_2_2_2 + 0.00224867724867724*G0_2_2_3 + 0.00198412698412697*G0_2_2_4 + 2.64550264550265e-05*G0_2_2_5 - 0.000238095238095237*G0_2_3_0 - 0.000582010582010579*G0_2_3_1 + 0.00224867724867724*G0_2_3_2 + 0.00232804232804232*G0_2_3_3 + 0.00137566137566137*G0_2_3_4 + 0.000423280423280422*G0_2_3_5 - 0.000449735449735448*G0_2_4_1 + 0.00198412698412697*G0_2_4_2 + 0.00137566137566137*G0_2_4_3 + 0.00338624338624337*G0_2_4_4 + 0.000846560846560843*G0_2_4_5 + 0.000238095238095237*G0_2_5_0 - 0.000211640211640211*G0_2_5_1 + 2.64550264550266e-05*G0_2_5_2 + 0.000423280423280422*G0_2_5_3 + 0.000846560846560843*G0_2_5_4 + 0.00105820105820105*G0_2_5_5 - 2.64550264550271e-05*G0_3_0_0 + 0.000211640211640211*G0_3_0_1 - 0.000238095238095237*G0_3_0_2 - 0.00105820105820105*G0_3_0_3 - 0.000846560846560844*G0_3_0_4 - 0.000423280423280422*G0_3_0_5 + 0.000211640211640211*G0_3_1_0 + 0.000264550264550263*G0_3_1_1 - 0.000582010582010579*G0_3_1_2 - 0.00105820105820105*G0_3_1_3 - 0.000423280423280422*G0_3_1_4 - 0.000238095238095237*G0_3_2_0 - 0.000582010582010579*G0_3_2_1 + 0.00224867724867724*G0_3_2_2 + 0.00232804232804232*G0_3_2_3 + 0.00137566137566137*G0_3_2_4 + 0.000423280423280422*G0_3_2_5 - 0.00105820105820105*G0_3_3_0 - 0.00105820105820105*G0_3_3_1 + 0.00232804232804232*G0_3_3_2 + 0.0114285714285714*G0_3_3_3 + 0.00296296296296295*G0_3_3_4 + 0.00126984126984127*G0_3_3_5 - 0.000846560846560844*G0_3_4_0 - 0.000423280423280422*G0_3_4_1 + 0.00137566137566137*G0_3_4_2 + 0.00296296296296295*G0_3_4_3 + 0.00169312169312169*G0_3_4_4 - 0.000423280423280422*G0_3_5_0 + 0.000423280423280422*G0_3_5_2 + 0.00126984126984127*G0_3_5_3 - 0.00126984126984126*G0_3_5_5 - 0.00198412698412697*G0_4_0_0 + 0.000449735449735448*G0_4_0_1 - 0.000846560846560844*G0_4_0_3 - 0.00338624338624337*G0_4_0_4 - 0.00137566137566137*G0_4_0_5 + 0.000449735449735448*G0_4_1_0 - 0.000449735449735448*G0_4_1_2 - 0.000423280423280422*G0_4_1_3 + 0.000423280423280422*G0_4_1_5 - 0.000449735449735448*G0_4_2_1 + 0.00198412698412697*G0_4_2_2 + 0.00137566137566137*G0_4_2_3 + 0.00338624338624337*G0_4_2_4 + 0.000846560846560844*G0_4_2_5 - 0.000846560846560844*G0_4_3_0 - 0.000423280423280422*G0_4_3_1 + 0.00137566137566137*G0_4_3_2 + 0.00296296296296295*G0_4_3_3 + 0.00169312169312169*G0_4_3_4 - 0.00338624338624337*G0_4_4_0 + 0.00338624338624337*G0_4_4_2 + 0.00169312169312169*G0_4_4_3 - 0.00169312169312169*G0_4_4_5 - 0.00137566137566137*G0_4_5_0 + 0.000423280423280422*G0_4_5_1 + 0.000846560846560843*G0_4_5_2 - 0.00169312169312169*G0_4_5_4 - 0.00296296296296295*G0_4_5_5 - 0.00224867724867724*G0_5_0_0 + 0.000582010582010579*G0_5_0_1 + 0.000238095238095237*G0_5_0_2 - 0.000423280423280422*G0_5_0_3 - 0.00137566137566137*G0_5_0_4 - 0.00232804232804232*G0_5_0_5 + 0.000582010582010579*G0_5_1_0 - 0.000264550264550263*G0_5_1_1 - 0.000211640211640211*G0_5_1_2 + 0.000423280423280422*G0_5_1_4 + 0.00105820105820105*G0_5_1_5 + 0.000238095238095237*G0_5_2_0 - 0.000211640211640211*G0_5_2_1 + 2.64550264550266e-05*G0_5_2_2 + 0.000423280423280422*G0_5_2_3 + 0.000846560846560843*G0_5_2_4 + 0.00105820105820105*G0_5_2_5 - 0.000423280423280422*G0_5_3_0 + 0.000423280423280422*G0_5_3_2 + 0.00126984126984127*G0_5_3_3 - 0.00126984126984126*G0_5_3_5 - 0.00137566137566137*G0_5_4_0 + 0.000423280423280422*G0_5_4_1 + 0.000846560846560843*G0_5_4_2 - 0.00169312169312169*G0_5_4_4 - 0.00296296296296295*G0_5_4_5 - 0.00232804232804232*G0_5_5_0 + 0.00105820105820105*G0_5_5_1 + 0.00105820105820105*G0_5_5_2 - 0.00126984126984126*G0_5_5_3 - 0.00296296296296295*G0_5_5_4 - 0.0114285714285714*G0_5_5_5; + A[3] = A[1]; + A[4] = A[0] - 0.00555555555555553*G0_0_0_0 + 0.000608465608465606*G0_0_0_1 + 0.000476190476190474*G0_0_0_2 - 2.6455026455027e-05*G0_0_0_3 - 0.00224867724867724*G0_0_0_4 - 0.00198412698412697*G0_0_0_5 + 0.000608465608465606*G0_0_1_0 - 0.000608465608465606*G0_0_1_1 - 0.000238095238095237*G0_0_1_3 + 0.000238095238095237*G0_0_1_4 + 0.000476190476190474*G0_0_2_0 - 0.000132275132275132*G0_0_2_2 + 0.000211640211640211*G0_0_2_3 + 0.00058201058201058*G0_0_2_4 + 0.000449735449735448*G0_0_2_5 - 2.6455026455027e-05*G0_0_3_0 - 0.000238095238095237*G0_0_3_1 + 0.000211640211640211*G0_0_3_2 - 0.00105820105820106*G0_0_3_3 - 0.000423280423280423*G0_0_3_4 - 0.000846560846560844*G0_0_3_5 - 0.00224867724867724*G0_0_4_0 + 0.000238095238095237*G0_0_4_1 + 0.00058201058201058*G0_0_4_2 - 0.000423280423280423*G0_0_4_3 - 0.00232804232804232*G0_0_4_4 - 0.00137566137566137*G0_0_4_5 - 0.00198412698412697*G0_0_5_0 + 0.000449735449735448*G0_0_5_2 - 0.000846560846560844*G0_0_5_3 - 0.00137566137566137*G0_0_5_4 - 0.00338624338624337*G0_0_5_5 + 0.000608465608465606*G0_1_0_0 - 0.000608465608465606*G0_1_0_1 - 0.000238095238095237*G0_1_0_3 + 0.000238095238095237*G0_1_0_4 - 0.000608465608465606*G0_1_1_0 + 0.00555555555555553*G0_1_1_1 - 0.000476190476190474*G0_1_1_2 + 0.00224867724867724*G0_1_1_3 + 2.64550264550263e-05*G0_1_1_4 + 0.00198412698412697*G0_1_1_5 - 0.000476190476190474*G0_1_2_1 + 0.000132275132275132*G0_1_2_2 - 0.00058201058201058*G0_1_2_3 - 0.000211640211640211*G0_1_2_4 - 0.000449735449735448*G0_1_2_5 - 0.000238095238095237*G0_1_3_0 + 0.00224867724867724*G0_1_3_1 - 0.00058201058201058*G0_1_3_2 + 0.00232804232804232*G0_1_3_3 + 0.000423280423280422*G0_1_3_4 + 0.00137566137566137*G0_1_3_5 + 0.000238095238095237*G0_1_4_0 + 2.64550264550263e-05*G0_1_4_1 - 0.000211640211640211*G0_1_4_2 + 0.000423280423280422*G0_1_4_3 + 0.00105820105820106*G0_1_4_4 + 0.000846560846560843*G0_1_4_5 + 0.00198412698412697*G0_1_5_1 - 0.000449735449735448*G0_1_5_2 + 0.00137566137566137*G0_1_5_3 + 0.000846560846560843*G0_1_5_4 + 0.00338624338624337*G0_1_5_5 + 0.000476190476190474*G0_2_0_0 - 0.000132275132275132*G0_2_0_2 + 0.000211640211640211*G0_2_0_3 + 0.00058201058201058*G0_2_0_4 + 0.000449735449735448*G0_2_0_5 - 0.000476190476190474*G0_2_1_1 + 0.000132275132275132*G0_2_1_2 - 0.00058201058201058*G0_2_1_3 - 0.000211640211640211*G0_2_1_4 - 0.000449735449735448*G0_2_1_5 - 0.000132275132275132*G0_2_2_0 + 0.000132275132275132*G0_2_2_1 + 0.000264550264550263*G0_2_2_3 - 0.000264550264550264*G0_2_2_4 + 0.000211640211640211*G0_2_3_0 - 0.00058201058201058*G0_2_3_1 + 0.000264550264550264*G0_2_3_2 - 0.00105820105820105*G0_2_3_3 - 0.000423280423280422*G0_2_3_5 + 0.00058201058201058*G0_2_4_0 - 0.000211640211640211*G0_2_4_1 - 0.000264550264550264*G0_2_4_2 + 0.00105820105820105*G0_2_4_4 + 0.000423280423280422*G0_2_4_5 + 0.000449735449735448*G0_2_5_0 - 0.000449735449735448*G0_2_5_1 - 0.000423280423280422*G0_2_5_3 + 0.000423280423280422*G0_2_5_4 - 2.6455026455027e-05*G0_3_0_0 - 0.000238095238095237*G0_3_0_1 + 0.000211640211640211*G0_3_0_2 - 0.00105820105820106*G0_3_0_3 - 0.000423280423280423*G0_3_0_4 - 0.000846560846560844*G0_3_0_5 - 0.000238095238095237*G0_3_1_0 + 0.00224867724867724*G0_3_1_1 - 0.00058201058201058*G0_3_1_2 + 0.00232804232804232*G0_3_1_3 + 0.000423280423280422*G0_3_1_4 + 0.00137566137566137*G0_3_1_5 + 0.000211640211640211*G0_3_2_0 - 0.00058201058201058*G0_3_2_1 + 0.000264550264550263*G0_3_2_2 - 0.00105820105820105*G0_3_2_3 - 0.000423280423280422*G0_3_2_5 - 0.00105820105820106*G0_3_3_0 + 0.00232804232804232*G0_3_3_1 - 0.00105820105820105*G0_3_3_2 + 0.0114285714285714*G0_3_3_3 + 0.00126984126984127*G0_3_3_4 + 0.00296296296296295*G0_3_3_5 - 0.000423280423280422*G0_3_4_0 + 0.000423280423280422*G0_3_4_1 + 0.00126984126984127*G0_3_4_3 - 0.00126984126984127*G0_3_4_4 - 0.000846560846560844*G0_3_5_0 + 0.00137566137566137*G0_3_5_1 - 0.000423280423280422*G0_3_5_2 + 0.00296296296296295*G0_3_5_3 + 0.00169312169312169*G0_3_5_5 - 0.00224867724867724*G0_4_0_0 + 0.000238095238095237*G0_4_0_1 + 0.00058201058201058*G0_4_0_2 - 0.000423280423280423*G0_4_0_3 - 0.00232804232804232*G0_4_0_4 - 0.00137566137566137*G0_4_0_5 + 0.000238095238095237*G0_4_1_0 + 2.64550264550263e-05*G0_4_1_1 - 0.000211640211640211*G0_4_1_2 + 0.000423280423280422*G0_4_1_3 + 0.00105820105820106*G0_4_1_4 + 0.000846560846560843*G0_4_1_5 + 0.00058201058201058*G0_4_2_0 - 0.000211640211640211*G0_4_2_1 - 0.000264550264550264*G0_4_2_2 + 0.00105820105820105*G0_4_2_4 + 0.000423280423280422*G0_4_2_5 - 0.000423280423280423*G0_4_3_0 + 0.000423280423280422*G0_4_3_1 + 0.00126984126984127*G0_4_3_3 - 0.00126984126984127*G0_4_3_4 - 0.00232804232804232*G0_4_4_0 + 0.00105820105820106*G0_4_4_1 + 0.00105820105820105*G0_4_4_2 - 0.00126984126984127*G0_4_4_3 - 0.0114285714285714*G0_4_4_4 - 0.00296296296296295*G0_4_4_5 - 0.00137566137566137*G0_4_5_0 + 0.000846560846560843*G0_4_5_1 + 0.000423280423280422*G0_4_5_2 - 0.00296296296296295*G0_4_5_4 - 0.00169312169312168*G0_4_5_5 - 0.00198412698412697*G0_5_0_0 + 0.000449735449735448*G0_5_0_2 - 0.000846560846560844*G0_5_0_3 - 0.00137566137566137*G0_5_0_4 - 0.00338624338624337*G0_5_0_5 + 0.00198412698412697*G0_5_1_1 - 0.000449735449735448*G0_5_1_2 + 0.00137566137566137*G0_5_1_3 + 0.000846560846560843*G0_5_1_4 + 0.00338624338624337*G0_5_1_5 + 0.000449735449735448*G0_5_2_0 - 0.000449735449735448*G0_5_2_1 - 0.000423280423280422*G0_5_2_3 + 0.000423280423280422*G0_5_2_4 - 0.000846560846560844*G0_5_3_0 + 0.00137566137566137*G0_5_3_1 - 0.000423280423280422*G0_5_3_2 + 0.00296296296296295*G0_5_3_3 + 0.00169312169312169*G0_5_3_5 - 0.00137566137566137*G0_5_4_0 + 0.000846560846560843*G0_5_4_1 + 0.000423280423280421*G0_5_4_2 - 0.00296296296296295*G0_5_4_4 - 0.00169312169312168*G0_5_4_5 - 0.00338624338624337*G0_5_5_0 + 0.00338624338624337*G0_5_5_1 + 0.00169312169312169*G0_5_5_3 - 0.00169312169312168*G0_5_5_4; + } + + /// 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 mass_matrix_f3_p2_q1_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f3_p2_q1_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p2_q1_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1)))), 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 3; + } + + /// 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 mass_matrix_f3_p2_q1_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f3_p2_q1_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f3_p2_q1_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p2_q1_tensor_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p2_q1_tensor_finite_element_0(); + 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 mass_matrix_f3_p2_q1_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f3_p2_q1_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f3_p2_q1_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p2_q1_tensor_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p2_q1_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f3_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/mass_matrix_2d/mass_matrix_f3_p2_q2_excafe.h b/mass_matrix_2d/mass_matrix_f3_p2_q2_excafe.h new file mode 100644 index 0000000..5fcc7cb --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f3_p2_q2_excafe.h @@ -0,0 +1,607 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 10 minutes and 18.83 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[1][1]*w[2][4] + w[1][4]*w[2][1]; + const double var_1 = w[1][4]*w[2][4]; + const double var_2 = w[1][2]*w[2][0] + w[1][0]*w[2][2]; + const double var_3 = -1.0000000000000000000000000*var_2; + const double var_4 = var_3 + -8.0000000000000000000000000*var_1 + var_0; + const double var_5 = var_4*w[0][5]; + const double var_6 = -1.0000000000000000000000000*x[0][1]; + const double var_7 = x[2][1] + var_6; + const double var_8 = -1.0000000000000000000000000*x[0][0]; + const double var_9 = var_8 + x[1][0]; + const double var_10 = x[1][1] + var_6; + const double var_11 = x[2][0] + var_8; + const double var_12 = -1.0000000000000000000000000*var_10*var_11 + var_7*var_9; + const double var_13 = std::abs(var_12); + const double var_14 = w[1][2]*w[2][2]; + const double var_15 = var_14*w[0][2]; + const double var_16 = var_2*w[0][1]; + const double var_17 = w[1][1]*w[2][2] + w[1][2]*w[2][1]; + const double var_18 = var_17*w[0][0]; + const double var_19 = var_16 + var_18; + const double var_20 = w[1][0]*w[2][1] + w[1][1]*w[2][0]; + const double var_21 = var_20*w[0][2]; + const double var_22 = var_19 + var_21; + const double var_23 = 0.0666666666666666657414808*var_22; + const double var_24 = var_15 + var_23; + const double var_25 = w[1][5]*w[2][1] + w[1][1]*w[2][5]; + const double var_26 = w[1][0]*w[2][5] + w[1][5]*w[2][0]; + const double var_27 = var_25*w[0][0] + var_26*w[0][1]; + const double var_28 = var_20*w[0][5] + var_27; + const double var_29 = -0.0010101010101010101001340*var_28; + const double var_30 = w[1][5]*w[2][5]; + const double var_31 = w[1][5]*w[2][4] + w[1][4]*w[2][5]; + const double var_32 = w[1][3]*w[2][4] + w[1][4]*w[2][3]; + const double var_33 = w[1][5]*w[2][3] + w[1][3]*w[2][5]; + const double var_34 = var_33*w[0][4] + var_31*w[0][3] + var_32*w[0][5]; + const double var_35 = 4.0000000000000000000000000*var_34; + const double var_36 = -1.0000000000000000000000000*var_35; + const double var_37 = -0.3333333333333333148296163*var_14*w[0][5] + var_36 + var_30*w[0][2]; + const double var_38 = 0.0121212121212121212016077*var_37 + var_29 + -0.0075757575757575759678453*var_24; + const double var_39 = w[1][0]*w[2][0]; + const double var_40 = w[1][3]*w[2][3]; + const double var_41 = 0.4000000000000000222044605*var_40; + const double var_42 = var_41 + -0.2500000000000000000000000*var_39; + const double var_43 = w[1][1]*w[2][3] + w[1][3]*w[2][1]; + const double var_44 = w[1][2]*w[2][3] + w[1][3]*w[2][2]; + const double var_45 = var_44*w[0][1] + var_43*w[0][2]; + const double var_46 = var_45 + var_17*w[0][3]; + const double var_47 = -0.0010101010101010101001340*var_46; + const double var_48 = -0.0040404040404040404005359*var_39*w[0][3] + var_47 + 0.0303030303030303038713811*var_42*w[0][0]; + const double var_49 = w[1][3]*w[2][0] + w[1][0]*w[2][3]; + const double var_50 = w[1][2]*w[2][5] + w[1][5]*w[2][2]; + const double var_51 = w[0][3] + w[0][5]; + const double var_52 = var_26*w[0][2]; + const double var_53 = var_44*w[0][0]; + const double var_54 = var_49*w[0][2] + var_2*var_51 + var_52 + var_53 + var_50*w[0][0]; + const double var_55 = var_20 + var_17; + const double var_56 = var_54 + -1.0000000000000000000000000*var_55*w[0][4]; + const double var_57 = w[1][1]*w[2][1]; + const double var_58 = w[1][0]*w[2][4] + w[1][4]*w[2][0]; + const double var_59 = w[1][2]*w[2][4] + w[1][4]*w[2][2]; + const double var_60 = var_58 + var_59; + const double var_61 = var_32 + var_31; + const double var_62 = var_30 + var_40; + const double var_63 = 0.4000000000000000222044605*var_1; + const double var_64 = 0.2222222222222222098864108*var_61 + -0.0666666666666666657414808*var_0 + 0.0833333333333333287074041*var_57 + -0.0083333333333333332176851*var_55 + 0.2666666666666666629659233*var_62 + var_63 + -0.0222222222222222230703093*var_60; + const double var_65 = var_39 + var_14; + const double var_66 = 0.0027777777777777778837887*var_65 + 0.0909090909090909116141432*var_64; + const double var_67 = w[0][2] + w[0][0]; + const double var_68 = var_58*w[0][2] + var_59*w[0][0]; + const double var_69 = var_2*w[0][4] + var_68; + const double var_70 = var_43 + var_25; + const double var_71 = 0.6666666666666666296592325*var_70 + -0.2000000000000000111022302*var_57 + -8.5333333333333332149095440*w[1][4]*w[2][4]; + const double var_72 = 0.1250000000000000000000000*w[1][0]*w[2][0]; + const double var_73 = 0.0303030303030303038713811*var_72 + -0.0242424242424242424032155*var_40 + 0.0083333333333333332176851*var_17 + 0.0363636363636363618700997*var_31; + const double var_74 = 0.1250000000000000000000000*w[1][2]*w[2][2]; + const double var_75 = 0.0363636363636363618700997*var_32 + -0.0242424242424242424032155*var_30 + 0.0083333333333333332176851*var_20 + 0.0303030303030303038713811*var_74; + const double var_76 = 0.6666666666666666296592325*w[0][5]; + const double var_77 = var_76 + w[0][3]; + const double var_78 = 0.6666666666666666296592325*w[0][3]; + const double var_79 = w[0][5] + var_78; + const double var_80 = var_43*var_77 + var_25*var_79; + const double var_81 = w[0][4] + var_78; + const double var_82 = w[0][4] + var_76; + const double var_83 = 0.6666666666666666296592325*w[0][4]; + const double var_84 = var_83 + w[0][3]; + const double var_85 = -1.0000000000000000000000000*w[0][0]; + const double var_86 = var_84 + var_85; + const double var_87 = var_83 + w[0][5]; + const double var_88 = -1.0000000000000000000000000*w[0][2]; + const double var_89 = var_88 + var_87; + const double var_90 = w[0][4] + w[0][5]; + const double var_91 = w[0][2] + w[0][1]; + const double var_92 = -0.3333333333333333148296163*var_91; + const double var_93 = var_92 + var_90; + const double var_94 = w[0][4] + w[0][3]; + const double var_95 = w[0][0] + w[0][1]; + const double var_96 = -0.3333333333333333148296163*var_95; + const double var_97 = var_96 + var_94; + const double var_98 = var_39 + 8.0000000000000000000000000*var_31; + const double var_99 = -8.0000000000000000000000000*var_51 + var_67 + 4.0000000000000000000000000*w[0][1]; + const double var_100 = -1.0000000000000000000000000*var_20; + const double var_101 = var_50 + var_100 + -8.0000000000000000000000000*var_30; + const double var_102 = var_101 + var_26; + const double var_103 = -1.0000000000000000000000000*var_17; + const double var_104 = var_103 + -8.0000000000000000000000000*var_40 + var_49; + const double var_105 = var_44 + var_104; + const double var_106 = w[0][5] + w[0][0]; + const double var_107 = w[0][2] + w[0][3]; + const double var_108 = var_90*w[1][5]*w[2][5] + var_94*w[1][3]*w[2][3]; + const double var_109 = -8.0000000000000000000000000*var_108 + -1.0000000000000000000000000*var_107*var_44 + var_67*w[1][4]*w[2][4] + -1.0000000000000000000000000*var_106*var_26; + const double var_110 = var_25*w[0][2]; + const double var_111 = var_43*w[0][0]; + const double var_112 = var_110 + var_111; + const double var_113 = var_102*w[0][3] + 2.0000000000000000000000000*var_109 + -1.0000000000000000000000000*var_112 + var_33*var_99 + var_105*w[0][5]; + const double var_114 = 8.0000000000000000000000000*var_32 + var_14; + const double var_115 = var_49*var_97 + var_59*var_89 + -1.0000000000000000000000000*var_114*var_81 + -1.0000000000000000000000000*var_82*var_98 + var_58*var_86 + -8.0000000000000000000000000*var_1*var_51 + var_50*var_93 + 0.3333333333333333148296163*var_113; + const double var_116 = 0.1250000000000000000000000*w[1][1]*w[2][1]; + const double var_117 = var_116 + 0.3333333333333333148296163*var_0; + const double var_118 = 0.0037878787878787879839226*var_2*var_67 + var_75*w[0][0] + 0.0727272727272727237401995*var_80 + 0.0363636363636363618700997*var_115 + -0.0181818181818181809350499*var_117*var_67 + 0.0151515151515151519356905*var_69 + var_73*w[0][2] + 0.0909090909090909116141432*var_71*w[0][4] + 0.0606060606060606077427622*var_0*var_51; + const double var_119 = 0.0363636363636363618700997*var_0*w[0][4] + 0.3333333333333333148296163*var_118 + 0.0020202020202020202002680*var_56 + var_48 + var_38 + var_66*w[0][1]; + A[10] = 0.0095238095238095246686250*var_119*var_13; + const double var_120 = var_43*w[0][1]; + const double var_121 = var_1*w[0][5] + var_30*w[0][4]; + const double var_122 = var_2 + var_17; + const double var_123 = 2.0000000000000000000000000*var_50 + -1.0000000000000000000000000*var_122; + const double var_124 = var_58*w[0][0]; + const double var_125 = 0.5000000000000000000000000*w[0][3] + -0.0500000000000000027755576*w[0][0] + 0.2000000000000000111022302*var_90 + 0.1250000000000000000000000*var_91; + const double var_126 = 1.3333333333333332593184650*var_32 + 3.2500000000000000000000000*w[1][2]*w[2][2] + 0.6666666666666666296592325*var_30; + const double var_127 = var_50 + -1.6000000000000000888178420*var_32; + const double var_128 = 0.6666666666666666296592325*var_127*w[0][5] + 0.0416666666666666643537020*var_19 + 0.0666666666666666657414808*var_27 + var_126*w[0][2]; + const double var_129 = var_59*w[0][2]; + const double var_130 = var_14*w[0][4] + var_129; + const double var_131 = -2.1333333333333333037273860*w[0][3] + 0.1666666666666666574148081*w[0][0] + -0.2666666666666666629659233*var_90 + -0.4000000000000000222044605*var_91; + const double var_132 = var_32 + var_33; + const double var_133 = var_57 + var_14; + const double var_134 = var_50 + var_0; + const double var_135 = 32.0000000000000000000000000*w[1][3]*w[2][3]; + const double var_136 = 0.0333333333333333328707404*var_134 + 0.5000000000000000000000000*var_133 + 0.0666666666666666657414808*var_135 + 0.2666666666666666629659233*var_132 + 0.0166666666666666664353702*w[1][0]*w[2][0]; + const double var_137 = 0.1666666666666666574148081*var_49 + -1.0000000000000000000000000*var_136; + const double var_138 = var_137 + 0.2416666666666666685170384*var_17; + const double var_139 = var_39*w[0][3] + var_49*w[0][0]; + const double var_140 = 0.2666666666666666629659233*var_40*w[0][0] + -0.0250000000000000013877788*w[0][0]*w[1][0]*w[2][0] + -0.0666666666666666657414808*var_139; + const double var_141 = var_79 + var_88; + const double var_142 = 2.0000000000000000000000000*w[0][5] + -1.0000000000000000000000000*var_95; + const double var_143 = -0.3333333333333333148296163*var_67; + const double var_144 = var_51 + var_143; + const double var_145 = var_25 + var_26; + const double var_146 = -4.0000000000000000000000000*var_30 + 0.3333333333333333148296163*var_145; + const double var_147 = 4.0000000000000000000000000*w[0][2] + var_95 + -8.0000000000000000000000000*var_94; + const double var_148 = 0.3333333333333333148296163*var_147 + -4.0000000000000000000000000*w[0][5]; + const double var_149 = w[0][4] + w[0][2]; + const double var_150 = w[0][5] + -2.0000000000000000000000000*var_149; + const double var_151 = w[0][3] + w[0][1]; + const double var_152 = var_151*var_25 + var_0*var_107; + const double var_153 = -2.0000000000000000000000000*var_152 + var_5 + var_150*var_58; + const double var_154 = var_148*var_31 + var_123*var_84 + var_141*var_49 + var_146*w[0][4] + -1.0000000000000000000000000*var_57*var_77 + 0.3333333333333333148296163*var_153 + var_142*var_44 + -8.0000000000000000000000000*var_30*var_79 + var_144*var_26; + const double var_155 = 2.0000000000000000000000000*var_51; + const double var_156 = w[0][4] + var_155; + const double var_157 = 1.0666666666666666518636930*var_156*var_33 + 0.0333333333333333328707404*var_57*w[0][4]; + const double var_158 = -1.0000000000000000000000000*var_157; + const double var_159 = 0.4000000000000000222044605*var_30; + const double var_160 = -0.1333333333333333314829616*var_50 + var_159 + -0.2500000000000000000000000*var_14; + const double var_161 = -0.2666666666666666629659233*w[1][4]*w[2][4] + 0.0666666666666666657414808*var_0 + 0.4000000000000000222044605*var_33; + const double var_162 = 0.0416666666666666643537020*var_57 + var_161; + const double var_163 = var_160 + var_162; + const double var_164 = var_44*w[0][2]; + const double var_165 = var_14*w[0][3] + var_164; + const double var_166 = 2.0000000000000000000000000*var_44*w[0][3]; + const double var_167 = var_165 + var_166; + const double var_168 = 0.2500000000000000000000000*var_3 + 1.3333333333333332593184650*var_1 + 0.2416666666666666685170384*w[1][1]*w[2][1] + 0.8000000000000000444089210*var_33; + const double var_169 = 4.0000000000000000000000000*var_40 + -0.5000000000000000000000000*var_17; + const double var_170 = var_168 + var_169; + const double var_171 = 0.2000000000000000111022302*var_142 + var_94; + const double var_172 = var_44*w[0][4]; + const double var_173 = var_171*var_59 + var_172; + const double var_174 = 0.5000000000000000000000000*var_17 + 2.0000000000000000000000000*var_39 + var_135; + const double var_175 = var_58*w[0][1]; + const double var_176 = var_39*w[0][4] + var_124; + const double var_177 = var_110 + var_176; + const double var_178 = var_175 + -0.5000000000000000000000000*var_177 + -1.0000000000000000000000000*var_174*w[0][5]; + const double var_179 = var_131*var_43 + 2.0000000000000000000000000*var_167 + 0.4000000000000000222044605*var_154 + var_140 + var_158 + var_130 + 1.3333333333333332593184650*var_173 + 0.0666666666666666657414808*var_178 + var_163*w[0][0] + 0.3333333333333333148296163*var_125*var_20 + var_128 + var_170*w[0][2] + var_138*w[0][1]; + const double var_180 = var_2*w[0][0] + w[0][2]*w[1][0]*w[2][0]; + A[15] = 0.0002886002886002886000383*var_13*var_179 + 0.0000264550264550264561329*var_13*var_180; + A[20] = A[15]; + const double var_181 = var_26*w[0][0]; + const double var_182 = -0.0242424242424242424032155*var_1 + 0.0083333333333333332176851*var_2 + 0.0303030303030303038713811*var_116 + 0.0363636363636363618700997*var_33; + const double var_183 = -1.0000000000000000000000000*var_30*var_95; + const double var_184 = -0.2000000000000000111022302*var_91; + const double var_185 = var_184 + w[0][0]; + const double var_186 = -1.0000000000000000000000000*var_151*var_43 + var_95*w[1][5]*w[2][5]; + const double var_187 = var_1 + var_40; + const double var_188 = -1.0000000000000000000000000*var_58*w[0][3]; + const double var_189 = var_59*w[0][5]; + const double var_190 = var_188 + -1.0000000000000000000000000*var_31*w[0][2] + -1.0000000000000000000000000*var_32*w[0][0] + -1.0000000000000000000000000*var_189; + const double var_191 = -1.0000000000000000000000000*var_69; + const double var_192 = var_34 + -1.0000000000000000000000000*var_0*w[0][4]; + const double var_193 = -1.0000000000000000000000000*var_50*var_90 + var_191 + -1.0000000000000000000000000*var_49*var_94 + 4.0000000000000000000000000*var_192 + -1.0000000000000000000000000*var_91*w[1][5]*w[2][5] + -1.0000000000000000000000000*var_95*w[1][3]*w[2][3] + var_190; + const double var_194 = var_61 + var_33; + const double var_195 = var_25 + var_59; + const double var_196 = var_42 + -0.1333333333333333314829616*var_49; + const double var_197 = var_184 + 0.3333333333333333148296163*var_90; + const double var_198 = 0.1666666666666666574148081*var_197 + -0.0222222222222222230703093*w[0][3] + 0.1000000000000000055511151*w[0][0]; + const double var_199 = -0.2000000000000000111022302*var_95 + 0.3333333333333333148296163*var_94; + const double var_200 = 0.1000000000000000055511151*w[0][2] + 0.1666666666666666574148081*var_199 + -0.0222222222222222230703093*w[0][5]; + const double var_201 = var_60*w[0][1] + var_0*var_67; + const double var_202 = var_181 + var_39*w[0][5]; + const double var_203 = var_165 + var_202; + const double var_204 = -0.3333333333333333148296163*var_203 + 0.1000000000000000055511151*var_2*var_67 + -0.0333333333333333328707404*var_16 + var_17*var_200 + 0.0555555555555555524716027*var_201 + var_198*var_20; + const double var_205 = -1.0000000000000000000000000*w[0][1]; + const double var_206 = var_205 + var_81; + const double var_207 = -1.0000000000000000000000000*var_43*w[0][4]; + const double var_208 = -1.0000000000000000000000000*var_49*w[0][4] + -1.0000000000000000000000000*var_32*var_95 + -1.0000000000000000000000000*var_0*w[0][3] + var_188 + var_207; + const double var_209 = var_208 + var_34; + const double var_210 = 0.3333333333333333148296163*var_209 + var_183 + var_206*var_40 + var_1*var_86; + const double var_211 = var_50*w[0][2] + var_14*w[0][5]; + const double var_212 = -0.2000000000000000111022302*w[0][2] + 1.3333333333333332593184650*w[0][5]; + const double var_213 = 16.0000000000000000000000000*var_212*var_30 + 0.6666666666666666296592325*var_211 + -0.2666666666666666629659233*var_28 + var_23; + const double var_214 = var_0*w[0][1] + var_57*w[0][4]; + const double var_215 = 1.3333333333333332593184650*w[0][4] + -0.2000000000000000111022302*w[0][1]; + const double var_216 = 16.0000000000000000000000000*var_1*var_215 + 0.6666666666666666296592325*var_214 + -0.2666666666666666629659233*var_69; + const double var_217 = var_2 + var_20; + const double var_218 = var_58 + var_26; + const double var_219 = 1.3333333333333332593184650*var_218 + var_39 + -1.6000000000000000888178420*w[1][3]*w[2][3] + -0.0333333333333333328707404*var_133 + -0.2666666666666666629659233*var_217; + const double var_220 = 32.0000000000000000000000000*w[1][4]*w[2][4]; + const double var_221 = 2.0000000000000000000000000*var_57 + 0.5000000000000000000000000*var_2 + var_220; + const double var_222 = 32.0000000000000000000000000*w[1][5]*w[2][5]; + const double var_223 = var_222 + 0.5000000000000000000000000*var_20 + 2.0000000000000000000000000*var_14; + const double var_224 = -1.0000000000000000000000000*var_223*w[0][1] + -1.0000000000000000000000000*var_221*w[0][2]; + const double var_225 = var_59*w[0][1]; + const double var_226 = var_50*w[0][1] + var_17*var_90 + var_0*w[0][2] + var_110 + var_225; + const double var_227 = var_44*w[0][5]; + const double var_228 = -1.0000000000000000000000000*var_32*w[0][1] + -1.0000000000000000000000000*var_33*w[0][2] + -1.0000000000000000000000000*var_227 + var_207; + const double var_229 = var_25*w[0][1]; + const double var_230 = var_229 + var_57*w[0][5]; + const double var_231 = var_130 + var_230; + const double var_232 = var_49 + var_0; + const double var_233 = var_50 + var_232; + const double var_234 = var_30 + var_187; + const double var_235 = var_217 + var_17; + const double var_236 = var_57 + var_39; + const double var_237 = var_236 + var_14; + const double var_238 = 0.3333333333333333148296163*var_235 + 1.3333333333333332593184650*var_237 + 21.3333333333333321490954404*var_234 + -4.0000000000000000000000000*var_233; + const double var_239 = var_60 + var_145; + const double var_240 = 16.0000000000000000000000000*var_31 + var_238 + -2.6666666666666665186369300*var_239; + const double var_241 = -1.0000000000000000000000000*var_50*var_87 + -1.0000000000000000000000000*var_0*var_82; + const double var_242 = 2.0000000000000000000000000*var_94; + const double var_243 = var_242 + var_96; + const double var_244 = 2.6666666666666665186369300*w[0][5] + var_243; + const double var_245 = var_155 + var_143; + const double var_246 = 2.6666666666666665186369300*w[0][4] + var_245; + const double var_247 = 2.0000000000000000000000000*var_90; + const double var_248 = var_92 + var_247; + const double var_249 = var_246*var_32 + var_241 + var_244*var_33 + var_248*var_40 + -0.6666666666666666296592325*var_195*var_90; + const double var_250 = 4.0000000000000000000000000*w[0][0] + -8.0000000000000000000000000*var_90 + var_91; + const double var_251 = -1.0000000000000000000000000*var_17*var_91; + const double var_252 = var_250*var_49 + var_43*var_99 + var_251 + var_147*var_44 + -2.0000000000000000000000000*var_91*var_98; + const double var_253 = 4.0000000000000000000000000*var_228 + var_240*w[0][3] + 2.0000000000000000000000000*var_231 + 0.3333333333333333148296163*var_252 + 8.0000000000000000000000000*var_249 + var_226; + const double var_254 = var_216 + 1.3333333333333332593184650*var_90*var_98 + var_213 + 0.0666666666666666657414808*var_224 + var_219*w[0][0] + 0.4000000000000000222044605*var_253 + 10.6666666666666660745477202*var_121; + const double var_255 = -1.0000000000000000000000000*var_217; + const double var_256 = 2.0000000000000000000000000*var_49 + var_255; + const double var_257 = -1.0000000000000000000000000*var_46; + const double var_258 = -1.0000000000000000000000000*var_50*var_51 + -4.0000000000000000000000000*var_49*w[0][3] + var_228 + var_257 + -1.0000000000000000000000000*var_0*var_94 + -1.0000000000000000000000000*var_95*w[1][4]*w[2][4] + -1.0000000000000000000000000*var_67*w[1][5]*w[2][5]; + const double var_259 = -0.6666666666666666296592325*var_33*var_67 + -1.0000000000000000000000000*var_50*var_79 + -1.0000000000000000000000000*var_49*var_77; + const double var_260 = var_248 + 2.6666666666666665186369300*w[0][3]; + const double var_261 = var_1*var_245 + var_260*var_32 + var_244*var_31 + var_259 + 2.0000000000000000000000000*var_33*w[0][4]; + const double var_262 = 2.0000000000000000000000000*w[0][4] + -1.0000000000000000000000000*var_67; + const double var_263 = 2.0000000000000000000000000*var_0 + -1.0000000000000000000000000*var_55; + const double var_264 = 0.3333333333333333148296163*var_60 + -4.0000000000000000000000000*var_1; + const double var_265 = -4.0000000000000000000000000*w[0][4] + 0.3333333333333333148296163*var_99; + const double var_266 = w[0][5] + w[0][1]; + const double var_267 = var_26*var_266 + var_151*var_50 + var_107*var_59; + const double var_268 = var_262*var_43 + -1.0000000000000000000000000*var_14*var_84 + -8.0000000000000000000000000*var_1*var_81 + -0.6666666666666666296592325*var_267 + var_58*var_97 + var_263*var_77 + var_264*w[0][5] + var_206*var_49 + var_265*var_31 + 0.3333333333333333148296163*var_102*w[0][4]; + const double var_269 = var_59*w[0][3]; + const double var_270 = var_269 + var_32*w[0][2] + var_172; + const double var_271 = var_77 + var_85; + const double var_272 = var_205 + var_82; + const double var_273 = var_1*w[0][3] + var_32*var_94 + var_40*w[0][4]; + const double var_274 = var_26*w[0][3]; + const double var_275 = var_25*w[0][4]; + const double var_276 = -1.0000000000000000000000000*var_33*w[0][0] + -1.0000000000000000000000000*var_275 + -1.0000000000000000000000000*var_274 + -1.0000000000000000000000000*var_31*w[0][1]; + const double var_277 = -1.0000000000000000000000000*var_28; + const double var_278 = var_276 + -1.0000000000000000000000000*var_0*var_90 + -1.0000000000000000000000000*var_67*w[1][3]*w[2][3] + var_277 + -4.0000000000000000000000000*var_50*w[0][5] + -1.0000000000000000000000000*var_91*w[1][4]*w[2][4] + -1.0000000000000000000000000*var_49*var_51; + const double var_279 = -1.0000000000000000000000000*var_20*var_95; + const double var_280 = var_225 + var_53; + const double var_281 = var_280 + var_232*w[0][2]; + const double var_282 = var_50*var_94 + var_44*var_79 + var_59*var_87; + const double var_283 = var_111 + var_49*w[0][1] + var_20*var_94 + var_175 + var_0*w[0][0]; + const double var_284 = var_145*w[0][2] + var_50*var_95; + const double var_285 = 4.0000000000000000000000000*var_208 + -1.0000000000000000000000000*var_283 + var_284; + const double var_286 = 0.6666666666666666296592325*var_285 + 5.3333333333333330372738601*var_278 + var_17*var_272 + var_279 + 16.0000000000000000000000000*var_273 + -8.0000000000000000000000000*var_282 + -4.0000000000000000000000000*var_270 + var_2*var_271 + var_281; + const double var_287 = -0.0666666666666666657414808*var_217 + -0.2000000000000000111022302*var_39 + 0.6666666666666666296592325*var_218 + -8.5333333333333332149095440*w[1][3]*w[2][3]; + const double var_288 = var_58*var_82 + var_26*var_87; + const double var_289 = var_101 + var_25; + const double var_290 = var_51*w[1][5]*w[2][5] + var_94*w[1][4]*w[2][4]; + const double var_291 = var_91*w[1][3]*w[2][3] + -1.0000000000000000000000000*var_25*var_266; + const double var_292 = var_175 + var_52; + const double var_293 = -1.0000000000000000000000000*var_292 + 2.0000000000000000000000000*var_291 + -16.0000000000000000000000000*var_290 + var_250*var_31 + var_5 + var_289*w[0][4] + var_150*var_59; + const double var_294 = var_57 + 8.0000000000000000000000000*var_33; + const double var_295 = -1.0000000000000000000000000*var_114*var_84 + var_0*var_97 + var_206*var_43 + var_141*var_44 + -8.0000000000000000000000000*var_40*var_90 + 0.3333333333333333148296163*var_293 + -1.0000000000000000000000000*var_294*var_77 + var_144*var_50; + const double var_296 = var_75*w[0][1] + 0.0363636363636363618700997*var_295 + 0.0037878787878787879839226*var_17*var_91 + 0.0606060606060606077427622*var_49*var_90 + 0.0151515151515151519356905*var_46 + 0.0727272727272727237401995*var_288 + 0.0909090909090909116141432*var_287*w[0][3] + 0.0060606060606060606008039*var_226 + var_182*w[0][2]; + const double var_297 = var_58*w[0][5]; + const double var_298 = var_26*w[0][4]; + const double var_299 = var_31*w[0][0] + var_298 + var_297; + const double var_300 = var_292 + var_134*w[0][0]; + const double var_301 = var_26*var_77 + var_49*var_90 + var_58*var_84; + const double var_302 = var_31*var_90 + var_121; + const double var_303 = var_189 + var_275 + var_50*w[0][4] + var_31*var_91 + var_0*w[0][5]; + const double var_304 = var_44 + var_43; + const double var_305 = var_304*w[0][0] + var_49*var_91; + const double var_306 = var_305 + -1.0000000000000000000000000*var_226 + 8.0000000000000000000000000*var_258 + -4.0000000000000000000000000*var_303; + const double var_307 = 16.0000000000000000000000000*var_302 + var_251 + var_141*var_2 + -4.0000000000000000000000000*var_299 + var_300 + var_20*var_206 + 0.6666666666666666296592325*var_306 + -8.0000000000000000000000000*var_301; + const double var_308 = -1.0000000000000000000000000*var_134*w[0][3] + var_228; + const double var_309 = 0.3333333333333333148296163*var_308 + var_241 + -1.0000000000000000000000000*var_59*var_82 + -1.0000000000000000000000000*var_25*var_87; + const double var_310 = 2.0000000000000000000000000*var_59*w[0][4]; + const double var_311 = 0.2500000000000000000000000*var_103 + 1.3333333333333332593184650*var_40 + 0.2416666666666666685170384*w[1][0]*w[2][0] + 0.8000000000000000444089210*var_31; + const double var_312 = -0.5000000000000000000000000*var_2 + 4.0000000000000000000000000*var_1; + const double var_313 = var_312 + var_311; + const double var_314 = 3.2500000000000000000000000*var_70 + -0.2000000000000000111022302*var_1 + 0.2500000000000000000000000*var_0; + const double var_315 = 2.0000000000000000000000000*w[0][3] + -1.0000000000000000000000000*var_91; + const double var_316 = -0.2500000000000000000000000*var_57 + var_63; + const double var_317 = -0.0010101010101010101001340*var_69; + const double var_318 = var_317 + 0.0303030303030303038713811*var_316*w[0][1] + -0.0040404040404040404005359*var_57*w[0][4]; + const double var_319 = var_44 + var_59; + const double var_320 = 0.6666666666666666296592325*var_319 + -8.5333333333333332149095440*w[1][5]*w[2][5] + -0.2000000000000000111022302*var_14; + const double var_321 = -0.0666666666666666657414808*var_122 + var_320; + const double var_322 = var_31 + var_33; + const double var_323 = 0.0833333333333333287074041*var_14 + 0.2666666666666666629659233*var_187 + 0.2222222222222222098864108*var_322 + -0.0222222222222222230703093*var_145 + var_159 + -0.0666666666666666657414808*var_50 + -0.0083333333333333332176851*var_122; + const double var_324 = 0.0909090909090909116141432*var_323 + 0.0027777777777777778837887*var_236; + const double var_325 = var_44*var_84 + var_59*var_81; + const double var_326 = 0.3333333333333333148296163*var_4*w[0][3] + -1.0000000000000000000000000*var_57*var_79; + const double var_327 = var_43 + var_104; + const double var_328 = w[0][4] + w[0][0]; + const double var_329 = w[0][3] + -2.0000000000000000000000000*var_328; + const double var_330 = var_90*w[1][4]*w[2][4] + var_51*w[1][3]*w[2][3]; + const double var_331 = var_329*var_58 + -1.0000000000000000000000000*var_280 + var_147*var_32 + -16.0000000000000000000000000*var_330 + 2.0000000000000000000000000*var_186 + var_327*w[0][4]; + const double var_332 = var_30*var_94 + var_33*var_79; + const double var_333 = -8.0000000000000000000000000*var_332 + 0.3333333333333333148296163*var_331 + var_326 + var_25*var_272 + var_36 + var_26*var_271 + -1.0000000000000000000000000*var_87*var_98 + var_0*var_93 + var_144*var_49; + const double var_334 = 0.3333333333333333148296163*var_50 + var_74; + const double var_335 = -0.0015151515151515151502010*var_22 + 0.0060606060606060606008039*var_283 + 0.0151515151515151519356905*var_28 + var_182*w[0][0] + 0.0606060606060606077427622*var_50*var_94 + 0.0727272727272727237401995*var_325 + 0.0037878787878787879839226*var_20*var_95 + -0.0181818181818181809350499*var_334*var_95 + 0.0363636363636363618700997*var_333 + var_73*w[0][1]; + const double var_336 = 0.0363636363636363618700997*var_50*w[0][5] + var_48 + 0.3333333333333333148296163*var_335 + var_324*w[0][2] + var_318 + 0.0303030303030303038713811*var_321*w[0][5]; + A[17] = 0.0095238095238095246686250*var_13*var_336; + A[32] = A[17]; + const double var_337 = var_130 + var_111; + const double var_338 = var_225 + -1.0000000000000000000000000*var_223*w[0][3] + -0.5000000000000000000000000*var_337; + const double var_339 = 0.3333333333333333148296163*var_304 + -4.0000000000000000000000000*var_40; + const double var_340 = -0.2000000000000000111022302*var_67; + const double var_341 = 0.3333333333333333148296163*var_51 + var_340; + const double var_342 = -0.0222222222222222230703093*w[0][4] + 0.1666666666666666574148081*var_341 + 0.1000000000000000055511151*w[0][1]; + const double var_343 = -0.3333333333333333148296163*var_231 + 0.1000000000000000055511151*var_17*var_91 + var_2*var_200 + var_20*var_342 + 0.0555555555555555524716027*var_305; + const double var_344 = 0.6666666666666666296592325*var_40 + 3.2500000000000000000000000*w[1][0]*w[2][0] + 1.3333333333333332593184650*var_31; + const double var_345 = -0.0303030303030303038713811*w[0][0] + 0.1111111111111111049432054*var_90 + 0.0909090909090909116141432*var_91; + const double var_346 = 0.1111111111111111049432054*var_51 + 0.0909090909090909116141432*var_67 + -0.0303030303030303038713811*w[0][1]; + const double var_347 = var_181 + var_229; + const double var_348 = var_346*w[1][0]*w[2][0] + 0.1111111111111111049432054*var_347 + var_345*w[1][1]*w[2][1]; + const double var_349 = var_106*var_58 + var_151*var_44 + var_266*var_49; + const double var_350 = var_106*var_25 + var_149*var_44 + var_328*var_50; + const double var_351 = var_44 + var_26; + const double var_352 = w[0][0]*w[1][2]*w[2][2] + var_2*w[0][2]; + const double var_353 = 0.0222222222222222230703093*var_40 + 0.2500000000000000000000000*var_39 + 0.0083333333333333332176851*var_49 + 0.0888888888888888922812370*var_31; + const double var_354 = 0.0250000000000000013877788*var_217 + -1.0000000000000000000000000*var_353; + const double var_355 = var_124 + var_129; + const double var_356 = var_1 + var_30; + const double var_357 = -0.0222222222222222230703093*var_304 + 0.2666666666666666629659233*var_356 + 0.0833333333333333287074041*var_39 + var_41 + -0.0083333333333333332176851*var_217 + 0.2222222222222222098864108*var_132 + -0.0666666666666666657414808*var_49; + const double var_358 = var_50 + var_49; + const double var_359 = var_190 + -1.0000000000000000000000000*var_358*w[0][4]; + const double var_360 = 0.3333333333333333148296163*var_359 + -1.0000000000000000000000000*var_44*var_77 + var_259 + -1.0000000000000000000000000*var_26*var_79; + const double var_361 = 0.2000000000000000111022302*var_51 + 0.5000000000000000000000000*w[0][4] + 0.1250000000000000000000000*var_67 + -0.0500000000000000027755576*w[0][1]; + const double var_362 = -1.0666666666666666518636930*var_31*w[0][3]; + const double var_363 = 0.0416666666666666643537020*var_21; + const double var_364 = 0.6666666666666666296592325*var_49*w[0][3] + 0.0416666666666666643537020*var_16 + var_362 + var_363 + var_344*w[0][0] + 0.0666666666666666657414808*var_45; + const double var_365 = -2.1333333333333333037273860*w[0][4] + -0.2666666666666666629659233*var_51 + -0.4000000000000000222044605*var_67 + 0.1666666666666666574148081*w[0][1]; + const double var_366 = 0.2666666666666666629659233*var_61 + 0.0666666666666666657414808*var_220 + 0.5000000000000000000000000*var_65 + 0.0166666666666666664353702*w[1][1]*w[2][1] + 0.0333333333333333328707404*var_358; + const double var_367 = -1.0000000000000000000000000*var_366 + 0.1666666666666666574148081*var_0; + const double var_368 = 0.2416666666666666685170384*var_2 + var_367; + const double var_369 = -0.0666666666666666657414808*var_214 + 0.2666666666666666629659233*var_1*w[0][1] + -0.0250000000000000013877788*w[0][1]*w[1][1]*w[2][1]; + const double var_370 = 0.3333333333333333148296163*var_250 + -4.0000000000000000000000000*w[0][3]; + const double var_371 = var_339*w[0][5] + var_33*var_370 + -1.0000000000000000000000000*var_14*var_81 + var_256*var_82 + 0.3333333333333333148296163*var_289*w[0][3] + var_0*var_86 + -0.6666666666666666296592325*var_350 + -8.0000000000000000000000000*var_40*var_84 + var_315*var_58 + var_43*var_97; + const double var_372 = var_58*w[0][4]; + const double var_373 = var_242 + w[0][5]; + const double var_374 = 0.0333333333333333328707404*var_14*w[0][5] + 1.0666666666666666518636930*var_32*var_373; + const double var_375 = -1.0000000000000000000000000*var_374; + const double var_376 = 0.2500000000000000000000000*var_100 + 0.2416666666666666685170384*w[1][2]*w[2][2] + 0.8000000000000000444089210*var_32 + 1.3333333333333332593184650*var_30; + const double var_377 = var_312 + var_376; + const double var_378 = 0.0666666666666666657414808*var_50 + 0.4000000000000000222044605*var_32 + -0.2666666666666666629659233*w[1][5]*w[2][5]; + const double var_379 = var_378 + 0.0416666666666666643537020*var_14; + const double var_380 = var_379 + var_196; + const double var_381 = var_90 + 0.2000000000000000111022302*var_315; + const double var_382 = var_26*var_381 + var_297; + const double var_383 = var_53 + var_230; + const double var_384 = var_110 + -0.5000000000000000000000000*var_383 + -1.0000000000000000000000000*var_221*w[0][3]; + const double var_385 = 1.3333333333333332593184650*var_382 + var_377*w[0][0] + var_364 + var_368*w[0][2] + var_202 + 0.4000000000000000222044605*var_371 + 0.0666666666666666657414808*var_384 + var_380*w[0][1] + 2.0000000000000000000000000*var_176 + 4.0000000000000000000000000*var_372 + var_375 + var_365*var_59 + 0.3333333333333333148296163*var_17*var_361 + var_369; + const double var_386 = w[0][0]*w[1][1]*w[2][1] + var_20*w[0][1]; + A[4] = 0.0000264550264550264561329*var_13*var_386 + 0.0002886002886002886000383*var_13*var_385; + A[24] = A[4]; + const double var_387 = var_33*var_51 + var_40*w[0][5] + var_30*w[0][3]; + const double var_388 = 1.3333333333333332593184650*w[0][3] + -0.2000000000000000111022302*w[0][0]; + const double var_389 = -0.2666666666666666629659233*var_46 + 0.6666666666666666296592325*var_139 + 16.0000000000000000000000000*var_388*var_40; + const double var_390 = var_57 + 1.3333333333333332593184650*var_70 + -0.0333333333333333328707404*var_65 + -1.6000000000000000888178420*w[1][4]*w[2][4]; + const double var_391 = var_51*var_57; + const double var_392 = -1.0000000000000000000000000*var_223*w[0][0] + -1.0000000000000000000000000*var_174*w[0][2]; + const double var_393 = -2.6666666666666665186369300*var_304 + var_238; + const double var_394 = -1.0000000000000000000000000*var_55*w[0][1] + -1.0000000000000000000000000*var_57*var_67; + const double var_395 = -1.0000000000000000000000000*var_2*var_67; + const double var_396 = var_147*var_59 + var_0*var_99 + var_395 + 2.0000000000000000000000000*var_394 + -16.0000000000000000000000000*var_351*var_51 + var_250*var_58 + -8.0000000000000000000000000*var_145*w[0][4]; + const double var_397 = 2.0000000000000000000000000*var_203 + 8.0000000000000000000000000*var_261 + 0.3333333333333333148296163*var_396 + var_393*w[0][4] + var_54 + 4.0000000000000000000000000*var_190; + const double var_398 = 10.6666666666666660745477202*var_387 + 1.3333333333333332593184650*var_391 + var_213 + var_389 + 0.4000000000000000222044605*var_397 + 0.0666666666666666657414808*var_392 + var_390*w[0][1]; + A[23] = 0.0002886002886002886000383*var_13*var_398; + A[33] = A[23]; + const double var_399 = var_266*var_43 + var_0*var_106; + const double var_400 = var_20*w[0][0] + w[0][1]*w[1][0]*w[2][0]; + const double var_401 = var_58 + var_43; + const double var_402 = w[0][1] + var_340; + const double var_403 = var_25*w[0][5]; + const double var_404 = var_43*w[0][3]; + const double var_405 = var_404 + var_403 + 0.2000000000000000111022302*var_360 + var_402*var_62; + const double var_406 = -0.0500000000000000027755576*w[0][2] + 0.5000000000000000000000000*w[0][5] + 0.1250000000000000000000000*var_95 + 0.2000000000000000111022302*var_94; + const double var_407 = 0.1666666666666666574148081*w[0][2] + -2.1333333333333333037273860*w[0][5] + -0.4000000000000000222044605*var_95 + -0.2666666666666666629659233*var_94; + const double var_408 = 0.2666666666666666629659233*var_322 + 0.0166666666666666664353702*w[1][2]*w[2][2] + 0.0666666666666666657414808*var_222 + 0.5000000000000000000000000*var_236 + 0.0333333333333333328707404*var_232; + const double var_409 = 0.1666666666666666574148081*var_50 + -1.0000000000000000000000000*var_408; + const double var_410 = var_409 + 0.2416666666666666685170384*var_20; + const double var_411 = -0.0250000000000000013877788*w[0][2]*w[1][2]*w[2][2] + -0.0666666666666666657414808*var_211 + 0.2666666666666666629659233*var_30*w[0][2]; + const double var_412 = var_32*var_370 + var_326 + var_271*var_50 + 0.3333333333333333148296163*var_329*var_59 + -8.0000000000000000000000000*var_40*var_77 + var_256*var_87 + var_339*w[0][4] + var_26*var_315 + var_144*var_44 + -0.6666666666666666296592325*var_399; + const double var_413 = var_26*w[0][5]; + const double var_414 = var_162 + var_196; + const double var_415 = 4.0000000000000000000000000*var_30 + -0.5000000000000000000000000*var_20; + const double var_416 = var_168 + var_415; + const double var_417 = var_298 + var_381*var_58; + const double var_418 = 0.3333333333333333148296163*var_17*var_406 + var_411 + var_364 + 0.4000000000000000222044605*var_412 + 2.0000000000000000000000000*var_202 + var_158 + 4.0000000000000000000000000*var_413 + 1.3333333333333332593184650*var_417 + var_414*w[0][2] + var_410*w[0][1] + var_25*var_407 + var_416*w[0][0] + 0.0666666666666666657414808*var_338 + var_176; + A[5] = 0.0002886002886002886000383*var_13*var_418 + 0.0000264550264550264561329*var_13*var_352; + const double var_419 = -0.3333333333333333148296163*var_60 + 2.0000000000000000000000000*var_32; + const double var_420 = var_112 + var_358*w[0][1]; + const double var_421 = -0.6666666666666666296592325*var_32*var_95 + -1.0000000000000000000000000*var_0*var_81 + -1.0000000000000000000000000*var_49*var_84; + const double var_422 = var_419*w[0][5] + -0.6666666666666666296592325*var_401*var_94 + var_243*var_30 + var_260*var_33 + var_246*var_31 + var_421; + const double var_423 = var_33*var_67 + var_50*w[0][3] + var_49*w[0][5] + var_227 + var_274; + const double var_424 = 8.0000000000000000000000000*var_193 + -4.0000000000000000000000000*var_423 + var_201 + -1.0000000000000000000000000*var_54; + const double var_425 = 0.0111111111111111115351546*var_22; + const double var_426 = var_425 + 0.1333333333333333314829616*var_402*var_57 + 0.0533333333333333367565210*var_214 + 0.5688888888888888883954564*var_34; + const double var_427 = -1.0000000000000000000000000*var_14*var_95; + const double var_428 = 0.0266666666666666683782605*var_427 + 0.0533333333333333367565210*var_211 + 0.1333333333333333314829616*var_15; + const double var_429 = var_30*var_51 + var_1*var_94 + var_32*w[0][4] + 2.0000000000000000000000000*var_90*w[1][3]*w[2][3] + var_33*w[0][5]; + const double var_430 = var_120 + var_57*w[0][3]; + const double var_431 = var_430 + var_165; + const double var_432 = var_184 + var_247; + const double var_433 = 7.1111111111111107163651468*var_40*w[0][3] + 0.0266666666666666683782605*var_307 + 1.0666666666666666518636930*var_132*var_388 + 0.0666666666666666657414808*var_287*w[0][0] + var_426 + 0.2666666666666666629659233*var_431 + 0.7111111111111111382498962*var_429 + 0.0800000000000000016653345*var_139 + 0.0888888888888888922812370*var_231 + 0.0222222222222222230703093*var_39*var_432 + var_428; + A[21] = 0.0043290043290043290005742*var_13*var_433; + const double var_434 = 0.0222222222222222230703093*var_194 + 0.0555555555555555524716027*var_234 + -0.0055555555555555557675773*var_233; + const double var_435 = var_434 + 0.0250000000000000013877788*var_39 + -0.0083333333333333332176851*var_17 + 0.0138888888888888881179007*var_195; + const double var_436 = var_72 + 0.3333333333333333148296163*var_49; + const double var_437 = 4.0000000000000000000000000*var_32 + var_30; + const double var_438 = 0.0022727272727272726168812*var_14*var_95 + -0.0020202020202020202002680*var_437*w[0][2] + -0.0060606060606060606008039*var_334*w[0][5] + -0.0121212121212121212016077*var_325 + 0.0040404040404040404005359*var_34 + -0.0227272727272727279035358*var_15 + -0.0007575757575757575751005*var_50*w[0][2]; + const double var_439 = -0.0060606060606060606008039*var_436*w[0][3] + -0.0909090909090909116141432*var_353*w[0][0] + 0.0022727272727272726168812*var_39*var_91 + -0.0121212121212121212016077*var_288; + const double var_440 = 0.0250000000000000013877788*var_57 + var_434 + 0.0138888888888888881179007*var_351; + const double var_441 = 0.1000000000000000055511151*var_190 + var_25*var_406 + var_125*var_43 + 0.7250000000000000888178420*var_69; + const double var_442 = -1.0000000000000000000000000*var_1*var_67; + const double var_443 = var_141*var_40 + var_271*var_30 + -0.3333333333333333148296163*var_423 + var_442; + const double var_444 = 0.1250000000000000000000000*var_341*w[1][1]*w[2][1] + var_367*w[0][4] + var_161*var_51 + 0.4000000000000000222044605*var_443 + -0.5000000000000000000000000*var_355; + const double var_445 = 0.0909090909090909116141432*var_440*w[0][1] + 0.0227272727272727279035358*var_204 + 0.0101010101010101018687015*var_441 + 0.0303030303030303038713811*var_444 + var_439 + var_438 + 0.0027777777777777778837887*var_54; + A[2] = 0.0095238095238095246686250*var_13*var_445; + const double var_446 = var_25*w[0][3]; + const double var_447 = var_43*w[0][5]; + const double var_448 = var_447 + var_446 + var_33*w[0][1]; + const double var_449 = var_31*w[0][4] + var_1*var_90 + var_33*w[0][3] + var_40*var_51 + 2.0000000000000000000000000*var_94*w[1][5]*w[2][5]; + const double var_450 = 0.1333333333333333314829616*var_185*var_39 + 0.0533333333333333367565210*var_139; + const double var_451 = -0.0333333333333333328707404*var_39*w[0][3] + -2.1333333333333333037273860*var_31*var_90 + var_362; + const double var_452 = var_107*var_43 + var_149*var_49 + var_26*var_328; + const double var_453 = var_25*var_93 + var_148*var_33 + -0.6666666666666666296592325*var_452 + var_123*var_81 + var_0*var_89 + var_142*var_59 + var_146*w[0][3] + -1.0000000000000000000000000*var_39*var_82 + -8.0000000000000000000000000*var_30*var_87; + const double var_454 = var_310 + var_130; + const double var_455 = 0.0666666666666666657414808*var_49 + 0.4000000000000000222044605*var_31 + -0.2666666666666666629659233*w[1][3]*w[2][3]; + const double var_456 = var_455 + 0.0416666666666666643537020*var_39; + const double var_457 = var_160 + var_456; + const double var_458 = var_269 + var_171*var_44; + const double var_459 = -1.0000000000000000000000000*var_221 + 2.0000000000000000000000000*var_327; + const double var_460 = var_430 + var_52; + const double var_461 = var_459*w[0][5] + -0.5000000000000000000000000*var_460 + var_111; + const double var_462 = 0.4000000000000000222044605*var_453 + 0.0666666666666666657414808*var_461 + var_313*w[0][2] + var_368*w[0][0] + 1.3333333333333332593184650*var_458 + var_165 + 2.0000000000000000000000000*var_454 + var_365*var_58 + 0.3333333333333333148296163*var_20*var_361 + var_457*w[0][1] + var_451 + var_128 + var_369; + const double var_463 = var_17*w[0][1] + w[0][2]*w[1][1]*w[2][1]; + A[16] = 0.0000264550264550264561329*var_13*var_463 + 0.0002886002886002886000383*var_13*var_462; + A[26] = A[16]; + const double var_464 = var_0 + -1.6000000000000000888178420*var_33; + A[30] = A[5]; + const double var_465 = var_1 + 4.0000000000000000000000000*var_33; + const double var_466 = var_205 + 0.1000000000000000055511151*var_67; + const double var_467 = 0.0227272727272727279035358*var_466*var_57 + -0.0121212121212121212016077*var_80 + -0.0060606060606060606008039*var_117*w[0][4] + -0.0020202020202020202002680*var_465*w[0][1] + -0.0007575757575757575751005*var_0*w[0][1]; + const double var_468 = 0.1000000000000000055511151*var_228 + var_26*var_406 + 0.7250000000000000888178420*var_46 + var_361*var_58 + -0.4000000000000000222044605*var_303; + const double var_469 = var_164 + var_120; + const double var_470 = var_272*var_30 + -1.0000000000000000000000000*var_40*var_91 + var_1*var_89; + const double var_471 = 0.4000000000000000222044605*var_470 + 0.1250000000000000000000000*var_197*w[1][0]*w[2][0] + -0.5000000000000000000000000*var_469 + var_137*w[0][3] + var_455*var_90; + const double var_472 = 0.0101010101010101018687015*var_468 + 0.0227272727272727279035358*var_343 + var_467 + 0.0909090909090909116141432*var_435*w[0][0] + 0.0303030303030303038713811*var_471 + 0.0027777777777777778837887*var_226 + var_438; + const double var_473 = -1.0000000000000000000000000*var_221*w[0][0] + -1.0000000000000000000000000*var_174*w[0][1]; + const double var_474 = -0.5000000000000000000000000*var_347 + var_378*var_94 + var_409*w[0][5] + 0.4000000000000000222044605*var_210; + const double var_475 = var_427 + -1.0000000000000000000000000*var_122*w[0][2]; + const double var_476 = 3.2500000000000000000000000*var_319 + 0.2500000000000000000000000*var_50 + -0.2000000000000000111022302*var_30 + 2.0000000000000000000000000*var_187; + const double var_477 = 0.6666666666666666296592325*var_1 + 3.2500000000000000000000000*w[1][1]*w[2][1] + 1.3333333333333332593184650*var_33; + const double var_478 = 0.0416666666666666643537020*var_18 + var_363 + var_477*w[0][1] + 0.0666666666666666657414808*var_68 + 0.6666666666666666296592325*var_464*w[0][4]; + const double var_479 = var_25*var_262 + -1.0000000000000000000000000*var_39*var_87 + var_272*var_50 + -8.0000000000000000000000000*var_1*var_82 + var_263*var_79 + -0.6666666666666666296592325*var_349 + var_265*var_32 + var_59*var_93 + var_264*w[0][3]; + const double var_480 = var_316 + -0.1333333333333333314829616*var_0; + const double var_481 = var_480 + var_456; + const double var_482 = var_415 + var_311; + const double var_483 = var_51 + 0.2000000000000000111022302*var_262; + const double var_484 = var_43*var_483 + var_446; + const double var_485 = 2.0000000000000000000000000*var_105 + -1.0000000000000000000000000*var_223; + const double var_486 = var_175 + var_165; + const double var_487 = var_485*w[0][4] + -0.5000000000000000000000000*var_486 + var_53; + const double var_488 = var_411 + var_482*w[0][1] + 0.3333333333333333148296163*var_2*var_406 + 4.0000000000000000000000000*var_403 + 0.4000000000000000222044605*var_479 + var_478 + 2.0000000000000000000000000*var_230 + var_430 + var_26*var_407 + var_481*w[0][2] + 0.0666666666666666657414808*var_487 + var_410*w[0][0] + var_451 + 1.3333333333333332593184650*var_484; + const double var_489 = w[0][1]*w[1][2]*w[2][2] + var_17*w[0][2]; + A[11] = 0.0002886002886002886000383*var_13*var_488 + 0.0000264550264550264561329*var_13*var_489; + const double var_490 = 1.3333333333333332593184650*var_319 + -0.0333333333333333328707404*var_236 + -1.6000000000000000888178420*w[1][5]*w[2][5]; + const double var_491 = 0.0909090909090909116141432*var_357 + 0.0027777777777777778837887*var_133; + const double var_492 = var_361*var_59 + var_125*var_44 + 0.1000000000000000055511151*var_276; + const double var_493 = var_491*w[0][0] + -0.0060606060606060606008039*var_436*var_91 + 0.0363636363636363618700997*var_49*w[0][3] + 0.3333333333333333148296163*var_296 + var_38 + var_318; + A[3] = 0.0095238095238095246686250*var_13*var_493; + const double var_494 = 2.0000000000000000000000000*var_51*w[1][4]*w[2][4] + var_40*var_94 + var_31*w[0][5] + var_30*var_90 + var_32*w[0][3]; + const double var_495 = var_0*var_51 + var_43*var_81 + var_25*var_82; + const double var_496 = var_420 + var_20*var_86 + -8.0000000000000000000000000*var_495 + var_17*var_89 + 16.0000000000000000000000000*var_387 + var_395 + 0.6666666666666666296592325*var_424 + -4.0000000000000000000000000*var_448; + const double var_497 = var_130 + var_176; + const double var_498 = var_450 + 0.0266666666666666683782605*var_496 + 0.2666666666666666629659233*var_497 + var_425 + 7.1111111111111107163651468*var_1*w[0][4] + 0.0888888888888888922812370*var_203 + 1.0666666666666666518636930*var_215*var_61 + var_428 + 0.0800000000000000016653345*var_214 + 0.0044444444444444444405895*var_394 + 0.7111111111111111382498962*var_494 + 0.0444444444444444461406185*var_391 + 0.0666666666666666657414808*var_71*w[0][1]; + A[28] = 0.0043290043290043290005742*var_13*var_498; + const double var_499 = var_47 + 0.0080808080808080808010718*var_40*w[0][3] + 0.0001851851851851851759895*var_49*w[0][0] + -0.0000673400673400673354914*var_299; + const double var_500 = 0.0080808080808080808010718*var_1*w[0][4] + 0.0001851851851851851759895*var_0*w[0][1] + var_317 + -0.0000673400673400673354914*var_448; + const double var_501 = -1.0000000000000000000000000*var_232*w[0][5] + var_276 + var_35; + const double var_502 = -1.0000000000000000000000000*var_58*var_81 + -1.0000000000000000000000000*var_187*var_95 + 0.3333333333333333148296163*var_501 + -1.0000000000000000000000000*var_43*var_84 + var_421; + const double var_503 = var_124 + var_120; + const double var_504 = var_279 + 9.6666666666666660745477202*var_503 + -1.0000000000000000000000000*var_284; + const double var_505 = 0.0666666666666666657414808*var_183 + 0.4000000000000000222044605*var_502 + var_166 + var_168*w[0][3] + 0.0416666666666666643537020*var_283 + var_270 + var_126*var_94 + var_476*w[0][2] + -0.2500000000000000000000000*var_281 + var_311*w[0][4] + 0.0250000000000000013877788*var_504 + var_310 + 0.0166666666666666664353702*var_277; + const double var_506 = var_122*var_95 + var_21; + const double var_507 = var_499 + 0.0016666666666666667736413*var_348 + 0.0020202020202020202002680*var_505 + 0.0001515151515151515150201*var_506 + var_500 + 0.0227272727272727279035358*var_15 + 0.0015151515151515151502010*var_475 + 0.0060606060606060606008039*var_323*w[0][5]; + A[14] = 0.1428571428571428492126927*var_13*var_507; + const double var_508 = var_29 + 0.0010774410774410773678628*var_34 + 0.0080808080808080808010718*var_30*w[0][5] + -0.0000673400673400673354914*var_270 + 0.0001851851851851851759895*var_50*w[0][2]; + const double var_509 = -0.0022222222222222222202948*var_304 + 0.0066666666666666670945651*var_17 + 0.2888888888888889172612551*var_218 + var_39 + 0.0666666666666666657414808*var_255 + 0.0222222222222222230703093*var_49; + const double var_510 = -0.0303030303030303038713811*w[0][2] + 0.0909090909090909116141432*var_95 + 0.1111111111111111049432054*var_94; + const double var_511 = var_510*w[1][1]*w[2][1] + var_346*w[1][2]*w[2][2]; + const double var_512 = var_413 + var_372 + 0.2000000000000000111022302*var_309 + var_185*var_356; + const double var_513 = var_229 + var_129; + const double var_514 = 0.0416666666666666643537020*var_226 + var_376*w[0][4] + 0.0166666666666666664353702*var_257 + -0.2000000000000000111022302*var_40*w[0][0] + 0.2416666666666666685170384*var_513 + var_344*var_90 + var_168*w[0][5] + 0.0250000000000000013877788*var_251 + var_299 + -0.2500000000000000000000000*var_300 + 2.0000000000000000000000000*var_512; + const double var_515 = 0.3333333333333333148296163*var_514 + var_354*var_91 + var_357*w[0][3]; + const double var_516 = var_508 + 0.0001851851851851851759895*var_469 + var_500 + 0.0060606060606060606008039*var_515 + 0.0227272727272727279035358*var_509*w[0][0] + 0.0016666666666666667736413*var_511; + A[0] = 0.1428571428571428492126927*var_13*var_516; + const double var_517 = var_430 + var_176; + const double var_518 = var_14*var_94; + const double var_519 = var_202 + var_230; + const double var_520 = var_450 + 1.0666666666666666518636930*var_212*var_322 + 7.1111111111111107163651468*var_30*w[0][5] + var_426 + 0.0444444444444444461406185*var_518 + 0.0666666666666666657414808*var_320*w[0][2] + 0.7111111111111111382498962*var_449 + 0.0266666666666666683782605*var_286 + 0.0800000000000000016653345*var_211 + 0.2666666666666666629659233*var_519 + 0.0044444444444444444405895*var_475 + 0.0888888888888888922812370*var_517; + A[35] = 0.0043290043290043290005742*var_13*var_520; + const double var_521 = var_510*w[1][0]*w[2][0] + 0.1111111111111111049432054*var_355 + var_345*w[1][2]*w[2][2]; + A[25] = A[10]; + const double var_522 = var_202 + var_225; + const double var_523 = -1.0000000000000000000000000*var_174*w[0][4] + -0.5000000000000000000000000*var_522 + var_52; + const double var_524 = var_250*var_26 + var_147*var_50 + var_279 + var_25*var_99 + 2.0000000000000000000000000*var_475; + const double var_525 = 0.3333333333333333148296163*var_524 + 4.0000000000000000000000000*var_276 + var_283 + var_393*w[0][5] + 8.0000000000000000000000000*var_422; + const double var_526 = var_434 + 0.0138888888888888881179007*var_401; + const double var_527 = var_16 + var_55*var_67; + const double var_528 = var_216 + 10.6666666666666660745477202*var_273 + var_389 + 1.3333333333333332593184650*var_518 + 0.8000000000000000444089210*var_517 + var_24 + var_490*w[0][2] + 0.4000000000000000222044605*var_525 + 0.0666666666666666657414808*var_473; + A[22] = 0.0002886002886002886000383*var_13*var_528; + const double var_529 = var_181 + var_164; + A[27] = A[22]; + const double var_530 = var_480 + var_379; + const double var_531 = var_169 + var_376; + const double var_532 = var_25*var_483 + var_447; + const double var_533 = var_138*w[0][2] + 4.0000000000000000000000000*var_404 + var_140 + 1.3333333333333332593184650*var_532 + var_131*var_44 + var_530*w[0][0] + 0.3333333333333333148296163*var_125*var_2 + var_531*w[0][1] + var_478 + 0.4000000000000000222044605*var_268 + var_230 + 2.0000000000000000000000000*var_430 + var_375 + 0.0666666666666666657414808*var_523; + const double var_534 = var_395 + -1.0000000000000000000000000*var_201 + 9.6666666666666660745477202*var_529; + const double var_535 = var_311*w[0][5] + 0.0250000000000000013877788*var_534 + var_376*w[0][3] + 0.0166666666666666664353702*var_191 + -0.2500000000000000000000000*var_420 + var_448 + var_314*w[0][1] + 0.0416666666666666643537020*var_54 + 2.0000000000000000000000000*var_405 + 0.0666666666666666657414808*var_442 + var_477*var_51; + const double var_536 = var_17*var_342 + var_198*var_2 + -0.3333333333333333148296163*var_517 + 0.1666666666666666574148081*var_199*w[1][2]*w[2][2] + 0.0555555555555555524716027*var_284; + const double var_537 = var_20*var_95 + 3.2222222222222218768195034*var_28 + -0.3333333333333333148296163*var_21 + var_15; + const double var_538 = 0.0022727272727272726168812*var_537 + 0.0027777777777777778837887*var_283 + 0.0101010101010101018687015*var_492 + 0.0909090909090909116141432*var_526*w[0][2] + var_439 + var_467 + 0.0227272727272727279035358*var_536 + 0.0303030303030303038713811*var_474; + A[1] = 0.0095238095238095246686250*var_13*var_538; + A[9] = 0.0002886002886002886000383*var_13*var_533 + 0.0000264550264550264561329*var_13*var_400; + A[19] = A[9]; + const double var_539 = var_508 + 0.0016666666666666667736413*var_521 + var_499 + 0.0015151515151515151502010*var_394 + 0.0020202020202020202002680*var_535 + 0.0060606060606060606008039*var_64*w[0][4] + 0.0001515151515151515150201*var_527 + 0.0227272727272727279035358*var_57*w[0][1]; + A[31] = A[11]; + A[7] = 0.1428571428571428492126927*var_13*var_539; + A[8] = 0.0095238095238095246686250*var_13*var_472; + A[13] = A[8]; + A[29] = 0.0002886002886002886000383*var_13*var_254; + A[34] = A[29]; + A[18] = A[3]; + A[6] = A[1]; + A[12] = 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/mass_matrix_2d/mass_matrix_f3_p2_q2_quadrature.h b/mass_matrix_2d/mass_matrix_f3_p2_q2_quadrature.h new file mode 100644 index 0000000..8330818 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f3_p2_q2_quadrature.h @@ -0,0 +1,2257 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F3_P2_Q2_QUADRATURE_H +#define __MASS_MATRIX_F3_P2_Q2_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p2_q2_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p2_q2_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f3_p2_q2_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p2_q2_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p2_q2_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_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 mass_matrix_f3_p2_q2_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class mass_matrix_f3_p2_q2_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f3_p2_q2_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Array of quadrature weights. + static const double W36[36] = {0.00619426535265906, 0.0116108747669979, 0.0120606064042655, 0.0084515357969434, 0.0037652982126918, 0.000748542561236343, 0.0130433943300833, 0.0244492622580587, 0.0253962715890485, 0.0177965759970269, 0.00792866733379675, 0.00157622175402364, 0.0169175056800133, 0.0317111115907051, 0.0329393989007878, 0.023082463651359, 0.0102836172287667, 0.00204438659154493, 0.0169175056800133, 0.0317111115907051, 0.0329393989007878, 0.023082463651359, 0.0102836172287667, 0.00204438659154493, 0.0130433943300833, 0.0244492622580587, 0.0253962715890485, 0.0177965759970269, 0.00792866733379675, 0.00157622175402364, 0.00619426535265908, 0.0116108747669979, 0.0120606064042655, 0.00845153579694342, 0.00376529821269181, 0.000748542561236345}; + // Quadrature points on the UFC reference element: (0.0327753666144599, 0.0293164271597849), (0.0287653330125591, 0.148078599668484), (0.0223868729780306, 0.336984690281154), (0.0149015633666711, 0.55867151877155), (0.00779187470128645, 0.769233862030055), (0.00246669715267023, 0.926945671319741), (0.164429241594827, 0.0293164271597849), (0.144311486950417, 0.148078599668484), (0.112311681780954, 0.336984690281154), (0.0747589734626491, 0.55867151877155), (0.0390907007328242, 0.769233862030055), (0.01237506041744, 0.926945671319741), (0.369529924372377, 0.0293164271597849), (0.324318304588776, 0.148078599668484), (0.252403568076518, 0.336984690281154), (0.168009519121192, 0.55867151877155), (0.0878504549759972, 0.769233862030055), (0.0278110821153606, 0.926945671319741), (0.601153648467838, 0.0293164271597849), (0.52760309574274, 0.148078599668484), (0.410611741642328, 0.336984690281154), (0.273318962107258, 0.55867151877155), (0.142915682993948, 0.769233862030055), (0.0452432465648983, 0.926945671319741), (0.806254331245388, 0.0293164271597849), (0.707609913381099, 0.148078599668484), (0.550703627937892, 0.336984690281154), (0.366569507765801, 0.55867151877155), (0.191675437237121, 0.769233862030055), (0.0606792682628189, 0.926945671319741), (0.937908206225755, 0.0293164271597849), (0.823156067318956, 0.148078599668484), (0.640628436740815, 0.336984690281154), (0.426426917861779, 0.55867151877155), (0.222974263268659, 0.769233862030055), (0.0705876315275886, 0.926945671319741) + + // Value of basis functions at quadrature points. + static const double FE0[36][6] = \ + {{0.821435400385472, -0.0306269173010354, -0.027597521356955, 0.00384342659195225, 0.109984470441528, 0.122961141239038}, + {0.532015755009065, -0.0271104442459123, -0.104224056308926, 0.0170381209259896, 0.487567191028831, 0.0947134335909535}, + {0.180181151181146, -0.0213845288145617, -0.109867327313383, 0.0301761338274608, 0.863527901361615, 0.0573666697577237}, + {-0.0627470853075864, -0.0144574501851293, 0.0655562130014708, 0.0333003161525148, 0.952930295387644, 0.0254177109510863}, + {-0.123539219108257, -0.00767044807856534, 0.414207606957291, 0.0239750954756995, 0.686077414669827, 0.00694955008400423}, + {-0.0606224040782395, -0.0024545279629842, 0.79151088383707, 0.00914597699249764, 0.261723597972845, 0.00069647323881139}, + {0.493837762058507, -0.110355290611927, -0.027597521356955, 0.0192819115366138, 0.0945459854968659, 0.530287152876896}, + {0.293813665649314, -0.102659876418736, -0.104224056308926, 0.0854777716147778, 0.419127540340042, 0.408464955123528}, + {0.0558453437100203, -0.0870838540520213, -0.109867327313383, 0.151389269199641, 0.742314765989434, 0.247401802466309}, + {-0.0978230997184779, -0.0635811652362709, 0.0655562130014709, 0.167062836984721, 0.819167774555438, 0.109617440413119}, + {-0.118196490757038, -0.0360345349652578, 0.414207606957291, 0.120279562776686, 0.58977294736884, 0.0299709086194782}, + {-0.0533153210689967, -0.0120687761767694, 0.79151088383707, 0.0458840347450652, 0.224985540220277, 0.00300363844335377}, + {0.121617769664549, -0.0964251943590678, -0.027597521356955, 0.0433331884448944, 0.0704947085885853, 0.888577049017995}, + {0.0291269575319054, -0.1139535792061, -0.104224056308926, 0.192098401561452, 0.312506910393369, 0.6844453660283}, + {-0.0734077368932363, -0.124988445721003, -0.109867327313383, 0.340224552856495, 0.553479482332581, 0.414559474738547}, + {-0.123912452012481, -0.111555122090524, 0.0655562130014709, 0.375448532862056, 0.610782078678102, 0.183680749561375}, + {-0.102065898102695, -0.0724150500970178, 0.414207606957291, 0.270310179049135, 0.439742331096391, 0.050220831096895}, + {-0.041149343845434, -0.0262641695385059, 0.79151088383707, 0.103117448726206, 0.167752126239137, 0.00503305458152761}, + {-0.0964251943590678, 0.121617769664549, -0.027597521356955, 0.0704947085885853, 0.0433331884448943, 0.888577049017995}, + {-0.1139535792061, 0.0291269575319054, -0.104224056308926, 0.312506910393369, 0.192098401561452, 0.6844453660283}, + {-0.124988445721003, -0.0734077368932363, -0.109867327313383, 0.553479482332581, 0.340224552856495, 0.414559474738547}, + {-0.111555122090524, -0.123912452012481, 0.0655562130014709, 0.610782078678102, 0.375448532862056, 0.183680749561375}, + {-0.0724150500970178, -0.102065898102695, 0.414207606957291, 0.439742331096391, 0.270310179049135, 0.050220831096895}, + {-0.026264169538506, -0.0411493438454339, 0.79151088383707, 0.167752126239137, 0.103117448726206, 0.00503305458152761}, + {-0.110355290611927, 0.493837762058507, -0.027597521356955, 0.094545985496866, 0.0192819115366137, 0.530287152876895}, + {-0.102659876418736, 0.293813665649314, -0.104224056308926, 0.419127540340043, 0.0854777716147777, 0.408464955123527}, + {-0.0870838540520213, 0.0558453437100204, -0.109867327313383, 0.742314765989434, 0.151389269199641, 0.247401802466309}, + {-0.0635811652362708, -0.0978230997184778, 0.0655562130014709, 0.819167774555438, 0.16706283698472, 0.109617440413119}, + {-0.0360345349652578, -0.118196490757038, 0.414207606957291, 0.58977294736884, 0.120279562776686, 0.0299709086194782}, + {-0.0120687761767695, -0.0533153210689966, 0.79151088383707, 0.224985540220277, 0.0458840347450654, 0.00300363844335377}, + {-0.0306269173010354, 0.821435400385472, -0.027597521356955, 0.109984470441527, 0.00384342659195216, 0.122961141239039}, + {-0.0271104442459124, 0.532015755009064, -0.104224056308926, 0.487567191028831, 0.0170381209259896, 0.0947134335909537}, + {-0.0213845288145617, 0.180181151181146, -0.109867327313383, 0.863527901361614, 0.0301761338274608, 0.0573666697577238}, + {-0.0144574501851293, -0.0627470853075864, 0.0655562130014709, 0.952930295387644, 0.0333003161525146, 0.0254177109510863}, + {-0.00767044807856535, -0.123539219108256, 0.414207606957291, 0.686077414669827, 0.0239750954756995, 0.00694955008400424}, + {-0.00245452796298434, -0.0606224040782394, 0.79151088383707, 0.261723597972845, 0.00914597699249803, 0.000696473238811418}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 36; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 5328 + for (unsigned int ip = 0; ip < 36; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + + // Total number of operations to compute function values = 36 + for (unsigned int r = 0; r < 6; r++) + { + F0 += FE0[ip][r]*w[2][r]; + F1 += FE0[ip][r]*w[0][r]; + F2 += FE0[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 4 + double I[1]; + // Number of operations: 4 + I[0] = F0*F1*F2*W36[ip]*det; + + + // Number of operations for primary indices: 108 + for (unsigned int j = 0; j < 6; j++) + { + for (unsigned int k = 0; k < 6; k++) + { + // Number of operations to compute entry: 3 + A[j*6 + k] += FE0[ip][j]*FE0[ip][k]*I[0]; + }// 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 mass_matrix_f3_p2_q2_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f3_p2_q2_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p2_q2_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1)))), 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 3; + } + + /// 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 mass_matrix_f3_p2_q2_quadrature_finite_element_0(); + break; + } + case 1: + { + return new mass_matrix_f3_p2_q2_quadrature_finite_element_0(); + break; + } + case 2: + { + return new mass_matrix_f3_p2_q2_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p2_q2_quadrature_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p2_q2_quadrature_finite_element_0(); + 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 mass_matrix_f3_p2_q2_quadrature_dofmap_0(); + break; + } + case 1: + { + return new mass_matrix_f3_p2_q2_quadrature_dofmap_0(); + break; + } + case 2: + { + return new mass_matrix_f3_p2_q2_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p2_q2_quadrature_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p2_q2_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f3_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/mass_matrix_2d/mass_matrix_f3_p2_q2_tensor.h b/mass_matrix_2d/mass_matrix_f3_p2_q2_tensor.h new file mode 100644 index 0000000..898443f --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f3_p2_q2_tensor.h @@ -0,0 +1,2426 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F3_P2_Q2_TENSOR_H +#define __MASS_MATRIX_F3_P2_Q2_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p2_q2_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p2_q2_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f3_p2_q2_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p2_q2_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p2_q2_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_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 mass_matrix_f3_p2_q2_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class mass_matrix_f3_p2_q2_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f3_p2_q2_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 432 + // Number of operations (multiply-add pairs) for tensor contraction: 3982 + // Total number of operations (multiply-add pairs): 4423 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0 = det*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_0_0_1 = det*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_0_0_2 = det*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_0_0_3 = det*w[2][0]*w[0][0]*w[1][3]*(1.0); + const double G0_0_0_4 = det*w[2][0]*w[0][0]*w[1][4]*(1.0); + const double G0_0_0_5 = det*w[2][0]*w[0][0]*w[1][5]*(1.0); + const double G0_0_1_0 = det*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_0_1_1 = det*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_0_1_2 = det*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_0_1_3 = det*w[2][0]*w[0][1]*w[1][3]*(1.0); + const double G0_0_1_4 = det*w[2][0]*w[0][1]*w[1][4]*(1.0); + const double G0_0_1_5 = det*w[2][0]*w[0][1]*w[1][5]*(1.0); + const double G0_0_2_0 = det*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_0_2_1 = det*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_0_2_2 = det*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_0_2_3 = det*w[2][0]*w[0][2]*w[1][3]*(1.0); + const double G0_0_2_4 = det*w[2][0]*w[0][2]*w[1][4]*(1.0); + const double G0_0_2_5 = det*w[2][0]*w[0][2]*w[1][5]*(1.0); + const double G0_0_3_0 = det*w[2][0]*w[0][3]*w[1][0]*(1.0); + const double G0_0_3_1 = det*w[2][0]*w[0][3]*w[1][1]*(1.0); + const double G0_0_3_2 = det*w[2][0]*w[0][3]*w[1][2]*(1.0); + const double G0_0_3_3 = det*w[2][0]*w[0][3]*w[1][3]*(1.0); + const double G0_0_3_4 = det*w[2][0]*w[0][3]*w[1][4]*(1.0); + const double G0_0_3_5 = det*w[2][0]*w[0][3]*w[1][5]*(1.0); + const double G0_0_4_0 = det*w[2][0]*w[0][4]*w[1][0]*(1.0); + const double G0_0_4_1 = det*w[2][0]*w[0][4]*w[1][1]*(1.0); + const double G0_0_4_2 = det*w[2][0]*w[0][4]*w[1][2]*(1.0); + const double G0_0_4_3 = det*w[2][0]*w[0][4]*w[1][3]*(1.0); + const double G0_0_4_4 = det*w[2][0]*w[0][4]*w[1][4]*(1.0); + const double G0_0_4_5 = det*w[2][0]*w[0][4]*w[1][5]*(1.0); + const double G0_0_5_0 = det*w[2][0]*w[0][5]*w[1][0]*(1.0); + const double G0_0_5_1 = det*w[2][0]*w[0][5]*w[1][1]*(1.0); + const double G0_0_5_2 = det*w[2][0]*w[0][5]*w[1][2]*(1.0); + const double G0_0_5_3 = det*w[2][0]*w[0][5]*w[1][3]*(1.0); + const double G0_0_5_4 = det*w[2][0]*w[0][5]*w[1][4]*(1.0); + const double G0_0_5_5 = det*w[2][0]*w[0][5]*w[1][5]*(1.0); + const double G0_1_0_0 = det*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_1_0_1 = det*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_1_0_2 = det*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_1_0_3 = det*w[2][1]*w[0][0]*w[1][3]*(1.0); + const double G0_1_0_4 = det*w[2][1]*w[0][0]*w[1][4]*(1.0); + const double G0_1_0_5 = det*w[2][1]*w[0][0]*w[1][5]*(1.0); + const double G0_1_1_0 = det*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_1_1_1 = det*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_1_1_2 = det*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_1_1_3 = det*w[2][1]*w[0][1]*w[1][3]*(1.0); + const double G0_1_1_4 = det*w[2][1]*w[0][1]*w[1][4]*(1.0); + const double G0_1_1_5 = det*w[2][1]*w[0][1]*w[1][5]*(1.0); + const double G0_1_2_0 = det*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_1_2_1 = det*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_1_2_2 = det*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_1_2_3 = det*w[2][1]*w[0][2]*w[1][3]*(1.0); + const double G0_1_2_4 = det*w[2][1]*w[0][2]*w[1][4]*(1.0); + const double G0_1_2_5 = det*w[2][1]*w[0][2]*w[1][5]*(1.0); + const double G0_1_3_0 = det*w[2][1]*w[0][3]*w[1][0]*(1.0); + const double G0_1_3_1 = det*w[2][1]*w[0][3]*w[1][1]*(1.0); + const double G0_1_3_2 = det*w[2][1]*w[0][3]*w[1][2]*(1.0); + const double G0_1_3_3 = det*w[2][1]*w[0][3]*w[1][3]*(1.0); + const double G0_1_3_4 = det*w[2][1]*w[0][3]*w[1][4]*(1.0); + const double G0_1_3_5 = det*w[2][1]*w[0][3]*w[1][5]*(1.0); + const double G0_1_4_0 = det*w[2][1]*w[0][4]*w[1][0]*(1.0); + const double G0_1_4_1 = det*w[2][1]*w[0][4]*w[1][1]*(1.0); + const double G0_1_4_2 = det*w[2][1]*w[0][4]*w[1][2]*(1.0); + const double G0_1_4_3 = det*w[2][1]*w[0][4]*w[1][3]*(1.0); + const double G0_1_4_4 = det*w[2][1]*w[0][4]*w[1][4]*(1.0); + const double G0_1_4_5 = det*w[2][1]*w[0][4]*w[1][5]*(1.0); + const double G0_1_5_0 = det*w[2][1]*w[0][5]*w[1][0]*(1.0); + const double G0_1_5_1 = det*w[2][1]*w[0][5]*w[1][1]*(1.0); + const double G0_1_5_2 = det*w[2][1]*w[0][5]*w[1][2]*(1.0); + const double G0_1_5_3 = det*w[2][1]*w[0][5]*w[1][3]*(1.0); + const double G0_1_5_4 = det*w[2][1]*w[0][5]*w[1][4]*(1.0); + const double G0_1_5_5 = det*w[2][1]*w[0][5]*w[1][5]*(1.0); + const double G0_2_0_0 = det*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_2_0_1 = det*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_2_0_2 = det*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_2_0_3 = det*w[2][2]*w[0][0]*w[1][3]*(1.0); + const double G0_2_0_4 = det*w[2][2]*w[0][0]*w[1][4]*(1.0); + const double G0_2_0_5 = det*w[2][2]*w[0][0]*w[1][5]*(1.0); + const double G0_2_1_0 = det*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_2_1_1 = det*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_2_1_2 = det*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_2_1_3 = det*w[2][2]*w[0][1]*w[1][3]*(1.0); + const double G0_2_1_4 = det*w[2][2]*w[0][1]*w[1][4]*(1.0); + const double G0_2_1_5 = det*w[2][2]*w[0][1]*w[1][5]*(1.0); + const double G0_2_2_0 = det*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_2_2_1 = det*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_2_2_2 = det*w[2][2]*w[0][2]*w[1][2]*(1.0); + const double G0_2_2_3 = det*w[2][2]*w[0][2]*w[1][3]*(1.0); + const double G0_2_2_4 = det*w[2][2]*w[0][2]*w[1][4]*(1.0); + const double G0_2_2_5 = det*w[2][2]*w[0][2]*w[1][5]*(1.0); + const double G0_2_3_0 = det*w[2][2]*w[0][3]*w[1][0]*(1.0); + const double G0_2_3_1 = det*w[2][2]*w[0][3]*w[1][1]*(1.0); + const double G0_2_3_2 = det*w[2][2]*w[0][3]*w[1][2]*(1.0); + const double G0_2_3_3 = det*w[2][2]*w[0][3]*w[1][3]*(1.0); + const double G0_2_3_4 = det*w[2][2]*w[0][3]*w[1][4]*(1.0); + const double G0_2_3_5 = det*w[2][2]*w[0][3]*w[1][5]*(1.0); + const double G0_2_4_0 = det*w[2][2]*w[0][4]*w[1][0]*(1.0); + const double G0_2_4_1 = det*w[2][2]*w[0][4]*w[1][1]*(1.0); + const double G0_2_4_2 = det*w[2][2]*w[0][4]*w[1][2]*(1.0); + const double G0_2_4_3 = det*w[2][2]*w[0][4]*w[1][3]*(1.0); + const double G0_2_4_4 = det*w[2][2]*w[0][4]*w[1][4]*(1.0); + const double G0_2_4_5 = det*w[2][2]*w[0][4]*w[1][5]*(1.0); + const double G0_2_5_0 = det*w[2][2]*w[0][5]*w[1][0]*(1.0); + const double G0_2_5_1 = det*w[2][2]*w[0][5]*w[1][1]*(1.0); + const double G0_2_5_2 = det*w[2][2]*w[0][5]*w[1][2]*(1.0); + const double G0_2_5_3 = det*w[2][2]*w[0][5]*w[1][3]*(1.0); + const double G0_2_5_4 = det*w[2][2]*w[0][5]*w[1][4]*(1.0); + const double G0_2_5_5 = det*w[2][2]*w[0][5]*w[1][5]*(1.0); + const double G0_3_0_0 = det*w[2][3]*w[0][0]*w[1][0]*(1.0); + const double G0_3_0_1 = det*w[2][3]*w[0][0]*w[1][1]*(1.0); + const double G0_3_0_2 = det*w[2][3]*w[0][0]*w[1][2]*(1.0); + const double G0_3_0_3 = det*w[2][3]*w[0][0]*w[1][3]*(1.0); + const double G0_3_0_4 = det*w[2][3]*w[0][0]*w[1][4]*(1.0); + const double G0_3_0_5 = det*w[2][3]*w[0][0]*w[1][5]*(1.0); + const double G0_3_1_0 = det*w[2][3]*w[0][1]*w[1][0]*(1.0); + const double G0_3_1_1 = det*w[2][3]*w[0][1]*w[1][1]*(1.0); + const double G0_3_1_2 = det*w[2][3]*w[0][1]*w[1][2]*(1.0); + const double G0_3_1_3 = det*w[2][3]*w[0][1]*w[1][3]*(1.0); + const double G0_3_1_4 = det*w[2][3]*w[0][1]*w[1][4]*(1.0); + const double G0_3_1_5 = det*w[2][3]*w[0][1]*w[1][5]*(1.0); + const double G0_3_2_0 = det*w[2][3]*w[0][2]*w[1][0]*(1.0); + const double G0_3_2_1 = det*w[2][3]*w[0][2]*w[1][1]*(1.0); + const double G0_3_2_2 = det*w[2][3]*w[0][2]*w[1][2]*(1.0); + const double G0_3_2_3 = det*w[2][3]*w[0][2]*w[1][3]*(1.0); + const double G0_3_2_4 = det*w[2][3]*w[0][2]*w[1][4]*(1.0); + const double G0_3_2_5 = det*w[2][3]*w[0][2]*w[1][5]*(1.0); + const double G0_3_3_0 = det*w[2][3]*w[0][3]*w[1][0]*(1.0); + const double G0_3_3_1 = det*w[2][3]*w[0][3]*w[1][1]*(1.0); + const double G0_3_3_2 = det*w[2][3]*w[0][3]*w[1][2]*(1.0); + const double G0_3_3_3 = det*w[2][3]*w[0][3]*w[1][3]*(1.0); + const double G0_3_3_4 = det*w[2][3]*w[0][3]*w[1][4]*(1.0); + const double G0_3_3_5 = det*w[2][3]*w[0][3]*w[1][5]*(1.0); + const double G0_3_4_0 = det*w[2][3]*w[0][4]*w[1][0]*(1.0); + const double G0_3_4_1 = det*w[2][3]*w[0][4]*w[1][1]*(1.0); + const double G0_3_4_2 = det*w[2][3]*w[0][4]*w[1][2]*(1.0); + const double G0_3_4_3 = det*w[2][3]*w[0][4]*w[1][3]*(1.0); + const double G0_3_4_4 = det*w[2][3]*w[0][4]*w[1][4]*(1.0); + const double G0_3_4_5 = det*w[2][3]*w[0][4]*w[1][5]*(1.0); + const double G0_3_5_0 = det*w[2][3]*w[0][5]*w[1][0]*(1.0); + const double G0_3_5_1 = det*w[2][3]*w[0][5]*w[1][1]*(1.0); + const double G0_3_5_2 = det*w[2][3]*w[0][5]*w[1][2]*(1.0); + const double G0_3_5_3 = det*w[2][3]*w[0][5]*w[1][3]*(1.0); + const double G0_3_5_4 = det*w[2][3]*w[0][5]*w[1][4]*(1.0); + const double G0_3_5_5 = det*w[2][3]*w[0][5]*w[1][5]*(1.0); + const double G0_4_0_0 = det*w[2][4]*w[0][0]*w[1][0]*(1.0); + const double G0_4_0_1 = det*w[2][4]*w[0][0]*w[1][1]*(1.0); + const double G0_4_0_2 = det*w[2][4]*w[0][0]*w[1][2]*(1.0); + const double G0_4_0_3 = det*w[2][4]*w[0][0]*w[1][3]*(1.0); + const double G0_4_0_4 = det*w[2][4]*w[0][0]*w[1][4]*(1.0); + const double G0_4_0_5 = det*w[2][4]*w[0][0]*w[1][5]*(1.0); + const double G0_4_1_0 = det*w[2][4]*w[0][1]*w[1][0]*(1.0); + const double G0_4_1_1 = det*w[2][4]*w[0][1]*w[1][1]*(1.0); + const double G0_4_1_2 = det*w[2][4]*w[0][1]*w[1][2]*(1.0); + const double G0_4_1_3 = det*w[2][4]*w[0][1]*w[1][3]*(1.0); + const double G0_4_1_4 = det*w[2][4]*w[0][1]*w[1][4]*(1.0); + const double G0_4_1_5 = det*w[2][4]*w[0][1]*w[1][5]*(1.0); + const double G0_4_2_0 = det*w[2][4]*w[0][2]*w[1][0]*(1.0); + const double G0_4_2_1 = det*w[2][4]*w[0][2]*w[1][1]*(1.0); + const double G0_4_2_2 = det*w[2][4]*w[0][2]*w[1][2]*(1.0); + const double G0_4_2_3 = det*w[2][4]*w[0][2]*w[1][3]*(1.0); + const double G0_4_2_4 = det*w[2][4]*w[0][2]*w[1][4]*(1.0); + const double G0_4_2_5 = det*w[2][4]*w[0][2]*w[1][5]*(1.0); + const double G0_4_3_0 = det*w[2][4]*w[0][3]*w[1][0]*(1.0); + const double G0_4_3_1 = det*w[2][4]*w[0][3]*w[1][1]*(1.0); + const double G0_4_3_2 = det*w[2][4]*w[0][3]*w[1][2]*(1.0); + const double G0_4_3_3 = det*w[2][4]*w[0][3]*w[1][3]*(1.0); + const double G0_4_3_4 = det*w[2][4]*w[0][3]*w[1][4]*(1.0); + const double G0_4_3_5 = det*w[2][4]*w[0][3]*w[1][5]*(1.0); + const double G0_4_4_0 = det*w[2][4]*w[0][4]*w[1][0]*(1.0); + const double G0_4_4_1 = det*w[2][4]*w[0][4]*w[1][1]*(1.0); + const double G0_4_4_2 = det*w[2][4]*w[0][4]*w[1][2]*(1.0); + const double G0_4_4_3 = det*w[2][4]*w[0][4]*w[1][3]*(1.0); + const double G0_4_4_4 = det*w[2][4]*w[0][4]*w[1][4]*(1.0); + const double G0_4_4_5 = det*w[2][4]*w[0][4]*w[1][5]*(1.0); + const double G0_4_5_0 = det*w[2][4]*w[0][5]*w[1][0]*(1.0); + const double G0_4_5_1 = det*w[2][4]*w[0][5]*w[1][1]*(1.0); + const double G0_4_5_2 = det*w[2][4]*w[0][5]*w[1][2]*(1.0); + const double G0_4_5_3 = det*w[2][4]*w[0][5]*w[1][3]*(1.0); + const double G0_4_5_4 = det*w[2][4]*w[0][5]*w[1][4]*(1.0); + const double G0_4_5_5 = det*w[2][4]*w[0][5]*w[1][5]*(1.0); + const double G0_5_0_0 = det*w[2][5]*w[0][0]*w[1][0]*(1.0); + const double G0_5_0_1 = det*w[2][5]*w[0][0]*w[1][1]*(1.0); + const double G0_5_0_2 = det*w[2][5]*w[0][0]*w[1][2]*(1.0); + const double G0_5_0_3 = det*w[2][5]*w[0][0]*w[1][3]*(1.0); + const double G0_5_0_4 = det*w[2][5]*w[0][0]*w[1][4]*(1.0); + const double G0_5_0_5 = det*w[2][5]*w[0][0]*w[1][5]*(1.0); + const double G0_5_1_0 = det*w[2][5]*w[0][1]*w[1][0]*(1.0); + const double G0_5_1_1 = det*w[2][5]*w[0][1]*w[1][1]*(1.0); + const double G0_5_1_2 = det*w[2][5]*w[0][1]*w[1][2]*(1.0); + const double G0_5_1_3 = det*w[2][5]*w[0][1]*w[1][3]*(1.0); + const double G0_5_1_4 = det*w[2][5]*w[0][1]*w[1][4]*(1.0); + const double G0_5_1_5 = det*w[2][5]*w[0][1]*w[1][5]*(1.0); + const double G0_5_2_0 = det*w[2][5]*w[0][2]*w[1][0]*(1.0); + const double G0_5_2_1 = det*w[2][5]*w[0][2]*w[1][1]*(1.0); + const double G0_5_2_2 = det*w[2][5]*w[0][2]*w[1][2]*(1.0); + const double G0_5_2_3 = det*w[2][5]*w[0][2]*w[1][3]*(1.0); + const double G0_5_2_4 = det*w[2][5]*w[0][2]*w[1][4]*(1.0); + const double G0_5_2_5 = det*w[2][5]*w[0][2]*w[1][5]*(1.0); + const double G0_5_3_0 = det*w[2][5]*w[0][3]*w[1][0]*(1.0); + const double G0_5_3_1 = det*w[2][5]*w[0][3]*w[1][1]*(1.0); + const double G0_5_3_2 = det*w[2][5]*w[0][3]*w[1][2]*(1.0); + const double G0_5_3_3 = det*w[2][5]*w[0][3]*w[1][3]*(1.0); + const double G0_5_3_4 = det*w[2][5]*w[0][3]*w[1][4]*(1.0); + const double G0_5_3_5 = det*w[2][5]*w[0][3]*w[1][5]*(1.0); + const double G0_5_4_0 = det*w[2][5]*w[0][4]*w[1][0]*(1.0); + const double G0_5_4_1 = det*w[2][5]*w[0][4]*w[1][1]*(1.0); + const double G0_5_4_2 = det*w[2][5]*w[0][4]*w[1][2]*(1.0); + const double G0_5_4_3 = det*w[2][5]*w[0][4]*w[1][3]*(1.0); + const double G0_5_4_4 = det*w[2][5]*w[0][4]*w[1][4]*(1.0); + const double G0_5_4_5 = det*w[2][5]*w[0][4]*w[1][5]*(1.0); + const double G0_5_5_0 = det*w[2][5]*w[0][5]*w[1][0]*(1.0); + const double G0_5_5_1 = det*w[2][5]*w[0][5]*w[1][1]*(1.0); + const double G0_5_5_2 = det*w[2][5]*w[0][5]*w[1][2]*(1.0); + const double G0_5_5_3 = det*w[2][5]*w[0][5]*w[1][3]*(1.0); + const double G0_5_5_4 = det*w[2][5]*w[0][5]*w[1][4]*(1.0); + const double G0_5_5_5 = det*w[2][5]*w[0][5]*w[1][5]*(1.0); + + // Compute element tensor + A[9] = -7.2150072150075e-06*G0_0_0_0 + 2.64550264550274e-05*G0_0_0_1 - 4.81000481000497e-06*G0_0_0_2 - 1.92400192400198e-05*G0_0_0_3 - 3.84800384800398e-05*G0_0_0_4 - 9.62000962000995e-06*G0_0_0_5 + 2.64550264550274e-05*G0_0_1_0 - 7.21500721500749e-05*G0_0_1_1 + 1.20250120250125e-05*G0_0_1_2 - 0.00011544011544012*G0_0_1_3 - 3.84800384800398e-05*G0_0_1_4 - 7.69600769600797e-05*G0_0_1_5 - 4.81000481000497e-06*G0_0_2_0 + 1.20250120250125e-05*G0_0_2_1 + 1.20250120250124e-05*G0_0_2_2 + 4.81000481000498e-05*G0_0_2_3 + 1.92400192400199e-05*G0_0_2_4 + 1.92400192400199e-05*G0_0_2_5 - 1.92400192400198e-05*G0_0_3_0 - 0.00011544011544012*G0_0_3_1 + 4.81000481000498e-05*G0_0_3_2 + 7.69600769600791e-05*G0_0_3_3 + 0.000115440115440119*G0_0_3_4 - 3.84800384800398e-05*G0_0_4_0 - 3.84800384800398e-05*G0_0_4_1 + 1.92400192400199e-05*G0_0_4_2 + 0.000115440115440119*G0_0_4_3 + 0.000115440115440119*G0_0_4_4 + 3.84800384800397e-05*G0_0_4_5 - 9.62000962000995e-06*G0_0_5_0 - 7.69600769600797e-05*G0_0_5_1 + 1.92400192400199e-05*G0_0_5_2 + 3.84800384800397e-05*G0_0_5_4 - 7.69600769600798e-05*G0_0_5_5 + 2.64550264550274e-05*G0_1_0_0 - 7.21500721500749e-05*G0_1_0_1 + 1.20250120250125e-05*G0_1_0_2 - 0.00011544011544012*G0_1_0_3 - 3.84800384800398e-05*G0_1_0_4 - 7.69600769600797e-05*G0_1_0_5 - 7.21500721500749e-05*G0_1_1_0 + 0.000937950937950971*G0_1_1_1 - 0.000144300144300149*G0_1_1_2 + 0.000577200577200598*G0_1_1_3 + 0.0002886002886003*G0_1_1_5 + 1.20250120250125e-05*G0_1_2_0 - 0.000144300144300149*G0_1_2_1 + 6.97450697450722e-05*G0_1_2_2 - 0.00011544011544012*G0_1_2_3 - 9.62000962000999e-06*G0_1_2_4 - 7.69600769600798e-05*G0_1_2_5 - 0.00011544011544012*G0_1_3_0 + 0.000577200577200598*G0_1_3_1 - 0.00011544011544012*G0_1_3_2 + 0.00115440115440119*G0_1_3_3 + 0.000230880230880239*G0_1_3_4 + 0.000384800384800399*G0_1_3_5 - 3.84800384800398e-05*G0_1_4_0 - 9.62000962000999e-06*G0_1_4_2 + 0.000230880230880239*G0_1_4_3 + 0.000192400192400199*G0_1_4_4 + 0.000153920153920159*G0_1_4_5 - 7.69600769600797e-05*G0_1_5_0 + 0.0002886002886003*G0_1_5_1 - 7.69600769600798e-05*G0_1_5_2 + 0.000384800384800399*G0_1_5_3 + 0.000153920153920159*G0_1_5_4 + 0.000384800384800399*G0_1_5_5 - 4.81000481000497e-06*G0_2_0_0 + 1.20250120250125e-05*G0_2_0_1 + 1.20250120250124e-05*G0_2_0_2 + 4.81000481000498e-05*G0_2_0_3 + 1.92400192400199e-05*G0_2_0_4 + 1.92400192400199e-05*G0_2_0_5 + 1.20250120250125e-05*G0_2_1_0 - 0.000144300144300149*G0_2_1_1 + 6.97450697450722e-05*G0_2_1_2 - 0.00011544011544012*G0_2_1_3 - 9.62000962000999e-06*G0_2_1_4 - 7.69600769600798e-05*G0_2_1_5 + 1.20250120250124e-05*G0_2_2_0 + 6.97450697450722e-05*G0_2_2_1 - 0.000144300144300149*G0_2_2_2 - 0.000115440115440119*G0_2_2_3 - 7.69600769600796e-05*G0_2_2_4 - 9.62000962000993e-06*G0_2_2_5 + 4.81000481000498e-05*G0_2_3_0 - 0.00011544011544012*G0_2_3_1 - 0.000115440115440119*G0_2_3_2 - 0.000615680615680637*G0_2_3_3 - 7.69600769600796e-05*G0_2_3_4 - 7.69600769600798e-05*G0_2_3_5 + 1.92400192400199e-05*G0_2_4_0 - 9.62000962000999e-06*G0_2_4_1 - 7.69600769600796e-05*G0_2_4_2 - 7.69600769600796e-05*G0_2_4_3 + 3.84800384800398e-05*G0_2_4_5 + 1.92400192400199e-05*G0_2_5_0 - 7.69600769600798e-05*G0_2_5_1 - 9.62000962000993e-06*G0_2_5_2 - 7.69600769600798e-05*G0_2_5_3 + 3.84800384800398e-05*G0_2_5_4 - 1.92400192400198e-05*G0_3_0_0 - 0.00011544011544012*G0_3_0_1 + 4.81000481000498e-05*G0_3_0_2 + 7.6960076960079e-05*G0_3_0_3 + 0.000115440115440119*G0_3_0_4 - 0.00011544011544012*G0_3_1_0 + 0.000577200577200598*G0_3_1_1 - 0.00011544011544012*G0_3_1_2 + 0.00115440115440119*G0_3_1_3 + 0.000230880230880239*G0_3_1_4 + 0.000384800384800399*G0_3_1_5 + 4.81000481000498e-05*G0_3_2_0 - 0.00011544011544012*G0_3_2_1 - 0.000115440115440119*G0_3_2_2 - 0.000615680615680637*G0_3_2_3 - 7.69600769600796e-05*G0_3_2_4 - 7.69600769600798e-05*G0_3_2_5 + 7.6960076960079e-05*G0_3_3_0 + 0.00115440115440119*G0_3_3_1 - 0.000615680615680637*G0_3_3_2 - 0.000615680615680636*G0_3_3_4 + 0.000115440115440119*G0_3_4_0 + 0.000230880230880239*G0_3_4_1 - 7.69600769600796e-05*G0_3_4_2 - 0.000615680615680636*G0_3_4_3 - 0.000615680615680637*G0_3_4_4 - 0.000307840307840318*G0_3_4_5 + 0.000384800384800399*G0_3_5_1 - 7.69600769600798e-05*G0_3_5_2 - 0.000307840307840318*G0_3_5_4 - 3.84800384800398e-05*G0_4_0_0 - 3.84800384800398e-05*G0_4_0_1 + 1.92400192400199e-05*G0_4_0_2 + 0.000115440115440119*G0_4_0_3 + 0.000115440115440119*G0_4_0_4 + 3.84800384800397e-05*G0_4_0_5 - 3.84800384800398e-05*G0_4_1_0 - 9.62000962000999e-06*G0_4_1_2 + 0.000230880230880239*G0_4_1_3 + 0.000192400192400199*G0_4_1_4 + 0.000153920153920159*G0_4_1_5 + 1.92400192400199e-05*G0_4_2_0 - 9.62000962000999e-06*G0_4_2_1 - 7.69600769600796e-05*G0_4_2_2 - 7.69600769600796e-05*G0_4_2_3 + 3.84800384800398e-05*G0_4_2_5 + 0.000115440115440119*G0_4_3_0 + 0.000230880230880239*G0_4_3_1 - 7.69600769600796e-05*G0_4_3_2 - 0.000615680615680636*G0_4_3_3 - 0.000615680615680637*G0_4_3_4 - 0.000307840307840318*G0_4_3_5 + 0.000115440115440119*G0_4_4_0 + 0.000192400192400199*G0_4_4_1 - 0.000615680615680637*G0_4_4_3 - 0.000923520923520955*G0_4_4_4 - 0.000461760461760477*G0_4_4_5 + 3.84800384800397e-05*G0_4_5_0 + 0.000153920153920159*G0_4_5_1 + 3.84800384800398e-05*G0_4_5_2 - 0.000307840307840318*G0_4_5_3 - 0.000461760461760477*G0_4_5_4 - 0.000307840307840318*G0_4_5_5 - 9.62000962000995e-06*G0_5_0_0 - 7.69600769600797e-05*G0_5_0_1 + 1.92400192400199e-05*G0_5_0_2 + 3.84800384800397e-05*G0_5_0_4 - 7.69600769600798e-05*G0_5_0_5 - 7.69600769600797e-05*G0_5_1_0 + 0.0002886002886003*G0_5_1_1 - 7.69600769600798e-05*G0_5_1_2 + 0.000384800384800399*G0_5_1_3 + 0.000153920153920159*G0_5_1_4 + 0.000384800384800399*G0_5_1_5 + 1.92400192400199e-05*G0_5_2_0 - 7.69600769600798e-05*G0_5_2_1 - 9.62000962000993e-06*G0_5_2_2 - 7.69600769600798e-05*G0_5_2_3 + 3.84800384800398e-05*G0_5_2_4 + 0.000384800384800399*G0_5_3_1 - 7.69600769600798e-05*G0_5_3_2 - 0.000307840307840318*G0_5_3_4 + 3.84800384800397e-05*G0_5_4_0 + 0.000153920153920159*G0_5_4_1 + 3.84800384800398e-05*G0_5_4_2 - 0.000307840307840318*G0_5_4_3 - 0.000461760461760477*G0_5_4_4 - 0.000307840307840318*G0_5_4_5 - 7.69600769600798e-05*G0_5_5_0 + 0.000384800384800399*G0_5_5_1 - 0.000307840307840318*G0_5_5_4; + A[18] = 7.21500721500748e-05*G0_0_0_0 - 7.2150072150075e-06*G0_0_0_1 - 7.21500721500749e-06*G0_0_0_2 - 5.77200577200596e-05*G0_0_0_3 - 7.2150072150075e-06*G0_0_1_0 + 2.64550264550274e-05*G0_0_1_1 - 4.81000481000497e-06*G0_0_1_2 - 1.92400192400198e-05*G0_0_1_3 - 3.84800384800398e-05*G0_0_1_4 - 9.62000962000995e-06*G0_0_1_5 - 7.21500721500749e-06*G0_0_2_0 - 4.81000481000497e-06*G0_0_2_1 + 2.64550264550274e-05*G0_0_2_2 - 1.92400192400199e-05*G0_0_2_3 - 9.62000962000997e-06*G0_0_2_4 - 3.84800384800398e-05*G0_0_2_5 - 5.77200577200596e-05*G0_0_3_0 - 1.92400192400198e-05*G0_0_3_1 - 1.92400192400199e-05*G0_0_3_2 + 0.000346320346320358*G0_0_3_3 + 0.000192400192400199*G0_0_3_4 + 0.000192400192400199*G0_0_3_5 - 3.84800384800398e-05*G0_0_4_1 - 9.62000962000997e-06*G0_0_4_2 + 0.000192400192400199*G0_0_4_3 + 0.000230880230880239*G0_0_4_4 + 0.000153920153920159*G0_0_4_5 - 9.62000962000995e-06*G0_0_5_1 - 3.84800384800398e-05*G0_0_5_2 + 0.000192400192400199*G0_0_5_3 + 0.000153920153920159*G0_0_5_4 + 0.000230880230880239*G0_0_5_5 - 7.2150072150075e-06*G0_1_0_0 + 2.64550264550274e-05*G0_1_0_1 - 4.81000481000497e-06*G0_1_0_2 - 1.92400192400198e-05*G0_1_0_3 - 3.84800384800398e-05*G0_1_0_4 - 9.62000962000995e-06*G0_1_0_5 + 2.64550264550274e-05*G0_1_1_0 - 7.21500721500749e-05*G0_1_1_1 + 1.20250120250125e-05*G0_1_1_2 - 0.00011544011544012*G0_1_1_3 - 3.84800384800398e-05*G0_1_1_4 - 7.69600769600797e-05*G0_1_1_5 - 4.81000481000497e-06*G0_1_2_0 + 1.20250120250125e-05*G0_1_2_1 + 1.20250120250124e-05*G0_1_2_2 + 4.81000481000498e-05*G0_1_2_3 + 1.92400192400199e-05*G0_1_2_4 + 1.92400192400199e-05*G0_1_2_5 - 1.92400192400198e-05*G0_1_3_0 - 0.00011544011544012*G0_1_3_1 + 4.81000481000498e-05*G0_1_3_2 + 7.69600769600791e-05*G0_1_3_3 + 0.000115440115440119*G0_1_3_4 - 3.84800384800398e-05*G0_1_4_0 - 3.84800384800398e-05*G0_1_4_1 + 1.92400192400199e-05*G0_1_4_2 + 0.000115440115440119*G0_1_4_3 + 0.000115440115440119*G0_1_4_4 + 3.84800384800397e-05*G0_1_4_5 - 9.62000962000995e-06*G0_1_5_0 - 7.69600769600797e-05*G0_1_5_1 + 1.92400192400199e-05*G0_1_5_2 + 3.84800384800397e-05*G0_1_5_4 - 7.69600769600798e-05*G0_1_5_5 - 7.21500721500749e-06*G0_2_0_0 - 4.81000481000497e-06*G0_2_0_1 + 2.64550264550274e-05*G0_2_0_2 - 1.92400192400199e-05*G0_2_0_3 - 9.62000962000997e-06*G0_2_0_4 - 3.84800384800398e-05*G0_2_0_5 - 4.81000481000497e-06*G0_2_1_0 + 1.20250120250125e-05*G0_2_1_1 + 1.20250120250124e-05*G0_2_1_2 + 4.81000481000498e-05*G0_2_1_3 + 1.92400192400199e-05*G0_2_1_4 + 1.92400192400199e-05*G0_2_1_5 + 2.64550264550274e-05*G0_2_2_0 + 1.20250120250124e-05*G0_2_2_1 - 7.21500721500746e-05*G0_2_2_2 - 0.000115440115440119*G0_2_2_3 - 7.69600769600796e-05*G0_2_2_4 - 3.84800384800398e-05*G0_2_2_5 - 1.92400192400199e-05*G0_2_3_0 + 4.81000481000498e-05*G0_2_3_1 - 0.000115440115440119*G0_2_3_2 + 7.69600769600797e-05*G0_2_3_3 + 0.000115440115440119*G0_2_3_5 - 9.62000962000997e-06*G0_2_4_0 + 1.92400192400199e-05*G0_2_4_1 - 7.69600769600796e-05*G0_2_4_2 - 7.69600769600796e-05*G0_2_4_4 + 3.84800384800398e-05*G0_2_4_5 - 3.84800384800398e-05*G0_2_5_0 + 1.92400192400199e-05*G0_2_5_1 - 3.84800384800398e-05*G0_2_5_2 + 0.000115440115440119*G0_2_5_3 + 3.84800384800398e-05*G0_2_5_4 + 0.000115440115440119*G0_2_5_5 - 5.77200577200596e-05*G0_3_0_0 - 1.92400192400198e-05*G0_3_0_1 - 1.92400192400199e-05*G0_3_0_2 + 0.000346320346320358*G0_3_0_3 + 0.000192400192400199*G0_3_0_4 + 0.000192400192400199*G0_3_0_5 - 1.92400192400198e-05*G0_3_1_0 - 0.00011544011544012*G0_3_1_1 + 4.81000481000498e-05*G0_3_1_2 + 7.69600769600791e-05*G0_3_1_3 + 0.000115440115440119*G0_3_1_4 - 1.92400192400199e-05*G0_3_2_0 + 4.81000481000498e-05*G0_3_2_1 - 0.000115440115440119*G0_3_2_2 + 7.69600769600797e-05*G0_3_2_3 + 0.000115440115440119*G0_3_2_5 + 0.000346320346320358*G0_3_3_0 + 7.69600769600791e-05*G0_3_3_1 + 7.69600769600797e-05*G0_3_3_2 - 0.00246272246272255*G0_3_3_3 - 0.000923520923520954*G0_3_3_4 - 0.000923520923520955*G0_3_3_5 + 0.000192400192400199*G0_3_4_0 + 0.000115440115440119*G0_3_4_1 - 0.000923520923520954*G0_3_4_3 - 0.000615680615680636*G0_3_4_4 - 0.000461760461760477*G0_3_4_5 + 0.000192400192400199*G0_3_5_0 + 0.000115440115440119*G0_3_5_2 - 0.000923520923520955*G0_3_5_3 - 0.000461760461760477*G0_3_5_4 - 0.000615680615680636*G0_3_5_5 - 3.84800384800398e-05*G0_4_0_1 - 9.62000962000997e-06*G0_4_0_2 + 0.000192400192400199*G0_4_0_3 + 0.000230880230880239*G0_4_0_4 + 0.000153920153920159*G0_4_0_5 - 3.84800384800398e-05*G0_4_1_0 - 3.84800384800398e-05*G0_4_1_1 + 1.92400192400199e-05*G0_4_1_2 + 0.000115440115440119*G0_4_1_3 + 0.000115440115440119*G0_4_1_4 + 3.84800384800397e-05*G0_4_1_5 - 9.62000962000997e-06*G0_4_2_0 + 1.92400192400199e-05*G0_4_2_1 - 7.69600769600796e-05*G0_4_2_2 - 7.69600769600796e-05*G0_4_2_4 + 3.84800384800398e-05*G0_4_2_5 + 0.000192400192400199*G0_4_3_0 + 0.000115440115440119*G0_4_3_1 - 0.000923520923520954*G0_4_3_3 - 0.000615680615680636*G0_4_3_4 - 0.000461760461760477*G0_4_3_5 + 0.000230880230880239*G0_4_4_0 + 0.000115440115440119*G0_4_4_1 - 7.69600769600796e-05*G0_4_4_2 - 0.000615680615680636*G0_4_4_3 - 0.000615680615680637*G0_4_4_4 - 0.000307840307840318*G0_4_4_5 + 0.000153920153920159*G0_4_5_0 + 3.84800384800397e-05*G0_4_5_1 + 3.84800384800398e-05*G0_4_5_2 - 0.000461760461760477*G0_4_5_3 - 0.000307840307840318*G0_4_5_4 - 0.000307840307840318*G0_4_5_5 - 9.62000962000995e-06*G0_5_0_1 - 3.84800384800398e-05*G0_5_0_2 + 0.000192400192400199*G0_5_0_3 + 0.000153920153920159*G0_5_0_4 + 0.000230880230880239*G0_5_0_5 - 9.62000962000995e-06*G0_5_1_0 - 7.69600769600797e-05*G0_5_1_1 + 1.92400192400199e-05*G0_5_1_2 + 3.84800384800397e-05*G0_5_1_4 - 7.69600769600798e-05*G0_5_1_5 - 3.84800384800398e-05*G0_5_2_0 + 1.92400192400199e-05*G0_5_2_1 - 3.84800384800398e-05*G0_5_2_2 + 0.000115440115440119*G0_5_2_3 + 3.84800384800398e-05*G0_5_2_4 + 0.000115440115440119*G0_5_2_5 + 0.000192400192400199*G0_5_3_0 + 0.000115440115440119*G0_5_3_2 - 0.000923520923520955*G0_5_3_3 - 0.000461760461760477*G0_5_3_4 - 0.000615680615680636*G0_5_3_5 + 0.000153920153920159*G0_5_4_0 + 3.84800384800397e-05*G0_5_4_1 + 3.84800384800398e-05*G0_5_4_2 - 0.000461760461760477*G0_5_4_3 - 0.000307840307840318*G0_5_4_4 - 0.000307840307840318*G0_5_4_5 + 0.000230880230880239*G0_5_5_0 - 7.69600769600798e-05*G0_5_5_1 + 0.000115440115440119*G0_5_5_2 - 0.000615680615680636*G0_5_5_3 - 0.000307840307840318*G0_5_5_4 - 0.000615680615680636*G0_5_5_5; + A[20] = -7.21500721500749e-06*G0_0_0_0 - 4.81000481000497e-06*G0_0_0_1 + 2.64550264550274e-05*G0_0_0_2 - 1.92400192400199e-05*G0_0_0_3 - 9.62000962000996e-06*G0_0_0_4 - 3.84800384800398e-05*G0_0_0_5 - 4.81000481000497e-06*G0_0_1_0 + 1.20250120250125e-05*G0_0_1_1 + 1.20250120250124e-05*G0_0_1_2 + 4.81000481000498e-05*G0_0_1_3 + 1.92400192400199e-05*G0_0_1_4 + 1.92400192400199e-05*G0_0_1_5 + 2.64550264550274e-05*G0_0_2_0 + 1.20250120250124e-05*G0_0_2_1 - 7.21500721500746e-05*G0_0_2_2 - 0.000115440115440119*G0_0_2_3 - 7.69600769600796e-05*G0_0_2_4 - 3.84800384800398e-05*G0_0_2_5 - 1.92400192400199e-05*G0_0_3_0 + 4.81000481000498e-05*G0_0_3_1 - 0.000115440115440119*G0_0_3_2 + 7.69600769600797e-05*G0_0_3_3 + 0.000115440115440119*G0_0_3_5 - 9.62000962000997e-06*G0_0_4_0 + 1.92400192400199e-05*G0_0_4_1 - 7.69600769600796e-05*G0_0_4_2 - 7.69600769600796e-05*G0_0_4_4 + 3.84800384800398e-05*G0_0_4_5 - 3.84800384800398e-05*G0_0_5_0 + 1.92400192400199e-05*G0_0_5_1 - 3.84800384800398e-05*G0_0_5_2 + 0.000115440115440119*G0_0_5_3 + 3.84800384800398e-05*G0_0_5_4 + 0.000115440115440119*G0_0_5_5 - 4.81000481000497e-06*G0_1_0_0 + 1.20250120250125e-05*G0_1_0_1 + 1.20250120250124e-05*G0_1_0_2 + 4.81000481000498e-05*G0_1_0_3 + 1.92400192400199e-05*G0_1_0_4 + 1.92400192400199e-05*G0_1_0_5 + 1.20250120250125e-05*G0_1_1_0 - 0.000144300144300149*G0_1_1_1 + 6.97450697450722e-05*G0_1_1_2 - 0.00011544011544012*G0_1_1_3 - 9.62000962000998e-06*G0_1_1_4 - 7.69600769600798e-05*G0_1_1_5 + 1.20250120250124e-05*G0_1_2_0 + 6.97450697450722e-05*G0_1_2_1 - 0.000144300144300149*G0_1_2_2 - 0.000115440115440119*G0_1_2_3 - 7.69600769600796e-05*G0_1_2_4 - 9.62000962000993e-06*G0_1_2_5 + 4.81000481000498e-05*G0_1_3_0 - 0.00011544011544012*G0_1_3_1 - 0.000115440115440119*G0_1_3_2 - 0.000615680615680637*G0_1_3_3 - 7.69600769600796e-05*G0_1_3_4 - 7.69600769600798e-05*G0_1_3_5 + 1.92400192400199e-05*G0_1_4_0 - 9.62000962000998e-06*G0_1_4_1 - 7.69600769600796e-05*G0_1_4_2 - 7.69600769600796e-05*G0_1_4_3 + 3.84800384800398e-05*G0_1_4_5 + 1.92400192400199e-05*G0_1_5_0 - 7.69600769600798e-05*G0_1_5_1 - 9.62000962000993e-06*G0_1_5_2 - 7.69600769600798e-05*G0_1_5_3 + 3.84800384800398e-05*G0_1_5_4 + 2.64550264550274e-05*G0_2_0_0 + 1.20250120250124e-05*G0_2_0_1 - 7.21500721500746e-05*G0_2_0_2 - 0.000115440115440119*G0_2_0_3 - 7.69600769600796e-05*G0_2_0_4 - 3.84800384800398e-05*G0_2_0_5 + 1.20250120250124e-05*G0_2_1_0 + 6.97450697450722e-05*G0_2_1_1 - 0.000144300144300149*G0_2_1_2 - 0.000115440115440119*G0_2_1_3 - 7.69600769600796e-05*G0_2_1_4 - 9.62000962000993e-06*G0_2_1_5 - 7.21500721500746e-05*G0_2_2_0 - 0.000144300144300149*G0_2_2_1 + 0.00093795093795097*G0_2_2_2 + 0.000577200577200597*G0_2_2_3 + 0.000288600288600299*G0_2_2_4 - 0.000115440115440119*G0_2_3_0 - 0.000115440115440119*G0_2_3_1 + 0.000577200577200597*G0_2_3_2 + 0.00115440115440119*G0_2_3_3 + 0.000384800384800398*G0_2_3_4 + 0.000230880230880239*G0_2_3_5 - 7.69600769600796e-05*G0_2_4_0 - 7.69600769600796e-05*G0_2_4_1 + 0.000288600288600299*G0_2_4_2 + 0.000384800384800398*G0_2_4_3 + 0.000384800384800398*G0_2_4_4 + 0.000153920153920159*G0_2_4_5 - 3.84800384800398e-05*G0_2_5_0 - 9.62000962000993e-06*G0_2_5_1 + 0.000230880230880239*G0_2_5_3 + 0.000153920153920159*G0_2_5_4 + 0.000192400192400199*G0_2_5_5 - 1.92400192400199e-05*G0_3_0_0 + 4.81000481000498e-05*G0_3_0_1 - 0.000115440115440119*G0_3_0_2 + 7.69600769600797e-05*G0_3_0_3 + 0.000115440115440119*G0_3_0_5 + 4.81000481000498e-05*G0_3_1_0 - 0.00011544011544012*G0_3_1_1 - 0.000115440115440119*G0_3_1_2 - 0.000615680615680637*G0_3_1_3 - 7.69600769600796e-05*G0_3_1_4 - 7.69600769600798e-05*G0_3_1_5 - 0.000115440115440119*G0_3_2_0 - 0.000115440115440119*G0_3_2_1 + 0.000577200577200597*G0_3_2_2 + 0.00115440115440119*G0_3_2_3 + 0.000384800384800398*G0_3_2_4 + 0.000230880230880239*G0_3_2_5 + 7.69600769600797e-05*G0_3_3_0 - 0.000615680615680637*G0_3_3_1 + 0.00115440115440119*G0_3_3_2 - 0.000615680615680637*G0_3_3_5 - 7.69600769600796e-05*G0_3_4_1 + 0.000384800384800398*G0_3_4_2 - 0.000307840307840318*G0_3_4_5 + 0.000115440115440119*G0_3_5_0 - 7.69600769600798e-05*G0_3_5_1 + 0.000230880230880239*G0_3_5_2 - 0.000615680615680637*G0_3_5_3 - 0.000307840307840318*G0_3_5_4 - 0.000615680615680637*G0_3_5_5 - 9.62000962000997e-06*G0_4_0_0 + 1.92400192400199e-05*G0_4_0_1 - 7.69600769600796e-05*G0_4_0_2 - 7.69600769600796e-05*G0_4_0_4 + 3.84800384800398e-05*G0_4_0_5 + 1.92400192400199e-05*G0_4_1_0 - 9.62000962000999e-06*G0_4_1_1 - 7.69600769600796e-05*G0_4_1_2 - 7.69600769600796e-05*G0_4_1_3 + 3.84800384800398e-05*G0_4_1_5 - 7.69600769600796e-05*G0_4_2_0 - 7.69600769600796e-05*G0_4_2_1 + 0.000288600288600299*G0_4_2_2 + 0.000384800384800398*G0_4_2_3 + 0.000384800384800398*G0_4_2_4 + 0.000153920153920159*G0_4_2_5 - 7.69600769600796e-05*G0_4_3_1 + 0.000384800384800398*G0_4_3_2 - 0.000307840307840318*G0_4_3_5 - 7.69600769600796e-05*G0_4_4_0 + 0.000384800384800398*G0_4_4_2 - 0.000307840307840319*G0_4_4_5 + 3.84800384800398e-05*G0_4_5_0 + 3.84800384800398e-05*G0_4_5_1 + 0.000153920153920159*G0_4_5_2 - 0.000307840307840318*G0_4_5_3 - 0.000307840307840319*G0_4_5_4 - 0.000461760461760478*G0_4_5_5 - 3.84800384800398e-05*G0_5_0_0 + 1.92400192400199e-05*G0_5_0_1 - 3.84800384800398e-05*G0_5_0_2 + 0.000115440115440119*G0_5_0_3 + 3.84800384800398e-05*G0_5_0_4 + 0.000115440115440119*G0_5_0_5 + 1.92400192400199e-05*G0_5_1_0 - 7.69600769600798e-05*G0_5_1_1 - 9.62000962000993e-06*G0_5_1_2 - 7.69600769600798e-05*G0_5_1_3 + 3.84800384800398e-05*G0_5_1_4 - 3.84800384800398e-05*G0_5_2_0 - 9.62000962000993e-06*G0_5_2_1 + 0.000230880230880239*G0_5_2_3 + 0.000153920153920159*G0_5_2_4 + 0.000192400192400199*G0_5_2_5 + 0.000115440115440119*G0_5_3_0 - 7.69600769600797e-05*G0_5_3_1 + 0.000230880230880239*G0_5_3_2 - 0.000615680615680637*G0_5_3_3 - 0.000307840307840318*G0_5_3_4 - 0.000615680615680637*G0_5_3_5 + 3.84800384800398e-05*G0_5_4_0 + 3.84800384800398e-05*G0_5_4_1 + 0.000153920153920159*G0_5_4_2 - 0.000307840307840318*G0_5_4_3 - 0.000307840307840319*G0_5_4_4 - 0.000461760461760478*G0_5_4_5 + 0.000115440115440119*G0_5_5_0 + 0.000192400192400199*G0_5_5_2 - 0.000615680615680637*G0_5_5_3 - 0.000461760461760478*G0_5_5_4 - 0.000923520923520955*G0_5_5_5; + A[13] = 2.16450216450224e-05*G0_0_0_0 - 7.21500721500748e-06*G0_0_0_1 - 7.21500721500746e-06*G0_0_0_2 - 4.81000481000497e-06*G0_0_0_3 + 1.20250120250124e-05*G0_0_0_4 + 1.20250120250125e-05*G0_0_0_5 - 7.21500721500748e-06*G0_0_1_0 + 2.16450216450225e-05*G0_0_1_1 - 7.21500721500747e-06*G0_0_1_2 + 1.20250120250125e-05*G0_0_1_3 - 4.81000481000497e-06*G0_0_1_4 + 1.20250120250125e-05*G0_0_1_5 - 7.21500721500746e-06*G0_0_2_0 - 7.21500721500747e-06*G0_0_2_1 + 2.16450216450224e-05*G0_0_2_2 + 1.20250120250124e-05*G0_0_2_3 + 1.20250120250124e-05*G0_0_2_4 - 4.81000481000498e-06*G0_0_2_5 - 4.81000481000497e-06*G0_0_3_0 + 1.20250120250125e-05*G0_0_3_1 + 1.20250120250124e-05*G0_0_3_2 + 4.81000481000498e-05*G0_0_3_3 + 1.92400192400199e-05*G0_0_3_4 + 1.92400192400199e-05*G0_0_3_5 + 1.20250120250124e-05*G0_0_4_0 - 4.81000481000497e-06*G0_0_4_1 + 1.20250120250124e-05*G0_0_4_2 + 1.92400192400199e-05*G0_0_4_3 + 4.81000481000498e-05*G0_0_4_4 + 1.92400192400199e-05*G0_0_4_5 + 1.20250120250125e-05*G0_0_5_0 + 1.20250120250125e-05*G0_0_5_1 - 4.81000481000498e-06*G0_0_5_2 + 1.92400192400199e-05*G0_0_5_3 + 1.92400192400199e-05*G0_0_5_4 + 4.81000481000498e-05*G0_0_5_5 - 7.21500721500748e-06*G0_1_0_0 + 2.16450216450225e-05*G0_1_0_1 - 7.21500721500747e-06*G0_1_0_2 + 1.20250120250125e-05*G0_1_0_3 - 4.81000481000497e-06*G0_1_0_4 + 1.20250120250125e-05*G0_1_0_5 + 2.16450216450225e-05*G0_1_1_0 - 0.000216450216450224*G0_1_1_1 + 2.16450216450224e-05*G0_1_1_2 - 0.000144300144300149*G0_1_1_3 - 7.21500721500747e-06*G0_1_1_4 - 7.21500721500749e-05*G0_1_1_5 - 7.21500721500747e-06*G0_1_2_0 + 2.16450216450224e-05*G0_1_2_1 + 2.16450216450224e-05*G0_1_2_2 + 6.97450697450722e-05*G0_1_2_3 + 2.64550264550274e-05*G0_1_2_4 + 2.64550264550274e-05*G0_1_2_5 + 1.20250120250125e-05*G0_1_3_0 - 0.000144300144300149*G0_1_3_1 + 6.97450697450722e-05*G0_1_3_2 - 0.00011544011544012*G0_1_3_3 - 9.62000962000999e-06*G0_1_3_4 - 7.69600769600798e-05*G0_1_3_5 - 4.81000481000497e-06*G0_1_4_0 - 7.21500721500747e-06*G0_1_4_1 + 2.64550264550274e-05*G0_1_4_2 - 9.62000962000999e-06*G0_1_4_3 - 1.92400192400199e-05*G0_1_4_4 - 3.84800384800398e-05*G0_1_4_5 + 1.20250120250125e-05*G0_1_5_0 - 7.21500721500749e-05*G0_1_5_1 + 2.64550264550274e-05*G0_1_5_2 - 7.69600769600798e-05*G0_1_5_3 - 3.84800384800398e-05*G0_1_5_4 - 0.00011544011544012*G0_1_5_5 - 7.21500721500746e-06*G0_2_0_0 - 7.21500721500747e-06*G0_2_0_1 + 2.16450216450224e-05*G0_2_0_2 + 1.20250120250124e-05*G0_2_0_3 + 1.20250120250124e-05*G0_2_0_4 - 4.81000481000498e-06*G0_2_0_5 - 7.21500721500747e-06*G0_2_1_0 + 2.16450216450224e-05*G0_2_1_1 + 2.16450216450224e-05*G0_2_1_2 + 6.97450697450722e-05*G0_2_1_3 + 2.64550264550274e-05*G0_2_1_4 + 2.64550264550274e-05*G0_2_1_5 + 2.16450216450224e-05*G0_2_2_0 + 2.16450216450223e-05*G0_2_2_1 - 0.000216450216450224*G0_2_2_2 - 0.000144300144300149*G0_2_2_3 - 7.21500721500746e-05*G0_2_2_4 - 7.21500721500747e-06*G0_2_2_5 + 1.20250120250124e-05*G0_2_3_0 + 6.97450697450722e-05*G0_2_3_1 - 0.000144300144300149*G0_2_3_2 - 0.000115440115440119*G0_2_3_3 - 7.69600769600796e-05*G0_2_3_4 - 9.62000962000993e-06*G0_2_3_5 + 1.20250120250124e-05*G0_2_4_0 + 2.64550264550274e-05*G0_2_4_1 - 7.21500721500746e-05*G0_2_4_2 - 7.69600769600796e-05*G0_2_4_3 - 0.000115440115440119*G0_2_4_4 - 3.84800384800398e-05*G0_2_4_5 - 4.81000481000498e-06*G0_2_5_0 + 2.64550264550274e-05*G0_2_5_1 - 7.21500721500747e-06*G0_2_5_2 - 9.62000962000993e-06*G0_2_5_3 - 3.84800384800398e-05*G0_2_5_4 - 1.92400192400199e-05*G0_2_5_5 - 4.81000481000497e-06*G0_3_0_0 + 1.20250120250125e-05*G0_3_0_1 + 1.20250120250124e-05*G0_3_0_2 + 4.81000481000498e-05*G0_3_0_3 + 1.92400192400199e-05*G0_3_0_4 + 1.92400192400199e-05*G0_3_0_5 + 1.20250120250125e-05*G0_3_1_0 - 0.000144300144300149*G0_3_1_1 + 6.97450697450722e-05*G0_3_1_2 - 0.00011544011544012*G0_3_1_3 - 9.62000962000998e-06*G0_3_1_4 - 7.69600769600798e-05*G0_3_1_5 + 1.20250120250124e-05*G0_3_2_0 + 6.97450697450722e-05*G0_3_2_1 - 0.000144300144300149*G0_3_2_2 - 0.000115440115440119*G0_3_2_3 - 7.69600769600796e-05*G0_3_2_4 - 9.62000962000993e-06*G0_3_2_5 + 4.81000481000498e-05*G0_3_3_0 - 0.00011544011544012*G0_3_3_1 - 0.000115440115440119*G0_3_3_2 - 0.000615680615680637*G0_3_3_3 - 7.69600769600796e-05*G0_3_3_4 - 7.69600769600798e-05*G0_3_3_5 + 1.92400192400199e-05*G0_3_4_0 - 9.62000962000999e-06*G0_3_4_1 - 7.69600769600796e-05*G0_3_4_2 - 7.69600769600796e-05*G0_3_4_3 + 3.84800384800398e-05*G0_3_4_5 + 1.92400192400199e-05*G0_3_5_0 - 7.69600769600798e-05*G0_3_5_1 - 9.62000962000992e-06*G0_3_5_2 - 7.69600769600798e-05*G0_3_5_3 + 3.84800384800398e-05*G0_3_5_4 + 1.20250120250125e-05*G0_4_0_0 - 4.81000481000497e-06*G0_4_0_1 + 1.20250120250124e-05*G0_4_0_2 + 1.92400192400199e-05*G0_4_0_3 + 4.81000481000497e-05*G0_4_0_4 + 1.92400192400199e-05*G0_4_0_5 - 4.81000481000497e-06*G0_4_1_0 - 7.21500721500747e-06*G0_4_1_1 + 2.64550264550274e-05*G0_4_1_2 - 9.62000962000998e-06*G0_4_1_3 - 1.92400192400199e-05*G0_4_1_4 - 3.84800384800398e-05*G0_4_1_5 + 1.20250120250124e-05*G0_4_2_0 + 2.64550264550274e-05*G0_4_2_1 - 7.21500721500746e-05*G0_4_2_2 - 7.69600769600796e-05*G0_4_2_3 - 0.000115440115440119*G0_4_2_4 - 3.84800384800398e-05*G0_4_2_5 + 1.92400192400199e-05*G0_4_3_0 - 9.62000962000998e-06*G0_4_3_1 - 7.69600769600796e-05*G0_4_3_2 - 7.69600769600796e-05*G0_4_3_3 + 3.84800384800398e-05*G0_4_3_5 + 4.81000481000498e-05*G0_4_4_0 - 1.92400192400199e-05*G0_4_4_1 - 0.000115440115440119*G0_4_4_2 + 7.69600769600798e-05*G0_4_4_4 + 0.00011544011544012*G0_4_4_5 + 1.92400192400199e-05*G0_4_5_0 - 3.84800384800398e-05*G0_4_5_1 - 3.84800384800398e-05*G0_4_5_2 + 3.84800384800398e-05*G0_4_5_3 + 0.00011544011544012*G0_4_5_4 + 0.00011544011544012*G0_4_5_5 + 1.20250120250124e-05*G0_5_0_0 + 1.20250120250125e-05*G0_5_0_1 - 4.81000481000498e-06*G0_5_0_2 + 1.92400192400199e-05*G0_5_0_3 + 1.92400192400199e-05*G0_5_0_4 + 4.81000481000498e-05*G0_5_0_5 + 1.20250120250125e-05*G0_5_1_0 - 7.21500721500749e-05*G0_5_1_1 + 2.64550264550274e-05*G0_5_1_2 - 7.69600769600798e-05*G0_5_1_3 - 3.84800384800398e-05*G0_5_1_4 - 0.00011544011544012*G0_5_1_5 - 4.81000481000498e-06*G0_5_2_0 + 2.64550264550274e-05*G0_5_2_1 - 7.21500721500748e-06*G0_5_2_2 - 9.62000962000993e-06*G0_5_2_3 - 3.84800384800398e-05*G0_5_2_4 - 1.92400192400199e-05*G0_5_2_5 + 1.92400192400199e-05*G0_5_3_0 - 7.69600769600798e-05*G0_5_3_1 - 9.62000962000993e-06*G0_5_3_2 - 7.69600769600798e-05*G0_5_3_3 + 3.84800384800398e-05*G0_5_3_4 + 1.92400192400199e-05*G0_5_4_0 - 3.84800384800398e-05*G0_5_4_1 - 3.84800384800398e-05*G0_5_4_2 + 3.84800384800398e-05*G0_5_4_3 + 0.00011544011544012*G0_5_4_4 + 0.00011544011544012*G0_5_4_5 + 4.81000481000498e-05*G0_5_5_0 - 0.00011544011544012*G0_5_5_1 - 1.92400192400199e-05*G0_5_5_2 + 0.00011544011544012*G0_5_5_4 + 7.69600769600796e-05*G0_5_5_5; + A[31] = A[9] - 0.000137085137085142*G0_0_0_0 + 4.32900432900448e-05*G0_0_0_1 + 1.68350168350174e-05*G0_0_0_2 + 9.62000962000987e-06*G0_0_0_3 - 3.84800384800399e-05*G0_0_0_4 - 0.00010582010582011*G0_0_0_5 + 4.32900432900448e-05*G0_0_1_0 - 7.21500721500747e-05*G0_0_1_1 + 3.84800384800399e-05*G0_0_1_3 + 2.88600288600299e-05*G0_0_1_4 - 3.84800384800398e-05*G0_0_1_5 + 1.68350168350174e-05*G0_0_2_0 - 1.68350168350174e-05*G0_0_2_2 - 2.88600288600299e-05*G0_0_2_3 + 2.88600288600299e-05*G0_0_2_5 + 9.62000962000988e-06*G0_0_3_0 + 3.84800384800398e-05*G0_0_3_1 - 2.88600288600299e-05*G0_0_3_2 - 7.69600769600793e-05*G0_0_3_3 - 7.69600769600795e-05*G0_0_3_4 - 7.69600769600796e-05*G0_0_3_5 - 3.84800384800399e-05*G0_0_4_0 + 2.88600288600299e-05*G0_0_4_1 - 7.69600769600795e-05*G0_0_4_3 - 0.000115440115440119*G0_0_4_4 - 0.000115440115440119*G0_0_4_5 - 0.00010582010582011*G0_0_5_0 - 3.84800384800398e-05*G0_0_5_1 + 2.88600288600299e-05*G0_0_5_2 - 7.69600769600795e-05*G0_0_5_3 - 0.000115440115440119*G0_0_5_4 - 0.000538720538720558*G0_0_5_5 + 4.32900432900448e-05*G0_1_0_0 - 7.21500721500748e-05*G0_1_0_1 + 3.84800384800399e-05*G0_1_0_3 + 2.88600288600299e-05*G0_1_0_4 - 3.84800384800398e-05*G0_1_0_5 - 7.21500721500748e-05*G0_1_1_0 + 7.21500721500745e-05*G0_1_1_2 - 0.000288600288600298*G0_1_1_3 + 0.000288600288600299*G0_1_1_5 + 7.21500721500745e-05*G0_1_2_1 - 4.32900432900448e-05*G0_1_2_2 + 3.84800384800398e-05*G0_1_2_3 - 2.88600288600298e-05*G0_1_2_4 - 3.84800384800398e-05*G0_1_2_5 + 3.84800384800399e-05*G0_1_3_0 - 0.000288600288600298*G0_1_3_1 + 3.84800384800398e-05*G0_1_3_2 - 0.000769600769600796*G0_1_3_3 - 7.69600769600796e-05*G0_1_3_4 + 2.88600288600299e-05*G0_1_4_0 - 2.88600288600298e-05*G0_1_4_2 - 7.69600769600796e-05*G0_1_4_3 + 7.69600769600796e-05*G0_1_4_5 - 3.84800384800398e-05*G0_1_5_0 + 0.000288600288600299*G0_1_5_1 - 3.84800384800398e-05*G0_1_5_2 + 7.69600769600796e-05*G0_1_5_4 + 0.000769600769600797*G0_1_5_5 + 1.68350168350174e-05*G0_2_0_0 - 1.68350168350174e-05*G0_2_0_2 - 2.88600288600299e-05*G0_2_0_3 + 2.88600288600299e-05*G0_2_0_5 + 7.21500721500745e-05*G0_2_1_1 - 4.32900432900448e-05*G0_2_1_2 + 3.84800384800398e-05*G0_2_1_3 - 2.88600288600298e-05*G0_2_1_4 - 3.84800384800398e-05*G0_2_1_5 - 1.68350168350174e-05*G0_2_2_0 - 4.32900432900448e-05*G0_2_2_1 + 0.000137085137085142*G0_2_2_2 + 0.000105820105820109*G0_2_2_3 + 3.84800384800398e-05*G0_2_2_4 - 9.62000962000997e-06*G0_2_2_5 - 2.88600288600299e-05*G0_2_3_0 + 3.84800384800398e-05*G0_2_3_1 + 0.000105820105820109*G0_2_3_2 + 0.000538720538720558*G0_2_3_3 + 0.000115440115440119*G0_2_3_4 + 7.69600769600797e-05*G0_2_3_5 - 2.88600288600298e-05*G0_2_4_1 + 3.84800384800398e-05*G0_2_4_2 + 0.000115440115440119*G0_2_4_3 + 0.000115440115440119*G0_2_4_4 + 7.69600769600797e-05*G0_2_4_5 + 2.88600288600299e-05*G0_2_5_0 - 3.84800384800398e-05*G0_2_5_1 - 9.62000962000997e-06*G0_2_5_2 + 7.69600769600797e-05*G0_2_5_3 + 7.69600769600797e-05*G0_2_5_4 + 7.69600769600796e-05*G0_2_5_5 + 9.62000962000987e-06*G0_3_0_0 + 3.84800384800398e-05*G0_3_0_1 - 2.88600288600299e-05*G0_3_0_2 - 7.69600769600792e-05*G0_3_0_3 - 7.69600769600795e-05*G0_3_0_4 - 7.69600769600796e-05*G0_3_0_5 + 3.84800384800398e-05*G0_3_1_0 - 0.000288600288600298*G0_3_1_1 + 3.84800384800398e-05*G0_3_1_2 - 0.000769600769600796*G0_3_1_3 - 7.69600769600796e-05*G0_3_1_4 - 2.88600288600299e-05*G0_3_2_0 + 3.84800384800398e-05*G0_3_2_1 + 0.000105820105820109*G0_3_2_2 + 0.000538720538720558*G0_3_2_3 + 0.000115440115440119*G0_3_2_4 + 7.69600769600797e-05*G0_3_2_5 - 7.69600769600792e-05*G0_3_3_0 - 0.000769600769600796*G0_3_3_1 + 0.000538720538720558*G0_3_3_2 + 0.000307840307840318*G0_3_3_4 - 7.69600769600795e-05*G0_3_4_0 - 7.69600769600796e-05*G0_3_4_1 + 0.000115440115440119*G0_3_4_2 + 0.000307840307840318*G0_3_4_3 + 0.000153920153920159*G0_3_4_4 - 7.69600769600796e-05*G0_3_5_0 + 7.69600769600797e-05*G0_3_5_2 - 3.84800384800398e-05*G0_4_0_0 + 2.88600288600298e-05*G0_4_0_1 - 7.69600769600795e-05*G0_4_0_3 - 0.000115440115440119*G0_4_0_4 - 0.000115440115440119*G0_4_0_5 + 2.88600288600298e-05*G0_4_1_0 - 2.88600288600298e-05*G0_4_1_2 - 7.69600769600796e-05*G0_4_1_3 + 7.69600769600796e-05*G0_4_1_5 - 2.88600288600298e-05*G0_4_2_1 + 3.84800384800398e-05*G0_4_2_2 + 0.000115440115440119*G0_4_2_3 + 0.000115440115440119*G0_4_2_4 + 7.69600769600797e-05*G0_4_2_5 - 7.69600769600795e-05*G0_4_3_0 - 7.69600769600796e-05*G0_4_3_1 + 0.000115440115440119*G0_4_3_2 + 0.000307840307840318*G0_4_3_3 + 0.000153920153920159*G0_4_3_4 - 0.000115440115440119*G0_4_4_0 + 0.000115440115440119*G0_4_4_2 + 0.000153920153920159*G0_4_4_3 - 0.00015392015392016*G0_4_4_5 - 0.000115440115440119*G0_4_5_0 + 7.69600769600796e-05*G0_4_5_1 + 7.69600769600797e-05*G0_4_5_2 - 0.00015392015392016*G0_4_5_4 - 0.000307840307840319*G0_4_5_5 - 0.00010582010582011*G0_5_0_0 - 3.84800384800398e-05*G0_5_0_1 + 2.88600288600299e-05*G0_5_0_2 - 7.69600769600795e-05*G0_5_0_3 - 0.000115440115440119*G0_5_0_4 - 0.000538720538720558*G0_5_0_5 - 3.84800384800398e-05*G0_5_1_0 + 0.000288600288600299*G0_5_1_1 - 3.84800384800398e-05*G0_5_1_2 + 7.69600769600796e-05*G0_5_1_4 + 0.000769600769600797*G0_5_1_5 + 2.88600288600299e-05*G0_5_2_0 - 3.84800384800398e-05*G0_5_2_1 - 9.62000962000997e-06*G0_5_2_2 + 7.69600769600797e-05*G0_5_2_3 + 7.69600769600797e-05*G0_5_2_4 + 7.69600769600796e-05*G0_5_2_5 - 7.69600769600795e-05*G0_5_3_0 + 7.69600769600797e-05*G0_5_3_2 - 0.000115440115440119*G0_5_4_0 + 7.69600769600796e-05*G0_5_4_1 + 7.69600769600797e-05*G0_5_4_2 - 0.00015392015392016*G0_5_4_4 - 0.000307840307840319*G0_5_4_5 - 0.000538720538720558*G0_5_5_0 + 0.000769600769600797*G0_5_5_1 + 7.69600769600797e-05*G0_5_5_2 - 0.000307840307840319*G0_5_5_4; + A[3] = A[18]; + A[17] = -7.21500721500747e-05*G0_0_0_0 + 1.20250120250125e-05*G0_0_0_1 + 2.64550264550274e-05*G0_0_0_2 - 3.84800384800398e-05*G0_0_0_3 - 7.69600769600796e-05*G0_0_0_4 - 0.000115440115440119*G0_0_0_5 + 1.20250120250125e-05*G0_0_1_0 + 1.20250120250125e-05*G0_0_1_1 - 4.81000481000498e-06*G0_0_1_2 + 1.92400192400199e-05*G0_0_1_3 + 1.92400192400199e-05*G0_0_1_4 + 4.81000481000498e-05*G0_0_1_5 + 2.64550264550274e-05*G0_0_2_0 - 4.81000481000498e-06*G0_0_2_1 - 7.21500721500748e-06*G0_0_2_2 - 3.84800384800398e-05*G0_0_2_3 - 9.62000962000994e-06*G0_0_2_4 - 1.92400192400199e-05*G0_0_2_5 - 3.84800384800398e-05*G0_0_3_0 + 1.92400192400199e-05*G0_0_3_1 - 3.84800384800398e-05*G0_0_3_2 + 0.000115440115440119*G0_0_3_3 + 3.84800384800398e-05*G0_0_3_4 + 0.000115440115440119*G0_0_3_5 - 7.69600769600796e-05*G0_0_4_0 + 1.92400192400199e-05*G0_0_4_1 - 9.62000962000995e-06*G0_0_4_2 + 3.84800384800398e-05*G0_0_4_3 - 7.69600769600796e-05*G0_0_4_4 - 0.00011544011544012*G0_0_5_0 + 4.81000481000498e-05*G0_0_5_1 - 1.92400192400199e-05*G0_0_5_2 + 0.000115440115440119*G0_0_5_3 + 7.69600769600793e-05*G0_0_5_5 + 1.20250120250125e-05*G0_1_0_0 + 1.20250120250125e-05*G0_1_0_1 - 4.81000481000498e-06*G0_1_0_2 + 1.92400192400199e-05*G0_1_0_3 + 1.92400192400199e-05*G0_1_0_4 + 4.81000481000498e-05*G0_1_0_5 + 1.20250120250125e-05*G0_1_1_0 - 7.21500721500749e-05*G0_1_1_1 + 2.64550264550274e-05*G0_1_1_2 - 7.69600769600798e-05*G0_1_1_3 - 3.84800384800398e-05*G0_1_1_4 - 0.00011544011544012*G0_1_1_5 - 4.81000481000498e-06*G0_1_2_0 + 2.64550264550274e-05*G0_1_2_1 - 7.21500721500748e-06*G0_1_2_2 - 9.62000962000993e-06*G0_1_2_3 - 3.84800384800398e-05*G0_1_2_4 - 1.92400192400199e-05*G0_1_2_5 + 1.92400192400199e-05*G0_1_3_0 - 7.69600769600798e-05*G0_1_3_1 - 9.62000962000993e-06*G0_1_3_2 - 7.69600769600798e-05*G0_1_3_3 + 3.84800384800398e-05*G0_1_3_4 + 1.92400192400199e-05*G0_1_4_0 - 3.84800384800398e-05*G0_1_4_1 - 3.84800384800398e-05*G0_1_4_2 + 3.84800384800398e-05*G0_1_4_3 + 0.00011544011544012*G0_1_4_4 + 0.00011544011544012*G0_1_4_5 + 4.81000481000498e-05*G0_1_5_0 - 0.00011544011544012*G0_1_5_1 - 1.92400192400199e-05*G0_1_5_2 + 0.00011544011544012*G0_1_5_4 + 7.69600769600796e-05*G0_1_5_5 + 2.64550264550274e-05*G0_2_0_0 - 4.81000481000498e-06*G0_2_0_1 - 7.21500721500748e-06*G0_2_0_2 - 3.84800384800398e-05*G0_2_0_3 - 9.62000962000994e-06*G0_2_0_4 - 1.92400192400199e-05*G0_2_0_5 - 4.81000481000498e-06*G0_2_1_0 + 2.64550264550274e-05*G0_2_1_1 - 7.21500721500747e-06*G0_2_1_2 - 9.62000962000993e-06*G0_2_1_3 - 3.84800384800398e-05*G0_2_1_4 - 1.92400192400199e-05*G0_2_1_5 - 7.21500721500748e-06*G0_2_2_0 - 7.21500721500747e-06*G0_2_2_1 + 7.21500721500748e-05*G0_2_2_2 - 5.77200577200597e-05*G0_2_2_5 - 3.84800384800398e-05*G0_2_3_0 - 9.62000962000993e-06*G0_2_3_1 + 0.000230880230880239*G0_2_3_3 + 0.000153920153920159*G0_2_3_4 + 0.000192400192400199*G0_2_3_5 - 9.62000962000994e-06*G0_2_4_0 - 3.84800384800398e-05*G0_2_4_1 + 0.000153920153920159*G0_2_4_3 + 0.000230880230880239*G0_2_4_4 + 0.000192400192400199*G0_2_4_5 - 1.92400192400199e-05*G0_2_5_0 - 1.92400192400199e-05*G0_2_5_1 - 5.77200577200597e-05*G0_2_5_2 + 0.000192400192400199*G0_2_5_3 + 0.000192400192400199*G0_2_5_4 + 0.000346320346320358*G0_2_5_5 - 3.84800384800398e-05*G0_3_0_0 + 1.92400192400199e-05*G0_3_0_1 - 3.84800384800398e-05*G0_3_0_2 + 0.000115440115440119*G0_3_0_3 + 3.84800384800398e-05*G0_3_0_4 + 0.000115440115440119*G0_3_0_5 + 1.92400192400199e-05*G0_3_1_0 - 7.69600769600798e-05*G0_3_1_1 - 9.62000962000993e-06*G0_3_1_2 - 7.69600769600798e-05*G0_3_1_3 + 3.84800384800398e-05*G0_3_1_4 - 3.84800384800398e-05*G0_3_2_0 - 9.62000962000993e-06*G0_3_2_1 + 0.000230880230880239*G0_3_2_3 + 0.000153920153920159*G0_3_2_4 + 0.000192400192400199*G0_3_2_5 + 0.000115440115440119*G0_3_3_0 - 7.69600769600798e-05*G0_3_3_1 + 0.000230880230880239*G0_3_3_2 - 0.000615680615680637*G0_3_3_3 - 0.000307840307840318*G0_3_3_4 - 0.000615680615680637*G0_3_3_5 + 3.84800384800398e-05*G0_3_4_0 + 3.84800384800398e-05*G0_3_4_1 + 0.000153920153920159*G0_3_4_2 - 0.000307840307840318*G0_3_4_3 - 0.000307840307840319*G0_3_4_4 - 0.000461760461760478*G0_3_4_5 + 0.000115440115440119*G0_3_5_0 + 0.000192400192400199*G0_3_5_2 - 0.000615680615680637*G0_3_5_3 - 0.000461760461760478*G0_3_5_4 - 0.000923520923520955*G0_3_5_5 - 7.69600769600796e-05*G0_4_0_0 + 1.92400192400199e-05*G0_4_0_1 - 9.62000962000994e-06*G0_4_0_2 + 3.84800384800398e-05*G0_4_0_3 - 7.69600769600796e-05*G0_4_0_4 + 1.92400192400199e-05*G0_4_1_0 - 3.84800384800398e-05*G0_4_1_1 - 3.84800384800398e-05*G0_4_1_2 + 3.84800384800398e-05*G0_4_1_3 + 0.000115440115440119*G0_4_1_4 + 0.00011544011544012*G0_4_1_5 - 9.62000962000994e-06*G0_4_2_0 - 3.84800384800398e-05*G0_4_2_1 + 0.000153920153920159*G0_4_2_3 + 0.000230880230880239*G0_4_2_4 + 0.000192400192400199*G0_4_2_5 + 3.84800384800398e-05*G0_4_3_0 + 3.84800384800398e-05*G0_4_3_1 + 0.000153920153920159*G0_4_3_2 - 0.000307840307840318*G0_4_3_3 - 0.000307840307840319*G0_4_3_4 - 0.000461760461760478*G0_4_3_5 - 7.69600769600796e-05*G0_4_4_0 + 0.000115440115440119*G0_4_4_1 + 0.000230880230880239*G0_4_4_2 - 0.000307840307840319*G0_4_4_3 - 0.000615680615680637*G0_4_4_4 - 0.000615680615680637*G0_4_4_5 + 0.00011544011544012*G0_4_5_1 + 0.000192400192400199*G0_4_5_2 - 0.000461760461760478*G0_4_5_3 - 0.000615680615680637*G0_4_5_4 - 0.000923520923520956*G0_4_5_5 - 0.00011544011544012*G0_5_0_0 + 4.81000481000498e-05*G0_5_0_1 - 1.92400192400199e-05*G0_5_0_2 + 0.000115440115440119*G0_5_0_3 + 7.69600769600793e-05*G0_5_0_5 + 4.81000481000498e-05*G0_5_1_0 - 0.00011544011544012*G0_5_1_1 - 1.92400192400199e-05*G0_5_1_2 + 0.00011544011544012*G0_5_1_4 + 7.69600769600796e-05*G0_5_1_5 - 1.92400192400199e-05*G0_5_2_0 - 1.92400192400199e-05*G0_5_2_1 - 5.77200577200597e-05*G0_5_2_2 + 0.000192400192400199*G0_5_2_3 + 0.000192400192400199*G0_5_2_4 + 0.000346320346320358*G0_5_2_5 + 0.000115440115440119*G0_5_3_0 + 0.000192400192400199*G0_5_3_2 - 0.000615680615680637*G0_5_3_3 - 0.000461760461760478*G0_5_3_4 - 0.000923520923520955*G0_5_3_5 + 0.00011544011544012*G0_5_4_1 + 0.000192400192400199*G0_5_4_2 - 0.000461760461760478*G0_5_4_3 - 0.000615680615680637*G0_5_4_4 - 0.000923520923520956*G0_5_4_5 + 7.69600769600793e-05*G0_5_5_0 + 7.69600769600796e-05*G0_5_5_1 + 0.000346320346320358*G0_5_5_2 - 0.000923520923520955*G0_5_5_3 - 0.000923520923520956*G0_5_5_4 - 0.00246272246272255*G0_5_5_5; + A[24] = 0.00093795093795097*G0_0_0_0 - 7.21500721500747e-05*G0_0_0_1 - 0.000144300144300149*G0_0_0_2 + 0.000577200577200597*G0_0_0_4 + 0.000288600288600299*G0_0_0_5 - 7.21500721500747e-05*G0_0_1_0 + 2.64550264550274e-05*G0_0_1_1 + 1.20250120250125e-05*G0_0_1_2 - 3.84800384800398e-05*G0_0_1_3 - 0.000115440115440119*G0_0_1_4 - 7.69600769600796e-05*G0_0_1_5 - 0.000144300144300149*G0_0_2_0 + 1.20250120250125e-05*G0_0_2_1 + 6.97450697450721e-05*G0_0_2_2 - 9.62000962000996e-06*G0_0_2_3 - 0.000115440115440119*G0_0_2_4 - 7.69600769600796e-05*G0_0_2_5 - 3.84800384800398e-05*G0_0_3_1 - 9.62000962000997e-06*G0_0_3_2 + 0.000192400192400199*G0_0_3_3 + 0.000230880230880239*G0_0_3_4 + 0.000153920153920159*G0_0_3_5 + 0.000577200577200597*G0_0_4_0 - 0.000115440115440119*G0_0_4_1 - 0.000115440115440119*G0_0_4_2 + 0.000230880230880239*G0_0_4_3 + 0.00115440115440119*G0_0_4_4 + 0.000384800384800398*G0_0_4_5 + 0.000288600288600299*G0_0_5_0 - 7.69600769600796e-05*G0_0_5_1 - 7.69600769600796e-05*G0_0_5_2 + 0.000153920153920159*G0_0_5_3 + 0.000384800384800398*G0_0_5_4 + 0.000384800384800398*G0_0_5_5 - 7.21500721500746e-05*G0_1_0_0 + 2.64550264550274e-05*G0_1_0_1 + 1.20250120250124e-05*G0_1_0_2 - 3.84800384800398e-05*G0_1_0_3 - 0.000115440115440119*G0_1_0_4 - 7.69600769600796e-05*G0_1_0_5 + 2.64550264550274e-05*G0_1_1_0 - 7.21500721500747e-06*G0_1_1_1 - 4.81000481000497e-06*G0_1_1_2 - 3.84800384800398e-05*G0_1_1_3 - 1.92400192400199e-05*G0_1_1_4 - 9.62000962000992e-06*G0_1_1_5 + 1.20250120250125e-05*G0_1_2_0 - 4.81000481000498e-06*G0_1_2_1 + 1.20250120250124e-05*G0_1_2_2 + 1.92400192400199e-05*G0_1_2_3 + 4.81000481000497e-05*G0_1_2_4 + 1.92400192400199e-05*G0_1_2_5 - 3.84800384800398e-05*G0_1_3_0 - 3.84800384800398e-05*G0_1_3_1 + 1.92400192400199e-05*G0_1_3_2 + 0.000115440115440119*G0_1_3_3 + 0.000115440115440119*G0_1_3_4 + 3.84800384800397e-05*G0_1_3_5 - 0.000115440115440119*G0_1_4_0 - 1.92400192400199e-05*G0_1_4_1 + 4.81000481000497e-05*G0_1_4_2 + 0.000115440115440119*G0_1_4_3 + 7.69600769600795e-05*G0_1_4_4 - 7.69600769600796e-05*G0_1_5_0 - 9.62000962000992e-06*G0_1_5_1 + 1.92400192400199e-05*G0_1_5_2 + 3.84800384800397e-05*G0_1_5_3 - 7.69600769600797e-05*G0_1_5_5 - 0.000144300144300149*G0_2_0_0 + 1.20250120250125e-05*G0_2_0_1 + 6.97450697450721e-05*G0_2_0_2 - 9.62000962000997e-06*G0_2_0_3 - 0.000115440115440119*G0_2_0_4 - 7.69600769600796e-05*G0_2_0_5 + 1.20250120250125e-05*G0_2_1_0 - 4.81000481000497e-06*G0_2_1_1 + 1.20250120250124e-05*G0_2_1_2 + 1.92400192400199e-05*G0_2_1_3 + 4.81000481000497e-05*G0_2_1_4 + 1.92400192400199e-05*G0_2_1_5 + 6.97450697450721e-05*G0_2_2_0 + 1.20250120250124e-05*G0_2_2_1 - 0.000144300144300149*G0_2_2_2 - 7.69600769600796e-05*G0_2_2_3 - 0.000115440115440119*G0_2_2_4 - 9.62000962000994e-06*G0_2_2_5 - 9.62000962000996e-06*G0_2_3_0 + 1.92400192400199e-05*G0_2_3_1 - 7.69600769600796e-05*G0_2_3_2 - 7.69600769600797e-05*G0_2_3_4 + 3.84800384800397e-05*G0_2_3_5 - 0.000115440115440119*G0_2_4_0 + 4.81000481000497e-05*G0_2_4_1 - 0.000115440115440119*G0_2_4_2 - 7.69600769600796e-05*G0_2_4_3 - 0.000615680615680637*G0_2_4_4 - 7.69600769600796e-05*G0_2_4_5 - 7.69600769600796e-05*G0_2_5_0 + 1.92400192400199e-05*G0_2_5_1 - 9.62000962000994e-06*G0_2_5_2 + 3.84800384800398e-05*G0_2_5_3 - 7.69600769600796e-05*G0_2_5_4 - 3.84800384800398e-05*G0_3_0_1 - 9.62000962000997e-06*G0_3_0_2 + 0.000192400192400199*G0_3_0_3 + 0.000230880230880239*G0_3_0_4 + 0.000153920153920159*G0_3_0_5 - 3.84800384800398e-05*G0_3_1_0 - 3.84800384800398e-05*G0_3_1_1 + 1.92400192400199e-05*G0_3_1_2 + 0.000115440115440119*G0_3_1_3 + 0.000115440115440119*G0_3_1_4 + 3.84800384800397e-05*G0_3_1_5 - 9.62000962000997e-06*G0_3_2_0 + 1.92400192400199e-05*G0_3_2_1 - 7.69600769600796e-05*G0_3_2_2 - 7.69600769600796e-05*G0_3_2_4 + 3.84800384800398e-05*G0_3_2_5 + 0.000192400192400199*G0_3_3_0 + 0.000115440115440119*G0_3_3_1 - 0.000923520923520954*G0_3_3_3 - 0.000615680615680636*G0_3_3_4 - 0.000461760461760477*G0_3_3_5 + 0.000230880230880239*G0_3_4_0 + 0.000115440115440119*G0_3_4_1 - 7.69600769600796e-05*G0_3_4_2 - 0.000615680615680636*G0_3_4_3 - 0.000615680615680637*G0_3_4_4 - 0.000307840307840318*G0_3_4_5 + 0.000153920153920159*G0_3_5_0 + 3.84800384800397e-05*G0_3_5_1 + 3.84800384800398e-05*G0_3_5_2 - 0.000461760461760477*G0_3_5_3 - 0.000307840307840318*G0_3_5_4 - 0.000307840307840318*G0_3_5_5 + 0.000577200577200597*G0_4_0_0 - 0.000115440115440119*G0_4_0_1 - 0.000115440115440119*G0_4_0_2 + 0.000230880230880239*G0_4_0_3 + 0.00115440115440119*G0_4_0_4 + 0.000384800384800398*G0_4_0_5 - 0.000115440115440119*G0_4_1_0 - 1.92400192400199e-05*G0_4_1_1 + 4.81000481000497e-05*G0_4_1_2 + 0.000115440115440119*G0_4_1_3 + 7.69600769600795e-05*G0_4_1_4 - 0.000115440115440119*G0_4_2_0 + 4.81000481000497e-05*G0_4_2_1 - 0.000115440115440119*G0_4_2_2 - 7.69600769600796e-05*G0_4_2_3 - 0.000615680615680637*G0_4_2_4 - 7.69600769600796e-05*G0_4_2_5 + 0.000230880230880239*G0_4_3_0 + 0.000115440115440119*G0_4_3_1 - 7.69600769600796e-05*G0_4_3_2 - 0.000615680615680636*G0_4_3_3 - 0.000615680615680637*G0_4_3_4 - 0.000307840307840318*G0_4_3_5 + 0.00115440115440119*G0_4_4_0 + 7.69600769600795e-05*G0_4_4_1 - 0.000615680615680637*G0_4_4_2 - 0.000615680615680637*G0_4_4_3 + 0.000384800384800398*G0_4_5_0 - 7.69600769600796e-05*G0_4_5_2 - 0.000307840307840318*G0_4_5_3 + 0.000288600288600299*G0_5_0_0 - 7.69600769600796e-05*G0_5_0_1 - 7.69600769600796e-05*G0_5_0_2 + 0.000153920153920159*G0_5_0_3 + 0.000384800384800398*G0_5_0_4 + 0.000384800384800398*G0_5_0_5 - 7.69600769600796e-05*G0_5_1_0 - 9.62000962000992e-06*G0_5_1_1 + 1.92400192400199e-05*G0_5_1_2 + 3.84800384800397e-05*G0_5_1_3 - 7.69600769600797e-05*G0_5_1_5 - 7.69600769600796e-05*G0_5_2_0 + 1.92400192400199e-05*G0_5_2_1 - 9.62000962000994e-06*G0_5_2_2 + 3.84800384800398e-05*G0_5_2_3 - 7.69600769600796e-05*G0_5_2_4 + 0.000153920153920159*G0_5_3_0 + 3.84800384800397e-05*G0_5_3_1 + 3.84800384800398e-05*G0_5_3_2 - 0.000461760461760477*G0_5_3_3 - 0.000307840307840318*G0_5_3_4 - 0.000307840307840318*G0_5_3_5 + 0.000384800384800398*G0_5_4_0 - 7.69600769600796e-05*G0_5_4_2 - 0.000307840307840318*G0_5_4_3 + 0.000384800384800398*G0_5_5_0 - 7.69600769600797e-05*G0_5_5_1 - 0.000307840307840318*G0_5_5_3; + A[8] = A[13]; + A[21] = -5.77200577200596e-05*G0_0_0_0 - 1.92400192400198e-05*G0_0_0_1 - 1.92400192400199e-05*G0_0_0_2 + 0.000346320346320358*G0_0_0_3 + 0.000192400192400199*G0_0_0_4 + 0.000192400192400199*G0_0_0_5 - 1.92400192400198e-05*G0_0_1_0 - 0.00011544011544012*G0_0_1_1 + 4.81000481000498e-05*G0_0_1_2 + 7.69600769600791e-05*G0_0_1_3 + 0.000115440115440119*G0_0_1_4 - 1.92400192400199e-05*G0_0_2_0 + 4.81000481000498e-05*G0_0_2_1 - 0.000115440115440119*G0_0_2_2 + 7.69600769600798e-05*G0_0_2_3 + 0.000115440115440119*G0_0_2_5 + 0.000346320346320358*G0_0_3_0 + 7.69600769600791e-05*G0_0_3_1 + 7.69600769600797e-05*G0_0_3_2 - 0.00246272246272255*G0_0_3_3 - 0.000923520923520954*G0_0_3_4 - 0.000923520923520955*G0_0_3_5 + 0.000192400192400199*G0_0_4_0 + 0.000115440115440119*G0_0_4_1 - 0.000923520923520954*G0_0_4_3 - 0.000615680615680636*G0_0_4_4 - 0.000461760461760477*G0_0_4_5 + 0.000192400192400199*G0_0_5_0 + 0.000115440115440119*G0_0_5_2 - 0.000923520923520955*G0_0_5_3 - 0.000461760461760477*G0_0_5_4 - 0.000615680615680636*G0_0_5_5 - 1.92400192400198e-05*G0_1_0_0 - 0.00011544011544012*G0_1_0_1 + 4.81000481000498e-05*G0_1_0_2 + 7.6960076960079e-05*G0_1_0_3 + 0.000115440115440119*G0_1_0_4 - 0.00011544011544012*G0_1_1_0 + 0.000577200577200598*G0_1_1_1 - 0.00011544011544012*G0_1_1_2 + 0.00115440115440119*G0_1_1_3 + 0.000230880230880239*G0_1_1_4 + 0.000384800384800399*G0_1_1_5 + 4.81000481000498e-05*G0_1_2_0 - 0.00011544011544012*G0_1_2_1 - 0.000115440115440119*G0_1_2_2 - 0.000615680615680637*G0_1_2_3 - 7.69600769600796e-05*G0_1_2_4 - 7.69600769600798e-05*G0_1_2_5 + 7.6960076960079e-05*G0_1_3_0 + 0.00115440115440119*G0_1_3_1 - 0.000615680615680637*G0_1_3_2 - 0.000615680615680636*G0_1_3_4 + 0.000115440115440119*G0_1_4_0 + 0.000230880230880239*G0_1_4_1 - 7.69600769600796e-05*G0_1_4_2 - 0.000615680615680636*G0_1_4_3 - 0.000615680615680637*G0_1_4_4 - 0.000307840307840318*G0_1_4_5 + 0.000384800384800399*G0_1_5_1 - 7.69600769600798e-05*G0_1_5_2 - 0.000307840307840318*G0_1_5_4 - 1.92400192400199e-05*G0_2_0_0 + 4.81000481000498e-05*G0_2_0_1 - 0.000115440115440119*G0_2_0_2 + 7.69600769600797e-05*G0_2_0_3 + 0.000115440115440119*G0_2_0_5 + 4.81000481000498e-05*G0_2_1_0 - 0.00011544011544012*G0_2_1_1 - 0.000115440115440119*G0_2_1_2 - 0.000615680615680637*G0_2_1_3 - 7.69600769600796e-05*G0_2_1_4 - 7.69600769600798e-05*G0_2_1_5 - 0.000115440115440119*G0_2_2_0 - 0.000115440115440119*G0_2_2_1 + 0.000577200577200597*G0_2_2_2 + 0.00115440115440119*G0_2_2_3 + 0.000384800384800398*G0_2_2_4 + 0.000230880230880239*G0_2_2_5 + 7.69600769600797e-05*G0_2_3_0 - 0.000615680615680637*G0_2_3_1 + 0.00115440115440119*G0_2_3_2 - 0.000615680615680637*G0_2_3_5 - 7.69600769600796e-05*G0_2_4_1 + 0.000384800384800398*G0_2_4_2 - 0.000307840307840318*G0_2_4_5 + 0.000115440115440119*G0_2_5_0 - 7.69600769600798e-05*G0_2_5_1 + 0.000230880230880239*G0_2_5_2 - 0.000615680615680637*G0_2_5_3 - 0.000307840307840318*G0_2_5_4 - 0.000615680615680637*G0_2_5_5 + 0.000346320346320358*G0_3_0_0 + 7.69600769600791e-05*G0_3_0_1 + 7.69600769600797e-05*G0_3_0_2 - 0.00246272246272255*G0_3_0_3 - 0.000923520923520954*G0_3_0_4 - 0.000923520923520955*G0_3_0_5 + 7.69600769600791e-05*G0_3_1_0 + 0.00115440115440119*G0_3_1_1 - 0.000615680615680637*G0_3_1_2 - 0.000615680615680636*G0_3_1_4 + 7.69600769600797e-05*G0_3_2_0 - 0.000615680615680637*G0_3_2_1 + 0.00115440115440119*G0_3_2_2 - 0.000615680615680637*G0_3_2_5 - 0.00246272246272255*G0_3_3_0 + 0.0307840307840319*G0_3_3_3 + 0.00615680615680636*G0_3_3_4 + 0.00615680615680637*G0_3_3_5 - 0.000923520923520954*G0_3_4_0 - 0.000615680615680636*G0_3_4_1 + 0.00615680615680636*G0_3_4_3 + 0.00307840307840318*G0_3_4_4 + 0.00246272246272254*G0_3_4_5 - 0.000923520923520955*G0_3_5_0 - 0.000615680615680637*G0_3_5_2 + 0.00615680615680637*G0_3_5_3 + 0.00246272246272254*G0_3_5_4 + 0.00307840307840318*G0_3_5_5 + 0.000192400192400199*G0_4_0_0 + 0.000115440115440119*G0_4_0_1 - 0.000923520923520954*G0_4_0_3 - 0.000615680615680636*G0_4_0_4 - 0.000461760461760477*G0_4_0_5 + 0.000115440115440119*G0_4_1_0 + 0.000230880230880239*G0_4_1_1 - 7.69600769600796e-05*G0_4_1_2 - 0.000615680615680636*G0_4_1_3 - 0.000615680615680637*G0_4_1_4 - 0.000307840307840318*G0_4_1_5 - 7.69600769600796e-05*G0_4_2_1 + 0.000384800384800398*G0_4_2_2 - 0.000307840307840318*G0_4_2_5 - 0.000923520923520954*G0_4_3_0 - 0.000615680615680636*G0_4_3_1 + 0.00615680615680636*G0_4_3_3 + 0.00307840307840318*G0_4_3_4 + 0.00246272246272254*G0_4_3_5 - 0.000615680615680636*G0_4_4_0 - 0.000615680615680637*G0_4_4_1 + 0.00307840307840318*G0_4_4_3 + 0.00307840307840318*G0_4_4_4 + 0.00184704184704191*G0_4_4_5 - 0.000461760461760477*G0_4_5_0 - 0.000307840307840318*G0_4_5_1 - 0.000307840307840318*G0_4_5_2 + 0.00246272246272255*G0_4_5_3 + 0.00184704184704191*G0_4_5_4 + 0.00184704184704191*G0_4_5_5 + 0.000192400192400199*G0_5_0_0 + 0.000115440115440119*G0_5_0_2 - 0.000923520923520955*G0_5_0_3 - 0.000461760461760477*G0_5_0_4 - 0.000615680615680636*G0_5_0_5 + 0.000384800384800399*G0_5_1_1 - 7.69600769600798e-05*G0_5_1_2 - 0.000307840307840318*G0_5_1_4 + 0.000115440115440119*G0_5_2_0 - 7.69600769600798e-05*G0_5_2_1 + 0.000230880230880239*G0_5_2_2 - 0.000615680615680637*G0_5_2_3 - 0.000307840307840318*G0_5_2_4 - 0.000615680615680637*G0_5_2_5 - 0.000923520923520955*G0_5_3_0 - 0.000615680615680637*G0_5_3_2 + 0.00615680615680637*G0_5_3_3 + 0.00246272246272255*G0_5_3_4 + 0.00307840307840318*G0_5_3_5 - 0.000461760461760477*G0_5_4_0 - 0.000307840307840318*G0_5_4_1 - 0.000307840307840318*G0_5_4_2 + 0.00246272246272255*G0_5_4_3 + 0.00184704184704191*G0_5_4_4 + 0.00184704184704191*G0_5_4_5 - 0.000615680615680636*G0_5_5_0 - 0.000615680615680637*G0_5_5_2 + 0.00307840307840318*G0_5_5_3 + 0.00184704184704191*G0_5_5_4 + 0.00307840307840318*G0_5_5_5; + A[28] = A[21] + 0.000634920634920656*G0_0_0_0 - 9.62000962000996e-05*G0_0_0_1 - 9.62000962000994e-05*G0_0_0_2 - 0.000115440115440119*G0_0_0_3 + 0.000962000962000995*G0_0_0_4 + 0.000192400192400199*G0_0_0_5 - 9.62000962000996e-05*G0_0_1_0 + 9.62000962000997e-05*G0_0_1_1 + 3.84800384800402e-05*G0_0_1_3 - 3.84800384800397e-05*G0_0_1_4 - 9.62000962000994e-05*G0_0_2_0 - 0.000153920153920159*G0_0_2_3 - 0.000615680615680637*G0_0_2_4 - 0.000192400192400199*G0_0_2_5 - 0.000115440115440119*G0_0_3_0 + 3.84800384800402e-05*G0_0_3_1 - 0.000153920153920159*G0_0_3_2 + 0.00184704184704191*G0_0_3_3 + 0.000307840307840318*G0_0_3_4 + 0.000615680615680636*G0_0_3_5 + 0.000962000962000995*G0_0_4_0 - 3.84800384800398e-05*G0_0_4_1 - 0.000615680615680637*G0_0_4_2 + 0.000307840307840318*G0_0_4_3 + 0.000615680615680637*G0_0_4_4 + 0.000461760461760477*G0_0_4_5 + 0.000192400192400199*G0_0_5_0 - 0.000192400192400199*G0_0_5_2 + 0.000615680615680636*G0_0_5_3 + 0.000461760461760477*G0_0_5_4 + 0.000615680615680637*G0_0_5_5 - 9.62000962000996e-05*G0_1_0_0 + 9.62000962000997e-05*G0_1_0_1 + 3.84800384800403e-05*G0_1_0_3 - 3.84800384800398e-05*G0_1_0_4 + 9.62000962000997e-05*G0_1_1_0 - 0.000634920634920657*G0_1_1_1 + 9.62000962000997e-05*G0_1_1_2 - 0.000962000962000996*G0_1_1_3 + 0.000115440115440119*G0_1_1_4 - 0.0001924001924002*G0_1_1_5 + 9.62000962000997e-05*G0_1_2_1 + 0.000615680615680638*G0_1_2_3 + 0.000153920153920159*G0_1_2_4 + 0.000192400192400199*G0_1_2_5 + 3.84800384800403e-05*G0_1_3_0 - 0.000962000962000996*G0_1_3_1 + 0.000615680615680638*G0_1_3_2 - 0.00061568061568064*G0_1_3_3 - 0.000307840307840319*G0_1_3_4 - 0.000461760461760479*G0_1_3_5 - 3.84800384800398e-05*G0_1_4_0 + 0.000115440115440119*G0_1_4_1 + 0.000153920153920159*G0_1_4_2 - 0.000307840307840319*G0_1_4_3 - 0.00184704184704191*G0_1_4_4 - 0.000615680615680637*G0_1_4_5 - 0.0001924001924002*G0_1_5_1 + 0.000192400192400199*G0_1_5_2 - 0.000461760461760479*G0_1_5_3 - 0.000615680615680637*G0_1_5_4 - 0.000615680615680638*G0_1_5_5 - 9.62000962000994e-05*G0_2_0_0 - 0.000153920153920159*G0_2_0_3 - 0.000615680615680637*G0_2_0_4 - 0.000192400192400199*G0_2_0_5 + 9.62000962000997e-05*G0_2_1_1 + 0.000615680615680638*G0_2_1_3 + 0.000153920153920159*G0_2_1_4 + 0.000192400192400199*G0_2_1_5 - 0.000769600769600796*G0_2_2_3 + 0.000769600769600796*G0_2_2_4 - 0.000153920153920159*G0_2_3_0 + 0.000615680615680638*G0_2_3_1 - 0.000769600769600796*G0_2_3_2 + 0.000307840307840318*G0_2_3_5 - 0.000615680615680637*G0_2_4_0 + 0.000153920153920159*G0_2_4_1 + 0.000769600769600796*G0_2_4_2 - 0.000307840307840319*G0_2_4_5 - 0.000192400192400199*G0_2_5_0 + 0.000192400192400199*G0_2_5_1 + 0.000307840307840318*G0_2_5_3 - 0.000307840307840319*G0_2_5_4 - 0.000115440115440119*G0_3_0_0 + 3.84800384800402e-05*G0_3_0_1 - 0.000153920153920159*G0_3_0_2 + 0.00184704184704191*G0_3_0_3 + 0.000307840307840318*G0_3_0_4 + 0.000615680615680637*G0_3_0_5 + 3.84800384800403e-05*G0_3_1_0 - 0.000962000962000996*G0_3_1_1 + 0.000615680615680638*G0_3_1_2 - 0.00061568061568064*G0_3_1_3 - 0.000307840307840319*G0_3_1_4 - 0.000461760461760479*G0_3_1_5 - 0.000153920153920159*G0_3_2_0 + 0.000615680615680638*G0_3_2_1 - 0.000769600769600797*G0_3_2_2 + 0.000307840307840318*G0_3_2_5 + 0.00184704184704191*G0_3_3_0 - 0.00061568061568064*G0_3_3_1 - 0.0277056277056287*G0_3_3_3 - 0.00307840307840318*G0_3_3_4 - 0.00430976430976446*G0_3_3_5 + 0.000307840307840318*G0_3_4_0 - 0.000307840307840319*G0_3_4_1 - 0.00307840307840318*G0_3_4_3 + 0.00307840307840319*G0_3_4_4 + 0.000615680615680637*G0_3_5_0 - 0.000461760461760479*G0_3_5_1 + 0.000307840307840318*G0_3_5_2 - 0.00430976430976446*G0_3_5_3 - 0.00123136123136127*G0_3_5_5 + 0.000962000962000995*G0_4_0_0 - 3.84800384800398e-05*G0_4_0_1 - 0.000615680615680637*G0_4_0_2 + 0.000307840307840318*G0_4_0_3 + 0.000615680615680636*G0_4_0_4 + 0.000461760461760477*G0_4_0_5 - 3.84800384800398e-05*G0_4_1_0 + 0.000115440115440119*G0_4_1_1 + 0.000153920153920159*G0_4_1_2 - 0.000307840307840319*G0_4_1_3 - 0.00184704184704191*G0_4_1_4 - 0.000615680615680637*G0_4_1_5 - 0.000615680615680637*G0_4_2_0 + 0.000153920153920159*G0_4_2_1 + 0.000769600769600796*G0_4_2_2 - 0.000307840307840319*G0_4_2_5 + 0.000307840307840318*G0_4_3_0 - 0.000307840307840319*G0_4_3_1 - 0.00307840307840318*G0_4_3_3 + 0.00307840307840319*G0_4_3_4 + 0.000615680615680636*G0_4_4_0 - 0.00184704184704191*G0_4_4_1 + 0.00307840307840319*G0_4_4_3 + 0.0277056277056286*G0_4_4_4 + 0.00430976430976446*G0_4_4_5 + 0.000461760461760477*G0_4_5_0 - 0.000615680615680637*G0_4_5_1 - 0.000307840307840319*G0_4_5_2 + 0.00430976430976446*G0_4_5_4 + 0.00123136123136128*G0_4_5_5 + 0.000192400192400199*G0_5_0_0 - 0.000192400192400199*G0_5_0_2 + 0.000615680615680637*G0_5_0_3 + 0.000461760461760477*G0_5_0_4 + 0.000615680615680637*G0_5_0_5 - 0.0001924001924002*G0_5_1_1 + 0.000192400192400199*G0_5_1_2 - 0.000461760461760479*G0_5_1_3 - 0.000615680615680637*G0_5_1_4 - 0.000615680615680638*G0_5_1_5 - 0.000192400192400199*G0_5_2_0 + 0.000192400192400199*G0_5_2_1 + 0.000307840307840318*G0_5_2_3 - 0.000307840307840319*G0_5_2_4 + 0.000615680615680637*G0_5_3_0 - 0.000461760461760479*G0_5_3_1 + 0.000307840307840318*G0_5_3_2 - 0.00430976430976446*G0_5_3_3 - 0.00123136123136127*G0_5_3_5 + 0.000461760461760477*G0_5_4_0 - 0.000615680615680637*G0_5_4_1 - 0.000307840307840319*G0_5_4_2 + 0.00430976430976446*G0_5_4_4 + 0.00123136123136128*G0_5_4_5 + 0.000615680615680637*G0_5_5_0 - 0.000615680615680638*G0_5_5_1 - 0.00123136123136127*G0_5_5_3 + 0.00123136123136128*G0_5_5_4; + A[11] = A[31]; + A[30] = A[24] - 7.21500721500747e-05*G0_0_0_1 + 7.21500721500745e-05*G0_0_0_2 - 0.000288600288600298*G0_0_0_4 + 0.000288600288600299*G0_0_0_5 - 7.21500721500747e-05*G0_0_1_0 + 4.32900432900448e-05*G0_0_1_1 + 2.88600288600298e-05*G0_0_1_3 + 3.84800384800398e-05*G0_0_1_4 - 3.84800384800399e-05*G0_0_1_5 + 7.21500721500745e-05*G0_0_2_0 - 4.32900432900448e-05*G0_0_2_2 - 2.88600288600298e-05*G0_0_2_3 + 3.84800384800397e-05*G0_0_2_4 - 3.84800384800399e-05*G0_0_2_5 + 2.88600288600298e-05*G0_0_3_1 - 2.88600288600298e-05*G0_0_3_2 - 7.69600769600797e-05*G0_0_3_4 + 7.69600769600797e-05*G0_0_3_5 - 0.000288600288600298*G0_0_4_0 + 3.84800384800398e-05*G0_0_4_1 + 3.84800384800397e-05*G0_0_4_2 - 7.69600769600797e-05*G0_0_4_3 - 0.000769600769600796*G0_0_4_4 + 0.000288600288600299*G0_0_5_0 - 3.84800384800399e-05*G0_0_5_1 - 3.84800384800399e-05*G0_0_5_2 + 7.69600769600797e-05*G0_0_5_3 + 0.000769600769600797*G0_0_5_5 - 7.21500721500747e-05*G0_1_0_0 + 4.32900432900448e-05*G0_1_0_1 + 2.88600288600298e-05*G0_1_0_3 + 3.84800384800398e-05*G0_1_0_4 - 3.84800384800399e-05*G0_1_0_5 + 4.32900432900448e-05*G0_1_1_0 - 0.000137085137085142*G0_1_1_1 + 1.68350168350174e-05*G0_1_1_2 - 3.84800384800399e-05*G0_1_1_3 + 9.62000962000996e-06*G0_1_1_4 - 0.00010582010582011*G0_1_1_5 + 1.68350168350174e-05*G0_1_2_1 - 1.68350168350174e-05*G0_1_2_2 - 2.88600288600298e-05*G0_1_2_4 + 2.88600288600299e-05*G0_1_2_5 + 2.88600288600298e-05*G0_1_3_0 - 3.84800384800399e-05*G0_1_3_1 - 0.000115440115440119*G0_1_3_3 - 7.69600769600796e-05*G0_1_3_4 - 0.000115440115440119*G0_1_3_5 + 3.84800384800398e-05*G0_1_4_0 + 9.62000962000996e-06*G0_1_4_1 - 2.88600288600298e-05*G0_1_4_2 - 7.69600769600796e-05*G0_1_4_3 - 7.69600769600795e-05*G0_1_4_4 - 7.69600769600796e-05*G0_1_4_5 - 3.84800384800399e-05*G0_1_5_0 - 0.00010582010582011*G0_1_5_1 + 2.88600288600299e-05*G0_1_5_2 - 0.000115440115440119*G0_1_5_3 - 7.69600769600796e-05*G0_1_5_4 - 0.000538720538720558*G0_1_5_5 + 7.21500721500745e-05*G0_2_0_0 - 4.32900432900448e-05*G0_2_0_2 - 2.88600288600298e-05*G0_2_0_3 + 3.84800384800397e-05*G0_2_0_4 - 3.84800384800399e-05*G0_2_0_5 + 1.68350168350174e-05*G0_2_1_1 - 1.68350168350174e-05*G0_2_1_2 - 2.88600288600298e-05*G0_2_1_4 + 2.88600288600299e-05*G0_2_1_5 - 4.32900432900448e-05*G0_2_2_0 - 1.68350168350174e-05*G0_2_2_1 + 0.000137085137085142*G0_2_2_2 + 3.84800384800398e-05*G0_2_2_3 + 0.000105820105820109*G0_2_2_4 - 9.62000962000993e-06*G0_2_2_5 - 2.88600288600298e-05*G0_2_3_0 + 3.84800384800398e-05*G0_2_3_2 + 0.000115440115440119*G0_2_3_3 + 0.000115440115440119*G0_2_3_4 + 7.69600769600796e-05*G0_2_3_5 + 3.84800384800397e-05*G0_2_4_0 - 2.88600288600298e-05*G0_2_4_1 + 0.000105820105820109*G0_2_4_2 + 0.000115440115440119*G0_2_4_3 + 0.000538720538720557*G0_2_4_4 + 7.69600769600796e-05*G0_2_4_5 - 3.84800384800399e-05*G0_2_5_0 + 2.88600288600299e-05*G0_2_5_1 - 9.62000962000993e-06*G0_2_5_2 + 7.69600769600796e-05*G0_2_5_3 + 7.69600769600796e-05*G0_2_5_4 + 7.69600769600794e-05*G0_2_5_5 + 2.88600288600298e-05*G0_3_0_1 - 2.88600288600298e-05*G0_3_0_2 - 7.69600769600797e-05*G0_3_0_4 + 7.69600769600797e-05*G0_3_0_5 + 2.88600288600298e-05*G0_3_1_0 - 3.84800384800399e-05*G0_3_1_1 - 0.000115440115440119*G0_3_1_3 - 7.69600769600796e-05*G0_3_1_4 - 0.000115440115440119*G0_3_1_5 - 2.88600288600298e-05*G0_3_2_0 + 3.84800384800398e-05*G0_3_2_2 + 0.000115440115440119*G0_3_2_3 + 0.000115440115440119*G0_3_2_4 + 7.69600769600796e-05*G0_3_2_5 - 0.000115440115440119*G0_3_3_1 + 0.000115440115440119*G0_3_3_2 + 0.000153920153920159*G0_3_3_4 - 0.000153920153920159*G0_3_3_5 - 7.69600769600797e-05*G0_3_4_0 - 7.69600769600796e-05*G0_3_4_1 + 0.000115440115440119*G0_3_4_2 + 0.000153920153920159*G0_3_4_3 + 0.000307840307840319*G0_3_4_4 + 7.69600769600797e-05*G0_3_5_0 - 0.000115440115440119*G0_3_5_1 + 7.69600769600796e-05*G0_3_5_2 - 0.000153920153920159*G0_3_5_3 - 0.000307840307840318*G0_3_5_5 - 0.000288600288600298*G0_4_0_0 + 3.84800384800398e-05*G0_4_0_1 + 3.84800384800397e-05*G0_4_0_2 - 7.69600769600797e-05*G0_4_0_3 - 0.000769600769600796*G0_4_0_4 + 3.84800384800398e-05*G0_4_1_0 + 9.62000962000995e-06*G0_4_1_1 - 2.88600288600298e-05*G0_4_1_2 - 7.69600769600796e-05*G0_4_1_3 - 7.69600769600795e-05*G0_4_1_4 - 7.69600769600796e-05*G0_4_1_5 + 3.84800384800397e-05*G0_4_2_0 - 2.88600288600298e-05*G0_4_2_1 + 0.000105820105820109*G0_4_2_2 + 0.000115440115440119*G0_4_2_3 + 0.000538720538720557*G0_4_2_4 + 7.69600769600796e-05*G0_4_2_5 - 7.69600769600797e-05*G0_4_3_0 - 7.69600769600796e-05*G0_4_3_1 + 0.000115440115440119*G0_4_3_2 + 0.000153920153920159*G0_4_3_3 + 0.000307840307840319*G0_4_3_4 - 0.000769600769600796*G0_4_4_0 - 7.69600769600795e-05*G0_4_4_1 + 0.000538720538720557*G0_4_4_2 + 0.000307840307840318*G0_4_4_3 - 7.69600769600796e-05*G0_4_5_1 + 7.69600769600796e-05*G0_4_5_2 + 0.000288600288600299*G0_5_0_0 - 3.84800384800399e-05*G0_5_0_1 - 3.84800384800399e-05*G0_5_0_2 + 7.69600769600797e-05*G0_5_0_3 + 0.000769600769600797*G0_5_0_5 - 3.84800384800399e-05*G0_5_1_0 - 0.00010582010582011*G0_5_1_1 + 2.88600288600299e-05*G0_5_1_2 - 0.000115440115440119*G0_5_1_3 - 7.69600769600796e-05*G0_5_1_4 - 0.000538720538720558*G0_5_1_5 - 3.84800384800399e-05*G0_5_2_0 + 2.88600288600299e-05*G0_5_2_1 - 9.62000962000993e-06*G0_5_2_2 + 7.69600769600796e-05*G0_5_2_3 + 7.69600769600795e-05*G0_5_2_4 + 7.69600769600794e-05*G0_5_2_5 + 7.69600769600797e-05*G0_5_3_0 - 0.000115440115440119*G0_5_3_1 + 7.69600769600796e-05*G0_5_3_2 - 0.000153920153920159*G0_5_3_3 - 0.000307840307840318*G0_5_3_5 - 7.69600769600796e-05*G0_5_4_1 + 7.69600769600796e-05*G0_5_4_2 + 0.000769600769600797*G0_5_5_0 - 0.000538720538720558*G0_5_5_1 + 7.69600769600794e-05*G0_5_5_2 - 0.000307840307840318*G0_5_5_3; + A[4] = A[24]; + A[25] = -7.21500721500747e-05*G0_0_0_0 + 2.64550264550274e-05*G0_0_0_1 + 1.20250120250125e-05*G0_0_0_2 - 3.84800384800398e-05*G0_0_0_3 - 0.000115440115440119*G0_0_0_4 - 7.69600769600796e-05*G0_0_0_5 + 2.64550264550274e-05*G0_0_1_0 - 7.21500721500747e-06*G0_0_1_1 - 4.81000481000497e-06*G0_0_1_2 - 3.84800384800398e-05*G0_0_1_3 - 1.92400192400199e-05*G0_0_1_4 - 9.62000962000993e-06*G0_0_1_5 + 1.20250120250125e-05*G0_0_2_0 - 4.81000481000497e-06*G0_0_2_1 + 1.20250120250124e-05*G0_0_2_2 + 1.92400192400199e-05*G0_0_2_3 + 4.81000481000497e-05*G0_0_2_4 + 1.92400192400199e-05*G0_0_2_5 - 3.84800384800398e-05*G0_0_3_0 - 3.84800384800398e-05*G0_0_3_1 + 1.92400192400199e-05*G0_0_3_2 + 0.000115440115440119*G0_0_3_3 + 0.000115440115440119*G0_0_3_4 + 3.84800384800397e-05*G0_0_3_5 - 0.000115440115440119*G0_0_4_0 - 1.92400192400199e-05*G0_0_4_1 + 4.81000481000497e-05*G0_0_4_2 + 0.000115440115440119*G0_0_4_3 + 7.69600769600795e-05*G0_0_4_4 - 7.69600769600796e-05*G0_0_5_0 - 9.62000962000993e-06*G0_0_5_1 + 1.92400192400199e-05*G0_0_5_2 + 3.84800384800397e-05*G0_0_5_3 - 7.69600769600796e-05*G0_0_5_5 + 2.64550264550274e-05*G0_1_0_0 - 7.21500721500747e-06*G0_1_0_1 - 4.81000481000497e-06*G0_1_0_2 - 3.84800384800398e-05*G0_1_0_3 - 1.92400192400199e-05*G0_1_0_4 - 9.62000962000992e-06*G0_1_0_5 - 7.21500721500747e-06*G0_1_1_0 + 7.21500721500745e-05*G0_1_1_1 - 7.21500721500746e-06*G0_1_1_2 - 5.77200577200597e-05*G0_1_1_4 - 4.81000481000497e-06*G0_1_2_0 - 7.21500721500746e-06*G0_1_2_1 + 2.64550264550274e-05*G0_1_2_2 - 9.62000962000999e-06*G0_1_2_3 - 1.92400192400199e-05*G0_1_2_4 - 3.84800384800398e-05*G0_1_2_5 - 3.84800384800398e-05*G0_1_3_0 - 9.62000962000999e-06*G0_1_3_2 + 0.000230880230880239*G0_1_3_3 + 0.000192400192400199*G0_1_3_4 + 0.000153920153920159*G0_1_3_5 - 1.92400192400199e-05*G0_1_4_0 - 5.77200577200597e-05*G0_1_4_1 - 1.92400192400199e-05*G0_1_4_2 + 0.000192400192400199*G0_1_4_3 + 0.000346320346320358*G0_1_4_4 + 0.000192400192400199*G0_1_4_5 - 9.62000962000993e-06*G0_1_5_0 - 3.84800384800398e-05*G0_1_5_2 + 0.000153920153920159*G0_1_5_3 + 0.000192400192400199*G0_1_5_4 + 0.000230880230880239*G0_1_5_5 + 1.20250120250125e-05*G0_2_0_0 - 4.81000481000497e-06*G0_2_0_1 + 1.20250120250124e-05*G0_2_0_2 + 1.92400192400199e-05*G0_2_0_3 + 4.81000481000497e-05*G0_2_0_4 + 1.92400192400199e-05*G0_2_0_5 - 4.81000481000497e-06*G0_2_1_0 - 7.21500721500747e-06*G0_2_1_1 + 2.64550264550274e-05*G0_2_1_2 - 9.62000962000998e-06*G0_2_1_3 - 1.92400192400199e-05*G0_2_1_4 - 3.84800384800398e-05*G0_2_1_5 + 1.20250120250124e-05*G0_2_2_0 + 2.64550264550274e-05*G0_2_2_1 - 7.21500721500746e-05*G0_2_2_2 - 7.69600769600796e-05*G0_2_2_3 - 0.000115440115440119*G0_2_2_4 - 3.84800384800398e-05*G0_2_2_5 + 1.92400192400199e-05*G0_2_3_0 - 9.62000962000999e-06*G0_2_3_1 - 7.69600769600796e-05*G0_2_3_2 - 7.69600769600796e-05*G0_2_3_3 + 3.84800384800398e-05*G0_2_3_5 + 4.81000481000497e-05*G0_2_4_0 - 1.924001924002e-05*G0_2_4_1 - 0.000115440115440119*G0_2_4_2 + 7.69600769600799e-05*G0_2_4_4 + 0.00011544011544012*G0_2_4_5 + 1.92400192400199e-05*G0_2_5_0 - 3.84800384800398e-05*G0_2_5_1 - 3.84800384800398e-05*G0_2_5_2 + 3.84800384800398e-05*G0_2_5_3 + 0.00011544011544012*G0_2_5_4 + 0.00011544011544012*G0_2_5_5 - 3.84800384800398e-05*G0_3_0_0 - 3.84800384800398e-05*G0_3_0_1 + 1.92400192400199e-05*G0_3_0_2 + 0.000115440115440119*G0_3_0_3 + 0.000115440115440119*G0_3_0_4 + 3.84800384800397e-05*G0_3_0_5 - 3.84800384800398e-05*G0_3_1_0 - 9.62000962000999e-06*G0_3_1_2 + 0.000230880230880239*G0_3_1_3 + 0.000192400192400199*G0_3_1_4 + 0.000153920153920159*G0_3_1_5 + 1.92400192400199e-05*G0_3_2_0 - 9.62000962000999e-06*G0_3_2_1 - 7.69600769600796e-05*G0_3_2_2 - 7.69600769600796e-05*G0_3_2_3 + 3.84800384800398e-05*G0_3_2_5 + 0.000115440115440119*G0_3_3_0 + 0.000230880230880239*G0_3_3_1 - 7.69600769600796e-05*G0_3_3_2 - 0.000615680615680636*G0_3_3_3 - 0.000615680615680637*G0_3_3_4 - 0.000307840307840318*G0_3_3_5 + 0.000115440115440119*G0_3_4_0 + 0.000192400192400199*G0_3_4_1 - 0.000615680615680637*G0_3_4_3 - 0.000923520923520955*G0_3_4_4 - 0.000461760461760478*G0_3_4_5 + 3.84800384800397e-05*G0_3_5_0 + 0.000153920153920159*G0_3_5_1 + 3.84800384800398e-05*G0_3_5_2 - 0.000307840307840318*G0_3_5_3 - 0.000461760461760478*G0_3_5_4 - 0.000307840307840318*G0_3_5_5 - 0.000115440115440119*G0_4_0_0 - 1.92400192400199e-05*G0_4_0_1 + 4.81000481000497e-05*G0_4_0_2 + 0.000115440115440119*G0_4_0_3 + 7.69600769600795e-05*G0_4_0_4 - 1.92400192400199e-05*G0_4_1_0 - 5.77200577200597e-05*G0_4_1_1 - 1.92400192400199e-05*G0_4_1_2 + 0.000192400192400199*G0_4_1_3 + 0.000346320346320358*G0_4_1_4 + 0.000192400192400199*G0_4_1_5 + 4.81000481000497e-05*G0_4_2_0 - 1.924001924002e-05*G0_4_2_1 - 0.000115440115440119*G0_4_2_2 + 7.69600769600799e-05*G0_4_2_4 + 0.00011544011544012*G0_4_2_5 + 0.000115440115440119*G0_4_3_0 + 0.000192400192400199*G0_4_3_1 - 0.000615680615680637*G0_4_3_3 - 0.000923520923520955*G0_4_3_4 - 0.000461760461760477*G0_4_3_5 + 7.69600769600795e-05*G0_4_4_0 + 0.000346320346320358*G0_4_4_1 + 7.69600769600798e-05*G0_4_4_2 - 0.000923520923520955*G0_4_4_3 - 0.00246272246272255*G0_4_4_4 - 0.000923520923520956*G0_4_4_5 + 0.000192400192400199*G0_4_5_1 + 0.00011544011544012*G0_4_5_2 - 0.000461760461760477*G0_4_5_3 - 0.000923520923520956*G0_4_5_4 - 0.000615680615680637*G0_4_5_5 - 7.69600769600796e-05*G0_5_0_0 - 9.62000962000993e-06*G0_5_0_1 + 1.92400192400199e-05*G0_5_0_2 + 3.84800384800397e-05*G0_5_0_3 - 7.69600769600797e-05*G0_5_0_5 - 9.62000962000992e-06*G0_5_1_0 - 3.84800384800398e-05*G0_5_1_2 + 0.000153920153920159*G0_5_1_3 + 0.000192400192400199*G0_5_1_4 + 0.000230880230880239*G0_5_1_5 + 1.92400192400199e-05*G0_5_2_0 - 3.84800384800398e-05*G0_5_2_1 - 3.84800384800398e-05*G0_5_2_2 + 3.84800384800398e-05*G0_5_2_3 + 0.000115440115440119*G0_5_2_4 + 0.00011544011544012*G0_5_2_5 + 3.84800384800397e-05*G0_5_3_0 + 0.000153920153920159*G0_5_3_1 + 3.84800384800398e-05*G0_5_3_2 - 0.000307840307840318*G0_5_3_3 - 0.000461760461760477*G0_5_3_4 - 0.000307840307840318*G0_5_3_5 + 0.000192400192400199*G0_5_4_1 + 0.000115440115440119*G0_5_4_2 - 0.000461760461760477*G0_5_4_3 - 0.000923520923520956*G0_5_4_4 - 0.000615680615680637*G0_5_4_5 - 7.69600769600796e-05*G0_5_5_0 + 0.000230880230880239*G0_5_5_1 + 0.00011544011544012*G0_5_5_2 - 0.000307840307840318*G0_5_5_3 - 0.000615680615680637*G0_5_5_4 - 0.000615680615680637*G0_5_5_5; + A[7] = 2.16450216450224e-05*G0_0_0_0 + 2.16450216450225e-05*G0_0_0_1 - 7.21500721500748e-06*G0_0_0_2 + 2.64550264550274e-05*G0_0_0_3 + 2.64550264550274e-05*G0_0_0_4 + 6.97450697450722e-05*G0_0_0_5 + 2.16450216450225e-05*G0_0_1_0 - 0.000216450216450225*G0_0_1_1 + 2.16450216450225e-05*G0_0_1_2 - 7.21500721500749e-05*G0_0_1_3 - 7.21500721500747e-06*G0_0_1_4 - 0.00014430014430015*G0_0_1_5 - 7.21500721500748e-06*G0_0_2_0 + 2.16450216450225e-05*G0_0_2_1 - 7.21500721500747e-06*G0_0_2_2 + 1.20250120250125e-05*G0_0_2_3 - 4.81000481000497e-06*G0_0_2_4 + 1.20250120250125e-05*G0_0_2_5 + 2.64550264550274e-05*G0_0_3_0 - 7.21500721500749e-05*G0_0_3_1 + 1.20250120250125e-05*G0_0_3_2 - 0.00011544011544012*G0_0_3_3 - 3.84800384800398e-05*G0_0_3_4 - 7.69600769600797e-05*G0_0_3_5 + 2.64550264550274e-05*G0_0_4_0 - 7.21500721500747e-06*G0_0_4_1 - 4.81000481000497e-06*G0_0_4_2 - 3.84800384800398e-05*G0_0_4_3 - 1.92400192400199e-05*G0_0_4_4 - 9.62000962000992e-06*G0_0_4_5 + 6.97450697450722e-05*G0_0_5_0 - 0.00014430014430015*G0_0_5_1 + 1.20250120250125e-05*G0_0_5_2 - 7.69600769600797e-05*G0_0_5_3 - 9.62000962000992e-06*G0_0_5_4 - 0.00011544011544012*G0_0_5_5 + 2.16450216450225e-05*G0_1_0_0 - 0.000216450216450225*G0_1_0_1 + 2.16450216450225e-05*G0_1_0_2 - 7.21500721500749e-05*G0_1_0_3 - 7.21500721500747e-06*G0_1_0_4 - 0.00014430014430015*G0_1_0_5 - 0.000216450216450225*G0_1_1_0 + 0.00324675324675336*G0_1_1_1 - 0.000216450216450224*G0_1_1_2 + 0.000937950937950971*G0_1_1_3 + 7.21500721500745e-05*G0_1_1_4 + 0.000937950937950974*G0_1_1_5 + 2.16450216450225e-05*G0_1_2_0 - 0.000216450216450224*G0_1_2_1 + 2.16450216450224e-05*G0_1_2_2 - 0.000144300144300149*G0_1_2_3 - 7.21500721500747e-06*G0_1_2_4 - 7.21500721500749e-05*G0_1_2_5 - 7.21500721500749e-05*G0_1_3_0 + 0.000937950937950971*G0_1_3_1 - 0.000144300144300149*G0_1_3_2 + 0.000577200577200598*G0_1_3_3 + 0.0002886002886003*G0_1_3_5 - 7.21500721500747e-06*G0_1_4_0 + 7.21500721500745e-05*G0_1_4_1 - 7.21500721500746e-06*G0_1_4_2 - 5.77200577200597e-05*G0_1_4_4 - 0.00014430014430015*G0_1_5_0 + 0.000937950937950974*G0_1_5_1 - 7.21500721500749e-05*G0_1_5_2 + 0.0002886002886003*G0_1_5_3 + 0.000577200577200599*G0_1_5_5 - 7.21500721500748e-06*G0_2_0_0 + 2.16450216450225e-05*G0_2_0_1 - 7.21500721500747e-06*G0_2_0_2 + 1.20250120250125e-05*G0_2_0_3 - 4.81000481000497e-06*G0_2_0_4 + 1.20250120250125e-05*G0_2_0_5 + 2.16450216450225e-05*G0_2_1_0 - 0.000216450216450224*G0_2_1_1 + 2.16450216450224e-05*G0_2_1_2 - 0.000144300144300149*G0_2_1_3 - 7.21500721500747e-06*G0_2_1_4 - 7.21500721500749e-05*G0_2_1_5 - 7.21500721500747e-06*G0_2_2_0 + 2.16450216450224e-05*G0_2_2_1 + 2.16450216450223e-05*G0_2_2_2 + 6.97450697450722e-05*G0_2_2_3 + 2.64550264550274e-05*G0_2_2_4 + 2.64550264550274e-05*G0_2_2_5 + 1.20250120250125e-05*G0_2_3_0 - 0.000144300144300149*G0_2_3_1 + 6.97450697450722e-05*G0_2_3_2 - 0.00011544011544012*G0_2_3_3 - 9.62000962000999e-06*G0_2_3_4 - 7.69600769600798e-05*G0_2_3_5 - 4.81000481000497e-06*G0_2_4_0 - 7.21500721500747e-06*G0_2_4_1 + 2.64550264550274e-05*G0_2_4_2 - 9.62000962000998e-06*G0_2_4_3 - 1.92400192400199e-05*G0_2_4_4 - 3.84800384800398e-05*G0_2_4_5 + 1.20250120250125e-05*G0_2_5_0 - 7.21500721500749e-05*G0_2_5_1 + 2.64550264550274e-05*G0_2_5_2 - 7.69600769600798e-05*G0_2_5_3 - 3.84800384800398e-05*G0_2_5_4 - 0.00011544011544012*G0_2_5_5 + 2.64550264550274e-05*G0_3_0_0 - 7.21500721500749e-05*G0_3_0_1 + 1.20250120250125e-05*G0_3_0_2 - 0.00011544011544012*G0_3_0_3 - 3.84800384800398e-05*G0_3_0_4 - 7.69600769600797e-05*G0_3_0_5 - 7.21500721500749e-05*G0_3_1_0 + 0.000937950937950971*G0_3_1_1 - 0.000144300144300149*G0_3_1_2 + 0.000577200577200598*G0_3_1_3 + 0.0002886002886003*G0_3_1_5 + 1.20250120250125e-05*G0_3_2_0 - 0.000144300144300149*G0_3_2_1 + 6.97450697450722e-05*G0_3_2_2 - 0.00011544011544012*G0_3_2_3 - 9.62000962000999e-06*G0_3_2_4 - 7.69600769600798e-05*G0_3_2_5 - 0.00011544011544012*G0_3_3_0 + 0.000577200577200598*G0_3_3_1 - 0.00011544011544012*G0_3_3_2 + 0.00115440115440119*G0_3_3_3 + 0.000230880230880239*G0_3_3_4 + 0.000384800384800399*G0_3_3_5 - 3.84800384800398e-05*G0_3_4_0 - 9.62000962000999e-06*G0_3_4_2 + 0.000230880230880239*G0_3_4_3 + 0.000192400192400199*G0_3_4_4 + 0.000153920153920159*G0_3_4_5 - 7.69600769600797e-05*G0_3_5_0 + 0.0002886002886003*G0_3_5_1 - 7.69600769600798e-05*G0_3_5_2 + 0.000384800384800399*G0_3_5_3 + 0.000153920153920159*G0_3_5_4 + 0.000384800384800399*G0_3_5_5 + 2.64550264550274e-05*G0_4_0_0 - 7.21500721500747e-06*G0_4_0_1 - 4.81000481000497e-06*G0_4_0_2 - 3.84800384800398e-05*G0_4_0_3 - 1.92400192400199e-05*G0_4_0_4 - 9.62000962000992e-06*G0_4_0_5 - 7.21500721500747e-06*G0_4_1_0 + 7.21500721500745e-05*G0_4_1_1 - 7.21500721500746e-06*G0_4_1_2 - 5.77200577200597e-05*G0_4_1_4 - 4.81000481000497e-06*G0_4_2_0 - 7.21500721500746e-06*G0_4_2_1 + 2.64550264550274e-05*G0_4_2_2 - 9.62000962000999e-06*G0_4_2_3 - 1.92400192400199e-05*G0_4_2_4 - 3.84800384800398e-05*G0_4_2_5 - 3.84800384800398e-05*G0_4_3_0 - 9.62000962000999e-06*G0_4_3_2 + 0.000230880230880239*G0_4_3_3 + 0.000192400192400199*G0_4_3_4 + 0.000153920153920159*G0_4_3_5 - 1.92400192400199e-05*G0_4_4_0 - 5.77200577200597e-05*G0_4_4_1 - 1.92400192400199e-05*G0_4_4_2 + 0.000192400192400199*G0_4_4_3 + 0.000346320346320358*G0_4_4_4 + 0.000192400192400199*G0_4_4_5 - 9.62000962000992e-06*G0_4_5_0 - 3.84800384800398e-05*G0_4_5_2 + 0.000153920153920159*G0_4_5_3 + 0.000192400192400199*G0_4_5_4 + 0.000230880230880239*G0_4_5_5 + 6.97450697450722e-05*G0_5_0_0 - 0.00014430014430015*G0_5_0_1 + 1.20250120250125e-05*G0_5_0_2 - 7.69600769600797e-05*G0_5_0_3 - 9.62000962000992e-06*G0_5_0_4 - 0.00011544011544012*G0_5_0_5 - 0.00014430014430015*G0_5_1_0 + 0.000937950937950974*G0_5_1_1 - 7.21500721500749e-05*G0_5_1_2 + 0.0002886002886003*G0_5_1_3 + 0.000577200577200599*G0_5_1_5 + 1.20250120250125e-05*G0_5_2_0 - 7.21500721500749e-05*G0_5_2_1 + 2.64550264550274e-05*G0_5_2_2 - 7.69600769600798e-05*G0_5_2_3 - 3.84800384800398e-05*G0_5_2_4 - 0.00011544011544012*G0_5_2_5 - 7.69600769600797e-05*G0_5_3_0 + 0.0002886002886003*G0_5_3_1 - 7.69600769600798e-05*G0_5_3_2 + 0.000384800384800399*G0_5_3_3 + 0.000153920153920159*G0_5_3_4 + 0.000384800384800399*G0_5_3_5 - 9.62000962000992e-06*G0_5_4_0 - 3.84800384800398e-05*G0_5_4_2 + 0.000153920153920159*G0_5_4_3 + 0.000192400192400199*G0_5_4_4 + 0.000230880230880239*G0_5_4_5 - 0.00011544011544012*G0_5_5_0 + 0.000577200577200599*G0_5_5_1 - 0.00011544011544012*G0_5_5_2 + 0.000384800384800399*G0_5_5_3 + 0.000230880230880239*G0_5_5_4 + 0.0011544011544012*G0_5_5_5; + A[34] = A[28] - 0.000288600288600298*G0_0_0_0 + 3.84800384800398e-05*G0_0_0_1 + 3.84800384800397e-05*G0_0_0_2 - 7.69600769600797e-05*G0_0_0_3 - 0.000769600769600796*G0_0_0_4 + 3.84800384800398e-05*G0_0_1_0 + 9.62000962000996e-06*G0_0_1_1 - 2.88600288600298e-05*G0_0_1_2 - 7.69600769600796e-05*G0_0_1_3 - 7.69600769600796e-05*G0_0_1_4 - 7.69600769600796e-05*G0_0_1_5 + 3.84800384800397e-05*G0_0_2_0 - 2.88600288600298e-05*G0_0_2_1 + 0.000105820105820109*G0_0_2_2 + 0.000115440115440119*G0_0_2_3 + 0.000538720538720557*G0_0_2_4 + 7.69600769600796e-05*G0_0_2_5 - 7.69600769600797e-05*G0_0_3_0 - 7.69600769600796e-05*G0_0_3_1 + 0.000115440115440119*G0_0_3_2 + 0.000153920153920159*G0_0_3_3 + 0.000307840307840319*G0_0_3_4 - 0.000769600769600796*G0_0_4_0 - 7.69600769600796e-05*G0_0_4_1 + 0.000538720538720557*G0_0_4_2 + 0.000307840307840319*G0_0_4_3 - 7.69600769600796e-05*G0_0_5_1 + 7.69600769600796e-05*G0_0_5_2 + 3.84800384800398e-05*G0_1_0_0 + 9.62000962000996e-06*G0_1_0_1 - 2.88600288600298e-05*G0_1_0_2 - 7.69600769600796e-05*G0_1_0_3 - 7.69600769600795e-05*G0_1_0_4 - 7.69600769600796e-05*G0_1_0_5 + 9.62000962000995e-06*G0_1_1_0 + 5.77200577200597e-05*G0_1_1_1 - 1.92400192400199e-05*G0_1_1_2 - 3.84800384800398e-05*G0_1_1_3 - 0.000153920153920159*G0_1_1_4 + 3.84800384800398e-05*G0_1_1_5 - 2.88600288600298e-05*G0_1_2_0 - 1.92400192400199e-05*G0_1_2_1 + 7.69600769600796e-05*G0_1_2_2 + 3.84800384800397e-05*G0_1_2_3 + 3.84800384800396e-05*G0_1_2_4 - 7.69600769600796e-05*G0_1_3_0 - 3.84800384800398e-05*G0_1_3_1 + 3.84800384800398e-05*G0_1_3_2 + 0.000307840307840318*G0_1_3_3 + 0.000461760461760478*G0_1_3_4 + 0.000153920153920159*G0_1_3_5 - 7.69600769600795e-05*G0_1_4_0 - 0.000153920153920159*G0_1_4_1 + 3.84800384800396e-05*G0_1_4_2 + 0.000461760461760478*G0_1_4_3 + 0.00153920153920159*G0_1_4_4 + 0.000307840307840318*G0_1_4_5 - 7.69600769600796e-05*G0_1_5_0 + 3.84800384800398e-05*G0_1_5_1 + 0.000153920153920159*G0_1_5_3 + 0.000307840307840318*G0_1_5_4 + 3.84800384800397e-05*G0_2_0_0 - 2.88600288600298e-05*G0_2_0_1 + 0.000105820105820109*G0_2_0_2 + 0.000115440115440119*G0_2_0_3 + 0.000538720538720557*G0_2_0_4 + 7.69600769600796e-05*G0_2_0_5 - 2.88600288600298e-05*G0_2_1_0 - 1.92400192400199e-05*G0_2_1_1 + 7.69600769600796e-05*G0_2_1_2 + 3.84800384800397e-05*G0_2_1_3 + 3.84800384800397e-05*G0_2_1_4 + 0.000105820105820109*G0_2_2_0 + 7.69600769600796e-05*G0_2_2_1 - 0.000577200577200596*G0_2_2_2 - 0.000230880230880239*G0_2_2_3 - 0.000923520923520955*G0_2_2_4 - 3.84800384800399e-05*G0_2_2_5 + 0.000115440115440119*G0_2_3_0 + 3.84800384800397e-05*G0_2_3_1 - 0.000230880230880239*G0_2_3_2 - 0.000307840307840318*G0_2_3_3 - 0.000307840307840318*G0_2_3_4 - 0.000153920153920159*G0_2_3_5 + 0.000538720538720557*G0_2_4_0 + 3.84800384800397e-05*G0_2_4_1 - 0.000923520923520955*G0_2_4_2 - 0.000307840307840318*G0_2_4_3 - 0.000615680615680635*G0_2_4_4 + 7.69600769600796e-05*G0_2_5_0 - 3.84800384800398e-05*G0_2_5_2 - 0.000153920153920159*G0_2_5_3 - 0.000307840307840319*G0_2_5_5 - 7.69600769600796e-05*G0_3_0_0 - 7.69600769600796e-05*G0_3_0_1 + 0.000115440115440119*G0_3_0_2 + 0.000153920153920159*G0_3_0_3 + 0.000307840307840319*G0_3_0_4 - 7.69600769600796e-05*G0_3_1_0 - 3.84800384800398e-05*G0_3_1_1 + 3.84800384800397e-05*G0_3_1_2 + 0.000307840307840318*G0_3_1_3 + 0.000461760461760478*G0_3_1_4 + 0.000153920153920159*G0_3_1_5 + 0.000115440115440119*G0_3_2_0 + 3.84800384800397e-05*G0_3_2_1 - 0.000230880230880239*G0_3_2_2 - 0.000307840307840318*G0_3_2_3 - 0.000307840307840318*G0_3_2_4 - 0.000153920153920159*G0_3_2_5 + 0.000153920153920159*G0_3_3_0 + 0.000307840307840318*G0_3_3_1 - 0.000307840307840318*G0_3_3_2 - 0.000615680615680638*G0_3_3_3 - 0.00123136123136127*G0_3_3_4 + 0.000307840307840318*G0_3_4_0 + 0.000461760461760478*G0_3_4_1 - 0.000307840307840318*G0_3_4_2 - 0.00123136123136127*G0_3_4_3 - 0.00369408369408382*G0_3_4_4 - 0.000615680615680638*G0_3_4_5 + 0.000153920153920159*G0_3_5_1 - 0.000153920153920159*G0_3_5_2 - 0.000615680615680638*G0_3_5_4 + 0.000615680615680636*G0_3_5_5 - 0.000769600769600796*G0_4_0_0 - 7.69600769600795e-05*G0_4_0_1 + 0.000538720538720557*G0_4_0_2 + 0.000307840307840319*G0_4_0_3 - 7.69600769600795e-05*G0_4_1_0 - 0.000153920153920159*G0_4_1_1 + 3.84800384800397e-05*G0_4_1_2 + 0.000461760461760478*G0_4_1_3 + 0.00153920153920159*G0_4_1_4 + 0.000307840307840318*G0_4_1_5 + 0.000538720538720557*G0_4_2_0 + 3.84800384800397e-05*G0_4_2_1 - 0.000923520923520955*G0_4_2_2 - 0.000307840307840318*G0_4_2_3 - 0.000615680615680635*G0_4_2_4 + 0.000307840307840319*G0_4_3_0 + 0.000461760461760478*G0_4_3_1 - 0.000307840307840318*G0_4_3_2 - 0.00123136123136127*G0_4_3_3 - 0.00369408369408382*G0_4_3_4 - 0.000615680615680638*G0_4_3_5 + 0.00153920153920159*G0_4_4_1 - 0.000615680615680635*G0_4_4_2 - 0.00369408369408382*G0_4_4_3 - 0.0246272246272255*G0_4_4_4 - 0.00307840307840318*G0_4_4_5 + 0.000307840307840318*G0_4_5_1 - 0.000615680615680638*G0_4_5_3 - 0.00307840307840318*G0_4_5_4 - 7.69600769600796e-05*G0_5_0_1 + 7.69600769600796e-05*G0_5_0_2 - 7.69600769600796e-05*G0_5_1_0 + 3.84800384800398e-05*G0_5_1_1 + 0.000153920153920159*G0_5_1_3 + 0.000307840307840318*G0_5_1_4 + 7.69600769600796e-05*G0_5_2_0 - 3.84800384800398e-05*G0_5_2_2 - 0.000153920153920159*G0_5_2_3 - 0.000307840307840319*G0_5_2_5 + 0.000153920153920159*G0_5_3_1 - 0.000153920153920159*G0_5_3_2 - 0.000615680615680638*G0_5_3_4 + 0.000615680615680636*G0_5_3_5 + 0.000307840307840318*G0_5_4_1 - 0.000615680615680638*G0_5_4_3 - 0.00307840307840318*G0_5_4_4 - 0.000307840307840319*G0_5_5_2 + 0.000615680615680636*G0_5_5_3 + 0.00307840307840319*G0_5_5_5; + A[0] = 0.00324675324675336*G0_0_0_0 - 0.000216450216450224*G0_0_0_1 - 0.000216450216450224*G0_0_0_2 + 7.21500721500748e-05*G0_0_0_3 + 0.00093795093795097*G0_0_0_4 + 0.000937950937950971*G0_0_0_5 - 0.000216450216450224*G0_0_1_0 + 2.16450216450224e-05*G0_0_1_1 + 2.16450216450224e-05*G0_0_1_2 - 7.21500721500749e-06*G0_0_1_3 - 7.21500721500747e-05*G0_0_1_4 - 0.000144300144300149*G0_0_1_5 - 0.000216450216450224*G0_0_2_0 + 2.16450216450224e-05*G0_0_2_1 + 2.16450216450224e-05*G0_0_2_2 - 7.21500721500749e-06*G0_0_2_3 - 0.000144300144300149*G0_0_2_4 - 7.21500721500747e-05*G0_0_2_5 + 7.21500721500748e-05*G0_0_3_0 - 7.21500721500749e-06*G0_0_3_1 - 7.21500721500749e-06*G0_0_3_2 - 5.77200577200596e-05*G0_0_3_3 + 0.00093795093795097*G0_0_4_0 - 7.21500721500746e-05*G0_0_4_1 - 0.000144300144300149*G0_0_4_2 + 0.000577200577200596*G0_0_4_4 + 0.000288600288600299*G0_0_4_5 + 0.000937950937950971*G0_0_5_0 - 0.000144300144300149*G0_0_5_1 - 7.21500721500747e-05*G0_0_5_2 + 0.000288600288600299*G0_0_5_4 + 0.000577200577200598*G0_0_5_5 - 0.000216450216450224*G0_1_0_0 + 2.16450216450224e-05*G0_1_0_1 + 2.16450216450224e-05*G0_1_0_2 - 7.2150072150075e-06*G0_1_0_3 - 7.21500721500747e-05*G0_1_0_4 - 0.000144300144300149*G0_1_0_5 + 2.16450216450224e-05*G0_1_1_0 + 2.16450216450225e-05*G0_1_1_1 - 7.21500721500748e-06*G0_1_1_2 + 2.64550264550274e-05*G0_1_1_3 + 2.64550264550274e-05*G0_1_1_4 + 6.97450697450722e-05*G0_1_1_5 + 2.16450216450224e-05*G0_1_2_0 - 7.21500721500748e-06*G0_1_2_1 - 7.21500721500746e-06*G0_1_2_2 - 4.81000481000497e-06*G0_1_2_3 + 1.20250120250125e-05*G0_1_2_4 + 1.20250120250125e-05*G0_1_2_5 - 7.2150072150075e-06*G0_1_3_0 + 2.64550264550274e-05*G0_1_3_1 - 4.81000481000497e-06*G0_1_3_2 - 1.92400192400198e-05*G0_1_3_3 - 3.84800384800398e-05*G0_1_3_4 - 9.62000962000995e-06*G0_1_3_5 - 7.21500721500746e-05*G0_1_4_0 + 2.64550264550274e-05*G0_1_4_1 + 1.20250120250124e-05*G0_1_4_2 - 3.84800384800398e-05*G0_1_4_3 - 0.000115440115440119*G0_1_4_4 - 7.69600769600796e-05*G0_1_4_5 - 0.000144300144300149*G0_1_5_0 + 6.97450697450722e-05*G0_1_5_1 + 1.20250120250125e-05*G0_1_5_2 - 9.62000962000995e-06*G0_1_5_3 - 7.69600769600796e-05*G0_1_5_4 - 0.00011544011544012*G0_1_5_5 - 0.000216450216450224*G0_2_0_0 + 2.16450216450224e-05*G0_2_0_1 + 2.16450216450224e-05*G0_2_0_2 - 7.21500721500749e-06*G0_2_0_3 - 0.000144300144300149*G0_2_0_4 - 7.21500721500747e-05*G0_2_0_5 + 2.16450216450224e-05*G0_2_1_0 - 7.21500721500748e-06*G0_2_1_1 - 7.21500721500746e-06*G0_2_1_2 - 4.81000481000497e-06*G0_2_1_3 + 1.20250120250124e-05*G0_2_1_4 + 1.20250120250125e-05*G0_2_1_5 + 2.16450216450224e-05*G0_2_2_0 - 7.21500721500746e-06*G0_2_2_1 + 2.16450216450224e-05*G0_2_2_2 + 2.64550264550274e-05*G0_2_2_3 + 6.97450697450721e-05*G0_2_2_4 + 2.64550264550274e-05*G0_2_2_5 - 7.21500721500749e-06*G0_2_3_0 - 4.81000481000497e-06*G0_2_3_1 + 2.64550264550274e-05*G0_2_3_2 - 1.92400192400199e-05*G0_2_3_3 - 9.62000962000997e-06*G0_2_3_4 - 3.84800384800398e-05*G0_2_3_5 - 0.000144300144300149*G0_2_4_0 + 1.20250120250124e-05*G0_2_4_1 + 6.97450697450721e-05*G0_2_4_2 - 9.62000962000996e-06*G0_2_4_3 - 0.000115440115440119*G0_2_4_4 - 7.69600769600796e-05*G0_2_4_5 - 7.21500721500747e-05*G0_2_5_0 + 1.20250120250125e-05*G0_2_5_1 + 2.64550264550274e-05*G0_2_5_2 - 3.84800384800398e-05*G0_2_5_3 - 7.69600769600796e-05*G0_2_5_4 - 0.00011544011544012*G0_2_5_5 + 7.21500721500748e-05*G0_3_0_0 - 7.21500721500749e-06*G0_3_0_1 - 7.21500721500749e-06*G0_3_0_2 - 5.77200577200596e-05*G0_3_0_3 - 7.2150072150075e-06*G0_3_1_0 + 2.64550264550274e-05*G0_3_1_1 - 4.81000481000497e-06*G0_3_1_2 - 1.92400192400198e-05*G0_3_1_3 - 3.84800384800398e-05*G0_3_1_4 - 9.62000962000995e-06*G0_3_1_5 - 7.21500721500749e-06*G0_3_2_0 - 4.81000481000497e-06*G0_3_2_1 + 2.64550264550274e-05*G0_3_2_2 - 1.92400192400199e-05*G0_3_2_3 - 9.62000962000996e-06*G0_3_2_4 - 3.84800384800398e-05*G0_3_2_5 - 5.77200577200596e-05*G0_3_3_0 - 1.92400192400198e-05*G0_3_3_1 - 1.92400192400199e-05*G0_3_3_2 + 0.000346320346320358*G0_3_3_3 + 0.000192400192400199*G0_3_3_4 + 0.000192400192400199*G0_3_3_5 - 3.84800384800398e-05*G0_3_4_1 - 9.62000962000996e-06*G0_3_4_2 + 0.000192400192400199*G0_3_4_3 + 0.000230880230880239*G0_3_4_4 + 0.000153920153920159*G0_3_4_5 - 9.62000962000995e-06*G0_3_5_1 - 3.84800384800398e-05*G0_3_5_2 + 0.000192400192400199*G0_3_5_3 + 0.000153920153920159*G0_3_5_4 + 0.000230880230880239*G0_3_5_5 + 0.00093795093795097*G0_4_0_0 - 7.21500721500746e-05*G0_4_0_1 - 0.000144300144300149*G0_4_0_2 + 0.000577200577200596*G0_4_0_4 + 0.000288600288600299*G0_4_0_5 - 7.21500721500746e-05*G0_4_1_0 + 2.64550264550274e-05*G0_4_1_1 + 1.20250120250124e-05*G0_4_1_2 - 3.84800384800398e-05*G0_4_1_3 - 0.000115440115440119*G0_4_1_4 - 7.69600769600796e-05*G0_4_1_5 - 0.000144300144300149*G0_4_2_0 + 1.20250120250124e-05*G0_4_2_1 + 6.97450697450721e-05*G0_4_2_2 - 9.62000962000996e-06*G0_4_2_3 - 0.000115440115440119*G0_4_2_4 - 7.69600769600796e-05*G0_4_2_5 - 3.84800384800398e-05*G0_4_3_1 - 9.62000962000997e-06*G0_4_3_2 + 0.000192400192400199*G0_4_3_3 + 0.000230880230880239*G0_4_3_4 + 0.000153920153920159*G0_4_3_5 + 0.000577200577200596*G0_4_4_0 - 0.000115440115440119*G0_4_4_1 - 0.000115440115440119*G0_4_4_2 + 0.000230880230880239*G0_4_4_3 + 0.00115440115440119*G0_4_4_4 + 0.000384800384800398*G0_4_4_5 + 0.000288600288600299*G0_4_5_0 - 7.69600769600796e-05*G0_4_5_1 - 7.69600769600796e-05*G0_4_5_2 + 0.000153920153920159*G0_4_5_3 + 0.000384800384800398*G0_4_5_4 + 0.000384800384800398*G0_4_5_5 + 0.000937950937950971*G0_5_0_0 - 0.000144300144300149*G0_5_0_1 - 7.21500721500747e-05*G0_5_0_2 + 0.000288600288600299*G0_5_0_4 + 0.000577200577200598*G0_5_0_5 - 0.000144300144300149*G0_5_1_0 + 6.97450697450722e-05*G0_5_1_1 + 1.20250120250125e-05*G0_5_1_2 - 9.62000962000995e-06*G0_5_1_3 - 7.69600769600796e-05*G0_5_1_4 - 0.00011544011544012*G0_5_1_5 - 7.21500721500747e-05*G0_5_2_0 + 1.20250120250125e-05*G0_5_2_1 + 2.64550264550274e-05*G0_5_2_2 - 3.84800384800398e-05*G0_5_2_3 - 7.69600769600796e-05*G0_5_2_4 - 0.00011544011544012*G0_5_2_5 - 9.62000962000995e-06*G0_5_3_1 - 3.84800384800398e-05*G0_5_3_2 + 0.000192400192400199*G0_5_3_3 + 0.000153920153920159*G0_5_3_4 + 0.000230880230880239*G0_5_3_5 + 0.000288600288600299*G0_5_4_0 - 7.69600769600796e-05*G0_5_4_1 - 7.69600769600796e-05*G0_5_4_2 + 0.000153920153920159*G0_5_4_3 + 0.000384800384800398*G0_5_4_4 + 0.000384800384800398*G0_5_4_5 + 0.000577200577200598*G0_5_5_0 - 0.00011544011544012*G0_5_5_1 - 0.00011544011544012*G0_5_5_2 + 0.000230880230880239*G0_5_5_3 + 0.000384800384800398*G0_5_5_4 + 0.00115440115440119*G0_5_5_5; + A[29] = A[34]; + A[14] = 2.16450216450224e-05*G0_0_0_0 - 7.21500721500746e-06*G0_0_0_1 + 2.16450216450224e-05*G0_0_0_2 + 2.64550264550274e-05*G0_0_0_3 + 6.97450697450721e-05*G0_0_0_4 + 2.64550264550274e-05*G0_0_0_5 - 7.21500721500746e-06*G0_0_1_0 - 7.21500721500747e-06*G0_0_1_1 + 2.16450216450224e-05*G0_0_1_2 + 1.20250120250124e-05*G0_0_1_3 + 1.20250120250124e-05*G0_0_1_4 - 4.81000481000498e-06*G0_0_1_5 + 2.16450216450224e-05*G0_0_2_0 + 2.16450216450224e-05*G0_0_2_1 - 0.000216450216450224*G0_0_2_2 - 7.21500721500746e-05*G0_0_2_3 - 0.000144300144300149*G0_0_2_4 - 7.21500721500748e-06*G0_0_2_5 + 2.64550264550274e-05*G0_0_3_0 + 1.20250120250124e-05*G0_0_3_1 - 7.21500721500746e-05*G0_0_3_2 - 0.000115440115440119*G0_0_3_3 - 7.69600769600796e-05*G0_0_3_4 - 3.84800384800398e-05*G0_0_3_5 + 6.97450697450721e-05*G0_0_4_0 + 1.20250120250124e-05*G0_0_4_1 - 0.000144300144300149*G0_0_4_2 - 7.69600769600796e-05*G0_0_4_3 - 0.000115440115440119*G0_0_4_4 - 9.62000962000994e-06*G0_0_4_5 + 2.64550264550274e-05*G0_0_5_0 - 4.81000481000498e-06*G0_0_5_1 - 7.21500721500748e-06*G0_0_5_2 - 3.84800384800398e-05*G0_0_5_3 - 9.62000962000995e-06*G0_0_5_4 - 1.92400192400199e-05*G0_0_5_5 - 7.21500721500746e-06*G0_1_0_0 - 7.21500721500747e-06*G0_1_0_1 + 2.16450216450224e-05*G0_1_0_2 + 1.20250120250124e-05*G0_1_0_3 + 1.20250120250124e-05*G0_1_0_4 - 4.81000481000498e-06*G0_1_0_5 - 7.21500721500747e-06*G0_1_1_0 + 2.16450216450224e-05*G0_1_1_1 + 2.16450216450223e-05*G0_1_1_2 + 6.97450697450722e-05*G0_1_1_3 + 2.64550264550274e-05*G0_1_1_4 + 2.64550264550274e-05*G0_1_1_5 + 2.16450216450224e-05*G0_1_2_0 + 2.16450216450223e-05*G0_1_2_1 - 0.000216450216450224*G0_1_2_2 - 0.000144300144300149*G0_1_2_3 - 7.21500721500746e-05*G0_1_2_4 - 7.21500721500748e-06*G0_1_2_5 + 1.20250120250124e-05*G0_1_3_0 + 6.97450697450722e-05*G0_1_3_1 - 0.000144300144300149*G0_1_3_2 - 0.000115440115440119*G0_1_3_3 - 7.69600769600796e-05*G0_1_3_4 - 9.62000962000993e-06*G0_1_3_5 + 1.20250120250124e-05*G0_1_4_0 + 2.64550264550274e-05*G0_1_4_1 - 7.21500721500746e-05*G0_1_4_2 - 7.69600769600796e-05*G0_1_4_3 - 0.000115440115440119*G0_1_4_4 - 3.84800384800398e-05*G0_1_4_5 - 4.81000481000498e-06*G0_1_5_0 + 2.64550264550274e-05*G0_1_5_1 - 7.21500721500747e-06*G0_1_5_2 - 9.62000962000993e-06*G0_1_5_3 - 3.84800384800398e-05*G0_1_5_4 - 1.92400192400199e-05*G0_1_5_5 + 2.16450216450224e-05*G0_2_0_0 + 2.16450216450224e-05*G0_2_0_1 - 0.000216450216450224*G0_2_0_2 - 7.21500721500746e-05*G0_2_0_3 - 0.000144300144300149*G0_2_0_4 - 7.21500721500748e-06*G0_2_0_5 + 2.16450216450224e-05*G0_2_1_0 + 2.16450216450223e-05*G0_2_1_1 - 0.000216450216450224*G0_2_1_2 - 0.000144300144300149*G0_2_1_3 - 7.21500721500746e-05*G0_2_1_4 - 7.21500721500747e-06*G0_2_1_5 - 0.000216450216450224*G0_2_2_0 - 0.000216450216450224*G0_2_2_1 + 0.00324675324675335*G0_2_2_2 + 0.00093795093795097*G0_2_2_3 + 0.00093795093795097*G0_2_2_4 + 7.21500721500748e-05*G0_2_2_5 - 7.21500721500746e-05*G0_2_3_0 - 0.000144300144300149*G0_2_3_1 + 0.00093795093795097*G0_2_3_2 + 0.000577200577200597*G0_2_3_3 + 0.000288600288600299*G0_2_3_4 - 0.000144300144300149*G0_2_4_0 - 7.21500721500746e-05*G0_2_4_1 + 0.00093795093795097*G0_2_4_2 + 0.000288600288600299*G0_2_4_3 + 0.000577200577200597*G0_2_4_4 - 7.21500721500748e-06*G0_2_5_0 - 7.21500721500747e-06*G0_2_5_1 + 7.21500721500748e-05*G0_2_5_2 - 5.77200577200597e-05*G0_2_5_5 + 2.64550264550274e-05*G0_3_0_0 + 1.20250120250124e-05*G0_3_0_1 - 7.21500721500746e-05*G0_3_0_2 - 0.000115440115440119*G0_3_0_3 - 7.69600769600796e-05*G0_3_0_4 - 3.84800384800398e-05*G0_3_0_5 + 1.20250120250124e-05*G0_3_1_0 + 6.97450697450722e-05*G0_3_1_1 - 0.000144300144300149*G0_3_1_2 - 0.000115440115440119*G0_3_1_3 - 7.69600769600796e-05*G0_3_1_4 - 9.62000962000993e-06*G0_3_1_5 - 7.21500721500746e-05*G0_3_2_0 - 0.000144300144300149*G0_3_2_1 + 0.00093795093795097*G0_3_2_2 + 0.000577200577200597*G0_3_2_3 + 0.000288600288600299*G0_3_2_4 - 0.000115440115440119*G0_3_3_0 - 0.000115440115440119*G0_3_3_1 + 0.000577200577200597*G0_3_3_2 + 0.00115440115440119*G0_3_3_3 + 0.000384800384800398*G0_3_3_4 + 0.000230880230880239*G0_3_3_5 - 7.69600769600796e-05*G0_3_4_0 - 7.69600769600796e-05*G0_3_4_1 + 0.000288600288600299*G0_3_4_2 + 0.000384800384800398*G0_3_4_3 + 0.000384800384800398*G0_3_4_4 + 0.000153920153920159*G0_3_4_5 - 3.84800384800398e-05*G0_3_5_0 - 9.62000962000993e-06*G0_3_5_1 + 0.000230880230880239*G0_3_5_3 + 0.000153920153920159*G0_3_5_4 + 0.000192400192400199*G0_3_5_5 + 6.97450697450721e-05*G0_4_0_0 + 1.20250120250124e-05*G0_4_0_1 - 0.000144300144300149*G0_4_0_2 - 7.69600769600796e-05*G0_4_0_3 - 0.000115440115440119*G0_4_0_4 - 9.62000962000994e-06*G0_4_0_5 + 1.20250120250124e-05*G0_4_1_0 + 2.64550264550274e-05*G0_4_1_1 - 7.21500721500746e-05*G0_4_1_2 - 7.69600769600796e-05*G0_4_1_3 - 0.000115440115440119*G0_4_1_4 - 3.84800384800398e-05*G0_4_1_5 - 0.000144300144300149*G0_4_2_0 - 7.21500721500746e-05*G0_4_2_1 + 0.00093795093795097*G0_4_2_2 + 0.000288600288600299*G0_4_2_3 + 0.000577200577200597*G0_4_2_4 - 7.69600769600796e-05*G0_4_3_0 - 7.69600769600796e-05*G0_4_3_1 + 0.000288600288600299*G0_4_3_2 + 0.000384800384800398*G0_4_3_3 + 0.000384800384800398*G0_4_3_4 + 0.000153920153920159*G0_4_3_5 - 0.000115440115440119*G0_4_4_0 - 0.000115440115440119*G0_4_4_1 + 0.000577200577200597*G0_4_4_2 + 0.000384800384800398*G0_4_4_3 + 0.00115440115440119*G0_4_4_4 + 0.000230880230880239*G0_4_4_5 - 9.62000962000994e-06*G0_4_5_0 - 3.84800384800398e-05*G0_4_5_1 + 0.000153920153920159*G0_4_5_3 + 0.000230880230880239*G0_4_5_4 + 0.000192400192400199*G0_4_5_5 + 2.64550264550274e-05*G0_5_0_0 - 4.81000481000498e-06*G0_5_0_1 - 7.21500721500748e-06*G0_5_0_2 - 3.84800384800398e-05*G0_5_0_3 - 9.62000962000994e-06*G0_5_0_4 - 1.92400192400199e-05*G0_5_0_5 - 4.81000481000498e-06*G0_5_1_0 + 2.64550264550274e-05*G0_5_1_1 - 7.21500721500747e-06*G0_5_1_2 - 9.62000962000993e-06*G0_5_1_3 - 3.84800384800398e-05*G0_5_1_4 - 1.92400192400199e-05*G0_5_1_5 - 7.21500721500748e-06*G0_5_2_0 - 7.21500721500747e-06*G0_5_2_1 + 7.21500721500748e-05*G0_5_2_2 - 5.77200577200597e-05*G0_5_2_5 - 3.84800384800398e-05*G0_5_3_0 - 9.62000962000993e-06*G0_5_3_1 + 0.000230880230880239*G0_5_3_3 + 0.000153920153920159*G0_5_3_4 + 0.000192400192400199*G0_5_3_5 - 9.62000962000994e-06*G0_5_4_0 - 3.84800384800398e-05*G0_5_4_1 + 0.000153920153920159*G0_5_4_3 + 0.000230880230880239*G0_5_4_4 + 0.000192400192400199*G0_5_4_5 - 1.92400192400199e-05*G0_5_5_0 - 1.92400192400199e-05*G0_5_5_1 - 5.77200577200597e-05*G0_5_5_2 + 0.000192400192400199*G0_5_5_3 + 0.000192400192400199*G0_5_5_4 + 0.000346320346320358*G0_5_5_5; + A[10] = A[25]; + A[5] = A[30]; + A[26] = A[20] - 0.000137085137085142*G0_0_0_0 + 1.68350168350174e-05*G0_0_0_1 + 4.32900432900448e-05*G0_0_0_2 + 9.62000962000995e-06*G0_0_0_3 - 0.000105820105820109*G0_0_0_4 - 3.84800384800398e-05*G0_0_0_5 + 1.68350168350174e-05*G0_0_1_0 - 1.68350168350175e-05*G0_0_1_1 - 2.88600288600299e-05*G0_0_1_3 + 2.88600288600298e-05*G0_0_1_4 + 4.32900432900448e-05*G0_0_2_0 - 7.21500721500746e-05*G0_0_2_2 + 3.84800384800398e-05*G0_0_2_3 - 3.84800384800397e-05*G0_0_2_4 + 2.88600288600299e-05*G0_0_2_5 + 9.62000962000995e-06*G0_0_3_0 - 2.88600288600299e-05*G0_0_3_1 + 3.84800384800398e-05*G0_0_3_2 - 7.69600769600797e-05*G0_0_3_3 - 7.69600769600796e-05*G0_0_3_4 - 7.69600769600796e-05*G0_0_3_5 - 0.000105820105820109*G0_0_4_0 + 2.88600288600298e-05*G0_0_4_1 - 3.84800384800397e-05*G0_0_4_2 - 7.69600769600796e-05*G0_0_4_3 - 0.000538720538720557*G0_0_4_4 - 0.000115440115440119*G0_0_4_5 - 3.84800384800398e-05*G0_0_5_0 + 2.88600288600299e-05*G0_0_5_2 - 7.69600769600796e-05*G0_0_5_3 - 0.000115440115440119*G0_0_5_4 - 0.000115440115440119*G0_0_5_5 + 1.68350168350174e-05*G0_1_0_0 - 1.68350168350175e-05*G0_1_0_1 - 2.88600288600299e-05*G0_1_0_3 + 2.88600288600298e-05*G0_1_0_4 - 1.68350168350175e-05*G0_1_1_0 + 0.000137085137085142*G0_1_1_1 - 4.32900432900448e-05*G0_1_1_2 + 0.00010582010582011*G0_1_1_3 - 9.62000962000996e-06*G0_1_1_4 + 3.848003848004e-05*G0_1_1_5 - 4.32900432900448e-05*G0_1_2_1 + 7.21500721500746e-05*G0_1_2_2 + 3.84800384800397e-05*G0_1_2_3 - 3.84800384800398e-05*G0_1_2_4 - 2.88600288600299e-05*G0_1_2_5 - 2.88600288600299e-05*G0_1_3_0 + 0.00010582010582011*G0_1_3_1 + 3.84800384800397e-05*G0_1_3_2 + 0.000538720538720558*G0_1_3_3 + 7.69600769600797e-05*G0_1_3_4 + 0.00011544011544012*G0_1_3_5 + 2.88600288600298e-05*G0_1_4_0 - 9.62000962000996e-06*G0_1_4_1 - 3.84800384800398e-05*G0_1_4_2 + 7.69600769600797e-05*G0_1_4_3 + 7.69600769600798e-05*G0_1_4_4 + 7.69600769600797e-05*G0_1_4_5 + 3.848003848004e-05*G0_1_5_1 - 2.88600288600299e-05*G0_1_5_2 + 0.00011544011544012*G0_1_5_3 + 7.69600769600797e-05*G0_1_5_4 + 0.00011544011544012*G0_1_5_5 + 4.32900432900448e-05*G0_2_0_0 - 7.21500721500746e-05*G0_2_0_2 + 3.84800384800398e-05*G0_2_0_3 - 3.84800384800397e-05*G0_2_0_4 + 2.88600288600299e-05*G0_2_0_5 - 4.32900432900448e-05*G0_2_1_1 + 7.21500721500746e-05*G0_2_1_2 + 3.84800384800397e-05*G0_2_1_3 - 3.84800384800398e-05*G0_2_1_4 - 2.88600288600299e-05*G0_2_1_5 - 7.21500721500746e-05*G0_2_2_0 + 7.21500721500746e-05*G0_2_2_1 - 0.000288600288600298*G0_2_2_3 + 0.000288600288600298*G0_2_2_4 + 3.84800384800398e-05*G0_2_3_0 + 3.84800384800397e-05*G0_2_3_1 - 0.000288600288600298*G0_2_3_2 - 0.000769600769600797*G0_2_3_3 - 7.69600769600796e-05*G0_2_3_5 - 3.84800384800398e-05*G0_2_4_0 - 3.84800384800398e-05*G0_2_4_1 + 0.000288600288600298*G0_2_4_2 + 0.000769600769600796*G0_2_4_4 + 7.69600769600796e-05*G0_2_4_5 + 2.88600288600299e-05*G0_2_5_0 - 2.88600288600299e-05*G0_2_5_1 - 7.69600769600797e-05*G0_2_5_3 + 7.69600769600796e-05*G0_2_5_4 + 9.62000962000995e-06*G0_3_0_0 - 2.88600288600299e-05*G0_3_0_1 + 3.84800384800398e-05*G0_3_0_2 - 7.69600769600797e-05*G0_3_0_3 - 7.69600769600796e-05*G0_3_0_4 - 7.69600769600796e-05*G0_3_0_5 - 2.88600288600299e-05*G0_3_1_0 + 0.00010582010582011*G0_3_1_1 + 3.84800384800397e-05*G0_3_1_2 + 0.000538720538720558*G0_3_1_3 + 7.69600769600797e-05*G0_3_1_4 + 0.00011544011544012*G0_3_1_5 + 3.84800384800398e-05*G0_3_2_0 + 3.84800384800397e-05*G0_3_2_1 - 0.000288600288600298*G0_3_2_2 - 0.000769600769600797*G0_3_2_3 - 7.69600769600796e-05*G0_3_2_5 - 7.69600769600797e-05*G0_3_3_0 + 0.000538720538720558*G0_3_3_1 - 0.000769600769600797*G0_3_3_2 + 0.000307840307840319*G0_3_3_5 - 7.69600769600796e-05*G0_3_4_0 + 7.69600769600796e-05*G0_3_4_1 - 7.69600769600796e-05*G0_3_5_0 + 0.00011544011544012*G0_3_5_1 - 7.69600769600796e-05*G0_3_5_2 + 0.000307840307840319*G0_3_5_3 + 0.000153920153920159*G0_3_5_5 - 0.000105820105820109*G0_4_0_0 + 2.88600288600298e-05*G0_4_0_1 - 3.84800384800398e-05*G0_4_0_2 - 7.69600769600796e-05*G0_4_0_3 - 0.000538720538720557*G0_4_0_4 - 0.000115440115440119*G0_4_0_5 + 2.88600288600299e-05*G0_4_1_0 - 9.62000962000994e-06*G0_4_1_1 - 3.84800384800398e-05*G0_4_1_2 + 7.69600769600796e-05*G0_4_1_3 + 7.69600769600797e-05*G0_4_1_4 + 7.69600769600797e-05*G0_4_1_5 - 3.84800384800397e-05*G0_4_2_0 - 3.84800384800398e-05*G0_4_2_1 + 0.000288600288600298*G0_4_2_2 + 0.000769600769600796*G0_4_2_4 + 7.69600769600796e-05*G0_4_2_5 - 7.69600769600796e-05*G0_4_3_0 + 7.69600769600796e-05*G0_4_3_1 - 0.000538720538720557*G0_4_4_0 + 7.69600769600797e-05*G0_4_4_1 + 0.000769600769600796*G0_4_4_2 - 0.000307840307840318*G0_4_4_5 - 0.000115440115440119*G0_4_5_0 + 7.69600769600797e-05*G0_4_5_1 + 7.69600769600796e-05*G0_4_5_2 - 0.000307840307840318*G0_4_5_4 - 0.000153920153920159*G0_4_5_5 - 3.84800384800398e-05*G0_5_0_0 + 2.88600288600299e-05*G0_5_0_2 - 7.69600769600796e-05*G0_5_0_3 - 0.000115440115440119*G0_5_0_4 - 0.000115440115440119*G0_5_0_5 + 3.848003848004e-05*G0_5_1_1 - 2.88600288600299e-05*G0_5_1_2 + 0.00011544011544012*G0_5_1_3 + 7.69600769600796e-05*G0_5_1_4 + 0.00011544011544012*G0_5_1_5 + 2.88600288600299e-05*G0_5_2_0 - 2.88600288600299e-05*G0_5_2_1 - 7.69600769600796e-05*G0_5_2_3 + 7.69600769600797e-05*G0_5_2_4 - 7.69600769600796e-05*G0_5_3_0 + 0.00011544011544012*G0_5_3_1 - 7.69600769600796e-05*G0_5_3_2 + 0.000307840307840319*G0_5_3_3 + 0.000153920153920159*G0_5_3_5 - 0.000115440115440119*G0_5_4_0 + 7.69600769600797e-05*G0_5_4_1 + 7.69600769600796e-05*G0_5_4_2 - 0.000307840307840318*G0_5_4_4 - 0.000153920153920159*G0_5_4_5 - 0.000115440115440119*G0_5_5_0 + 0.00011544011544012*G0_5_5_1 + 0.000153920153920159*G0_5_5_3 - 0.000153920153920159*G0_5_5_4; + A[6] = -0.000216450216450224*G0_0_0_0 + 2.16450216450224e-05*G0_0_0_1 + 2.16450216450224e-05*G0_0_0_2 - 7.2150072150075e-06*G0_0_0_3 - 7.21500721500747e-05*G0_0_0_4 - 0.000144300144300149*G0_0_0_5 + 2.16450216450224e-05*G0_0_1_0 + 2.16450216450225e-05*G0_0_1_1 - 7.21500721500748e-06*G0_0_1_2 + 2.64550264550274e-05*G0_0_1_3 + 2.64550264550274e-05*G0_0_1_4 + 6.97450697450722e-05*G0_0_1_5 + 2.16450216450224e-05*G0_0_2_0 - 7.21500721500748e-06*G0_0_2_1 - 7.21500721500746e-06*G0_0_2_2 - 4.81000481000497e-06*G0_0_2_3 + 1.20250120250125e-05*G0_0_2_4 + 1.20250120250125e-05*G0_0_2_5 - 7.2150072150075e-06*G0_0_3_0 + 2.64550264550274e-05*G0_0_3_1 - 4.81000481000497e-06*G0_0_3_2 - 1.92400192400198e-05*G0_0_3_3 - 3.84800384800398e-05*G0_0_3_4 - 9.62000962000995e-06*G0_0_3_5 - 7.21500721500746e-05*G0_0_4_0 + 2.64550264550274e-05*G0_0_4_1 + 1.20250120250124e-05*G0_0_4_2 - 3.84800384800398e-05*G0_0_4_3 - 0.000115440115440119*G0_0_4_4 - 7.69600769600796e-05*G0_0_4_5 - 0.000144300144300149*G0_0_5_0 + 6.97450697450722e-05*G0_0_5_1 + 1.20250120250125e-05*G0_0_5_2 - 9.62000962000995e-06*G0_0_5_3 - 7.69600769600796e-05*G0_0_5_4 - 0.00011544011544012*G0_0_5_5 + 2.16450216450224e-05*G0_1_0_0 + 2.16450216450225e-05*G0_1_0_1 - 7.21500721500748e-06*G0_1_0_2 + 2.64550264550274e-05*G0_1_0_3 + 2.64550264550274e-05*G0_1_0_4 + 6.97450697450722e-05*G0_1_0_5 + 2.16450216450225e-05*G0_1_1_0 - 0.000216450216450225*G0_1_1_1 + 2.16450216450225e-05*G0_1_1_2 - 7.21500721500749e-05*G0_1_1_3 - 7.21500721500747e-06*G0_1_1_4 - 0.00014430014430015*G0_1_1_5 - 7.21500721500748e-06*G0_1_2_0 + 2.16450216450225e-05*G0_1_2_1 - 7.21500721500747e-06*G0_1_2_2 + 1.20250120250125e-05*G0_1_2_3 - 4.81000481000498e-06*G0_1_2_4 + 1.20250120250125e-05*G0_1_2_5 + 2.64550264550274e-05*G0_1_3_0 - 7.21500721500749e-05*G0_1_3_1 + 1.20250120250125e-05*G0_1_3_2 - 0.00011544011544012*G0_1_3_3 - 3.84800384800398e-05*G0_1_3_4 - 7.69600769600797e-05*G0_1_3_5 + 2.64550264550274e-05*G0_1_4_0 - 7.21500721500747e-06*G0_1_4_1 - 4.81000481000497e-06*G0_1_4_2 - 3.84800384800398e-05*G0_1_4_3 - 1.92400192400199e-05*G0_1_4_4 - 9.62000962000992e-06*G0_1_4_5 + 6.97450697450722e-05*G0_1_5_0 - 0.00014430014430015*G0_1_5_1 + 1.20250120250125e-05*G0_1_5_2 - 7.69600769600797e-05*G0_1_5_3 - 9.62000962000992e-06*G0_1_5_4 - 0.00011544011544012*G0_1_5_5 + 2.16450216450224e-05*G0_2_0_0 - 7.21500721500748e-06*G0_2_0_1 - 7.21500721500746e-06*G0_2_0_2 - 4.81000481000497e-06*G0_2_0_3 + 1.20250120250125e-05*G0_2_0_4 + 1.20250120250125e-05*G0_2_0_5 - 7.21500721500748e-06*G0_2_1_0 + 2.16450216450225e-05*G0_2_1_1 - 7.21500721500747e-06*G0_2_1_2 + 1.20250120250125e-05*G0_2_1_3 - 4.81000481000497e-06*G0_2_1_4 + 1.20250120250125e-05*G0_2_1_5 - 7.21500721500746e-06*G0_2_2_0 - 7.21500721500747e-06*G0_2_2_1 + 2.16450216450224e-05*G0_2_2_2 + 1.20250120250124e-05*G0_2_2_3 + 1.20250120250124e-05*G0_2_2_4 - 4.81000481000498e-06*G0_2_2_5 - 4.81000481000497e-06*G0_2_3_0 + 1.20250120250125e-05*G0_2_3_1 + 1.20250120250124e-05*G0_2_3_2 + 4.81000481000498e-05*G0_2_3_3 + 1.92400192400199e-05*G0_2_3_4 + 1.92400192400199e-05*G0_2_3_5 + 1.20250120250125e-05*G0_2_4_0 - 4.81000481000497e-06*G0_2_4_1 + 1.20250120250124e-05*G0_2_4_2 + 1.92400192400199e-05*G0_2_4_3 + 4.81000481000497e-05*G0_2_4_4 + 1.92400192400199e-05*G0_2_4_5 + 1.20250120250125e-05*G0_2_5_0 + 1.20250120250125e-05*G0_2_5_1 - 4.81000481000498e-06*G0_2_5_2 + 1.92400192400199e-05*G0_2_5_3 + 1.92400192400199e-05*G0_2_5_4 + 4.81000481000498e-05*G0_2_5_5 - 7.2150072150075e-06*G0_3_0_0 + 2.64550264550274e-05*G0_3_0_1 - 4.81000481000497e-06*G0_3_0_2 - 1.92400192400198e-05*G0_3_0_3 - 3.84800384800398e-05*G0_3_0_4 - 9.62000962000995e-06*G0_3_0_5 + 2.64550264550274e-05*G0_3_1_0 - 7.21500721500749e-05*G0_3_1_1 + 1.20250120250125e-05*G0_3_1_2 - 0.00011544011544012*G0_3_1_3 - 3.84800384800398e-05*G0_3_1_4 - 7.69600769600797e-05*G0_3_1_5 - 4.81000481000497e-06*G0_3_2_0 + 1.20250120250125e-05*G0_3_2_1 + 1.20250120250124e-05*G0_3_2_2 + 4.81000481000498e-05*G0_3_2_3 + 1.92400192400199e-05*G0_3_2_4 + 1.92400192400199e-05*G0_3_2_5 - 1.92400192400198e-05*G0_3_3_0 - 0.00011544011544012*G0_3_3_1 + 4.81000481000498e-05*G0_3_3_2 + 7.69600769600791e-05*G0_3_3_3 + 0.000115440115440119*G0_3_3_4 - 3.84800384800398e-05*G0_3_4_0 - 3.84800384800398e-05*G0_3_4_1 + 1.92400192400199e-05*G0_3_4_2 + 0.000115440115440119*G0_3_4_3 + 0.000115440115440119*G0_3_4_4 + 3.84800384800397e-05*G0_3_4_5 - 9.62000962000995e-06*G0_3_5_0 - 7.69600769600797e-05*G0_3_5_1 + 1.92400192400199e-05*G0_3_5_2 + 3.84800384800397e-05*G0_3_5_4 - 7.69600769600798e-05*G0_3_5_5 - 7.21500721500746e-05*G0_4_0_0 + 2.64550264550274e-05*G0_4_0_1 + 1.20250120250124e-05*G0_4_0_2 - 3.84800384800398e-05*G0_4_0_3 - 0.000115440115440119*G0_4_0_4 - 7.69600769600796e-05*G0_4_0_5 + 2.64550264550274e-05*G0_4_1_0 - 7.21500721500747e-06*G0_4_1_1 - 4.81000481000497e-06*G0_4_1_2 - 3.84800384800398e-05*G0_4_1_3 - 1.92400192400199e-05*G0_4_1_4 - 9.62000962000992e-06*G0_4_1_5 + 1.20250120250125e-05*G0_4_2_0 - 4.81000481000497e-06*G0_4_2_1 + 1.20250120250124e-05*G0_4_2_2 + 1.92400192400199e-05*G0_4_2_3 + 4.81000481000497e-05*G0_4_2_4 + 1.92400192400199e-05*G0_4_2_5 - 3.84800384800398e-05*G0_4_3_0 - 3.84800384800398e-05*G0_4_3_1 + 1.92400192400199e-05*G0_4_3_2 + 0.000115440115440119*G0_4_3_3 + 0.000115440115440119*G0_4_3_4 + 3.84800384800397e-05*G0_4_3_5 - 0.000115440115440119*G0_4_4_0 - 1.92400192400199e-05*G0_4_4_1 + 4.81000481000498e-05*G0_4_4_2 + 0.000115440115440119*G0_4_4_3 + 7.69600769600795e-05*G0_4_4_4 - 7.69600769600796e-05*G0_4_5_0 - 9.62000962000992e-06*G0_4_5_1 + 1.92400192400199e-05*G0_4_5_2 + 3.84800384800397e-05*G0_4_5_3 - 7.69600769600797e-05*G0_4_5_5 - 0.000144300144300149*G0_5_0_0 + 6.97450697450722e-05*G0_5_0_1 + 1.20250120250125e-05*G0_5_0_2 - 9.62000962000995e-06*G0_5_0_3 - 7.69600769600796e-05*G0_5_0_4 - 0.00011544011544012*G0_5_0_5 + 6.97450697450722e-05*G0_5_1_0 - 0.00014430014430015*G0_5_1_1 + 1.20250120250125e-05*G0_5_1_2 - 7.69600769600797e-05*G0_5_1_3 - 9.62000962000992e-06*G0_5_1_4 - 0.00011544011544012*G0_5_1_5 + 1.20250120250125e-05*G0_5_2_0 + 1.20250120250125e-05*G0_5_2_1 - 4.81000481000498e-06*G0_5_2_2 + 1.92400192400199e-05*G0_5_2_3 + 1.92400192400199e-05*G0_5_2_4 + 4.81000481000498e-05*G0_5_2_5 - 9.62000962000995e-06*G0_5_3_0 - 7.69600769600797e-05*G0_5_3_1 + 1.92400192400199e-05*G0_5_3_2 + 3.84800384800397e-05*G0_5_3_4 - 7.69600769600798e-05*G0_5_3_5 - 7.69600769600796e-05*G0_5_4_0 - 9.62000962000992e-06*G0_5_4_1 + 1.92400192400199e-05*G0_5_4_2 + 3.84800384800397e-05*G0_5_4_3 - 7.69600769600797e-05*G0_5_4_5 - 0.00011544011544012*G0_5_5_0 - 0.00011544011544012*G0_5_5_1 + 4.81000481000498e-05*G0_5_5_2 - 7.69600769600798e-05*G0_5_5_3 - 7.69600769600797e-05*G0_5_5_4 - 0.000615680615680638*G0_5_5_5; + A[1] = A[6]; + A[35] = A[21] + 0.000634920634920657*G0_0_0_0 - 9.62000962000997e-05*G0_0_0_1 - 9.62000962000996e-05*G0_0_0_2 - 0.000115440115440119*G0_0_0_3 + 0.000192400192400199*G0_0_0_4 + 0.000962000962000996*G0_0_0_5 - 9.62000962000997e-05*G0_0_1_0 - 0.000153920153920159*G0_0_1_3 - 0.000192400192400199*G0_0_1_4 - 0.000615680615680638*G0_0_1_5 - 9.62000962000996e-05*G0_0_2_0 + 9.62000962000995e-05*G0_0_2_2 + 3.84800384800396e-05*G0_0_2_3 - 3.848003848004e-05*G0_0_2_5 - 0.000115440115440119*G0_0_3_0 - 0.000153920153920159*G0_0_3_1 + 3.84800384800396e-05*G0_0_3_2 + 0.00184704184704191*G0_0_3_3 + 0.000615680615680636*G0_0_3_4 + 0.000307840307840318*G0_0_3_5 + 0.000192400192400199*G0_0_4_0 - 0.000192400192400199*G0_0_4_1 + 0.000615680615680636*G0_0_4_3 + 0.000615680615680637*G0_0_4_4 + 0.000461760461760478*G0_0_4_5 + 0.000962000962000996*G0_0_5_0 - 0.000615680615680638*G0_0_5_1 - 3.84800384800401e-05*G0_0_5_2 + 0.000307840307840318*G0_0_5_3 + 0.000461760461760478*G0_0_5_4 + 0.00061568061568064*G0_0_5_5 - 9.62000962000997e-05*G0_1_0_0 - 0.000153920153920159*G0_1_0_3 - 0.000192400192400199*G0_1_0_4 - 0.000615680615680637*G0_1_0_5 - 0.000769600769600796*G0_1_1_3 + 0.000769600769600797*G0_1_1_5 + 9.62000962000994e-05*G0_1_2_2 + 0.000615680615680637*G0_1_2_3 + 0.000192400192400199*G0_1_2_4 + 0.000153920153920159*G0_1_2_5 - 0.000153920153920159*G0_1_3_0 - 0.000769600769600796*G0_1_3_1 + 0.000615680615680637*G0_1_3_2 + 0.000307840307840318*G0_1_3_4 - 0.000192400192400199*G0_1_4_0 + 0.000192400192400199*G0_1_4_2 + 0.000307840307840318*G0_1_4_3 - 0.000307840307840319*G0_1_4_5 - 0.000615680615680637*G0_1_5_0 + 0.000769600769600797*G0_1_5_1 + 0.000153920153920159*G0_1_5_2 - 0.000307840307840319*G0_1_5_4 - 9.62000962000996e-05*G0_2_0_0 + 9.62000962000995e-05*G0_2_0_2 + 3.84800384800396e-05*G0_2_0_3 - 3.848003848004e-05*G0_2_0_5 + 9.62000962000994e-05*G0_2_1_2 + 0.000615680615680637*G0_2_1_3 + 0.000192400192400199*G0_2_1_4 + 0.000153920153920159*G0_2_1_5 + 9.62000962000995e-05*G0_2_2_0 + 9.62000962000994e-05*G0_2_2_1 - 0.000634920634920657*G0_2_2_2 - 0.000962000962000996*G0_2_2_3 - 0.000192400192400199*G0_2_2_4 + 0.000115440115440119*G0_2_2_5 + 3.84800384800396e-05*G0_2_3_0 + 0.000615680615680637*G0_2_3_1 - 0.000962000962000996*G0_2_3_2 - 0.000615680615680637*G0_2_3_3 - 0.000461760461760478*G0_2_3_4 - 0.000307840307840318*G0_2_3_5 + 0.000192400192400199*G0_2_4_1 - 0.000192400192400199*G0_2_4_2 - 0.000461760461760478*G0_2_4_3 - 0.000615680615680637*G0_2_4_4 - 0.000615680615680637*G0_2_4_5 - 3.84800384800401e-05*G0_2_5_0 + 0.000153920153920159*G0_2_5_1 + 0.000115440115440119*G0_2_5_2 - 0.000307840307840318*G0_2_5_3 - 0.000615680615680637*G0_2_5_4 - 0.00184704184704191*G0_2_5_5 - 0.000115440115440119*G0_3_0_0 - 0.000153920153920159*G0_3_0_1 + 3.84800384800396e-05*G0_3_0_2 + 0.00184704184704191*G0_3_0_3 + 0.000615680615680636*G0_3_0_4 + 0.000307840307840319*G0_3_0_5 - 0.000153920153920159*G0_3_1_0 - 0.000769600769600796*G0_3_1_1 + 0.000615680615680637*G0_3_1_2 + 0.000307840307840318*G0_3_1_4 + 3.84800384800396e-05*G0_3_2_0 + 0.000615680615680637*G0_3_2_1 - 0.000962000962000996*G0_3_2_2 - 0.000615680615680637*G0_3_2_3 - 0.000461760461760478*G0_3_2_4 - 0.000307840307840318*G0_3_2_5 + 0.00184704184704191*G0_3_3_0 - 0.000615680615680637*G0_3_3_2 - 0.0277056277056287*G0_3_3_3 - 0.00430976430976445*G0_3_3_4 - 0.00307840307840318*G0_3_3_5 + 0.000615680615680636*G0_3_4_0 + 0.000307840307840318*G0_3_4_1 - 0.000461760461760478*G0_3_4_2 - 0.00430976430976445*G0_3_4_3 - 0.00123136123136127*G0_3_4_4 + 0.000307840307840319*G0_3_5_0 - 0.000307840307840318*G0_3_5_2 - 0.00307840307840318*G0_3_5_3 + 0.00307840307840319*G0_3_5_5 + 0.000192400192400199*G0_4_0_0 - 0.000192400192400199*G0_4_0_1 + 0.000615680615680636*G0_4_0_3 + 0.000615680615680637*G0_4_0_4 + 0.000461760461760478*G0_4_0_5 - 0.000192400192400199*G0_4_1_0 + 0.000192400192400199*G0_4_1_2 + 0.000307840307840318*G0_4_1_3 - 0.000307840307840319*G0_4_1_5 + 0.000192400192400199*G0_4_2_1 - 0.000192400192400199*G0_4_2_2 - 0.000461760461760478*G0_4_2_3 - 0.000615680615680637*G0_4_2_4 - 0.000615680615680637*G0_4_2_5 + 0.000615680615680636*G0_4_3_0 + 0.000307840307840318*G0_4_3_1 - 0.000461760461760478*G0_4_3_2 - 0.00430976430976445*G0_4_3_3 - 0.00123136123136127*G0_4_3_4 + 0.000615680615680637*G0_4_4_0 - 0.000615680615680637*G0_4_4_2 - 0.00123136123136127*G0_4_4_3 + 0.00123136123136128*G0_4_4_5 + 0.000461760461760478*G0_4_5_0 - 0.000307840307840319*G0_4_5_1 - 0.000615680615680637*G0_4_5_2 + 0.00123136123136128*G0_4_5_4 + 0.00430976430976446*G0_4_5_5 + 0.000962000962000996*G0_5_0_0 - 0.000615680615680638*G0_5_0_1 - 3.848003848004e-05*G0_5_0_2 + 0.000307840307840318*G0_5_0_3 + 0.000461760461760478*G0_5_0_4 + 0.00061568061568064*G0_5_0_5 - 0.000615680615680638*G0_5_1_0 + 0.000769600769600797*G0_5_1_1 + 0.000153920153920159*G0_5_1_2 - 0.000307840307840319*G0_5_1_4 - 3.848003848004e-05*G0_5_2_0 + 0.000153920153920159*G0_5_2_1 + 0.000115440115440119*G0_5_2_2 - 0.000307840307840318*G0_5_2_3 - 0.000615680615680637*G0_5_2_4 - 0.00184704184704191*G0_5_2_5 + 0.000307840307840318*G0_5_3_0 - 0.000307840307840318*G0_5_3_2 - 0.00307840307840318*G0_5_3_3 + 0.00307840307840319*G0_5_3_5 + 0.000461760461760478*G0_5_4_0 - 0.000307840307840319*G0_5_4_1 - 0.000615680615680637*G0_5_4_2 + 0.00123136123136128*G0_5_4_4 + 0.00430976430976446*G0_5_4_5 + 0.00061568061568064*G0_5_5_0 - 0.00184704184704191*G0_5_5_2 + 0.00307840307840319*G0_5_5_3 + 0.00430976430976446*G0_5_5_4 + 0.0277056277056287*G0_5_5_5; + A[23] = A[21] + 5.77200577200598e-05*G0_0_0_0 + 9.62000962000988e-06*G0_0_0_1 - 1.92400192400199e-05*G0_0_0_2 - 0.000153920153920159*G0_0_0_3 - 3.84800384800397e-05*G0_0_0_4 + 3.84800384800399e-05*G0_0_0_5 + 9.62000962000988e-06*G0_0_1_0 + 3.84800384800399e-05*G0_0_1_1 - 2.88600288600299e-05*G0_0_1_2 - 7.69600769600793e-05*G0_0_1_3 - 7.69600769600795e-05*G0_0_1_4 - 7.69600769600796e-05*G0_0_1_5 - 1.92400192400199e-05*G0_0_2_0 - 2.88600288600299e-05*G0_0_2_1 + 7.69600769600796e-05*G0_0_2_2 + 3.84800384800396e-05*G0_0_2_3 + 3.84800384800398e-05*G0_0_2_4 - 0.000153920153920159*G0_0_3_0 - 7.69600769600793e-05*G0_0_3_1 + 3.84800384800396e-05*G0_0_3_2 + 0.00153920153920159*G0_0_3_3 + 0.000461760461760477*G0_0_3_4 + 0.000307840307840318*G0_0_3_5 - 3.84800384800397e-05*G0_0_4_0 - 7.69600769600795e-05*G0_0_4_1 + 3.84800384800398e-05*G0_0_4_2 + 0.000461760461760477*G0_0_4_3 + 0.000307840307840318*G0_0_4_4 + 0.000153920153920159*G0_0_4_5 + 3.84800384800399e-05*G0_0_5_0 - 7.69600769600796e-05*G0_0_5_1 + 0.000307840307840318*G0_0_5_3 + 0.000153920153920159*G0_0_5_4 + 9.62000962000987e-06*G0_1_0_0 + 3.84800384800398e-05*G0_1_0_1 - 2.88600288600299e-05*G0_1_0_2 - 7.69600769600792e-05*G0_1_0_3 - 7.69600769600795e-05*G0_1_0_4 - 7.69600769600796e-05*G0_1_0_5 + 3.84800384800398e-05*G0_1_1_0 - 0.000288600288600298*G0_1_1_1 + 3.84800384800398e-05*G0_1_1_2 - 0.000769600769600796*G0_1_1_3 - 7.69600769600796e-05*G0_1_1_4 - 2.88600288600299e-05*G0_1_2_0 + 3.84800384800398e-05*G0_1_2_1 + 0.000105820105820109*G0_1_2_2 + 0.000538720538720558*G0_1_2_3 + 0.000115440115440119*G0_1_2_4 + 7.69600769600797e-05*G0_1_2_5 - 7.69600769600792e-05*G0_1_3_0 - 0.000769600769600796*G0_1_3_1 + 0.000538720538720558*G0_1_3_2 + 0.000307840307840318*G0_1_3_4 - 7.69600769600795e-05*G0_1_4_0 - 7.69600769600796e-05*G0_1_4_1 + 0.000115440115440119*G0_1_4_2 + 0.000307840307840318*G0_1_4_3 + 0.000153920153920159*G0_1_4_4 - 7.69600769600796e-05*G0_1_5_0 + 7.69600769600797e-05*G0_1_5_2 - 1.92400192400199e-05*G0_2_0_0 - 2.88600288600299e-05*G0_2_0_1 + 7.69600769600796e-05*G0_2_0_2 + 3.84800384800397e-05*G0_2_0_3 + 3.84800384800398e-05*G0_2_0_4 - 2.88600288600299e-05*G0_2_1_0 + 3.84800384800398e-05*G0_2_1_1 + 0.000105820105820109*G0_2_1_2 + 0.000538720538720558*G0_2_1_3 + 0.000115440115440119*G0_2_1_4 + 7.69600769600797e-05*G0_2_1_5 + 7.69600769600796e-05*G0_2_2_0 + 0.000105820105820109*G0_2_2_1 - 0.000577200577200597*G0_2_2_2 - 0.000923520923520956*G0_2_2_3 - 0.000230880230880239*G0_2_2_4 - 3.84800384800399e-05*G0_2_2_5 + 3.84800384800397e-05*G0_2_3_0 + 0.000538720538720558*G0_2_3_1 - 0.000923520923520956*G0_2_3_2 - 0.000615680615680637*G0_2_3_3 - 0.000307840307840318*G0_2_3_4 + 3.84800384800398e-05*G0_2_4_0 + 0.000115440115440119*G0_2_4_1 - 0.000230880230880239*G0_2_4_2 - 0.000307840307840319*G0_2_4_3 - 0.000307840307840318*G0_2_4_4 - 0.000153920153920159*G0_2_4_5 + 7.69600769600797e-05*G0_2_5_1 - 3.84800384800398e-05*G0_2_5_2 - 0.000153920153920159*G0_2_5_4 - 0.000307840307840319*G0_2_5_5 - 0.000153920153920159*G0_3_0_0 - 7.69600769600793e-05*G0_3_0_1 + 3.84800384800397e-05*G0_3_0_2 + 0.00153920153920159*G0_3_0_3 + 0.000461760461760477*G0_3_0_4 + 0.000307840307840318*G0_3_0_5 - 7.69600769600793e-05*G0_3_1_0 - 0.000769600769600796*G0_3_1_1 + 0.000538720538720558*G0_3_1_2 + 0.000307840307840318*G0_3_1_4 + 3.84800384800397e-05*G0_3_2_0 + 0.000538720538720558*G0_3_2_1 - 0.000923520923520956*G0_3_2_2 - 0.000615680615680637*G0_3_2_3 - 0.000307840307840318*G0_3_2_4 + 0.00153920153920159*G0_3_3_0 - 0.000615680615680637*G0_3_3_2 - 0.0246272246272255*G0_3_3_3 - 0.00369408369408382*G0_3_3_4 - 0.00307840307840318*G0_3_3_5 + 0.000461760461760477*G0_3_4_0 + 0.000307840307840318*G0_3_4_1 - 0.000307840307840318*G0_3_4_2 - 0.00369408369408382*G0_3_4_3 - 0.00123136123136127*G0_3_4_4 - 0.000615680615680635*G0_3_4_5 + 0.000307840307840318*G0_3_5_0 - 0.00307840307840319*G0_3_5_3 - 0.000615680615680635*G0_3_5_4 - 3.84800384800397e-05*G0_4_0_0 - 7.69600769600795e-05*G0_4_0_1 + 3.84800384800398e-05*G0_4_0_2 + 0.000461760461760477*G0_4_0_3 + 0.000307840307840318*G0_4_0_4 + 0.000153920153920159*G0_4_0_5 - 7.69600769600795e-05*G0_4_1_0 - 7.69600769600796e-05*G0_4_1_1 + 0.000115440115440119*G0_4_1_2 + 0.000307840307840318*G0_4_1_3 + 0.000153920153920159*G0_4_1_4 + 3.84800384800398e-05*G0_4_2_0 + 0.000115440115440119*G0_4_2_1 - 0.000230880230880239*G0_4_2_2 - 0.000307840307840318*G0_4_2_3 - 0.000307840307840319*G0_4_2_4 - 0.000153920153920159*G0_4_2_5 + 0.000461760461760477*G0_4_3_0 + 0.000307840307840318*G0_4_3_1 - 0.000307840307840318*G0_4_3_2 - 0.00369408369408382*G0_4_3_3 - 0.00123136123136127*G0_4_3_4 - 0.000615680615680635*G0_4_3_5 + 0.000307840307840318*G0_4_4_0 + 0.000153920153920159*G0_4_4_1 - 0.000307840307840319*G0_4_4_2 - 0.00123136123136127*G0_4_4_3 - 0.000615680615680636*G0_4_4_4 + 0.000153920153920159*G0_4_5_0 - 0.000153920153920159*G0_4_5_2 - 0.000615680615680636*G0_4_5_3 + 0.000615680615680637*G0_4_5_5 + 3.84800384800399e-05*G0_5_0_0 - 7.69600769600796e-05*G0_5_0_1 + 0.000307840307840318*G0_5_0_3 + 0.000153920153920159*G0_5_0_4 - 7.69600769600795e-05*G0_5_1_0 + 7.69600769600797e-05*G0_5_1_2 + 7.69600769600797e-05*G0_5_2_1 - 3.84800384800399e-05*G0_5_2_2 - 0.000153920153920159*G0_5_2_4 - 0.000307840307840318*G0_5_2_5 + 0.000307840307840318*G0_5_3_0 - 0.00307840307840319*G0_5_3_3 - 0.000615680615680636*G0_5_3_4 + 0.000153920153920159*G0_5_4_0 - 0.000153920153920159*G0_5_4_2 - 0.000615680615680635*G0_5_4_3 + 0.000615680615680636*G0_5_4_5 - 0.000307840307840318*G0_5_5_2 + 0.000615680615680636*G0_5_5_4 + 0.00307840307840319*G0_5_5_5; + A[33] = A[23]; + A[19] = A[9]; + A[16] = A[26]; + A[27] = A[21] + 5.77200577200598e-05*G0_0_0_0 - 1.92400192400199e-05*G0_0_0_1 + 9.62000962000996e-06*G0_0_0_2 - 0.000153920153920159*G0_0_0_3 + 3.848003848004e-05*G0_0_0_4 - 3.84800384800397e-05*G0_0_0_5 - 1.92400192400199e-05*G0_0_1_0 + 7.69600769600798e-05*G0_0_1_1 - 2.88600288600299e-05*G0_0_1_2 + 3.84800384800402e-05*G0_0_1_3 + 3.84800384800399e-05*G0_0_1_5 + 9.62000962000995e-06*G0_0_2_0 - 2.88600288600299e-05*G0_0_2_1 + 3.84800384800398e-05*G0_0_2_2 - 7.69600769600798e-05*G0_0_2_3 - 7.69600769600796e-05*G0_0_2_4 - 7.69600769600796e-05*G0_0_2_5 - 0.000153920153920159*G0_0_3_0 + 3.84800384800402e-05*G0_0_3_1 - 7.69600769600797e-05*G0_0_3_2 + 0.00153920153920159*G0_0_3_3 + 0.000307840307840318*G0_0_3_4 + 0.000461760461760477*G0_0_3_5 + 3.848003848004e-05*G0_0_4_0 - 7.69600769600796e-05*G0_0_4_2 + 0.000307840307840318*G0_0_4_3 + 0.000153920153920159*G0_0_4_5 - 3.84800384800397e-05*G0_0_5_0 + 3.84800384800399e-05*G0_0_5_1 - 7.69600769600796e-05*G0_0_5_2 + 0.000461760461760477*G0_0_5_3 + 0.000153920153920159*G0_0_5_4 + 0.000307840307840318*G0_0_5_5 - 1.92400192400199e-05*G0_1_0_0 + 7.69600769600798e-05*G0_1_0_1 - 2.88600288600299e-05*G0_1_0_2 + 3.84800384800402e-05*G0_1_0_3 + 3.84800384800399e-05*G0_1_0_5 + 7.69600769600798e-05*G0_1_1_0 - 0.000577200577200597*G0_1_1_1 + 0.00010582010582011*G0_1_1_2 - 0.000923520923520956*G0_1_1_3 - 3.84800384800398e-05*G0_1_1_4 - 0.000230880230880239*G0_1_1_5 - 2.88600288600299e-05*G0_1_2_0 + 0.00010582010582011*G0_1_2_1 + 3.84800384800397e-05*G0_1_2_2 + 0.000538720538720558*G0_1_2_3 + 7.69600769600797e-05*G0_1_2_4 + 0.00011544011544012*G0_1_2_5 + 3.84800384800402e-05*G0_1_3_0 - 0.000923520923520956*G0_1_3_1 + 0.000538720538720558*G0_1_3_2 - 0.000615680615680639*G0_1_3_3 - 0.00030784030784032*G0_1_3_5 - 3.84800384800398e-05*G0_1_4_1 + 7.69600769600797e-05*G0_1_4_2 - 0.000307840307840319*G0_1_4_4 - 0.000153920153920159*G0_1_4_5 + 3.84800384800399e-05*G0_1_5_0 - 0.000230880230880239*G0_1_5_1 + 0.00011544011544012*G0_1_5_2 - 0.00030784030784032*G0_1_5_3 - 0.000153920153920159*G0_1_5_4 - 0.000307840307840319*G0_1_5_5 + 9.62000962000995e-06*G0_2_0_0 - 2.88600288600299e-05*G0_2_0_1 + 3.84800384800398e-05*G0_2_0_2 - 7.69600769600797e-05*G0_2_0_3 - 7.69600769600796e-05*G0_2_0_4 - 7.69600769600796e-05*G0_2_0_5 - 2.88600288600299e-05*G0_2_1_0 + 0.00010582010582011*G0_2_1_1 + 3.84800384800397e-05*G0_2_1_2 + 0.000538720538720558*G0_2_1_3 + 7.69600769600797e-05*G0_2_1_4 + 0.00011544011544012*G0_2_1_5 + 3.84800384800398e-05*G0_2_2_0 + 3.84800384800397e-05*G0_2_2_1 - 0.000288600288600298*G0_2_2_2 - 0.000769600769600797*G0_2_2_3 - 7.69600769600797e-05*G0_2_2_5 - 7.69600769600797e-05*G0_2_3_0 + 0.000538720538720558*G0_2_3_1 - 0.000769600769600797*G0_2_3_2 + 0.000307840307840319*G0_2_3_5 - 7.69600769600796e-05*G0_2_4_0 + 7.69600769600796e-05*G0_2_4_1 - 7.69600769600796e-05*G0_2_5_0 + 0.00011544011544012*G0_2_5_1 - 7.69600769600796e-05*G0_2_5_2 + 0.000307840307840318*G0_2_5_3 + 0.000153920153920159*G0_2_5_5 - 0.000153920153920159*G0_3_0_0 + 3.84800384800402e-05*G0_3_0_1 - 7.69600769600797e-05*G0_3_0_2 + 0.00153920153920159*G0_3_0_3 + 0.000307840307840318*G0_3_0_4 + 0.000461760461760477*G0_3_0_5 + 3.84800384800402e-05*G0_3_1_0 - 0.000923520923520956*G0_3_1_1 + 0.000538720538720558*G0_3_1_2 - 0.000615680615680639*G0_3_1_3 - 0.00030784030784032*G0_3_1_5 - 7.69600769600797e-05*G0_3_2_0 + 0.000538720538720558*G0_3_2_1 - 0.000769600769600797*G0_3_2_2 + 0.000307840307840319*G0_3_2_5 + 0.00153920153920159*G0_3_3_0 - 0.000615680615680639*G0_3_3_1 - 0.0246272246272255*G0_3_3_3 - 0.00307840307840318*G0_3_3_4 - 0.00369408369408382*G0_3_3_5 + 0.000307840307840318*G0_3_4_0 - 0.00307840307840318*G0_3_4_3 - 0.000615680615680635*G0_3_4_5 + 0.000461760461760477*G0_3_5_0 - 0.00030784030784032*G0_3_5_1 + 0.000307840307840319*G0_3_5_2 - 0.00369408369408382*G0_3_5_3 - 0.000615680615680634*G0_3_5_4 - 0.00123136123136127*G0_3_5_5 + 3.848003848004e-05*G0_4_0_0 - 7.69600769600796e-05*G0_4_0_2 + 0.000307840307840318*G0_4_0_3 + 0.000153920153920159*G0_4_0_5 - 3.84800384800398e-05*G0_4_1_1 + 7.69600769600797e-05*G0_4_1_2 - 0.000307840307840318*G0_4_1_4 - 0.000153920153920159*G0_4_1_5 - 7.69600769600796e-05*G0_4_2_0 + 7.69600769600797e-05*G0_4_2_1 + 0.000307840307840318*G0_4_3_0 - 0.00307840307840318*G0_4_3_3 - 0.000615680615680635*G0_4_3_5 - 0.000307840307840319*G0_4_4_1 + 0.00307840307840319*G0_4_4_4 + 0.000615680615680638*G0_4_4_5 + 0.000153920153920159*G0_4_5_0 - 0.000153920153920159*G0_4_5_1 - 0.000615680615680635*G0_4_5_3 + 0.000615680615680638*G0_4_5_4 - 3.84800384800397e-05*G0_5_0_0 + 3.84800384800399e-05*G0_5_0_1 - 7.69600769600796e-05*G0_5_0_2 + 0.000461760461760477*G0_5_0_3 + 0.000153920153920159*G0_5_0_4 + 0.000307840307840318*G0_5_0_5 + 3.84800384800399e-05*G0_5_1_0 - 0.000230880230880239*G0_5_1_1 + 0.00011544011544012*G0_5_1_2 - 0.00030784030784032*G0_5_1_3 - 0.000153920153920159*G0_5_1_4 - 0.000307840307840319*G0_5_1_5 - 7.69600769600796e-05*G0_5_2_0 + 0.00011544011544012*G0_5_2_1 - 7.69600769600797e-05*G0_5_2_2 + 0.000307840307840319*G0_5_2_3 + 0.000153920153920159*G0_5_2_5 + 0.000461760461760477*G0_5_3_0 - 0.00030784030784032*G0_5_3_1 + 0.000307840307840319*G0_5_3_2 - 0.00369408369408382*G0_5_3_3 - 0.000615680615680635*G0_5_3_4 - 0.00123136123136127*G0_5_3_5 + 0.000153920153920159*G0_5_4_0 - 0.000153920153920159*G0_5_4_1 - 0.000615680615680635*G0_5_4_3 + 0.000615680615680638*G0_5_4_4 + 0.000307840307840318*G0_5_5_0 - 0.000307840307840319*G0_5_5_1 + 0.000153920153920159*G0_5_5_2 - 0.00123136123136127*G0_5_5_3 - 0.000615680615680638*G0_5_5_5; + A[22] = A[27]; + A[15] = A[20]; + A[32] = A[17]; + A[2] = -0.000216450216450224*G0_0_0_0 + 2.16450216450224e-05*G0_0_0_1 + 2.16450216450224e-05*G0_0_0_2 - 7.21500721500749e-06*G0_0_0_3 - 0.000144300144300149*G0_0_0_4 - 7.21500721500747e-05*G0_0_0_5 + 2.16450216450224e-05*G0_0_1_0 - 7.21500721500748e-06*G0_0_1_1 - 7.21500721500746e-06*G0_0_1_2 - 4.81000481000497e-06*G0_0_1_3 + 1.20250120250124e-05*G0_0_1_4 + 1.20250120250125e-05*G0_0_1_5 + 2.16450216450224e-05*G0_0_2_0 - 7.21500721500746e-06*G0_0_2_1 + 2.16450216450224e-05*G0_0_2_2 + 2.64550264550274e-05*G0_0_2_3 + 6.97450697450721e-05*G0_0_2_4 + 2.64550264550274e-05*G0_0_2_5 - 7.21500721500749e-06*G0_0_3_0 - 4.81000481000497e-06*G0_0_3_1 + 2.64550264550274e-05*G0_0_3_2 - 1.92400192400199e-05*G0_0_3_3 - 9.62000962000996e-06*G0_0_3_4 - 3.84800384800398e-05*G0_0_3_5 - 0.000144300144300149*G0_0_4_0 + 1.20250120250124e-05*G0_0_4_1 + 6.97450697450721e-05*G0_0_4_2 - 9.62000962000996e-06*G0_0_4_3 - 0.000115440115440119*G0_0_4_4 - 7.69600769600796e-05*G0_0_4_5 - 7.21500721500747e-05*G0_0_5_0 + 1.20250120250125e-05*G0_0_5_1 + 2.64550264550274e-05*G0_0_5_2 - 3.84800384800398e-05*G0_0_5_3 - 7.69600769600796e-05*G0_0_5_4 - 0.00011544011544012*G0_0_5_5 + 2.16450216450224e-05*G0_1_0_0 - 7.21500721500748e-06*G0_1_0_1 - 7.21500721500746e-06*G0_1_0_2 - 4.81000481000497e-06*G0_1_0_3 + 1.20250120250124e-05*G0_1_0_4 + 1.20250120250125e-05*G0_1_0_5 - 7.21500721500748e-06*G0_1_1_0 + 2.16450216450225e-05*G0_1_1_1 - 7.21500721500747e-06*G0_1_1_2 + 1.20250120250125e-05*G0_1_1_3 - 4.81000481000498e-06*G0_1_1_4 + 1.20250120250125e-05*G0_1_1_5 - 7.21500721500746e-06*G0_1_2_0 - 7.21500721500747e-06*G0_1_2_1 + 2.16450216450224e-05*G0_1_2_2 + 1.20250120250124e-05*G0_1_2_3 + 1.20250120250124e-05*G0_1_2_4 - 4.81000481000498e-06*G0_1_2_5 - 4.81000481000497e-06*G0_1_3_0 + 1.20250120250125e-05*G0_1_3_1 + 1.20250120250124e-05*G0_1_3_2 + 4.81000481000498e-05*G0_1_3_3 + 1.92400192400199e-05*G0_1_3_4 + 1.92400192400199e-05*G0_1_3_5 + 1.20250120250124e-05*G0_1_4_0 - 4.81000481000498e-06*G0_1_4_1 + 1.20250120250124e-05*G0_1_4_2 + 1.92400192400199e-05*G0_1_4_3 + 4.81000481000497e-05*G0_1_4_4 + 1.92400192400199e-05*G0_1_4_5 + 1.20250120250125e-05*G0_1_5_0 + 1.20250120250125e-05*G0_1_5_1 - 4.81000481000498e-06*G0_1_5_2 + 1.92400192400199e-05*G0_1_5_3 + 1.92400192400199e-05*G0_1_5_4 + 4.81000481000498e-05*G0_1_5_5 + 2.16450216450224e-05*G0_2_0_0 - 7.21500721500746e-06*G0_2_0_1 + 2.16450216450224e-05*G0_2_0_2 + 2.64550264550274e-05*G0_2_0_3 + 6.97450697450721e-05*G0_2_0_4 + 2.64550264550274e-05*G0_2_0_5 - 7.21500721500746e-06*G0_2_1_0 - 7.21500721500747e-06*G0_2_1_1 + 2.16450216450224e-05*G0_2_1_2 + 1.20250120250124e-05*G0_2_1_3 + 1.20250120250124e-05*G0_2_1_4 - 4.81000481000498e-06*G0_2_1_5 + 2.16450216450224e-05*G0_2_2_0 + 2.16450216450224e-05*G0_2_2_1 - 0.000216450216450224*G0_2_2_2 - 7.21500721500746e-05*G0_2_2_3 - 0.000144300144300149*G0_2_2_4 - 7.21500721500748e-06*G0_2_2_5 + 2.64550264550274e-05*G0_2_3_0 + 1.20250120250124e-05*G0_2_3_1 - 7.21500721500746e-05*G0_2_3_2 - 0.000115440115440119*G0_2_3_3 - 7.69600769600796e-05*G0_2_3_4 - 3.84800384800398e-05*G0_2_3_5 + 6.97450697450721e-05*G0_2_4_0 + 1.20250120250124e-05*G0_2_4_1 - 0.000144300144300149*G0_2_4_2 - 7.69600769600796e-05*G0_2_4_3 - 0.000115440115440119*G0_2_4_4 - 9.62000962000994e-06*G0_2_4_5 + 2.64550264550274e-05*G0_2_5_0 - 4.81000481000498e-06*G0_2_5_1 - 7.21500721500748e-06*G0_2_5_2 - 3.84800384800398e-05*G0_2_5_3 - 9.62000962000994e-06*G0_2_5_4 - 1.92400192400199e-05*G0_2_5_5 - 7.21500721500749e-06*G0_3_0_0 - 4.81000481000497e-06*G0_3_0_1 + 2.64550264550274e-05*G0_3_0_2 - 1.92400192400199e-05*G0_3_0_3 - 9.62000962000997e-06*G0_3_0_4 - 3.84800384800398e-05*G0_3_0_5 - 4.81000481000497e-06*G0_3_1_0 + 1.20250120250125e-05*G0_3_1_1 + 1.20250120250124e-05*G0_3_1_2 + 4.81000481000498e-05*G0_3_1_3 + 1.92400192400199e-05*G0_3_1_4 + 1.92400192400199e-05*G0_3_1_5 + 2.64550264550274e-05*G0_3_2_0 + 1.20250120250124e-05*G0_3_2_1 - 7.21500721500746e-05*G0_3_2_2 - 0.000115440115440119*G0_3_2_3 - 7.69600769600796e-05*G0_3_2_4 - 3.84800384800398e-05*G0_3_2_5 - 1.92400192400199e-05*G0_3_3_0 + 4.81000481000498e-05*G0_3_3_1 - 0.000115440115440119*G0_3_3_2 + 7.69600769600797e-05*G0_3_3_3 + 0.000115440115440119*G0_3_3_5 - 9.62000962000997e-06*G0_3_4_0 + 1.92400192400199e-05*G0_3_4_1 - 7.69600769600796e-05*G0_3_4_2 - 7.69600769600797e-05*G0_3_4_4 + 3.84800384800398e-05*G0_3_4_5 - 3.84800384800398e-05*G0_3_5_0 + 1.92400192400199e-05*G0_3_5_1 - 3.84800384800398e-05*G0_3_5_2 + 0.000115440115440119*G0_3_5_3 + 3.84800384800398e-05*G0_3_5_4 + 0.000115440115440119*G0_3_5_5 - 0.000144300144300149*G0_4_0_0 + 1.20250120250124e-05*G0_4_0_1 + 6.97450697450721e-05*G0_4_0_2 - 9.62000962000996e-06*G0_4_0_3 - 0.000115440115440119*G0_4_0_4 - 7.69600769600796e-05*G0_4_0_5 + 1.20250120250124e-05*G0_4_1_0 - 4.81000481000498e-06*G0_4_1_1 + 1.20250120250124e-05*G0_4_1_2 + 1.92400192400199e-05*G0_4_1_3 + 4.81000481000497e-05*G0_4_1_4 + 1.92400192400199e-05*G0_4_1_5 + 6.97450697450721e-05*G0_4_2_0 + 1.20250120250124e-05*G0_4_2_1 - 0.000144300144300149*G0_4_2_2 - 7.69600769600796e-05*G0_4_2_3 - 0.000115440115440119*G0_4_2_4 - 9.62000962000994e-06*G0_4_2_5 - 9.62000962000996e-06*G0_4_3_0 + 1.92400192400199e-05*G0_4_3_1 - 7.69600769600796e-05*G0_4_3_2 - 7.69600769600796e-05*G0_4_3_4 + 3.84800384800397e-05*G0_4_3_5 - 0.000115440115440119*G0_4_4_0 + 4.81000481000497e-05*G0_4_4_1 - 0.000115440115440119*G0_4_4_2 - 7.69600769600796e-05*G0_4_4_3 - 0.000615680615680637*G0_4_4_4 - 7.69600769600796e-05*G0_4_4_5 - 7.69600769600796e-05*G0_4_5_0 + 1.92400192400199e-05*G0_4_5_1 - 9.62000962000994e-06*G0_4_5_2 + 3.84800384800398e-05*G0_4_5_3 - 7.69600769600796e-05*G0_4_5_4 - 7.21500721500747e-05*G0_5_0_0 + 1.20250120250125e-05*G0_5_0_1 + 2.64550264550274e-05*G0_5_0_2 - 3.84800384800398e-05*G0_5_0_3 - 7.69600769600796e-05*G0_5_0_4 - 0.00011544011544012*G0_5_0_5 + 1.20250120250125e-05*G0_5_1_0 + 1.20250120250125e-05*G0_5_1_1 - 4.81000481000498e-06*G0_5_1_2 + 1.92400192400199e-05*G0_5_1_3 + 1.92400192400199e-05*G0_5_1_4 + 4.81000481000498e-05*G0_5_1_5 + 2.64550264550274e-05*G0_5_2_0 - 4.81000481000498e-06*G0_5_2_1 - 7.21500721500748e-06*G0_5_2_2 - 3.84800384800398e-05*G0_5_2_3 - 9.62000962000994e-06*G0_5_2_4 - 1.92400192400199e-05*G0_5_2_5 - 3.84800384800398e-05*G0_5_3_0 + 1.92400192400199e-05*G0_5_3_1 - 3.84800384800398e-05*G0_5_3_2 + 0.000115440115440119*G0_5_3_3 + 3.84800384800398e-05*G0_5_3_4 + 0.000115440115440119*G0_5_3_5 - 7.69600769600796e-05*G0_5_4_0 + 1.92400192400199e-05*G0_5_4_1 - 9.62000962000994e-06*G0_5_4_2 + 3.84800384800398e-05*G0_5_4_3 - 7.69600769600796e-05*G0_5_4_4 - 0.000115440115440119*G0_5_5_0 + 4.81000481000498e-05*G0_5_5_1 - 1.92400192400199e-05*G0_5_5_2 + 0.000115440115440119*G0_5_5_3 + 7.69600769600793e-05*G0_5_5_5; + A[12] = A[2]; + } + + /// 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 mass_matrix_f3_p2_q2_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f3_p2_q2_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p2_q2_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1)))), 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 3; + } + + /// 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 mass_matrix_f3_p2_q2_tensor_finite_element_0(); + break; + } + case 1: + { + return new mass_matrix_f3_p2_q2_tensor_finite_element_0(); + break; + } + case 2: + { + return new mass_matrix_f3_p2_q2_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p2_q2_tensor_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p2_q2_tensor_finite_element_0(); + 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 mass_matrix_f3_p2_q2_tensor_dofmap_0(); + break; + } + case 1: + { + return new mass_matrix_f3_p2_q2_tensor_dofmap_0(); + break; + } + case 2: + { + return new mass_matrix_f3_p2_q2_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p2_q2_tensor_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p2_q2_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f3_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/mass_matrix_2d/mass_matrix_f3_p2_q3_excafe.h b/mass_matrix_2d/mass_matrix_f3_p2_q3_excafe.h new file mode 100644 index 0000000..b24c4a2 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f3_p2_q3_excafe.h @@ -0,0 +1,644 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 110 minutes and 12.03 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[1][2]*w[2][5] + w[1][5]*w[2][2]; + const double var_1 = var_0*w[0][5] + w[0][2]*w[1][5]*w[2][5]; + const double var_2 = 0.0937500000000000000000000*w[0][2]*w[1][2]*w[2][2]; + const double var_3 = var_1 + var_2; + const double var_4 = -1.0000000000000000000000000*x[0][1]; + const double var_5 = x[2][1] + var_4; + const double var_6 = -1.0000000000000000000000000*x[0][0]; + const double var_7 = var_6 + x[1][0]; + const double var_8 = x[1][1] + var_4; + const double var_9 = x[2][0] + var_6; + const double var_10 = -1.0000000000000000000000000*var_8*var_9 + var_5*var_7; + const double var_11 = std::abs(var_10); + const double var_12 = w[1][0]*w[2][1] + w[1][1]*w[2][0]; + const double var_13 = w[1][0]*w[2][5] + w[1][5]*w[2][0]; + const double var_14 = w[1][5]*w[2][1] + w[1][1]*w[2][5]; + const double var_15 = var_14*w[0][0] + var_12*w[0][5] + var_13*w[0][1]; + const double var_16 = w[1][2]*w[2][0] + w[1][0]*w[2][2]; + const double var_17 = w[1][2]*w[2][4] + w[1][4]*w[2][2]; + const double var_18 = w[1][0]*w[2][4] + w[1][4]*w[2][0]; + const double var_19 = var_17*w[0][0] + var_18*w[0][2] + var_16*w[0][4]; + const double var_20 = w[1][1]*w[2][4] + w[1][4]*w[2][1]; + const double var_21 = var_20*w[0][4] + w[0][1]*w[1][4]*w[2][4]; + const double var_22 = w[0][4]*w[1][1]*w[2][1] + var_20*w[0][1]; + const double var_23 = var_0*w[0][2] + w[0][5]*w[1][2]*w[2][2]; + const double var_24 = w[0][4]*w[1][4]*w[2][4]; + const double var_25 = w[0][1]*w[1][1]*w[2][1]; + const double var_26 = w[1][3]*w[2][4] + w[1][4]*w[2][3]; + const double var_27 = w[1][2]*w[2][3] + w[1][3]*w[2][2]; + const double var_28 = var_17*w[0][3] + var_27*w[0][4] + var_26*w[0][2]; + const double var_29 = w[1][1]*w[2][2] + w[1][2]*w[2][1]; + const double var_30 = var_29*w[0][4] + var_20*w[0][2] + var_17*w[0][1]; + const double var_31 = w[1][3]*w[2][0] + w[1][0]*w[2][3]; + const double var_32 = var_31*w[0][2] + var_16*w[0][3] + var_27*w[0][0]; + const double var_33 = var_32 + var_30; + const double var_34 = var_28 + -0.2500000000000000000000000*var_33; + const double var_35 = w[1][5]*w[2][4] + w[1][4]*w[2][5]; + const double var_36 = var_18*w[0][5] + var_13*w[0][4] + var_35*w[0][0]; + const double var_37 = w[1][1]*w[2][3] + w[1][3]*w[2][1]; + const double var_38 = var_37*w[0][2] + var_29*w[0][3] + var_27*w[0][1]; + const double var_39 = var_31*w[0][0] + w[0][3]*w[1][0]*w[2][0]; + const double var_40 = w[0][0]*w[1][3]*w[2][3] + var_31*w[0][3]; + const double var_41 = w[0][3]*w[1][3]*w[2][3]; + const double var_42 = w[0][0]*w[1][0]*w[2][0]; + const double var_43 = var_12*w[0][2] + var_16*w[0][1] + var_29*w[0][0]; + const double var_44 = w[1][5]*w[2][3] + w[1][3]*w[2][5]; + const double var_45 = var_35*w[0][3] + var_44*w[0][4] + var_26*w[0][5]; + const double var_46 = 0.2611268939393939225723784*var_43 + -1.0000000000000000000000000*var_45; + const double var_47 = 0.0000069771498342926911875*var_46; + const double var_48 = 0.0000116550116550116550015*var_36 + 0.0000024050024050024051415*var_39 + -0.0000320314606028891752580*var_41 + 0.0001033688533688533687637*var_42 + 0.0000022464308178593891247*var_40 + var_47 + -0.0000054641126069697503465*var_38; + const double var_49 = var_16*w[0][5] + var_0*w[0][0] + var_13*w[0][2]; + const double var_50 = var_29*w[0][5] + var_14*w[0][2] + var_0*w[0][1]; + const double var_51 = var_49 + var_50; + const double var_52 = var_12*w[0][0] + w[0][1]*w[1][0]*w[2][0]; + const double var_53 = w[0][0]*w[1][1]*w[2][1] + var_12*w[0][1]; + const double var_54 = var_53 + var_52; + const double var_55 = var_44*w[0][3] + w[0][5]*w[1][3]*w[2][3]; + const double var_56 = w[0][5]*w[1][4]*w[2][4] + var_35*w[0][4]; + const double var_57 = var_55 + var_56; + const double var_58 = w[0][4]*w[1][2]*w[2][2] + var_17*w[0][2]; + const double var_59 = w[0][3]*w[1][2]*w[2][2] + var_27*w[0][2]; + const double var_60 = var_58 + var_59; + const double var_61 = w[0][3]*w[1][4]*w[2][4] + var_26*w[0][4]; + const double var_62 = w[0][4]*w[1][3]*w[2][3] + var_26*w[0][3]; + const double var_63 = var_61 + var_62; + const double var_64 = var_44*w[0][5] + w[0][3]*w[1][5]*w[2][5]; + const double var_65 = w[0][4]*w[1][5]*w[2][5] + var_35*w[0][5]; + const double var_66 = var_64 + var_65; + const double var_67 = var_29*w[0][2] + w[0][1]*w[1][2]*w[2][2]; + const double var_68 = var_16*w[0][2] + w[0][0]*w[1][2]*w[2][2]; + const double var_69 = var_68 + var_67; + const double var_70 = var_29*w[0][1] + w[0][2]*w[1][1]*w[2][1]; + const double var_71 = w[0][2]*w[1][0]*w[2][0] + var_16*w[0][0]; + const double var_72 = var_70 + var_71; + const double var_73 = var_12*w[0][3] + var_37*w[0][0] + var_31*w[0][1]; + const double var_74 = var_12*w[0][4] + var_20*w[0][0] + var_18*w[0][1]; + const double var_75 = var_73 + var_74; + const double var_76 = var_13*w[0][3] + var_31*w[0][5] + var_44*w[0][0]; + const double var_77 = var_20*w[0][5] + var_14*w[0][4] + var_35*w[0][1]; + const double var_78 = var_76 + var_77; + const double var_79 = w[0][2]*w[1][4]*w[2][4] + var_17*w[0][4]; + const double var_80 = var_27*w[0][3] + w[0][2]*w[1][3]*w[2][3]; + const double var_81 = var_80 + var_79; + const double var_82 = w[0][3]*w[1][1]*w[2][1] + var_37*w[0][1]; + const double var_83 = w[0][4]*w[1][0]*w[2][0] + var_18*w[0][0]; + const double var_84 = var_83 + var_82; + const double var_85 = var_0*w[0][4] + var_35*w[0][2] + var_17*w[0][5]; + const double var_86 = var_0*w[0][3] + var_27*w[0][5] + var_44*w[0][2]; + const double var_87 = var_86 + var_85; + const double var_88 = var_13*w[0][0] + w[0][5]*w[1][0]*w[2][0]; + const double var_89 = var_14*w[0][1] + w[0][5]*w[1][1]*w[2][1]; + const double var_90 = var_88 + var_89; + const double var_91 = var_20*w[0][3] + var_37*w[0][4] + var_26*w[0][1]; + const double var_92 = var_31*w[0][4] + var_26*w[0][0] + var_18*w[0][3]; + const double var_93 = var_92 + var_91; + const double var_94 = -1.0000000000000000000000000*var_1; + const double var_95 = w[0][0]*w[1][5]*w[2][5] + var_13*w[0][5]; + const double var_96 = w[0][1]*w[1][5]*w[2][5] + var_14*w[0][5]; + const double var_97 = var_95 + var_96; + const double var_98 = var_44*w[0][1] + var_37*w[0][5] + var_14*w[0][3]; + const double var_99 = w[0][1]*w[1][3]*w[2][3] + var_37*w[0][3]; + const double var_100 = var_18*w[0][4] + w[0][0]*w[1][4]*w[2][4]; + const double var_101 = var_99 + var_100; + const double var_102 = var_101 + var_98; + const double var_103 = 0.0000103913943199657475601*w[0][2]*w[1][2]*w[2][2] + -0.0000007845989988847131445*var_69 + 0.0001033688533688533687637*var_25 + 0.0000024050024050024051415*var_22 + 0.0000002907145764288621681*var_93 + -0.0000122496551067979636882*var_15 + 0.0000830915116629402420410*w[0][5]*w[1][5]*w[2][5] + 0.0000031978603407174839550*var_87 + -0.0000032771461342889913282*var_51 + 0.0000437525437525437479883*var_90 + var_48 + 0.0000233100233100233100031*var_97 + 0.0000093292950435807585037*var_34 + 0.0000062701848416134137222*var_60 + 0.0000277037777037777048831*var_84 + -0.0000320314606028891752580*var_24 + 0.0000124478695907267338151*var_81 + -0.0000108885823171537453124*var_57 + 0.0000023785738071452355936*var_94 + 0.0000007333935905364477543*var_23 + 0.0000116550116550116550015*var_102 + -0.0000086950086950086961305*var_54 + 0.0000017442874585731727969*var_78 + -0.0000054641126069697503465*var_19 + -0.0000061975061975061977832*var_72 + -0.0000050742907885765032208*var_63 + 0.0000012685726971441258052*var_66 + 0.0000022464308178593891247*var_21 + -0.0000025503596932168361726*var_75; + A[1] = var_103*var_11; + A[10] = A[1]; + const double var_104 = 0.0000799200799200799200106*var_45; + const double var_105 = 0.0003996003996003996000530*var_24; + const double var_106 = 0.0000031664763807620949846*w[0][1]*w[1][1]*w[2][1] + var_105 + 0.0000084439370153655877549*var_22 + var_104 + 0.0000611888111888111887581*var_19; + const double var_107 = 0.0000114171542742971311881*var_36; + const double var_108 = 0.0000999000999000999000133*var_41; + const double var_109 = 0.0000069573283858998143442*var_39 + 0.0000611888111888111887581*var_42 + var_108 + var_107 + 0.0000262237762237762237535*var_38; + const double var_110 = 0.0002882831454260025840983*w[0][5]*w[1][5]*w[2][5]; + const double var_111 = 0.0001370058512915655810332*var_65; + const double var_112 = 0.0000262237762237762237535*var_32 + 0.0000999000999000999000133*var_61 + 0.0000572344322344322343826*var_67 + 0.0000392464678178963902590*var_83 + 0.0000000297321725893154469*var_53 + 0.0001027543884686741789986*var_64 + 0.0000666000666000666000088*var_62 + 0.0000320512820512820512543*var_30 + 0.0001598401598401598400212*var_56 + 0.0001071844821844821843892*var_68 + var_110 + 0.0000058275058275058275008*var_50 + var_109 + 0.0000799200799200799200106*var_55 + var_106 + 0.0000323486037771752047505*var_88 + 0.0000599400599400599400080*var_100 + 0.0000069573283858998143442*var_82 + 0.0000127253698682270113151*var_89 + 0.0000137957280814423676287*var_95 + var_111; + const double var_113 = w[0][2]*w[1][2]*w[2][2]; + const double var_114 = 0.0000047868797868797868756*var_43; + const double var_115 = 0.0010052447552447551625682*var_113 + var_114 + 0.0000070167927310784457211*var_15 + 0.0000145687645687645687519*var_23 + 0.0001165501165501165500155*var_28 + 0.0000399600399600399600053*var_1; + const double var_116 = 0.0000114171542742971311881*var_98; + const double var_117 = 0.0000449550449550449550060*var_21 + var_116; + const double var_118 = var_99 + var_92; + const double var_119 = 0.0000166500166500166500022*var_40; + const double var_120 = 0.0003496503496503496500464*var_79; + const double var_121 = 0.0000285428856857428271232*var_77 + 0.0000083250083250083250011*var_70 + 0.0000166500166500166500022*var_91 + 0.0000262237762237762237535*var_71 + 0.0000012487512487512487502*var_49 + 0.0000256885971171685447497*var_96 + 0.0000001189286903572617876*var_73 + 0.0000349650349650349650046*var_85 + 0.0000044598258883973168439*var_74 + 0.0001165501165501165500155*var_80 + 0.0004578754578754578750607*var_58 + 0.0000233100233100233100031*var_86 + 0.0002289377289377289375304*var_59 + var_120 + var_117 + var_119 + -1.0000000000000000000000000*var_112 + var_115 + 0.0000066451405737120021567*var_52 + 0.0000049950049950049950007*var_118 + 0.0000114171542742971311881*var_76; + A[26] = var_11*var_121; + A[62] = A[26]; + const double var_122 = 0.0000086966604823747685655*var_43 + 0.0002568859711716854339440*var_45; + const double var_123 = -0.0002372627372627372625315*w[0][1]*w[1][1]*w[2][1] + -0.0001462822891394319809594*var_21 + var_122 + 0.0000246777032491318181189*var_22 + -0.0002295323723895152309704*var_98 + 0.0004852290566576280780343*var_24 + -0.0000660054231482802930163*var_19; + const double var_124 = -1.0000000000000000000000000*var_36; + const double var_125 = 0.0000081168831168831168761*var_43 + 0.0002397602397602397600318*var_45; + const double var_126 = -1.0000000000000000000000000*var_40; + const double var_127 = 0.0039960039960039960005300*var_41; + const double var_128 = var_125 + 0.0000599400599400599400080*var_39 + -0.0000262237762237762237535*w[0][0]*w[1][0]*w[2][0] + 0.0004395604395604395600583*var_126 + var_127 + 0.0000899100899100899100119*var_124 + -0.0000849150849150849150113*var_38; + const double var_129 = w[0][5]*w[1][5]*w[2][5]; + const double var_130 = var_73 + var_50; + const double var_131 = -0.2500000000000000000000000*var_130 + var_98; + const double var_132 = var_65 + var_62; + const double var_133 = var_89 + var_82; + const double var_134 = var_74 + var_30; + const double var_135 = var_68 + var_71; + const double var_136 = var_55 + var_64; + const double var_137 = var_56 + var_61; + const double var_138 = var_67 + var_52; + const double var_139 = var_53 + var_70; + const double var_140 = var_49 + var_32; + const double var_141 = var_99 + var_96; + const double var_142 = var_92 + var_85; + const double var_143 = var_77 + var_91; + const double var_144 = var_76 + var_86; + const double var_145 = var_58 + var_83; + const double var_146 = var_59 + var_88; + const double var_147 = -1.0000000000000000000000000*var_21; + const double var_148 = var_100 + var_79; + const double var_149 = var_95 + var_80; + const double var_150 = var_149 + var_28; + const double var_151 = 0.0000103913943199657475601*w[0][1]*w[1][1]*w[2][1] + 0.0000007333935905364477543*var_22 + 0.0000093292950435807585037*var_131 + -0.0000054641126069697503465*var_15 + 0.0000012685726971441258052*var_137 + 0.0000002907145764288621681*var_144 + -0.0000320314606028891752580*var_129 + 0.0000023785738071452355936*var_147 + 0.0000233100233100233100031*var_148 + var_48 + 0.0001033688533688533687637*var_113 + -0.0000061975061975061977832*var_138 + -0.0000007845989988847131445*var_139 + -0.0000050742907885765032208*var_136 + 0.0000116550116550116550015*var_150 + 0.0000031978603407174839550*var_143 + 0.0000024050024050024051415*var_23 + -0.0000025503596932168361726*var_140 + -0.0000086950086950086961305*var_135 + 0.0000022464308178593891247*var_1 + -0.0000122496551067979636882*var_19 + 0.0000017442874585731727969*var_142 + 0.0000830915116629402420410*w[0][4]*w[1][4]*w[2][4] + 0.0000277037777037777048831*var_146 + -0.0000108885823171537453124*var_132 + -0.0000032771461342889913282*var_134 + 0.0000124478695907267338151*var_141 + 0.0000062701848416134137222*var_133 + 0.0000437525437525437479883*var_145; + A[2] = var_11*var_151; + A[20] = A[2]; + const double var_152 = var_77 + var_85; + const double var_153 = 0.0000001486608629465772246*var_43 + 0.0000428143285286142389907*var_45; + const double var_154 = 0.0000999000999000999000133*var_24; + const double var_155 = 0.0001392357642357642491960*w[0][1]*w[1][1]*w[2][1] + -0.0000068978640407211838144*var_21 + 0.0000092764378478664185609*var_22 + var_154 + 0.0000585129156557728005153*var_98 + var_153 + 0.0000174825174825174825023*var_19; + const double var_156 = -1.0000000000000000000000000*var_58; + const double var_157 = -1.0000000000000000000000000*var_83; + const double var_158 = -1.0000000000000000000000000*var_28; + const double var_159 = 0.0000582750582750582750077*var_158; + const double var_160 = 0.0002112173540744969159680*var_129 + var_159 + -0.0000117144760001902863784*var_15 + -0.0000029137529137529137504*var_23 + -0.0004651598401598401729892*w[0][2]*w[1][2]*w[2][2] + -0.0000335378906807478255120*var_1; + const double var_161 = -1.0000000000000000000000000*var_100; + const double var_162 = -1.0000000000000000000000000*var_95; + const double var_163 = -1.0000000000000000000000000*var_41; + const double var_164 = -0.0000192664478378764102563*var_36 + 0.0000049355406498263644708*var_39 + -0.0000065113457970600824057*w[0][0]*w[1][0]*w[2][0] + 0.0001998001998001998000265*var_163 + -0.0000135578707007278438152*var_40; + const double var_165 = 0.0001855287569573283779946*var_56; + const double var_166 = 0.0002788877788877788875370*var_89 + var_165 + 0.0000392464678178963902590*var_77 + 0.0006279434850863422441433*var_64 + 0.0000484634413205841757489*var_49; + const double var_167 = -1.0000000000000000000000000*var_74; + const double var_168 = -1.0000000000000000000000000*var_86; + const double var_169 = -1.0000000000000000000000000*var_80; + const double var_170 = var_169 + 0.2000000000000000111022302*var_168; + const double var_171 = -1.0000000000000000000000000*var_85; + const double var_172 = -1.0000000000000000000000000*var_79; + const double var_173 = 0.2000000000000000111022302*var_171 + var_172; + const double var_174 = 0.0000333000333000333000044*var_61 + -0.0001852314352314352312746*var_59 + -0.0000143160411017553879413*var_53 + var_155 + 0.0001612673041244469659614*var_99 + 0.0000203962703962703962527*var_32 + 0.0000597022025593454145004*var_96 + -0.0000038057180914323772039*var_71 + var_164 + 0.0000185528756957328371218*var_161 + 0.0001748251748251748250232*var_170 + 0.0000087412587412587412512*var_30 + 0.0000514069264069264068818*var_67 + -0.0000132010846296560572480*var_50 + -0.0000160553731982303396215*var_73 + 0.0000582750582750582750077*var_173 + 0.0000463821892393320944986*var_162 + 0.0000049355406498263644708*var_88 + 0.0000264319014319014318785*var_68 + -0.0000097521526092954661879*var_92 + 0.0000135578707007278438152*var_91 + 0.0000023191094619666046402*var_157 + 0.0000041179059036201898149*var_52 + 0.0001073926073926073925142*var_82 + var_160 + 0.0000000594643451786308938*var_167 + 0.2000000000000000111022302*var_166 + -0.0000308619951477094304928*var_70 + -0.0000292564578278864002576*var_76 + 0.0001144688644688644687652*var_156 + 0.0000970458113315256210279*var_55 + 0.0000513771942343370894993*var_65; + const double var_175 = -1.0000000000000000000000000*var_134; + const double var_176 = -1.0000000000000000000000000*var_59; + const double var_177 = -1.0000000000000000000000000*var_82; + const double var_178 = -1.0000000000000000000000000*var_89; + const double var_179 = -1.0000000000000000000000000*var_88; + const double var_180 = -1.0000000000000000000000000*var_92; + const double var_181 = -1.0000000000000000000000000*var_24; + const double var_182 = 0.0000051287997716569139046*var_43 + 0.0000685029256457827905166*var_45; + const double var_183 = -1.0000000000000000000000000*var_182; + const double var_184 = var_183 + 0.0001427144284287141390039*var_181 + 0.0000112387612387612387515*var_25 + 0.0000406736121021835297516*var_21 + -0.0000108819751676894538783*var_22 + 0.0000306836021121735397503*var_98 + 0.0000242614528328814052570*var_19; + const double var_185 = -0.0000112387612387612387515*var_113 + -0.0006564863707720849797869*var_129 + 0.0000035678607107178533904*var_158 + 0.0000269373483659197934998*var_15 + -0.0000130226915941201648114*var_23 + 0.0000706436420722134929794*var_1; + const double var_186 = 0.2727272727272727625980053*var_42 + 0.0285714285714285705364279*var_39 + 0.0018552875695732838883661*var_38; + const double var_187 = -0.0004807692307692307959188*var_186 + 0.0000749250749250749250099*var_124 + 0.0000107035821321535597477*var_40 + -0.0001084629656058227505219*var_41; + const double var_188 = -1.0000000000000000000000000*var_30; + const double var_189 = -1.0000000000000000000000000*var_73; + const double var_190 = -1.0000000000000000000000000*var_55; + const double var_191 = -1.0000000000000000000000000*var_56; + const double var_192 = -1.0000000000000000000000000*var_61; + const double var_193 = var_76 + var_80; + const double var_194 = -0.2500000000000000000000000*var_68 + var_32; + const double var_195 = 41.0000000000000000000000000*var_49 + 29.0000000000000000000000000*var_74; + const double var_196 = 0.0000185528756957328371218*var_79 + var_187 + -0.0000074033109747395462827*var_53 + 0.0000306836021121735397503*var_99 + 0.0000428143285286142389907*var_190 + 0.0000076709005280433849376*var_194 + 0.0000117739403453689160612*var_178 + 0.0001127443984586841689999*var_96 + 0.0000181068931068931068774*var_71 + 0.0000749250749250749250099*var_161 + -0.0000685029256457827905166*var_62 + 0.0000035678607107178533904*var_180 + var_185 + 0.0000055747823604966458431*var_67 + -0.0000144498358784073059982*var_50 + var_184 + 0.0000008919651776794633476*var_189 + -0.0001084629656058227505219*var_64 + 0.0000742115027829313484873*var_192 + 0.0000019623233908948193435*var_177 + 0.0000107035821321535597477*var_86 + 0.0001498501498501498500199*var_162 + 0.0000137362637362637362518*var_176 + 0.0001569858712715855610358*var_191 + 0.0000235478806907378321225*var_91 + 0.0000811688311688311687608*var_157 + 0.0000999000999000999000133*var_179 + 0.0000237262737262737262531*var_52 + 0.0000004905808477237048359*var_70 + 0.0000005351791066076780509*var_195 + 0.0000506636220921935197530*var_77 + 0.0000224775224775224775030*var_156 + -0.0002426145283288140390172*var_65 + 0.0000058869701726844580306*var_188 + 0.0000378193235336092439900*var_85 + -0.0000164121592693021244947*var_193; + const double var_197 = 0.0000582750582750582750077*var_124; + const double var_198 = -0.0000029137529137529137504*var_39 + -0.0004651598401598401729892*w[0][0]*w[1][0]*w[2][0] + var_197 + 0.0002112173540744969159680*var_41 + -0.0000335378906807478255120*var_40 + -0.0000117144760001902863784*var_38; + const double var_199 = -1.0000000000000000000000000*var_19; + const double var_200 = -0.0867346938775510195585028*var_54 + 1.9285714285714283811046243*var_25 + -1.0000000000000000000000000*var_69 + var_199 + 0.0204081632653061208204637*var_22 + -0.4693877551020407823401115*var_72; + const double var_201 = var_161 + 0.2000000000000000111022302*var_180; + const double var_202 = -1.0000000000000000000000000*var_15; + const double var_203 = -1.0000000000000000000000000*var_99; + const double var_204 = -1.0000000000000000000000000*var_76; + const double var_205 = var_204 + var_169; + const double var_206 = var_96 + var_85; + const double var_207 = var_65 + var_91; + const double var_208 = -1.0000000000000000000000000*var_71; + const double var_209 = 0.0001855287569573283779946*var_64; + const double var_210 = 0.0000484634413205841757489*var_73 + 0.0006279434850863422441433*var_62 + 0.0002788877788877788875370*var_59 + 0.0000392464678178963902590*var_86 + var_209; + const double var_211 = -1.0000000000000000000000000*var_96; + const double var_212 = -1.0000000000000000000000000*var_98; + const double var_213 = 0.0002497502497502497500331*var_212 + -0.0001311188811188811187674*var_25 + -0.0002997002997002997000398*var_21 + 0.0000499500499500499500066*var_22 + 0.0015984015984015984002120*var_24 + -0.0000724275724275724275096*var_19; + const double var_214 = -1.0000000000000000000000000*var_129; + const double var_215 = -1.0000000000000000000000000*var_23; + const double var_216 = 0.0002622377622377622375348*var_113 + 0.0000174825174825174825023*var_215 + 0.0019980019980019980002650*var_214 + 0.0000774225774225774225103*var_15 + 0.0003496503496503496500464*var_28 + 0.0003296703296703296700437*var_1; + const double var_217 = -1.0000000000000000000000000*var_67; + const double var_218 = -1.0000000000000000000000000*var_68; + const double var_219 = -1.0000000000000000000000000*var_50; + const double var_220 = -1.0000000000000000000000000*var_64; + const double var_221 = 0.0000499500499500499500066*var_83 + 0.0003996003996003996000530*var_55; + const double var_222 = var_86 + var_56; + const double var_223 = -1.0000000000000000000000000*var_91; + const double var_224 = var_161 + var_223; + const double var_225 = -1.0000000000000000000000000*var_77; + const double var_226 = -0.2500000000000000000000000*var_52 + var_74; + const double var_227 = var_226 + var_225 + -0.5000000000000000000000000*var_49; + const double var_228 = 41.0000000000000000000000000*var_32 + 29.0000000000000000000000000*var_30; + const double var_229 = var_120 + 0.0011988011988011988001590*var_61 + 0.0005994005994005994000795*var_220 + 0.0007992007992007992001060*var_203 + 0.0002622377622377622375348*var_59 + 0.0000012487512487512487502*var_53 + 0.0001198801198801198800159*var_95 + 0.0006993006993006993000928*var_80 + 0.0000899100899100899100119*var_227 + 0.0000874125874125874125116*var_178 + 0.0000280969030969030968787*var_71 + 0.0015984015984015984002120*var_62 + 0.0002997002997002997000398*var_180 + 0.0002397602397602397600318*var_222 + 0.0003596403596403596400477*var_224 + 0.0001298701298701298700172*var_73 + 0.0001748251748251748250232*var_58 + 0.0000437062937062937062558*var_218 + var_213 + var_221 + 0.0000299700299700299700040*var_204 + 0.0000324675324675324675043*var_179 + 0.0000536963036963036962571*var_70 + 0.0000049950049950049950007*var_219 + 0.0000699300699300699300093*var_217 + 0.0000999000999000999000133*var_211 + -0.0000024975024975024975003*var_228 + -0.0004795204795204795200636*var_65 + var_128 + var_216 + 0.0001798201798201798200239*var_85; + A[49] = 1.2857142857142855874030829*var_11*var_229; + A[94] = A[49]; + const double var_230 = -0.0002295323723895152309704*var_36 + 0.0000246777032491318181189*var_39 + -0.0002372627372627372625315*w[0][0]*w[1][0]*w[2][0] + 0.0004852290566576280780343*var_41 + var_122 + -0.0001462822891394319809594*var_40 + -0.0000660054231482802930163*var_38; + const double var_231 = -1.0000000000000000000000000*var_113; + const double var_232 = var_159 + -0.0000793849008134722342305*var_15 + 0.0000353812853812853812547*var_23 + 0.0001248751248751248750166*var_231 + -0.0002961324389895818309792*var_1 + 0.0030540887683744824716847*w[0][5]*w[1][5]*w[2][5]; + const double var_233 = 0.0004745254745254745250629*var_25 + 0.0000035678607107178533904*var_21 + 0.0000389491460920032299864*var_22 + 0.0002985110127967270589495*var_98 + 0.0003139717425431711220717*var_24 + 0.0000597616669045240424892*var_19; + const double var_234 = 0.0001855287569573283779946*var_61; + const double var_235 = 0.0000484634413205841757489*var_32 + var_234 + 0.0000392464678178963902590*var_91 + 0.0006279434850863422441433*var_55 + 0.0002788877788877788875370*var_82; + const double var_236 = -0.0000959605870320156043290*var_53 + 0.0002925645782788639619187*var_99 + -0.0006457827886399314810256*var_95 + var_235 + 0.0006671899529042385869684*var_96 + 0.0000202178773607345021221*var_71 + 0.0002140716426430712220584*var_62 + 0.0001748251748251748250232*var_169 + 0.0000322594072594072593793*var_67 + -0.0000906831263974121077470*var_50 + -0.0000585723800009514285040*var_73 + 0.0010560867703724846882601*var_64 + -0.0002354788069073783551063*var_100 + 0.0000052031302031302031257*var_218 + -0.0001676894534037391140072*var_86 + -0.0000680866752295323742665*var_88 + -0.0000963322391893820445053*var_92 + 0.0003725441225441225709045*var_89 + 0.0000145687645687645687519*var_176 + var_230 + var_233 + 0.0002319109461966604860458*var_204 + 0.0000596873364730507558092*var_52 + -0.0000678636839351125074503*var_70 + 0.0001034679606108177419687*var_77 + 0.0000912777698491984147396*var_49 + 0.0000582750582750582750077*var_156 + 0.0000570857713714856542463*var_56 + 0.0000234884163455592007456*var_74 + var_232 + 0.0003853289567575281780211*var_65 + 0.0000193259121830550416332*var_188 + -0.0000321107463964606792430*var_85 + -0.0001171447600019028570080*var_83; + A[28] = 0.2000000000000000111022302*var_11*var_236; + A[82] = A[28]; + const double var_237 = -0.0000714910089910089977232*var_43 + -0.0005194805194805194800689*var_45; + const double var_238 = -1.0000000000000000000000000*var_42; + const double var_239 = 0.0014423076923076923877565*var_238 + var_237 + -0.0001573426573426573425209*var_39 + -0.0016983016983016983002253*var_41 + 0.0002647352647352647350351*var_40 + 0.0005244755244755244750696*var_124 + 0.0001086413586413586412644*var_38; + const double var_240 = var_169 + var_203; + const double var_241 = var_49 + var_74; + const double var_242 = -0.2500000000000000000000000*var_241 + var_36; + const double var_243 = var_70 + var_67; + const double var_244 = var_88 + var_83; + const double var_245 = var_32 + var_73; + const double var_246 = var_64 + var_61; + const double var_247 = var_65 + var_56; + const double var_248 = var_55 + var_62; + const double var_249 = var_68 + var_53; + const double var_250 = var_23 + var_22; + const double var_251 = var_52 + var_71; + const double var_252 = var_50 + var_30; + const double var_253 = var_95 + var_100; + const double var_254 = var_86 + var_91; + const double var_255 = var_24 + var_129; + const double var_256 = var_113 + var_25; + const double var_257 = var_59 + var_82; + const double var_258 = var_58 + var_89; + const double var_259 = var_28 + var_98; + const double var_260 = 0.0000056887556887556887508*var_43 + 0.0000281200281200281211331*var_45; + const double var_261 = var_15 + var_19; + const double var_262 = -1.0000000000000000000000000*var_261; + const double var_263 = var_1 + var_21; + const double var_264 = var_96 + var_79; + const double var_265 = var_264 + var_263; + const double var_266 = 0.0001517001517001516819501*var_253 + -0.0000151700151700151705667*var_40 + 0.0000421800421800421800056*var_246 + 0.0000379250379250379204875*var_262 + -0.0000070300070300070302833*var_254 + 0.0000758500758500758409750*var_242 + 0.0000167887667887667887522*var_258 + 0.0003704628704628704625491*var_244 + 0.0000703000703000702909743*var_247 + var_260 + -0.0000031053602482173907492*var_38 + 0.0000013742870885728029380*var_240 + -0.0000020085734371448657347*var_243 + -0.0000210900210900210900028*var_265 + 0.0018779831279831279543940*w[0][0]*w[1][0]*w[2][0] + 0.0000092434021005449580025*var_257 + 0.0000117739403453689160612*var_256 + 0.0000444000444000444000059*var_248 + -0.0000140600140600140605666*var_152 + 0.0000054112554112554112507*var_250 + 0.0000005550005550005550001*var_259 + 0.0000016187516187516188208*var_252 + 0.0001167086881372595715380*w[0][3]*w[1][3]*w[2][3] + 0.0002109002109002109000280*var_255 + 0.0000189625189625189602438*var_39 + -0.0000018962518962518963208*var_245 + -0.0000878750878750878704941*var_251 + 0.0000056887556887556887508*var_249; + const double var_267 = -1.0000000000000000000000000*var_25; + const double var_268 = 0.0000582750582750582750077*var_212; + const double var_269 = var_268 + 0.0030540887683744824716847*w[0][4]*w[1][4]*w[2][4] + -0.0002961324389895818309792*var_21 + 0.0000353812853812853812547*var_22 + 0.0001248751248751248750166*var_267 + -0.0000793849008134722342305*var_19; + const double var_270 = 0.0004745254745254745250629*var_113 + 0.0003139717425431711220717*var_129 + 0.0000597616669045240424892*var_15 + 0.0000389491460920032299864*var_23 + 0.0002985110127967270589495*var_28 + 0.0000035678607107178533904*var_1; + const double var_271 = -1.0000000000000000000000000*var_53; + const double var_272 = 0.0010560867703724846882601*var_61 + 0.0006671899529042385869684*var_79 + 0.0001748251748251748250232*var_203 + 0.0002925645782788639619187*var_80 + -0.0002354788069073783551063*var_95 + 0.0000582750582750582750077*var_178 + -0.0000585723800009514285040*var_32 + 0.0000596873364730507558092*var_71 + 0.0002319109461966604860458*var_180 + -0.0000906831263974121077470*var_30 + -0.0000678636839351125074503*var_67 + var_269 + 0.0003725441225441225709045*var_58 + -0.0006457827886399314810256*var_100 + 0.0000145687645687645687519*var_177 + 0.0000052031302031302031257*var_271 + -0.0001171447600019028570080*var_88 + -0.0000959605870320156043290*var_68 + -0.0001676894534037391140072*var_91 + var_230 + 0.0000202178773607345021221*var_52 + 0.0000322594072594072593793*var_70 + var_270 + var_210 + -0.0000321107463964606792430*var_77 + 0.0000193259121830550416332*var_219 + 0.0000234884163455592007456*var_49 + -0.0000963322391893820445053*var_76 + 0.0003853289567575281780211*var_56 + 0.0000912777698491984147396*var_74 + 0.0002140716426430712220584*var_55 + 0.0000570857713714856542463*var_65 + 0.0001034679606108177419687*var_85 + -0.0000680866752295323742665*var_83; + A[16] = 0.2000000000000000111022302*var_11*var_272; + A[61] = A[16]; + const double var_273 = 0.0005244755244755244750696*var_25 + 0.0000285428856857428271232*var_147 + 0.0000412087912087912087555*var_22 + 0.0002247752247752247750298*var_98 + 0.0002711574140145568559759*var_24 + -0.0000021407164264307122036*var_19; + const double var_274 = var_82 + var_79; + const double var_275 = -1.0000000000000000000000000*var_52; + const double var_276 = var_161 + var_172; + const double var_277 = var_40 + var_263; + const double var_278 = 0.0000235478806907378321225*var_277 + -0.0000000445982588839731687*var_43 + -0.0000428143285286142389907*var_45; + const double var_279 = -0.0000168581418581418581272*var_113 + 0.0003139717425431711220717*var_214 + -0.0000035678607107178533904*var_15 + -0.0000044598258883973168439*var_23 + var_278 + -0.0000164121592693021244947*var_28; + const double var_280 = -0.0000164121592693021244947*var_36 + -0.0000044598258883973168439*var_39 + -0.0003139717425431711220717*var_41 + -0.0000168581418581418581272*var_42 + -0.0000035678607107178533904*var_38; + const double var_281 = var_204 + var_168; + const double var_282 = var_179 + var_176; + const double var_283 = var_157 + var_156; + const double var_284 = -1.0000000000000000000000000*var_22; + const double var_285 = -1.0000000000000000000000000*var_136; + const double var_286 = 0.0000107035821321535597477*var_142 + 0.0000742115027829313484873*var_181 + 0.0000285428856857428271232*var_285 + 0.0000076709005280433849376*var_19 + var_279 + 0.0000090980448123305261243*var_140 + 0.0000312187812187812187541*var_133 + -0.0000102575995433138278092*var_139 + 0.0000137362637362637362518*var_283 + 0.0000535179106607678055146*var_131 + -0.0001084629656058227505219*var_132 + var_280 + -0.0000585129156557728005153*var_149 + 0.0000012933495076352218593*var_135 + 0.0000078492935635792773742*var_138 + 0.0000306836021121735397503*var_143 + 0.0000963322391893820445053*var_141 + 0.0000187312687312687312525*var_282 + 0.0000655594405594405593837*var_25 + -0.0000685029256457827905166*var_137 + 0.0000008919651776794633476*var_175 + 0.0000092764378478664185609*var_281 + 0.0000019623233908948193435*var_284 + 0.0000035678607107178533904*var_276; + A[47] = 3.0000000000000000000000000*var_11*var_286; + const double var_287 = -1.0000000000000000000000000*var_63; + const double var_288 = var_57 + var_246 + var_132; + const double var_289 = 0.0018552875695732838883661*var_19 + 0.2727272727272727625980053*var_25 + 0.0285714285714285705364279*var_22; + const double var_290 = -0.0004807692307692307959188*var_289 + 0.0000749250749250749250099*var_212 + 0.0001084629656058227505219*var_181 + var_183 + 0.0000107035821321535597477*var_21; + const double var_291 = 0.0000306836021121735397503*var_36 + -0.0000108819751676894538783*var_39 + 0.0000112387612387612387515*var_42 + 0.0001427144284287141390039*var_163 + 0.0000406736121021835297516*var_40 + 0.0000242614528328814052570*var_38; + const double var_292 = -1.0000000000000000000000000*var_32; + const double var_293 = -1.0000000000000000000000000*var_62; + const double var_294 = var_77 + var_79; + const double var_295 = -0.2500000000000000000000000*var_67 + var_30; + const double var_296 = 29.0000000000000000000000000*var_73 + 41.0000000000000000000000000*var_50; + const double var_297 = -0.0000685029256457827905166*var_61 + 0.0000035678607107178533904*var_223 + 0.0000749250749250749250099*var_203 + 0.0000237262737262737262531*var_53 + 0.0001569858712715855610358*var_190 + 0.0000742115027829313484873*var_293 + 0.0000185528756957328371218*var_80 + 0.0000076709005280433849376*var_295 + 0.0001127443984586841689999*var_95 + -0.0000164121592693021244947*var_294 + 0.0000999000999000999000133*var_178 + 0.0000004905808477237048359*var_71 + var_185 + -0.0002426145283288140390172*var_64 + 0.0000306836021121735397503*var_100 + 0.0000058869701726844580306*var_292 + 0.0000005351791066076780509*var_296 + 0.0000811688311688311687608*var_177 + 0.0000378193235336092439900*var_86 + 0.0000055747823604966458431*var_68 + 0.0000235478806907378321225*var_92 + 0.0000224775224775224775030*var_176 + 0.0000428143285286142389907*var_191 + 0.0000019623233908948193435*var_157 + 0.0000117739403453689160612*var_179 + -0.0000074033109747395462827*var_52 + 0.0000008919651776794633476*var_167 + 0.0000181068931068931068774*var_70 + -0.0000144498358784073059982*var_49 + 0.0000506636220921935197530*var_76 + var_290 + 0.0000137362637362637362518*var_156 + 0.0001498501498501498500199*var_211 + -0.0001084629656058227505219*var_65 + var_291 + 0.0000107035821321535597477*var_85; + A[48] = 3.0000000000000000000000000*var_11*var_297; + A[84] = A[48]; + const double var_298 = var_76 + var_92; + A[23] = var_11*var_174; + A[32] = A[23]; + const double var_299 = var_212 + var_158; + const double var_300 = var_299 + var_124; + const double var_301 = 0.0039960039960039960005300*var_24; + const double var_302 = var_125 + 0.0000899100899100899100119*var_212 + -0.0000262237762237762237535*w[0][1]*w[1][1]*w[2][1] + 0.0000599400599400599400080*var_22 + 0.0004395604395604395600583*var_147 + var_301 + -0.0000849150849150849150113*var_19; + const double var_303 = -1.0000000000000000000000000*var_39; + const double var_304 = 0.0003496503496503496500464*var_36 + -0.0019980019980019980002650*var_41 + 0.0002622377622377622375348*var_42 + 0.0003296703296703296700437*var_40 + 0.0000174825174825174825023*var_303 + 0.0000774225774225774225103*var_38; + const double var_305 = 0.0015984015984015984002120*var_129 + -0.0001311188811188811187674*var_113 + 0.0002497502497502497500331*var_158 + -0.0000724275724275724275096*var_15 + 0.0000499500499500499500066*var_23 + -0.0002997002997002997000398*var_1; + const double var_306 = 0.0000499500499500499500066*var_89 + 0.0003996003996003996000530*var_61; + const double var_307 = 0.0003496503496503496500464*var_95; + const double var_308 = var_92 + var_64; + const double var_309 = var_171 + var_211; + const double var_310 = -0.2500000000000000000000000*var_70 + var_50; + const double var_311 = var_310 + -0.5000000000000000000000000*var_73 + var_168; + const double var_312 = 29.0000000000000000000000000*var_49 + 41.0000000000000000000000000*var_74; + const double var_313 = -0.0000024975024975024975003*var_312 + 0.0000437062937062937062558*var_275 + 0.0000299700299700299700040*var_223 + 0.0001198801198801198800159*var_99 + 0.0000280969030969030968787*var_53 + 0.0002997002997002997000398*var_225 + var_307 + 0.0005994005994005994000795*var_293 + 0.0000999000999000999000133*var_169 + 0.0001298701298701298700172*var_30 + 0.0000012487512487512487502*var_67 + 0.0000699300699300699300093*var_208 + 0.0006993006993006993000928*var_100 + 0.0000049950049950049950007*var_292 + var_302 + 0.0007992007992007992001060*var_172 + 0.0002397602397602397600318*var_308 + 0.0003596403596403596400477*var_309 + 0.0000324675324675324675043*var_177 + 0.0001748251748251748250232*var_88 + 0.0000536963036963036962571*var_68 + var_305 + 0.0000874125874125874125116*var_176 + 0.0000899100899100899100119*var_311 + 0.0001798201798201798200239*var_76 + 0.0015984015984015984002120*var_56 + var_304 + -0.0004795204795204795200636*var_55 + 0.0011988011988011988001590*var_65 + var_306 + 0.0002622377622377622375348*var_83; + A[59] = 1.2857142857142855874030829*var_11*var_313; + A[95] = A[59]; + const double var_314 = 0.0000499500499500499500066*var_39 + 0.0015984015984015984002120*var_41 + -0.0001311188811188811187674*var_42 + -0.0002997002997002997000398*var_40 + 0.0002497502497502497500331*var_124 + -0.0000724275724275724275096*var_38; + const double var_315 = 0.0000067789353503639219076*var_43 + 0.0000342514628228913952583*var_45; + const double var_316 = -1.0000000000000000000000000*var_38; + const double var_317 = 0.0000456686170971885247523*var_36 + var_315 + 0.0000003567860710717853496*var_39 + 0.0000174825174825174825023*var_316 + 0.0000337162837162837162545*var_42 + 0.0003996003996003996000530*var_163 + 0.0000470957613814756642450*var_40; + const double var_318 = 0.0039960039960039960005300*var_129; + const double var_319 = var_125 + 0.0000899100899100899100119*var_158 + -0.0000849150849150849150113*var_15 + 0.0000599400599400599400080*var_23 + 0.0004395604395604395600583*var_94 + -0.0000262237762237762237535*w[0][2]*w[1][2]*w[2][2] + var_318; + const double var_320 = 0.0000174825174825174825023*var_284 + 0.0002622377622377622375348*var_25 + 0.0019980019980019980002650*var_181 + 0.0003296703296703296700437*var_21 + 0.0003496503496503496500464*var_98 + 0.0000774225774225774225103*var_19; + const double var_321 = -1.0000000000000000000000000*var_70; + const double var_322 = 0.0000499500499500499500066*var_59 + 0.0003996003996003996000530*var_65; + const double var_323 = var_77 + var_62; + const double var_324 = 0.0003496503496503496500464*var_99; + const double var_325 = var_194 + -0.5000000000000000000000000*var_30 + var_180; + const double var_326 = -0.0004795204795204795200636*var_61 + 0.0001198801198801198800159*var_79 + 0.0002997002997002997000398*var_168 + var_320 + 0.0006993006993006993000928*var_96 + 0.0000012487512487512487502*var_71 + 0.0000999000999000999000133*var_161 + 0.0002397602397602397600318*var_323 + 0.0000437062937062937062558*var_321 + 0.0000280969030969030968787*var_67 + var_314 + 0.0015984015984015984002120*var_64 + -0.0000024975024975024975003*var_296 + 0.0000899100899100899100119*var_325 + 0.0000299700299700299700040*var_171 + 0.0007992007992007992001060*var_162 + 0.0000699300699300699300093*var_271 + 0.0002622377622377622375348*var_89 + 0.0005994005994005994000795*var_191 + 0.0001798201798201798200239*var_91 + 0.0000874125874125874125116*var_157 + var_322 + 0.0000536963036963036962571*var_52 + 0.0001748251748251748250232*var_82 + 0.0000049950049950049950007*var_167 + var_319 + 0.0001298701298701298700172*var_49 + 0.0000324675324675324675043*var_156 + 0.0011988011988011988001590*var_55 + 0.0003596403596403596400477*var_205 + var_324; + const double var_327 = 0.0000512879977165691441281*var_43 + 0.0006850292564578278238507*var_45; + const double var_328 = var_223 + var_258 + var_168; + const double var_329 = -1.0000000000000000000000000*var_245; + const double var_330 = -1.0000000000000000000000000*var_263 + 0.1826923076923077093880465*var_252 + var_248; + const double var_331 = 0.0009133723419437704679411*var_246 + 0.0011238761238761239835693*var_253 + 0.0007492507492507492500994*var_242 + var_327 + 0.0009053446553446553709751*var_244 + 0.0019980019980019980002650*var_247 + 0.0000999000999000999000133*var_298 + 0.0000713572142143570695020*var_240 + 0.0005565862708719851881939*var_330 + -0.0000303268160411017548771*var_243 + 0.0000784929356357927805179*var_257 + 0.0001712573141144569559627*var_328 + -0.0006564863707720849797869*var_264 + 0.0001355787070072784279880*var_299 + -0.0004424147281290138119386*var_152 + 0.0001195233338090480849783*var_250 + 0.0010846296560582274239037*w[0][3]*w[1][3]*w[2][3] + 0.0039960039960039960005300*var_255 + -0.0002559940059940060208890*var_261 + 0.0000338946767518196069970*var_329 + 0.0001070358213215356110292*var_126 + -0.0002091658341658341792053*var_251 + 0.0000466051805337519613149*var_249 + 0.0048076923076923079591882*var_186; + A[57] = 0.6000000000000000888178420*var_11*var_331; + const double var_332 = var_162 + var_211; + const double var_333 = -0.0000168581418581418581272*var_25 + 0.0003139717425431711220717*var_181 + -0.0000044598258883973168439*var_22 + -0.0000164121592693021244947*var_98 + -0.0000035678607107178533904*var_19; + const double var_334 = var_223 + var_180; + const double var_335 = var_177 + var_157; + const double var_336 = var_179 + var_178; + const double var_337 = -1.0000000000000000000000000*var_51; + const double var_338 = -0.0000102575995433138278092*var_69 + -0.0000685029256457827905166*var_66 + 0.0000076709005280433849376*var_15 + -0.0000585129156557728005153*var_101 + 0.0000306836021121735397503*var_87 + 0.0000137362637362637362518*var_336 + 0.0000285428856857428271232*var_287 + -0.0001084629656058227505219*var_57 + 0.0000655594405594405593837*var_113 + 0.0000187312687312687312525*var_335 + 0.0000078492935635792773742*var_72 + 0.0000742115027829313484873*var_214 + var_280 + 0.0000107035821321535597477*var_78 + 0.0000963322391893820445053*var_81 + 0.0000012933495076352218593*var_54 + 0.0000090980448123305261243*var_75 + 0.0000535179106607678055146*var_34 + 0.0000092764378478664185609*var_334 + 0.0000035678607107178533904*var_332 + 0.0000019623233908948193435*var_215 + 0.0000312187812187812187541*var_60 + var_333 + var_278 + 0.0000008919651776794633476*var_337; + const double var_339 = var_259 + var_246; + const double var_340 = var_171 + var_225; + const double var_341 = 41.0000000000000000000000000*var_73 + 29.0000000000000000000000000*var_50; + const double var_342 = 0.0018552875695732838883661*var_15 + 0.2727272727272727625980053*var_113 + 0.0285714285714285705364279*var_23; + const double var_343 = 0.0000107035821321535597477*var_1 + 0.0001084629656058227505219*var_214 + 0.0000749250749250749250099*var_158 + -0.0004807692307692307959188*var_342; + const double var_344 = var_135 + var_54 + var_243; + const double var_345 = 0.0003996003996003996000530*var_41; + const double var_346 = 0.0000999000999000999000133*var_129; + const double var_347 = 0.0000174825174825174825023*var_15 + 0.0000092764378478664185609*var_23 + var_346 + var_153 + 0.0001392357642357642491960*w[0][2]*w[1][2]*w[2][2] + 0.0000585129156557728005153*var_28 + -0.0000068978640407211838144*var_1; + const double var_348 = var_268 + -0.0004651598401598401729892*w[0][1]*w[1][1]*w[2][1] + -0.0000335378906807478255120*var_21 + -0.0000029137529137529137504*var_22 + 0.0002112173540744969159680*var_24 + -0.0000117144760001902863784*var_19; + const double var_349 = 0.0001855287569573283779946*var_65; + const double var_350 = 0.0000484634413205841757489*var_74 + 0.0006279434850863422441433*var_61 + var_349 + 0.0000392464678178963902590*var_85 + 0.0002788877788877788875370*var_58; + const double var_351 = -1.0000000000000000000000000*var_49; + const double var_352 = 0.2000000000000000111022302*var_223 + var_203; + const double var_353 = 0.2000000000000000111022302*var_225 + var_211; + const double var_354 = 0.0000597022025593454145004*var_79 + 0.0001073926073926073925142*var_59 + 0.0000264319014319014318785*var_53 + 0.2000000000000000111022302*var_350 + 0.0001612673041244469659614*var_80 + 0.0001144688644688644687652*var_178 + -0.0000160553731982303396215*var_32 + 0.0001748251748251748250232*var_352 + 0.0000041179059036201898149*var_71 + var_164 + 0.0000463821892393320944986*var_161 + 0.0000970458113315256210279*var_62 + 0.0000000594643451786308938*var_351 + var_348 + -0.0000132010846296560572480*var_30 + -0.0000308619951477094304928*var_67 + 0.0000087412587412587412512*var_50 + 0.0000203962703962703962527*var_73 + 0.0000333000333000333000044*var_64 + 0.0000135578707007278438152*var_86 + 0.0000185528756957328371218*var_162 + -0.0000143160411017553879413*var_68 + -0.0000292564578278864002576*var_92 + 0.0000023191094619666046402*var_179 + -0.0000038057180914323772039*var_52 + -0.0001852314352314352312746*var_82 + 0.0000514069264069264068818*var_70 + -0.0000097521526092954661879*var_76 + 0.0000513771942343370894993*var_56 + 0.0000582750582750582750077*var_353 + var_347 + 0.0000049355406498263644708*var_83; + A[14] = var_11*var_354; + A[41] = A[14]; + const double var_355 = var_345 + 0.0000342514628228913952583*var_39 + 0.0000749250749250749250099*var_42 + -0.0000884829456258027705192*var_40 + 0.0000214071642643071194953*var_124 + -0.0000374625374625374625050*var_38; + const double var_356 = 0.0000005550005550005550001*var_36 + 0.0000054112554112554112507*var_39 + 0.0002109002109002109000280*var_41 + 0.0000117739403453689160612*var_42 + var_260 + -0.0000210900210900210900028*var_40 + -0.0000379250379250379204875*var_38; + const double var_357 = var_101 + var_21; + const double var_358 = 0.0001167086881372595715380*w[0][5]*w[1][5]*w[2][5] + 0.0000054112554112554112507*var_22 + -0.0000878750878750878704941*var_69 + -0.0000210900210900210900028*var_357 + 0.0002109002109002109000280*var_24 + var_356 + 0.0000444000444000444000059*var_66 + -0.0000031053602482173907492*var_15 + 0.0018779831279831279543940*w[0][2]*w[1][2]*w[2][2] + 0.0000167887667887667887522*var_84 + 0.0000421800421800421800056*var_57 + 0.0000056887556887556887508*var_72 + 0.0000189625189625189602438*var_23 + 0.0000703000703000702909743*var_63 + -0.0000151700151700151705667*var_1 + 0.0000379250379250379204875*var_199 + -0.0000070300070300070302833*var_78 + 0.0001517001517001516819501*var_81 + -0.0000020085734371448657347*var_54 + 0.0000016187516187516188208*var_75 + 0.0000758500758500758409750*var_34 + -0.0000018962518962518963208*var_51 + 0.0000013742870885728029380*var_332 + -0.0000140600140600140605666*var_93 + 0.0003704628704628704625491*var_60 + 0.0000117739403453689160612*var_25 + 0.0000092434021005449580025*var_90 + 0.0000005550005550005550001*var_98; + const double var_359 = 0.0003496503496503496500464*var_96; + const double var_360 = var_345 + 0.0000084439370153655877549*var_39 + 0.0000031664763807620949846*w[0][0]*w[1][0]*w[2][0] + var_104 + 0.0000611888111888111887581*var_38; + const double var_361 = var_116 + 0.0000611888111888111887581*var_25 + 0.0000069573283858998143442*var_22 + var_154 + 0.0000262237762237762237535*var_19; + const double var_362 = 0.0001370058512915655810332*var_64; + const double var_363 = 0.0000320512820512820512543*var_32 + 0.0000666000666000666000088*var_61 + 0.0000058275058275058275008*var_49 + 0.0001027543884686741789986*var_65 + 0.0000137957280814423676287*var_96 + 0.0001071844821844821843892*var_67 + 0.0000069573283858998143442*var_83 + 0.0000999000999000999000133*var_62 + 0.0000262237762237762237535*var_30 + 0.0000799200799200799200106*var_56 + 0.0000572344322344322343826*var_68 + var_110 + 0.0000599400599400599400080*var_99 + 0.0001598401598401598400212*var_55 + 0.0000127253698682270113151*var_88 + var_362 + 0.0000392464678178963902590*var_82 + var_360 + 0.0000000297321725893154469*var_52 + var_361 + 0.0000323486037771752047505*var_89; + const double var_364 = var_107 + 0.0000449550449550449550060*var_40; + const double var_365 = var_100 + var_91; + const double var_366 = 0.0000166500166500166500022*var_21; + const double var_367 = 0.0003496503496503496500464*var_80; + const double var_368 = 0.0000114171542742971311881*var_77 + 0.0000262237762237762237535*var_70 + 0.0000049950049950049950007*var_365 + var_367 + 0.0000166500166500166500022*var_92 + 0.0000083250083250083250011*var_71 + -1.0000000000000000000000000*var_363 + 0.0000066451405737120021567*var_53 + 0.0000044598258883973168439*var_73 + 0.0000233100233100233100031*var_85 + var_366 + 0.0000001189286903572617876*var_74 + 0.0000012487512487512487502*var_50 + 0.0002289377289377289375304*var_58 + 0.0001165501165501165500155*var_79 + var_364 + 0.0000349650349650349650046*var_86 + 0.0004578754578754578750607*var_59 + var_115 + 0.0000285428856857428271232*var_76 + 0.0000256885971171685447497*var_95; + A[24] = var_11*var_368; + const double var_369 = 0.0000162783644926502064378*var_43 + 0.0001826744683887540990092*var_45; + const double var_370 = 0.0937500000000000000000000*w[0][0]*w[1][0]*w[2][0]; + const double var_371 = var_369 + -0.0000627943485086342189933*var_370 + 0.0000353218210361067464897*var_39 + var_127 + -0.0002683031254459826040956*var_40 + 0.0000342514628228913952583*var_124 + -0.0001848151848151848150245*var_38; + const double var_372 = 0.0003996003996003996000530*var_129; + const double var_373 = 0.0000749250749250749250099*var_113 + 0.0000214071642643071194953*var_158 + -0.0000374625374625374625050*var_15 + var_372 + 0.0000342514628228913952583*var_23 + -0.0000884829456258027705192*var_1; + const double var_374 = 0.0000499500499500499500066*var_58 + 0.0003996003996003996000530*var_64; + const double var_375 = var_59 + var_96; + const double var_376 = var_204 + var_56; + const double var_377 = 0.0000214071642643071194953*var_79 + 0.0008991008991008991001193*var_99 + var_374 + 0.0000313971742543171094967*var_32 + -0.0000041030398173255311237*var_71 + 0.0004566861709718852339705*var_62 + 0.0004281432852861424441168*var_169 + 0.0001048951048951048950139*var_321 + var_111 + -0.0000206935921221635497490*var_30 + 0.0000165905523048380186253*var_67 + var_234 + -0.0000511988011988011987568*var_50 + -0.0000611888111888111887581*var_73 + -0.0000413871842443270994980*var_100 + 0.0000171257314114456976291*var_218 + 0.0000271157414014556876305*var_171 + -0.0001312972741544169959574*var_86 + 0.0000884829456258027705192*var_162 + 0.0000487012987012987012565*var_271 + 0.0000239046667618096169957*var_88 + -0.0000642214927929213584860*var_92 + 0.0001810689310689310687740*var_89 + 0.0001498501498501498500199*var_375 + 0.0000399600399600399600053*var_91 + 0.0000084736691879549017492*var_52 + 0.0005432067932067931792170*var_82 + var_373 + 0.0000199800199800199800027*var_77 + 0.0000203368060510917648758*var_49 + -0.0000032110746396460680937*var_74 + var_371 + 0.0007992007992007992001060*var_55 + 0.0001113172541743970295073*var_376 + var_273 + 0.0000153418010560867698752*var_83; + A[33] = 3.0000000000000000000000000*var_11*var_377; + const double var_378 = 0.0001370058512915655810332*var_56; + const double var_379 = var_162 + var_158 + var_169; + const double var_380 = var_138 + var_215; + const double var_381 = 0.0937500000000000000000000*w[0][1]*w[1][1]*w[2][1]; + const double var_382 = var_381 + var_21; + const double var_383 = -0.4800000000000000377475828*var_136 + -1.0000000000000000000000000*var_137 + 0.1087499999999999994448885*var_15 + 0.0924999999999999988897770*var_134 + 0.0250000000000000013877788*var_281 + -0.1012500000000000066613381*var_22 + 0.2850000000000000310862447*var_143 + 0.2650000000000000133226763*var_1 + var_24 + 0.1700000000000000122124533*var_140 + 1.7000000000000001776356839*var_214 + -0.0762499999999999983346655*var_133 + -0.0184374999999999990285549*var_139 + 0.3549999999999999822364316*var_141 + 0.3699999999999999955591079*var_382; + const double var_384 = 0.0001966783216783216917036*var_135 + 0.0014423076923076923877565*var_231 + 0.0009990009990009990001325*var_383 + 0.0010489510489510489501391*var_276 + -0.0010989010989010989001458*var_132 + 0.0013111888111888112418840*var_283 + 0.0001298701298701298700172*var_142 + var_239 + 0.0006168831168831169367919*var_19 + 0.0001648351648351648350219*var_131 + 0.0005681818181818181542203*var_282 + 0.0001573426573426573425209*var_380 + 0.0005244755244755244750696*var_379; + const double var_385 = 0.0030540887683744824716847*w[0][3]*w[1][3]*w[2][3] + 0.0001248751248751248750166*var_238 + 0.0000353812853812853812547*var_39 + var_197 + -0.0002961324389895818309792*var_40 + -0.0000793849008134722342305*var_38; + const double var_386 = 0.0000052031302031302031257*var_275 + 0.0002925645782788639619187*var_79 + 0.0002319109461966604860458*var_223 + 0.0000202178773607345021221*var_53 + -0.0006457827886399314810256*var_99 + 0.0003725441225441225709045*var_59 + var_350 + var_123 + 0.0006671899529042385869684*var_80 + -0.0000906831263974121077470*var_32 + -0.0002354788069073783551063*var_96 + 0.0000322594072594072593793*var_71 + 0.0001748251748251748250232*var_161 + 0.0010560867703724846882601*var_62 + 0.0000193259121830550416332*var_351 + -0.0000585723800009514285040*var_30 + -0.0000959605870320156043290*var_67 + 0.0000234884163455592007456*var_50 + 0.0000912777698491984147396*var_73 + 0.0000570857713714856542463*var_64 + 0.0001034679606108177419687*var_86 + -0.0000678636839351125074503*var_68 + -0.0001676894534037391140072*var_92 + -0.0001171447600019028570080*var_89 + 0.0000145687645687645687519*var_157 + 0.0000582750582750582750077*var_179 + -0.0000680866752295323742665*var_82 + 0.0000596873364730507558092*var_70 + var_270 + -0.0000963322391893820445053*var_77 + -0.0000321107463964606792430*var_76 + 0.0002140716426430712220584*var_56 + var_385 + 0.0003853289567575281780211*var_55; + A[4] = 0.2000000000000000111022302*var_11*var_386; + A[40] = A[4]; + A[89] = 1.2857142857142855874030829*var_11*var_326; + A[98] = A[89]; + const double var_387 = -1.0000000000000000000000000*var_65; + const double var_388 = 0.0000499500499500499500066*var_82 + 0.0003996003996003996000530*var_56; + const double var_389 = var_180 + var_203; + const double var_390 = var_55 + var_85; + const double var_391 = -0.2500000000000000000000000*var_53 + var_73; + const double var_392 = var_204 + -0.5000000000000000000000000*var_50 + var_391; + const double var_393 = 29.0000000000000000000000000*var_32 + 41.0000000000000000000000000*var_30; + const double var_394 = 0.0015984015984015984002120*var_61 + 0.0006993006993006993000928*var_79 + 0.0002997002997002997000398*var_223 + 0.0001748251748251748250232*var_59 + 0.0000299700299700299700040*var_225 + 0.0000324675324675324675043*var_178 + 0.0001198801198801198800159*var_96 + 0.0000536963036963036962571*var_71 + 0.0007992007992007992001060*var_161 + 0.0011988011988011988001590*var_62 + 0.0000049950049950049950007*var_351 + var_314 + 0.0002622377622377622375348*var_58 + -0.0004795204795204795200636*var_64 + var_367 + 0.0000699300699300699300093*var_218 + var_302 + var_388 + 0.0002397602397602397600318*var_390 + 0.0001798201798201798200239*var_86 + 0.0000999000999000999000133*var_162 + 0.0005994005994005994000795*var_387 + 0.0000899100899100899100119*var_392 + 0.0003596403596403596400477*var_389 + 0.0000874125874125874125116*var_179 + 0.0000012487512487512487502*var_52 + 0.0000280969030969030968787*var_70 + 0.0000437062937062937062558*var_217 + -0.0000024975024975024975003*var_393 + 0.0001298701298701298700172*var_74 + var_216; + const double var_395 = var_369 + 0.0000342514628228913952583*var_158 + -0.0001848151848151848150245*var_15 + -0.0000627943485086342189933*var_2 + 0.0000353218210361067464897*var_23 + -0.0002683031254459826040956*var_1 + var_318; + const double var_396 = 0.0000214071642643071194953*var_212 + var_105 + 0.0000749250749250749250099*var_25 + -0.0000884829456258027705192*var_21 + 0.0000342514628228913952583*var_22 + -0.0000374625374625374625050*var_19; + const double var_397 = 0.0002247752247752247750298*var_36 + 0.0000412087912087912087555*var_39 + 0.0002711574140145568559759*var_41 + 0.0000285428856857428271232*var_126 + 0.0005244755244755244750696*var_42 + -0.0000021407164264307122036*var_38; + const double var_398 = 0.0001855287569573283779946*var_55; + const double var_399 = 0.0001370058512915655810332*var_61; + const double var_400 = var_171 + var_62; + const double var_401 = var_100 + var_89; + const double var_402 = 0.0001048951048951048950139*var_275 + 0.0000271157414014556876305*var_223 + 0.0000214071642643071194953*var_99 + 0.0000165905523048380186253*var_53 + 0.0000153418010560867698752*var_59 + var_399 + -0.0000413871842443270994980*var_80 + 0.0008991008991008991001193*var_95 + var_396 + -0.0000032110746396460680937*var_32 + 0.0000171257314114456976291*var_321 + 0.0000203368060510917648758*var_30 + -0.0000041030398173255311237*var_67 + 0.0000487012987012987012565*var_208 + 0.0000313971742543171094967*var_50 + -0.0000206935921221635497490*var_73 + 0.0001498501498501498500199*var_401 + 0.0000239046667618096169957*var_58 + 0.0004566861709718852339705*var_64 + 0.0001113172541743970295073*var_400 + 0.0000884829456258027705192*var_172 + var_388 + -0.0000642214927929213584860*var_86 + 0.0005432067932067931792170*var_88 + 0.0000084736691879549017492*var_68 + 0.0000199800199800199800027*var_92 + var_397 + var_398 + -0.0001312972741544169959574*var_77 + -0.0000611888111888111887581*var_49 + 0.0000399600399600399600053*var_76 + var_395 + 0.0004281432852861424441168*var_211 + -0.0000511988011988011987568*var_74 + 0.0007992007992007992001060*var_65 + 0.0001810689310689310687740*var_83; + A[77] = 3.0000000000000000000000000*var_11*var_402; + const double var_403 = 0.0000611888111888111887581*var_15 + var_372 + 0.0000084439370153655877549*var_23 + var_104 + 0.0000031664763807620949846*w[0][2]*w[1][2]*w[2][2]; + const double var_404 = 0.0002882831454260025840983*w[0][4]*w[1][4]*w[2][4]; + const double var_405 = 0.0000572344322344322343826*var_70 + 0.0001027543884686741789986*var_61 + 0.0001598401598401598400212*var_65 + 0.0000323486037771752047505*var_83 + 0.0001071844821844821843892*var_53 + 0.0000262237762237762237535*var_73 + 0.0000999000999000999000133*var_64 + 0.0000799200799200799200106*var_62 + 0.0000058275058275058275008*var_30 + var_378 + 0.0000000297321725893154469*var_68 + 0.0000320512820512820512543*var_50 + 0.0000127253698682270113151*var_58 + var_109 + 0.0000666000666000666000088*var_55 + var_403 + 0.0000069573283858998143442*var_59 + 0.0000392464678178963902590*var_88 + 0.0000137957280814423676287*var_100 + var_404 + 0.0000599400599400599400080*var_95; + const double var_406 = 0.0000114171542742971311881*var_28; + const double var_407 = 0.0000611888111888111887581*var_113 + 0.0000262237762237762237535*var_15 + 0.0000069573283858998143442*var_23 + var_406 + var_346; + const double var_408 = 0.0002882831454260025840983*w[0][3]*w[1][3]*w[2][3]; + const double var_409 = 0.0001370058512915655810332*var_62; + const double var_410 = 0.0000000297321725893154469*var_70 + var_409 + 0.0001598401598401598400212*var_61 + 0.0001071844821844821843892*var_71 + 0.0000262237762237762237535*var_49 + 0.0000666000666000666000088*var_65 + var_407 + 0.0000058275058275058275008*var_73 + var_408 + 0.0000799200799200799200106*var_64 + 0.0000999000999000999000133*var_56 + 0.0000320512820512820512543*var_74 + 0.0000137957280814423676287*var_80 + 0.0000392464678178963902590*var_58 + 0.0000599400599400599400080*var_79 + 0.0001027543884686741789986*var_55 + var_106 + 0.0000323486037771752047505*var_59 + 0.0000127253698682270113151*var_82 + 0.0000572344322344322343826*var_52 + 0.0000069573283858998143442*var_89; + const double var_411 = 0.0001165501165501165500155*var_36 + var_114 + 0.0000145687645687645687519*var_39 + 0.0010052447552447551625682*var_42 + 0.0000399600399600399600053*var_40 + 0.0000070167927310784457211*var_38; + const double var_412 = 0.0000166500166500166500022*var_1; + const double var_413 = 0.0003496503496503496500464*var_100; + const double var_414 = 0.0000166500166500166500022*var_77 + 0.0000285428856857428271232*var_91 + 0.0000049950049950049950007*var_206 + 0.0000012487512487512487502*var_32 + var_413 + 0.0000349650349650349650046*var_92 + var_412 + 0.0000083250083250083250011*var_53 + 0.0000066451405737120021567*var_67 + 0.0004578754578754578750607*var_83 + 0.0000044598258883973168439*var_30 + 0.0000262237762237762237535*var_68 + -1.0000000000000000000000000*var_410 + var_411 + 0.0000001189286903572617876*var_50 + 0.0000256885971171685447497*var_99 + 0.0000114171542742971311881*var_86 + var_117 + 0.0002289377289377289375304*var_88 + 0.0000233100233100233100031*var_76 + 0.0001165501165501165500155*var_95; + A[5] = var_11*var_414; + const double var_415 = var_156 + var_178; + const double var_416 = var_177 + var_176; + const double var_417 = -1.0000000000000000000000000*var_247; + const double var_418 = 0.0000187312687312687312525*var_415 + -0.0001084629656058227505219*var_246 + 0.0000963322391893820445053*var_253 + 0.0000107035821321535597477*var_254 + 0.0000535179106607678055146*var_242 + 0.0000312187812187812187541*var_244 + 0.0000306836021121735397503*var_298 + 0.0000035678607107178533904*var_240 + 0.0000076709005280433849376*var_38 + 0.0000012933495076352218593*var_243 + 0.0000019623233908948193435*var_303 + var_279 + 0.0000742115027829313484873*var_163 + -0.0000585129156557728005153*var_264 + -0.0000685029256457827905166*var_248 + 0.0000092764378478664185609*var_340 + 0.0000090980448123305261243*var_252 + 0.0000285428856857428271232*var_417 + 0.0000137362637362637362518*var_416 + 0.0000008919651776794633476*var_329 + var_333 + -0.0000102575995433138278092*var_251 + 0.0000655594405594405593837*var_42 + 0.0000078492935635792773742*var_249; + A[68] = 3.0000000000000000000000000*var_11*var_418; + A[86] = A[68]; + const double var_419 = -0.0000130226915941201648114*var_39 + -0.0006564863707720849797869*var_41 + -0.0000112387612387612387515*var_42 + 0.0000706436420722134929794*var_40 + 0.0000035678607107178533904*var_124 + 0.0000269373483659197934998*var_38; + const double var_420 = var_86 + var_95; + const double var_421 = var_49 + -0.2500000000000000000000000*var_71; + const double var_422 = 0.0000428143285286142389907*var_220 + 0.0000004905808477237048359*var_53 + 0.0001127443984586841689999*var_99 + 0.0000019623233908948193435*var_178 + -0.0000164121592693021244947*var_420 + 0.0000306836021121735397503*var_96 + -0.0002426145283288140390172*var_62 + 0.0000076709005280433849376*var_421 + 0.0001498501498501498500199*var_169 + 0.0000237262737262737262531*var_67 + -0.0000144498358784073059982*var_73 + var_184 + 0.0000185528756957328371218*var_100 + 0.0001569858712715855610358*var_192 + 0.0000035678607107178533904*var_171 + 0.0000749250749250749250099*var_172 + 0.0000117739403453689160612*var_177 + var_343 + 0.0000181068931068931068774*var_68 + 0.0000378193235336092439900*var_92 + 0.0000999000999000999000133*var_176 + 0.0000742115027829313484873*var_191 + 0.0000506636220921935197530*var_91 + 0.0000224775224775224775030*var_157 + 0.0000137362637362637362518*var_179 + 0.0000055747823604966458431*var_52 + 0.0000058869701726844580306*var_167 + -0.0000074033109747395462827*var_70 + 0.0000008919651776794633476*var_219 + 0.0000235478806907378321225*var_77 + 0.0000107035821321535597477*var_76 + 0.0000811688311688311687608*var_156 + 0.0000005351791066076780509*var_228 + var_419 + -0.0001084629656058227505219*var_55 + -0.0000685029256457827905166*var_65; + A[45] = 3.0000000000000000000000000*var_11*var_422; + const double var_423 = var_225 + var_172; + const double var_424 = var_99 + var_80; + const double var_425 = var_259 + var_264; + const double var_426 = -0.0000122496551067979636882*var_38 + 0.0000022464308178593891247*var_263 + 0.0000023785738071452355936*var_126 + 0.0000093292950435807585037*var_242 + 0.0000103913943199657475601*w[0][0]*w[1][0]*w[2][0] + -0.0000061975061975061977832*var_249 + 0.0000277037777037777048831*var_258 + 0.0000031978603407174839550*var_298 + -0.0000050742907885765032208*var_247 + -0.0000320314606028891752580*var_255 + 0.0000012685726971441258052*var_248 + 0.0000062701848416134137222*var_244 + 0.0000017442874585731727969*var_254 + 0.0000002907145764288621681*var_152 + 0.0000116550116550116550015*var_425 + 0.0001033688533688533687637*var_256 + 0.0000007333935905364477543*var_39 + 0.0000024050024050024051415*var_250 + -0.0000086950086950086961305*var_243 + 0.0000233100233100233100031*var_424 + 0.0000124478695907267338151*var_253 + -0.0000007845989988847131445*var_251 + -0.0000054641126069697503465*var_261 + -0.0000025503596932168361726*var_252 + 0.0000437525437525437479883*var_257 + -0.0000108885823171537453124*var_246 + 0.0000830915116629402420410*w[0][3]*w[1][3]*w[2][3] + var_47 + -0.0000032771461342889913282*var_245; + A[12] = var_11*var_426; + A[21] = A[12]; + const double var_427 = var_171 + var_168; + const double var_428 = 0.0001998001998001998000265*var_214 + 0.0000049355406498263644708*var_23 + -0.0000065113457970600824057*w[0][2]*w[1][2]*w[2][2] + -0.0000192664478378764102563*var_28 + -0.0000135578707007278438152*var_1; + A[50] = A[5]; + const double var_429 = 0.0001071844821844821843892*var_70 + var_399 + 0.0000000297321725893154469*var_71 + 0.0000799200799200799200106*var_65 + var_407 + 0.0000127253698682270113151*var_83 + 0.0000572344322344322343826*var_53 + 0.0000320512820512820512543*var_73 + 0.0000666000666000666000088*var_64 + 0.0001598401598401598400212*var_62 + 0.0001027543884686741789986*var_56 + 0.0000058275058275058275008*var_74 + 0.0000262237762237762237535*var_50 + 0.0000599400599400599400080*var_80 + 0.0000323486037771752047505*var_58 + 0.0000137957280814423676287*var_79 + 0.0000999000999000999000133*var_55 + 0.0000392464678178963902590*var_59 + 0.0000069573283858998143442*var_88 + var_360 + var_404; + const double var_430 = var_66 + var_147; + const double var_431 = 0.0004852290566576280780343*var_129 + -0.0000660054231482802930163*var_15 + var_122 + 0.0000246777032491318181189*var_23 + -0.0002295323723895152309704*var_28 + -0.0002372627372627372625315*w[0][2]*w[1][2]*w[2][2] + -0.0001462822891394319809594*var_1; + const double var_432 = 0.0000570857713714856542463*var_61 + -0.0002354788069073783551063*var_79 + 0.0006671899529042385869684*var_99 + 0.0002319109461966604860458*var_168 + -0.0000678636839351125074503*var_53 + -0.0000680866752295323742665*var_59 + -0.0006457827886399314810256*var_80 + 0.0000912777698491984147396*var_32 + 0.0002925645782788639619187*var_96 + 0.0003853289567575281780211*var_62 + 0.0000234884163455592007456*var_30 + 0.0000596873364730507558092*var_67 + 0.0000052031302031302031257*var_208 + -0.0000585723800009514285040*var_50 + -0.0000906831263974121077470*var_73 + -0.0001171447600019028570080*var_58 + 0.0001748251748251748250232*var_162 + 0.0000202178773607345021221*var_68 + -0.0000321107463964606792430*var_92 + 0.0001034679606108177419687*var_91 + 0.0000582750582750582750077*var_157 + var_233 + 0.0000145687645687645687519*var_179 + 0.0000322594072594072593793*var_52 + 0.0003725441225441225709045*var_82 + 0.0000193259121830550416332*var_167 + var_166 + -0.0000959605870320156043290*var_70 + -0.0001676894534037391140072*var_76 + var_385 + var_431 + 0.0010560867703724846882601*var_55 + 0.0002140716426430712220584*var_65 + -0.0000963322391893820445053*var_85; + A[3] = 0.2000000000000000111022302*var_11*var_432; + A[30] = A[3]; + const double var_433 = var_369 + 0.0000342514628228913952583*var_212 + -0.0000627943485086342189933*var_381 + -0.0002683031254459826040956*var_21 + 0.0000353218210361067464897*var_22 + var_301 + -0.0001848151848151848150245*var_19; + const double var_434 = 0.0002711574140145568559759*var_129 + 0.0005244755244755244750696*var_113 + -0.0000021407164264307122036*var_15 + 0.0000412087912087912087555*var_23 + 0.0000285428856857428271232*var_94 + 0.0002247752247752247750298*var_28; + const double var_435 = 0.0000499500499500499500066*var_88 + 0.0003996003996003996000530*var_62; + const double var_436 = 0.0001370058512915655810332*var_55; + const double var_437 = var_83 + var_80; + const double var_438 = var_64 + var_223; + const double var_439 = 0.0001113172541743970295073*var_438 + 0.0007992007992007992001060*var_61 + 0.0000171257314114456976291*var_275 + var_349 + var_434 + 0.0008991008991008991001193*var_79 + 0.0000884829456258027705192*var_203 + -0.0000041030398173255311237*var_53 + 0.0001810689310689310687740*var_59 + 0.0000214071642643071194953*var_95 + var_436 + -0.0000511988011988011987568*var_32 + -0.0000413871842443270994980*var_96 + 0.0000165905523048380186253*var_71 + 0.0004281432852861424441168*var_161 + -0.0000611888111888111887581*var_30 + -0.0000032110746396460680937*var_50 + 0.0000203368060510917648758*var_73 + 0.0005432067932067931792170*var_58 + 0.0001048951048951048950139*var_218 + var_355 + 0.0000199800199800199800027*var_86 + -0.0001312972741544169959574*var_92 + 0.0000153418010560867698752*var_89 + 0.0000271157414014556876305*var_204 + 0.0000239046667618096169957*var_82 + 0.0001498501498501498500199*var_437 + var_433 + 0.0000084736691879549017492*var_70 + -0.0000642214927929213584860*var_77 + 0.0000487012987012987012565*var_217 + -0.0000206935921221635497490*var_49 + 0.0004566861709718852339705*var_56 + 0.0000313971742543171094967*var_74 + var_435 + 0.0000399600399600399600053*var_85; + A[66] = 3.0000000000000000000000000*var_11*var_439; + const double var_440 = var_76 + var_61; + const double var_441 = -0.5000000000000000000000000*var_32 + var_295 + var_223; + const double var_442 = 0.0000699300699300699300093*var_275 + 0.0000536963036963036962571*var_53 + 0.0000299700299700299700040*var_168 + 0.0000999000999000999000133*var_203 + 0.0005994005994005994000795*var_190 + var_374 + 0.0006993006993006993000928*var_95 + 0.0001198801198801198800159*var_80 + -0.0004795204795204795200636*var_62 + 0.0000437062937062937062558*var_208 + 0.0001298701298701298700172*var_50 + 0.0000049950049950049950007*var_189 + 0.0002997002997002997000398*var_171 + 0.0002397602397602397600318*var_440 + 0.0000874125874125874125116*var_177 + var_213 + 0.0002622377622377622375348*var_88 + 0.0000280969030969030968787*var_68 + 0.0001798201798201798200239*var_92 + 0.0000324675324675324675043*var_176 + 0.0000899100899100899100119*var_441 + var_319 + 0.0000012487512487512487502*var_70 + -0.0000024975024975024975003*var_195 + 0.0011988011988011988001590*var_56 + 0.0007992007992007992001060*var_211 + var_304 + 0.0003596403596403596400477*var_423 + 0.0015984015984015984002120*var_65 + 0.0001748251748251748250232*var_83 + var_413; + A[67] = 3.0000000000000000000000000*var_11*var_196; + const double var_443 = 0.0000035678607107178533904*var_212 + -0.0000112387612387612387515*var_25 + var_183 + 0.0000706436420722134929794*var_21 + -0.0000130226915941201648114*var_22 + -0.0006564863707720849797869*var_24 + 0.0000269373483659197934998*var_19; + const double var_444 = 0.0000112387612387612387515*var_113 + 0.0001427144284287141390039*var_214 + 0.0000242614528328814052570*var_15 + -0.0000108819751676894538783*var_23 + 0.0000306836021121735397503*var_28 + 0.0000406736121021835297516*var_1; + const double var_445 = 0.0000005351791066076780509*var_312 + 0.0000742115027829313484873*var_220 + -0.0001084629656058227505219*var_61 + 0.0001127443984586841689999*var_79 + var_187 + 0.0000428143285286142389907*var_293 + 0.0000076709005280433849376*var_391 + 0.0000306836021121735397503*var_80 + 0.0000224775224775224775030*var_178 + var_444 + 0.0000185528756957328371218*var_96 + 0.0000237262737262737262531*var_71 + 0.0001498501498501498500199*var_161 + -0.0000144498358784073059982*var_30 + 0.0000004905808477237048359*var_67 + 0.0000008919651776794633476*var_292 + 0.0000137362637362637362518*var_177 + 0.0000235478806907378321225*var_86 + 0.0000749250749250749250099*var_162 + -0.0000164121592693021244947*var_118 + 0.0001569858712715855610358*var_387 + -0.0000074033109747395462827*var_68 + 0.0000019623233908948193435*var_176 + 0.0000107035821321535597477*var_91 + 0.0000999000999000999000133*var_157 + 0.0000035678607107178533904*var_204 + 0.0000811688311688311687608*var_179 + 0.0000181068931068931068774*var_52 + var_443 + 0.0000055747823604966458431*var_70 + 0.0000058869701726844580306*var_219 + 0.0000378193235336092439900*var_77 + 0.0000117739403453689160612*var_156 + -0.0002426145283288140390172*var_56 + -0.0000685029256457827905166*var_55 + 0.0000506636220921935197530*var_85; + const double var_446 = var_249 + -1.0000000000000000000000000*var_250 + -0.6428571428571427937015414*var_39; + const double var_447 = var_1 + var_149; + const double var_448 = 0.0000092434021005449580025*var_145 + -0.0000018962518962518963208*var_134 + 0.0000189625189625189602438*var_22 + 0.0001167086881372595715380*w[0][4]*w[1][4]*w[2][4] + -0.0000070300070300070302833*var_142 + -0.0000210900210900210900028*var_447 + var_356 + -0.0000140600140600140605666*var_144 + -0.0000031053602482173907492*var_19 + 0.0000005550005550005550001*var_28 + 0.0000703000703000702909743*var_136 + 0.0000016187516187516188208*var_140 + 0.0018779831279831279543940*w[0][1]*w[1][1]*w[2][1] + 0.0003704628704628704625491*var_133 + -0.0000878750878750878704941*var_139 + -0.0000151700151700151705667*var_21 + 0.0000117739403453689160612*var_113 + 0.0000167887667887667887522*var_146 + 0.0000054112554112554112507*var_23 + 0.0000758500758500758409750*var_131 + 0.0000421800421800421800056*var_132 + 0.0000379250379250379204875*var_202 + -0.0000020085734371448657347*var_135 + 0.0000056887556887556887508*var_138 + 0.0002109002109002109000280*var_129 + 0.0001517001517001516819501*var_141 + 0.0000444000444000444000059*var_137 + 0.0000013742870885728029380*var_276; + const double var_449 = var_225 + var_84 + var_204; + const double var_450 = 0.2000000000000000111022302*var_204 + var_162; + const double var_451 = var_327 + 0.0001195233338090480849783*var_39 + var_127 + -0.0005565862708719851881939*var_40 + 0.0001355787070072784279880*var_124 + -0.0002559940059940060208890*var_38; + const double var_452 = 0.0010846296560582274239037*w[0][5]*w[1][5]*w[2][5] + 0.0001195233338090480849783*var_22 + -0.0002091658341658341792053*var_69 + var_301 + 0.0005565862708719851881939*var_430 + 0.0001712573141144569559627*var_449 + -0.0006564863707720849797869*var_101 + -0.0002559940059940060208890*var_19 + 0.0000999000999000999000133*var_87 + 0.0009133723419437704679411*var_57 + var_451 + 0.0000466051805337519613149*var_72 + 0.0019980019980019980002650*var_63 + 0.0011238761238761239835693*var_81 + -0.0000303268160411017548771*var_54 + 0.0001016840302554588209910*var_75 + 0.0048076923076923079591882*var_342 + 0.0007492507492507492500994*var_34 + 0.0000713572142143570695020*var_332 + -0.0004424147281290138119386*var_93 + 0.0001070358213215356110292*var_94 + 0.0009053446553446553709751*var_60 + 0.0000784929356357927805179*var_90 + 0.0001355787070072784279880*var_212 + 0.0000338946767518196069970*var_337; + A[46] = 0.6000000000000000888178420*var_11*var_452; + const double var_453 = var_428 + 0.0000049355406498263644708*var_59 + 0.0000597022025593454145004*var_99 + -0.0000308619951477094304928*var_53 + var_155 + 0.2000000000000000111022302*var_235 + 0.0001748251748251748250232*var_450 + 0.0001612673041244469659614*var_96 + 0.0000264319014319014318785*var_71 + 0.0000513771942343370894993*var_62 + 0.0000463821892393320944986*var_169 + 0.0000041179059036201898149*var_67 + -0.0000160553731982303396215*var_50 + -0.0000132010846296560572480*var_73 + 0.0000970458113315256210279*var_64 + 0.0000185528756957328371218*var_172 + -0.0000292564578278864002576*var_86 + -0.0001852314352314352312746*var_88 + -0.0000038057180914323772039*var_68 + 0.0001073926073926073925142*var_89 + 0.0001144688644688644687652*var_157 + 0.0000514069264069264068818*var_52 + 0.0000582750582750582750077*var_201 + -0.0000143160411017553879413*var_70 + 0.0000135578707007278438152*var_77 + 0.0000203962703962703962527*var_49 + 0.0000023191094619666046402*var_156 + 0.0000333000333000333000044*var_56 + var_198 + 0.0000087412587412587412512*var_74 + 0.0000000594643451786308938*var_188 + -0.0000097521526092954661879*var_85; + const double var_454 = -0.0000065113457970600824057*w[0][1]*w[1][1]*w[2][1] + 0.0001998001998001998000265*var_181 + -0.0000135578707007278438152*var_21 + 0.0000049355406498263644708*var_22 + -0.0000192664478378764102563*var_98; + const double var_455 = 0.0000970458113315256210279*var_61 + 0.0001612673041244469659614*var_79 + -0.0000038057180914323772039*var_53 + 0.0000463821892393320944986*var_203 + 0.0000597022025593454145004*var_80 + 0.0000023191094619666046402*var_178 + 0.0000582750582750582750077*var_450 + -0.0000132010846296560572480*var_32 + 0.0000514069264069264068818*var_71 + -0.0000160553731982303396215*var_30 + -0.0000143160411017553879413*var_67 + 0.0001073926073926073925142*var_58 + -0.0000308619951477094304928*var_68 + -0.0000292564578278864002576*var_91 + 0.0001144688644688644687652*var_179 + 0.0000264319014319014318785*var_52 + 0.0000049355406498263644708*var_82 + 0.0001748251748251748250232*var_201 + 0.0000041179059036201898149*var_70 + 0.0000000594643451786308938*var_219 + 0.2000000000000000111022302*var_210 + -0.0000097521526092954661879*var_77 + 0.0000087412587412587412512*var_49 + var_198 + 0.0000185528756957328371218*var_211 + 0.0000203962703962703962527*var_74 + 0.0000513771942343370894993*var_55 + 0.0000333000333000333000044*var_65 + var_454 + var_347 + 0.0000135578707007278438152*var_85 + -0.0001852314352314352312746*var_83; + A[6] = var_11*var_455; + A[60] = A[6]; + const double var_456 = var_162 + var_168; + const double var_457 = var_171 + -0.5000000000000000000000000*var_74 + var_421; + const double var_458 = 0.0006993006993006993000928*var_99 + 0.0000899100899100899100119*var_457 + var_320 + 0.0001298701298701298700172*var_32 + 0.0000299700299700299700040*var_180 + 0.0007992007992007992001060*var_169 + 0.0000699300699300699300093*var_321 + 0.0000536963036963036962571*var_67 + var_359 + 0.0011988011988011988001590*var_64 + 0.0001198801198801198800159*var_100 + 0.0005994005994005994000795*var_192 + 0.0000999000999000999000133*var_172 + 0.0000437062937062937062558*var_271 + 0.0000012487512487512487502*var_68 + var_305 + 0.0001748251748251748250232*var_89 + 0.0003596403596403596400477*var_456 + 0.0000324675324675324675043*var_157 + 0.0002997002997002997000398*var_204 + 0.0000280969030969030968787*var_52 + 0.0002622377622377622375348*var_82 + 0.0001798201798201798200239*var_77 + 0.0000874125874125874125116*var_156 + 0.0002397602397602397600318*var_207 + -0.0004795204795204795200636*var_56 + var_435 + -0.0000024975024975024975003*var_341 + 0.0015984015984015984002120*var_55 + 0.0000049950049950049950007*var_188 + var_128; + A[39] = 1.2857142857142855874030829*var_11*var_458; + A[93] = A[39]; + A[11] = var_11*var_448; + const double var_459 = 0.0002985110127967270589495*var_36 + 0.0000389491460920032299864*var_39 + 0.0003139717425431711220717*var_41 + 0.0004745254745254745250629*var_42 + 0.0000035678607107178533904*var_40 + 0.0000597616669045240424892*var_38; + const double var_460 = 0.0001855287569573283779946*var_62; + const double var_461 = 0.0000484634413205841757489*var_30 + var_460 + 0.0006279434850863422441433*var_56 + 0.0000392464678178963902590*var_92 + 0.0002788877788877788875370*var_83; + const double var_462 = 0.0002140716426430712220584*var_61 + 0.0000596873364730507558092*var_53 + 0.0002319109461966604860458*var_225 + -0.0002354788069073783551063*var_99 + var_123 + 0.0006671899529042385869684*var_95 + -0.0006457827886399314810256*var_96 + -0.0000678636839351125074503*var_71 + var_461 + 0.0000912777698491984147396*var_50 + 0.0000234884163455592007456*var_73 + 0.0003853289567575281780211*var_64 + 0.0002925645782788639619187*var_100 + 0.0000193259121830550416332*var_292 + 0.0001748251748251748250232*var_172 + -0.0000321107463964606792430*var_86 + 0.0003725441225441225709045*var_88 + var_459 + 0.0000322594072594072593793*var_68 + -0.0000680866752295323742665*var_89 + 0.0000582750582750582750077*var_176 + -0.0000963322391893820445053*var_91 + -0.0000959605870320156043290*var_52 + -0.0001171447600019028570080*var_82 + 0.0000202178773607345021221*var_70 + 0.0000052031302031302031257*var_217 + -0.0000906831263974121077470*var_49 + 0.0001034679606108177419687*var_76 + 0.0000145687645687645687519*var_156 + -0.0000585723800009514285040*var_74 + 0.0000570857713714856542463*var_55 + var_232 + 0.0010560867703724846882601*var_65 + -0.0001676894534037391140072*var_85; + A[27] = 0.2000000000000000111022302*var_11*var_462; + A[72] = A[27]; + A[79] = 1.2857142857142855874030829*var_11*var_442; + const double var_463 = var_276 + var_240 + var_332; + const double var_464 = var_60 + var_133 + var_244; + const double var_465 = var_340 + var_281 + var_334; + const double var_466 = var_51 + var_134 + var_245; + const double var_467 = var_250 + var_39; + const double var_468 = var_255 + var_41; + const double var_469 = var_261 + var_38 + 0.1875000000000000000000000*var_43 + -1.5000000000000000000000000*var_344; + const double var_470 = 0.0249350649350649350433073*var_45 + 0.0009740259740259740251292*var_466 + 0.0311688311688311688041342*var_288 + 0.0002597402597402597400345*var_469 + -0.0093506493506493506412403*var_277 + 0.0038961038961038961005168*var_300 + 0.0062337662337662337608268*var_465 + 0.0021428571428571429637044*var_467 + 0.0519480519480519514763373*var_468 + 0.0051948051948051948006890*var_463 + 0.0022727272727272726168812*var_464; + A[99] = 0.2967032967032967039067159*var_11*var_470; + const double var_471 = var_114 + 0.0010052447552447551625682*var_25 + 0.0000399600399600399600053*var_21 + 0.0000145687645687645687519*var_22 + 0.0001165501165501165500155*var_98 + 0.0000070167927310784457211*var_19; + const double var_472 = 0.0000233100233100233100031*var_77 + 0.0000349650349650349650046*var_91 + 0.0000044598258883973168439*var_32 + 0.0000285428856857428271232*var_92 + var_324 + 0.0000001189286903572617876*var_49 + 0.0001165501165501165500155*var_96 + var_412 + 0.0000262237762237762237535*var_67 + 0.0000049950049950049950007*var_420 + 0.0000114171542742971311881*var_85 + -1.0000000000000000000000000*var_429 + 0.0000012487512487512487502*var_30 + 0.0000066451405737120021567*var_68 + var_364 + 0.0000256885971171685447497*var_100 + 0.0004578754578754578750607*var_82 + 0.0000083250083250083250011*var_52 + var_471 + 0.0000166500166500166500022*var_76 + 0.0002289377289377289375304*var_89; + const double var_473 = var_181 + var_214; + const double var_474 = var_40 + var_370; + const double var_475 = var_41 + 0.3699999999999999955591079*var_474 + 0.0924999999999999988897770*var_245 + -0.0184374999999999990285549*var_251 + -0.4800000000000000377475828*var_247 + 0.2850000000000000310862447*var_298 + -1.0000000000000000000000000*var_248 + 0.2650000000000000133226763*var_263 + 0.0250000000000000013877788*var_340 + -0.0762499999999999983346655*var_244 + 0.1700000000000000122124533*var_252 + 1.7000000000000001776356839*var_473 + 0.1087499999999999994448885*var_261 + 0.3549999999999999822364316*var_253; + const double var_476 = var_171 + var_146 + var_180; + const double var_477 = var_137 + var_94; + const double var_478 = 0.0000784929356357927805179*var_145 + 0.0010846296560582274239037*w[0][4]*w[1][4]*w[2][4] + 0.0001070358213215356110292*var_147 + -0.0004424147281290138119386*var_144 + -0.0002559940059940060208890*var_15 + 0.0048076923076923079591882*var_289 + 0.0001712573141144569559627*var_476 + 0.0019980019980019980002650*var_136 + 0.0001016840302554588209910*var_140 + 0.0001355787070072784279880*var_158 + 0.0009053446553446553709751*var_133 + var_451 + -0.0002091658341658341792053*var_139 + 0.0005565862708719851881939*var_477 + 0.0001195233338090480849783*var_23 + 0.0007492507492507492500994*var_131 + 0.0009133723419437704679411*var_132 + -0.0006564863707720849797869*var_149 + -0.0000303268160411017548771*var_135 + 0.0000466051805337519613149*var_138 + 0.0000999000999000999000133*var_143 + var_318 + 0.0011238761238761239835693*var_141 + 0.0000338946767518196069970*var_175 + 0.0000713572142143570695020*var_276; + A[38] = 0.6000000000000000888178420*var_11*var_478; + A[83] = A[38]; + const double var_479 = var_168 + var_61; + const double var_480 = var_99 + var_88; + const double var_481 = -0.0000413871842443270994980*var_79 + 0.0000239046667618096169957*var_59 + 0.0000203368060510917648758*var_32 + var_165 + 0.0008991008991008991001193*var_96 + 0.0000271157414014556876305*var_180 + 0.0000884829456258027705192*var_169 + 0.0000487012987012987012565*var_321 + -0.0000032110746396460680937*var_30 + 0.0000084736691879549017492*var_67 + 0.0000171257314114456976291*var_208 + -0.0000611888111888111887581*var_50 + -0.0000511988011988011987568*var_73 + 0.0000153418010560867698752*var_58 + 0.0007992007992007992001060*var_64 + 0.0000214071642643071194953*var_100 + var_355 + 0.0004281432852861424441168*var_162 + 0.0001048951048951048950139*var_271 + 0.0001113172541743970295073*var_479 + -0.0000041030398173255311237*var_68 + var_221 + 0.0001498501498501498500199*var_480 + 0.0005432067932067931792170*var_89 + 0.0000199800199800199800027*var_91 + 0.0000165905523048380186253*var_52 + 0.0001810689310689310687740*var_82 + 0.0000399600399600399600053*var_77 + 0.0000313971742543171094967*var_49 + -0.0001312972741544169959574*var_76 + var_395 + var_409 + -0.0000206935921221635497490*var_74 + 0.0004566861709718852339705*var_65 + var_273 + -0.0000642214927929213584860*var_85; + A[56] = 0.4285714285714285476380780*var_11*var_384; + A[88] = 3.0000000000000000000000000*var_11*var_481; + const double var_482 = 0.0000585129156557728005153*var_36 + 0.0001392357642357642491960*w[0][0]*w[1][0]*w[2][0] + 0.0000092764378478664185609*var_39 + var_108 + var_153 + -0.0000068978640407211838144*var_40 + 0.0000174825174825174825023*var_38; + const double var_483 = var_428 + 0.0000513771942343370894993*var_61 + 0.0000514069264069264068818*var_53 + 0.0001612673041244469659614*var_95 + 0.0000582750582750582750077*var_352 + -0.0000143160411017553879413*var_71 + 0.0000185528756957328371218*var_169 + var_348 + -0.0000038057180914323772039*var_67 + 0.2000000000000000111022302*var_461 + 0.0000203962703962703962527*var_50 + 0.0000087412587412587412512*var_73 + 0.0000049355406498263644708*var_58 + 0.0000597022025593454145004*var_100 + 0.0000000594643451786308938*var_292 + 0.0000463821892393320944986*var_172 + 0.0001144688644688644687652*var_177 + -0.0000097521526092954661879*var_86 + 0.0001073926073926073925142*var_88 + 0.0000041179059036201898149*var_68 + -0.0001852314352314352312746*var_89 + 0.0000023191094619666046402*var_176 + var_482 + -0.0000308619951477094304928*var_52 + 0.0000264319014319014318785*var_70 + -0.0000160553731982303396215*var_49 + 0.0000135578707007278438152*var_76 + -0.0000132010846296560572480*var_74 + 0.0001748251748251748250232*var_353 + 0.0000333000333000333000044*var_55 + 0.0000970458113315256210279*var_65 + -0.0000292564578278864002576*var_85; + A[0] = var_11*var_266; + const double var_484 = var_58 + var_95; + const double var_485 = var_225 + var_55; + const double var_486 = 0.0000487012987012987012565*var_275 + 0.0004566861709718852339705*var_61 + -0.0000413871842443270994980*var_99 + 0.0000084736691879549017492*var_53 + 0.0000271157414014556876305*var_168 + 0.0000214071642643071194953*var_80 + 0.0001498501498501498500199*var_484 + -0.0000206935921221635497490*var_32 + 0.0000313971742543171094967*var_30 + 0.0001048951048951048950139*var_208 + 0.0000203368060510917648758*var_50 + -0.0000032110746396460680937*var_73 + var_362 + 0.0008991008991008991001193*var_100 + var_460 + 0.0004281432852861424441168*var_172 + 0.0001810689310689310687740*var_88 + 0.0000165905523048380186253*var_68 + 0.0000399600399600399600053*var_92 + var_397 + 0.0000239046667618096169957*var_89 + -0.0000642214927929213584860*var_91 + var_322 + 0.0000153418010560867698752*var_82 + var_373 + var_433 + -0.0000041030398173255311237*var_70 + 0.0000171257314114456976291*var_217 + -0.0000511988011988011987568*var_49 + 0.0000199800199800199800027*var_76 + 0.0007992007992007992001060*var_56 + 0.0000884829456258027705192*var_211 + -0.0000611888111888111887581*var_74 + 0.0001113172541743970295073*var_485 + -0.0001312972741544169959574*var_85 + 0.0005432067932067931792170*var_83; + A[35] = 3.0000000000000000000000000*var_11*var_338; + const double var_487 = 0.0002788877788877788875370*var_88 + var_398 + 0.0006279434850863422441433*var_65 + 0.0000484634413205841757489*var_50 + 0.0000392464678178963902590*var_76; + const double var_488 = 0.0000041179059036201898149*var_53 + 0.0000185528756957328371218*var_203 + 0.0000597022025593454145004*var_95 + 0.2000000000000000111022302*var_487 + 0.0000087412587412587412512*var_32 + -0.0000308619951477094304928*var_71 + 0.0000333000333000333000044*var_62 + 0.0000582750582750582750077*var_170 + 0.0000203962703962703962527*var_30 + 0.0000264319014319014318785*var_67 + 0.0000000594643451786308938*var_189 + -0.0001852314352314352312746*var_58 + 0.0000513771942343370894993*var_64 + 0.0001612673041244469659614*var_100 + 0.0001748251748251748250232*var_173 + 0.0000023191094619666046402*var_177 + 0.0000514069264069264068818*var_68 + 0.0000135578707007278438152*var_92 + 0.0000049355406498263644708*var_89 + 0.0001144688644688644687652*var_176 + -0.0000097521526092954661879*var_91 + var_482 + -0.0000143160411017553879413*var_52 + var_160 + -0.0000038057180914323772039*var_70 + -0.0000292564578278864002576*var_77 + -0.0000132010846296560572480*var_49 + 0.0000970458113315256210279*var_56 + 0.0000463821892393320944986*var_211 + -0.0000160553731982303396215*var_74 + var_454 + 0.0001073926073926073925142*var_83; + A[25] = var_11*var_488; + const double var_489 = 0.0001569858712715855610358*var_220 + 0.0000306836021121735397503*var_79 + 0.0001498501498501498500199*var_203 + 0.0000035678607107178533904*var_225 + 0.0000181068931068931068774*var_53 + 0.0000185528756957328371218*var_95 + 0.0001127443984586841689999*var_80 + 0.0000811688311688311687608*var_178 + var_444 + -0.0000144498358784073059982*var_32 + 0.0000055747823604966458431*var_71 + -0.0001084629656058227505219*var_62 + 0.0000058869701726844580306*var_351 + -0.0000074033109747395462827*var_67 + 0.0000428143285286142389907*var_192 + 0.0000999000999000999000133*var_177 + 0.0000506636220921935197530*var_86 + 0.0000076709005280433849376*var_226 + -0.0000164121592693021244947*var_365 + 0.0000742115027829313484873*var_387 + 0.0000004905808477237048359*var_68 + 0.0000107035821321535597477*var_92 + 0.0000117739403453689160612*var_176 + 0.0000137362637362637362518*var_157 + 0.0000224775224775224775030*var_179 + 0.0000237262737262737262531*var_70 + 0.0000378193235336092439900*var_76 + var_290 + 0.0000019623233908948193435*var_156 + -0.0000685029256457827905166*var_56 + 0.0000749250749250749250099*var_211 + var_419 + 0.0000005351791066076780509*var_341 + -0.0002426145283288140390172*var_55 + 0.0000008919651776794633476*var_188 + 0.0000235478806907378321225*var_85; + A[37] = 3.0000000000000000000000000*var_11*var_489; + A[73] = A[37]; + const double var_490 = var_65 + var_180; + const double var_491 = var_434 + 0.0004281432852861424441168*var_203 + 0.0005432067932067931792170*var_59 + 0.0000271157414014556876305*var_225 + 0.0001113172541743970295073*var_490 + -0.0000413871842443270994980*var_95 + 0.0008991008991008991001193*var_80 + var_396 + -0.0000611888111888111887581*var_32 + 0.0000214071642643071194953*var_96 + 0.0000084736691879549017492*var_71 + 0.0000884829456258027705192*var_161 + 0.0007992007992007992001060*var_62 + var_378 + var_209 + -0.0000511988011988011987568*var_30 + -0.0000206935921221635497490*var_50 + 0.0000313971742543171094967*var_73 + 0.0001810689310689310687740*var_58 + 0.0000487012987012987012565*var_218 + 0.0000399600399600399600053*var_86 + 0.0000171257314114456976291*var_271 + 0.0000153418010560867698752*var_88 + -0.0001312972741544169959574*var_91 + -0.0000041030398173255311237*var_52 + 0.0000165905523048380186253*var_70 + 0.0001048951048951048950139*var_217 + -0.0000032110746396460680937*var_49 + -0.0000642214927929213584860*var_76 + 0.0000203368060510917648758*var_74 + var_371 + 0.0004566861709718852339705*var_55 + 0.0001498501498501498500199*var_274 + 0.0000199800199800199800027*var_85 + var_306 + 0.0000239046667618096169957*var_83; + A[44] = 3.0000000000000000000000000*var_11*var_491; + const double var_492 = var_204 + var_180; + const double var_493 = 0.0204081632653061208204637*var_250 + 1.9285714285714283811046243*var_256 + -0.0867346938775510195585028*var_243 + -0.4693877551020407823401115*var_249 + var_262 + -1.0000000000000000000000000*var_251; + const double var_494 = -0.0001626944484087341190066*var_40 + -0.0000085628657057228488146*var_254 + 0.0000470957613814756642450*var_263 + 0.0000235478806907378321225*var_258 + 0.0000874125874125874125116*var_244 + 0.0000699300699300699300093*var_492 + 0.0000185528756957328371218*var_240 + 0.0000174825174825174825023*var_493 + 0.0000413871842443270994980*var_257 + 0.0001170258313115456010305*var_264 + 0.0003425146282289139119254*var_248 + 0.0000456686170971885247523*var_339 + 0.0000528043385186242289920*var_152 + var_315 + -0.0000267589553303839027573*var_252 + 0.0010732125017839304163825*w[0][3]*w[1][3]*w[2][3] + 0.0001998001998001998000265*var_417 + 0.0000349650349650349650046*var_39 + 0.0000039246467817896386871*var_245 + 0.0000313971742543171094967*var_316 + 0.0001498501498501498500199*var_42 + 0.0003996003996003996000530*var_473; + A[69] = 1.2857142857142855874030829*var_11*var_394; + A[97] = A[79]; + A[65] = A[56]; + const double var_495 = var_212 + var_161 + var_203; + A[22] = var_11*var_358; + A[17] = var_11*var_483; + const double var_496 = var_225 + var_223; + const double var_497 = var_28 + var_132; + const double var_498 = 1.9285714285714283811046243*var_113 + -1.0000000000000000000000000*var_139 + -0.4693877551020407823401115*var_138 + -0.0867346938775510195585028*var_135 + 0.0204081632653061208204637*var_23 + var_202; + const double var_499 = 0.0000413871842443270994980*var_145 + 0.0000349650349650349650046*var_22 + 0.0000039246467817896386871*var_134 + 0.0010732125017839304163825*w[0][4]*w[1][4]*w[2][4] + -0.0000085628657057228488146*var_142 + 0.0000528043385186242289920*var_144 + 0.0001998001998001998000265*var_285 + -0.0000267589553303839027573*var_140 + 0.0000874125874125874125116*var_133 + 0.0000174825174825174825023*var_498 + -0.0001626944484087341190066*var_21 + 0.0000235478806907378321225*var_146 + 0.0003996003996003996000530*var_214 + 0.0000456686170971885247523*var_497 + 0.0000470957613814756642450*var_1 + 0.0000313971742543171094967*var_199 + var_317 + 0.0001170258313115456010305*var_149 + 0.0001498501498501498500199*var_25 + 0.0003425146282289139119254*var_137 + 0.0000699300699300699300093*var_496 + 0.0000185528756957328371218*var_276; + A[96] = A[69]; + A[54] = A[45]; + A[52] = A[25]; + const double var_500 = var_57 + var_98; + const double var_501 = 0.0010732125017839304163825*w[0][5]*w[1][5]*w[2][5] + 0.0003425146282289139119254*var_66 + 0.0003996003996003996000530*var_181 + 0.0001170258313115456010305*var_101 + 0.0000456686170971885247523*var_500 + 0.0000235478806907378321225*var_84 + 0.0001998001998001998000265*var_287 + 0.0000470957613814756642450*var_21 + 0.0001498501498501498500199*var_113 + 0.0000349650349650349650046*var_23 + -0.0001626944484087341190066*var_1 + -0.0000085628657057228488146*var_78 + var_317 + 0.0000313971742543171094967*var_202 + 0.0000174825174825174825023*var_200 + -0.0000267589553303839027573*var_75 + 0.0000039246467817896386871*var_51 + 0.0000185528756957328371218*var_332 + 0.0000699300699300699300093*var_427 + 0.0000528043385186242289920*var_93 + 0.0000874125874125874125116*var_60 + 0.0000413871842443270994980*var_90; + const double var_502 = var_72 + var_284; + const double var_503 = 0.0924999999999999988897770*var_51 + 0.3549999999999999822364316*var_81 + var_129 + -1.0000000000000000000000000*var_66 + 1.7000000000000001776356839*var_181 + -0.0762499999999999983346655*var_60 + 0.1087499999999999994448885*var_19 + -0.1012500000000000066613381*var_23 + 0.2650000000000000133226763*var_21 + 0.0250000000000000013877788*var_334 + -0.4800000000000000377475828*var_63 + 0.1700000000000000122124533*var_75 + 0.2850000000000000310862447*var_87 + 0.3699999999999999955591079*var_3 + -0.0184374999999999990285549*var_69; + const double var_504 = 0.0001298701298701298700172*var_78 + 0.0001648351648351648350219*var_34 + 0.0001573426573426573425209*var_502 + 0.0013111888111888112418840*var_336 + 0.0006168831168831169367919*var_15 + 0.0005681818181818181542203*var_335 + var_239 + 0.0014423076923076923877565*var_267 + 0.0010489510489510489501391*var_332 + 0.0005244755244755244750696*var_495 + 0.0001966783216783216917036*var_54 + -0.0010989010989010989001458*var_57 + 0.0009990009990009990001325*var_503; + A[78] = 0.4285714285714285476380780*var_11*var_504; + const double var_505 = 0.0000058275058275058275008*var_32 + 0.0000799200799200799200106*var_61 + 0.0000572344322344322343826*var_71 + 0.0000999000999000999000133*var_65 + 0.0000320512820512820512543*var_49 + 0.0000599400599400599400080*var_96 + 0.0000000297321725893154469*var_67 + var_408 + 0.0001598401598401598400212*var_64 + 0.0001027543884686741789986*var_62 + 0.0000666000666000666000088*var_56 + 0.0000262237762237762237535*var_74 + 0.0000069573283858998143442*var_58 + 0.0000137957280814423676287*var_99 + var_403 + 0.0000127253698682270113151*var_59 + var_436 + 0.0000323486037771752047505*var_82 + 0.0001071844821844821843892*var_52 + var_361 + 0.0000392464678178963902590*var_89; + const double var_506 = 0.0000449550449550449550060*var_1 + var_406; + const double var_507 = -1.0000000000000000000000000*var_505 + 0.0000114171542742971311881*var_91 + 0.0000066451405737120021567*var_70 + 0.0000233100233100233100031*var_92 + 0.0000262237762237762237535*var_53 + 0.0002289377289377289375304*var_83 + 0.0000012487512487512487502*var_73 + 0.0000166500166500166500022*var_85 + var_506 + 0.0000001189286903572617876*var_30 + var_366 + 0.0000083250083250083250011*var_68 + var_411 + 0.0000049950049950049950007*var_294 + 0.0000044598258883973168439*var_50 + 0.0000256885971171685447497*var_80 + 0.0000285428856857428271232*var_86 + 0.0004578754578754578750607*var_88 + 0.0001165501165501165500155*var_100 + var_307 + 0.0000349650349650349650046*var_76; + const double var_508 = var_299 + var_211 + var_172; + const double var_509 = 0.0005681818181818181542203*var_415 + var_237 + 0.0010489510489510489501391*var_240 + 0.0001573426573426573425209*var_446 + 0.0013111888111888112418840*var_416 + 0.0001966783216783216917036*var_243 + -0.0014423076923076923877565*var_256 + 0.0001298701298701298700172*var_254 + 0.0005244755244755244750696*var_508 + 0.0006168831168831169367919*var_38 + -0.0010989010989010989001458*var_246 + 0.0001648351648351648350219*var_242 + 0.0009990009990009990001325*var_475; + A[34] = 0.4285714285714285476380780*var_11*var_509; + A[43] = A[34]; + A[87] = A[78]; + A[7] = var_11*var_507; + A[70] = A[7]; + A[71] = A[17]; + const double var_510 = -0.0002426145283288140390172*var_61 + 0.0000185528756957328371218*var_99 + 0.0000035678607107178533904*var_168 + 0.0000055747823604966458431*var_53 + 0.0000742115027829313484873*var_190 + 0.0001569858712715855610358*var_293 + 0.0000306836021121735397503*var_95 + 0.0000137362637362637362518*var_178 + -0.0000074033109747395462827*var_71 + -0.0000164121592693021244947*var_206 + 0.0000008919651776794633476*var_351 + 0.0000749250749250749250099*var_169 + 0.0000181068931068931068774*var_67 + 0.0000058869701726844580306*var_189 + -0.0000685029256457827905166*var_64 + 0.0001127443984586841689999*var_100 + 0.0000076709005280433849376*var_310 + 0.0001498501498501498500199*var_172 + 0.0000224775224775224775030*var_177 + var_343 + 0.0000428143285286142389907*var_387 + 0.0000237262737262737262531*var_68 + 0.0000506636220921935197530*var_92 + 0.0000811688311688311687608*var_176 + 0.0000378193235336092439900*var_91 + 0.0000117739403453689160612*var_157 + 0.0000019623233908948193435*var_179 + 0.0000004905808477237048359*var_52 + var_443 + 0.0000107035821321535597477*var_77 + 0.0000235478806907378321225*var_76 + 0.0000999000999000999000133*var_156 + -0.0001084629656058227505219*var_56 + 0.0000005351791066076780509*var_393 + -0.0000144498358784073059982*var_74 + var_291; + A[42] = A[24]; + A[75] = A[57]; + A[55] = 3.0000000000000000000000000*var_11*var_486; + A[19] = var_11*var_499; + A[36] = 3.0000000000000000000000000*var_11*var_510; + A[63] = A[36]; + A[13] = var_11*var_472; + A[31] = A[13]; + A[58] = 3.0000000000000000000000000*var_11*var_445; + A[85] = A[58]; + const double var_511 = 0.0000349650349650349650046*var_77 + 0.0000233100233100233100031*var_91 + 0.0000049950049950049950007*var_193 + 0.0000001189286903572617876*var_32 + var_359 + 0.0000114171542742971311881*var_92 + 0.0000066451405737120021567*var_71 + 0.0000044598258883973168439*var_49 + 0.0000083250083250083250011*var_67 + 0.0000285428856857428271232*var_85 + var_506 + 0.0000012487512487512487502*var_74 + -1.0000000000000000000000000*var_405 + 0.0000256885971171685447497*var_79 + 0.0001165501165501165500155*var_99 + 0.0000166500166500166500022*var_86 + var_119 + 0.0002289377289377289375304*var_82 + 0.0000262237762237762237535*var_52 + var_471 + 0.0004578754578754578750607*var_89; + A[18] = var_11*var_511; + A[81] = A[18]; + A[91] = A[19]; + const double var_512 = 0.0003853289567575281780211*var_61 + -0.0006457827886399314810256*var_79 + -0.0001171447600019028570080*var_59 + 0.0000322594072594072593793*var_53 + -0.0002354788069073783551063*var_80 + 0.0002925645782788639619187*var_95 + var_487 + 0.0000145687645687645687519*var_178 + 0.0000234884163455592007456*var_32 + -0.0000959605870320156043290*var_71 + 0.0000570857713714856542463*var_62 + 0.0000052031302031302031257*var_321 + 0.0000912777698491984147396*var_30 + 0.0000202178773607345021221*var_67 + var_269 + 0.0000193259121830550416332*var_189 + -0.0000680866752295323742665*var_58 + 0.0002140716426430712220584*var_64 + 0.0006671899529042385869684*var_100 + 0.0002319109461966604860458*var_171 + 0.0000582750582750582750077*var_177 + -0.0000963322391893820445053*var_86 + var_459 + 0.0000596873364730507558092*var_68 + 0.0001034679606108177419687*var_92 + -0.0000321107463964606792430*var_91 + -0.0000678636839351125074503*var_52 + -0.0001676894534037391140072*var_77 + -0.0000585723800009514285040*var_49 + 0.0010560867703724846882601*var_56 + 0.0001748251748251748250232*var_211 + var_431 + -0.0000906831263974121077470*var_74 + 0.0003725441225441225709045*var_83; + A[15] = 0.2000000000000000111022302*var_11*var_512; + A[51] = A[15]; + A[76] = A[67]; + A[9] = var_11*var_494; + A[64] = A[46]; + A[90] = A[9]; + A[74] = A[47]; + A[29] = var_11*var_501; + A[8] = var_11*var_453; + A[92] = A[29]; + A[53] = A[35]; + A[80] = A[8]; + } + + 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/mass_matrix_2d/mass_matrix_f3_p2_q3_quadrature.h b/mass_matrix_2d/mass_matrix_f3_p2_q3_quadrature.h new file mode 100644 index 0000000..3b02ab0 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f3_p2_q3_quadrature.h @@ -0,0 +1,5429 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F3_P2_Q3_QUADRATURE_H +#define __MASS_MATRIX_F3_P2_Q3_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p2_q3_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p2_q3_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f3_p2_q3_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p2_q3_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p2_q3_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p2_q3_quadrature_finite_element_1() + { + // 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f3_p2_q3_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p2_q3_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p2_q3_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_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 mass_matrix_f3_p2_q3_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p2_q3_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p2_q3_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_p2_q3_quadrature_dofmap_1() + { + // 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.0*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 mass_matrix_f3_p2_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 mass_matrix_f3_p2_q3_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f3_p2_q3_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Array of quadrature weights. + static const double W49[49] = {0.0036234660797264, 0.00715464377909735, 0.00824760301353097, 0.00693554275373524, 0.00429791008798315, 0.00177448507143835, 0.000337590756711431, 0.00782718664849641, 0.0154550176627367, 0.0178159604006788, 0.0149817292193919, 0.0092840787568901, 0.00383313257348533, 0.000729242610651687, 0.0106850106013168, 0.021097877818156, 0.0243208363749012, 0.0204517846225132, 0.0126738360020949, 0.00523266711568851, 0.000995500091625133, 0.0116960367644213, 0.0230941796709132, 0.0266220977213878, 0.0223869525046108, 0.0138730467715663, 0.00572778720065371, 0.00108969528483177, 0.0106850106013168, 0.021097877818156, 0.0243208363749012, 0.0204517846225133, 0.0126738360020949, 0.00523266711568852, 0.000995500091625133, 0.00782718664849641, 0.0154550176627367, 0.0178159604006788, 0.0149817292193919, 0.0092840787568901, 0.00383313257348533, 0.000729242610651687, 0.00362346607972641, 0.00715464377909737, 0.00824760301353099, 0.00693554275373526, 0.00429791008798316, 0.00177448507143835, 0.000337590756711432}; + // Quadrature points on the UFC reference element: (0.0248740323760607, 0.0224793864387125), (0.0225279156156636, 0.114679053160904), (0.0186827443488427, 0.265789822784589), (0.0139228951565961, 0.452846373669445), (0.00897290400671669, 0.64737528288683), (0.00458641254163789, 0.819759308263108), (0.00143165958133296, 0.943737439463078), (0.126329297019669, 0.0224793864387125), (0.114413927746761, 0.114679053160904), (0.0948852170128628, 0.265789822784589), (0.0707110745463253, 0.452846373669445), (0.045571246280295, 0.64737528288683), (0.0232932989499898, 0.819759308263108), (0.00727105865856026, 0.943737439463078), (0.29039930608799, 0.0224793864387125), (0.263008866575801, 0.114679053160904), (0.218117268350298, 0.265789822784589), (0.16254699001287, 0.452846373669445), (0.104756842708482, 0.64737528288683), (0.0535454404572833, 0.819759308263108), (0.0167143365694675, 0.943737439463078), (0.488760306780644, 0.0224793864387125), (0.442660473419548, 0.114679053160904), (0.367105088607705, 0.265789822784589), (0.273576813165278, 0.452846373669445), (0.176312358556585, 0.64737528288683), (0.0901203458684462, 0.819759308263108), (0.0281312802684611, 0.943737439463078), (0.687121307473297, 0.0224793864387125), (0.622312080263294, 0.114679053160904), (0.516092908865112, 0.265789822784589), (0.384606636317686, 0.452846373669445), (0.247867874404688, 0.64737528288683), (0.126695251279609, 0.819759308263108), (0.0395482239674546, 0.943737439463078), (0.851191316541618, 0.0224793864387125), (0.770907019092334, 0.114679053160904), (0.639324960202548, 0.265789822784589), (0.47644255178423, 0.452846373669445), (0.307053470832875, 0.64737528288683), (0.156947392786903, 0.819759308263108), (0.0489915018783619, 0.943737439463078), (0.952646581185227, 0.0224793864387125), (0.862793031223432, 0.114679053160904), (0.715527432866568, 0.265789822784589), (0.533230731173959, 0.452846373669445), (0.343651813106453, 0.64737528288683), (0.175654279195255, 0.819759308263108), (0.0548309009555892, 0.943737439463078) + + // Value of basis functions at quadrature points. + static const double FE0[49][6] = \ + {{0.862424436102575, -0.0236365974027701, -0.0214687408093905, 0.00223661194428196, 0.0856596425519242, 0.0947846476133797}, + {0.626030598232005, -0.0215129016516906, -0.0883764826931413, 0.0103339201299722, 0.395777151578119, 0.0777477144047362}, + {0.308431581502673, -0.0179846544760344, -0.124501362992863, 0.019862733238435, 0.760719638316469, 0.0534720644113193}, + {0.0354392941626712, -0.0135352011375129, -0.0427066973783121, 0.0252197303305777, 0.965886411764936, 0.0296964622576404}, + {-0.107458675803748, -0.00881187799408917, 0.190814230898777, 0.0232353450786585, 0.889886758897449, 0.0123342189229534}, + {-0.113945427596046, -0.0045443421816336, 0.52425133870491, 0.0150390174901693, 0.575976921626226, 0.00322249195637399}, + {-0.0488180455563859, -0.00142756028301924, 0.837543269825575, 0.00540444298987969, 0.206983896285125, 0.000313996738824818}, + {0.597861998170088, -0.0944111144487016, -0.0214687408093905, 0.0113592203449441, 0.0765370341512621, 0.430121602591798}, + {0.417688245079323, -0.0882328340218791, -0.0883764826931413, 0.0524835236096748, 0.353627548098416, 0.352809999927606}, + {0.178147849273431, -0.0768788081977068, -0.124501362992863, 0.100878100058905, 0.679704271496, 0.242649950362235}, + {-0.0224475414828926, -0.0607109624193334, -0.0427066973783121, 0.128085014746293, 0.863021127349221, 0.134759059185025}, + {-0.118489802931845, -0.0414177693052164, 0.190814230898777, 0.118006793808846, 0.795115310167261, 0.0559712373621772}, + {-0.10768242458169, -0.0222081433980425, 0.52425133870491, 0.0763795945376376, 0.514636344578758, 0.0146232901584272}, + {-0.0441911673657668, -0.00716532207052775, 0.837543269825575, 0.027447881122462, 0.184940458152543, 0.00142488033571425}, + {0.25715007489433, -0.121735792135218, -0.0214687408093906, 0.0261119928923436, 0.0617842616038626, 0.798158203554073}, + {0.152232570219964, -0.124661538780826, -0.0883764826931413, 0.120646431167342, 0.285464640540749, 0.654694379545912}, + {0.0166108722965938, -0.122966982845106, -0.124501362992863, 0.231893400404338, 0.548688971150566, 0.450275101986471}, + {-0.0887621069184766, -0.109703942088382, -0.0427066973783121, 0.294435259912846, 0.696670882182668, 0.250066604289657}, + {-0.124990908080892, -0.0828088505199825, 0.190814230898777, 0.271267962730938, 0.641854141245169, 0.10386342372599}, + {-0.0945918778860025, -0.0478112120697543, 0.52425133870491, 0.175577492919624, 0.415438446196772, 0.0271358121344515}, + {-0.0364200999294947, -0.0161555984755526, 0.837543269825575, 0.0630957807855735, 0.149292558489432, 0.00264408930446697}, + {-0.0109870318120258, -0.0109870318120257, -0.0214687408093905, 0.0439481272481031, 0.043948127248103, 0.955546549937236}, + {-0.0507638839635114, -0.0507638839635114, -0.0883764826931413, 0.203055535854046, 0.203055535854046, 0.783793178912073}, + {-0.097572796444363, -0.097572796444363, -0.124501362992863, 0.390291185777452, 0.390291185777452, 0.539064584326685}, + {-0.123888267761939, -0.123888267761939, -0.0427066973783121, 0.495553071047757, 0.495553071047757, 0.299377090806677}, + {-0.114140262997013, -0.114140262997013, 0.190814230898777, 0.456561051988053, 0.456561051988053, 0.124344191119143}, + {-0.0738769923895495, -0.0738769923895494, 0.52425133870491, 0.295507969558198, 0.295507969558198, 0.0324867069577935}, + {-0.0265485424093757, -0.0265485424093756, 0.837543269825575, 0.106194169637503, 0.106194169637503, 0.00316547571817094}, + {-0.121735792135218, 0.25715007489433, -0.0214687408093905, 0.0617842616038626, 0.0261119928923435, 0.798158203554073}, + {-0.124661538780826, 0.152232570219964, -0.0883764826931413, 0.285464640540749, 0.120646431167342, 0.654694379545913}, + {-0.122966982845106, 0.0166108722965939, -0.124501362992863, 0.548688971150566, 0.231893400404338, 0.450275101986471}, + {-0.109703942088382, -0.0887621069184766, -0.0427066973783121, 0.696670882182668, 0.294435259912846, 0.250066604289657}, + {-0.0828088505199825, -0.124990908080892, 0.190814230898777, 0.641854141245169, 0.271267962730938, 0.10386342372599}, + {-0.0478112120697543, -0.0945918778860025, 0.52425133870491, 0.415438446196772, 0.175577492919624, 0.0271358121344515}, + {-0.0161555984755526, -0.0364200999294947, 0.837543269825575, 0.149292558489432, 0.0630957807855734, 0.00264408930446697}, + {-0.0944111144487017, 0.597861998170089, -0.0214687408093906, 0.076537034151262, 0.011359220344944, 0.430121602591798}, + {-0.0882328340218791, 0.417688245079323, -0.0883764826931413, 0.353627548098416, 0.0524835236096748, 0.352809999927606}, + {-0.0768788081977066, 0.178147849273431, -0.124501362992863, 0.679704271496, 0.100878100058904, 0.242649950362234}, + {-0.0607109624193333, -0.0224475414828925, -0.0427066973783121, 0.863021127349221, 0.128085014746293, 0.134759059185025}, + {-0.0414177693052163, -0.118489802931845, 0.190814230898777, 0.795115310167261, 0.118006793808845, 0.0559712373621772}, + {-0.0222081433980425, -0.10768242458169, 0.52425133870491, 0.514636344578758, 0.0763795945376375, 0.0146232901584272}, + {-0.00716532207052781, -0.0441911673657667, 0.837543269825575, 0.184940458152543, 0.0274478811224619, 0.00142488033571425}, + {-0.0236365974027702, 0.862424436102575, -0.0214687408093906, 0.0856596425519241, 0.00223661194428187, 0.09478464761338}, + {-0.0215129016516907, 0.626030598232004, -0.0883764826931413, 0.395777151578119, 0.0103339201299722, 0.0777477144047368}, + {-0.0179846544760343, 0.308431581502674, -0.124501362992863, 0.760719638316469, 0.0198627332384348, 0.0534720644113193}, + {-0.013535201137513, 0.0354392941626711, -0.0427066973783121, 0.965886411764936, 0.0252197303305778, 0.0296964622576406}, + {-0.00881187799408919, -0.107458675803748, 0.190814230898777, 0.889886758897448, 0.0232353450786585, 0.0123342189229534}, + {-0.00454434218163365, -0.113945427596046, 0.52425133870491, 0.575976921626226, 0.0150390174901692, 0.00322249195637399}, + {-0.0014275602830193, -0.0488180455563859, 0.837543269825575, 0.206983896285125, 0.00540444298987969, 0.000313996738824845}}; + + static const double FE1[49][10] = \ + {{0.759259490549809, 0.0221590586807319, 0.0202565508334599, -0.00232842517935532, -0.00234650132061204, 0.179044261105492, -0.089868278171862, 0.198117184364795, -0.0986755707370276, 0.0143822298745689}, + {0.403169832432288, 0.020295583031815, 0.0622850658315548, -0.0108399544739676, -0.0076260010524023, 0.707224672483947, -0.292066992631152, 0.138929449658773, -0.0815548866260336, 0.060183231345177}, + {0.0601288715882343, 0.0171413871629327, 0.0323851163046929, -0.0210931449040643, -0.00452789572055771, 0.981256130427186, -0.17341315283902, 0.0689738878390519, -0.056784430894179, 0.0959332310357222}, + {-0.0640040756677871, 0.0130627287158153, -0.0520748014962052, -0.0271871272651127, 0.0101725424378916, 0.651638858584826, 0.389596573201606, 0.0200348286650143, -0.0320130900742899, 0.090773562898242}, + {-0.00515429610053729, 0.00861384643795105, -0.0176489825313883, -0.0254361144552718, 0.0246269466012943, 0.0309901900119197, 0.943183482680242, 0.00042953756109863, -0.0135024723402444, 0.0538978621349365}, + {0.061198066754193, 0.00449218837368866, 0.274707138662764, -0.0166861035842363, 0.024689369513165, -0.306515799699927, 0.94557420778192, -0.00171490325731424, -0.0035754220392769, 0.0178312574950235}, + {0.0420437794348034, 0.0014224493649266, 0.718243758548968, -0.00605388489987946, 0.0111337678992377, -0.194553625202202, 0.426410393158711, -0.000295139887384777, -0.000351729145693924, 0.00200023072851307}, + {0.366019955489299, 0.0635858397592476, 0.0202565508334599, -0.00793599005513186, -0.0119173223628164, 0.133769185243817, -0.0802974571296576, 0.7517539315772, -0.300499563967438, 0.0652648706120207}, + {0.158234646728241, 0.0622463008387584, 0.0622850658315548, -0.038777608547051, -0.0387306463807783, 0.522241119924781, -0.260962347302776, 0.521033755638225, -0.260674724708381, 0.273104437977427}, + {-0.0240696255023906, 0.0582150166968705, 0.0323851163046929, -0.0811829011624889, -0.0229961059271973, 0.701945378409426, -0.15494494263238, 0.250589879114876, -0.195275554613315, 0.435333739311908}, + {-0.0583655036819059, 0.049801839277281, -0.0520748014962052, -0.113528168626855, 0.0516639246766598, 0.416833691765261, 0.348105190962837, 0.065087764782121, -0.119443708738743, 0.41191977107955}, + {0.0130582576350319, 0.0366518011112075, -0.0176489825313883, -0.114607849295939, 0.12507440711047, -0.0705223834533175, 0.842736022171066, -0.00496434292377278, -0.0543591002641987, 0.244582170440841}, + {0.0634982330351343, 0.0209085718766358, 0.274707138662764, -0.0799224708936431, 0.125391438239775, -0.306364327912917, 0.84487213905531, -0.00870528191111183, -0.0153015931693676, 0.08091615301742}, + {0.0387198943189268, 0.00703488117358859, 0.718243758548968, -0.0302053001190503, 0.0565457602782775, -0.177478791461603, 0.380998400779671, -0.00136739165938145, -0.0015680240664827, 0.00907681220708495}, + {0.0223759175857751, 0.0211108763763082, 0.0202565508334599, -0.00378368892316171, -0.0273949291750587, 0.0737725345196537, -0.0648198503174152, 0.953028361840235, -0.11565499294401, 0.121109220204214}, + {-0.0358942747511902, 0.0335971702606884, 0.0622850658315548, -0.0286348362908939, -0.0890320226476534, 0.278414597642437, -0.210660971035901, 0.638525569803523, -0.155388486816179, 0.506788188003614}, + {-0.0639101497865511, 0.0507254467671889, 0.0323851163046929, -0.0901727271791658, -0.0528622683853314, 0.338438801699255, -0.125078780174246, 0.277735791976569, -0.175091373261166, 0.807830142038755}, + {-0.0250300738487932, 0.0629764585450424, -0.0520748014962053, -0.169713634674798, 0.118762379193389, 0.120557083126032, 0.281006736446109, 0.0432733750920395, -0.144139368149536, 0.764381845766722}, + {0.0399235182020919, 0.0605470656066382, -0.0176489825313883, -0.209268491422469, 0.287514629552574, -0.185140210770349, 0.680295799728962, -0.0299589812144173, -0.0801249870360447, 0.453860639884402}, + {0.063614187301803, 0.0413342706009022, 0.274707138662764, -0.165795041633989, 0.288243404445893, -0.289728237600496, 0.682020172849192, -0.0189246110887122, -0.0256239169827024, 0.150152633445345}, + {0.0327882963196601, 0.0154781884654098, 0.718243758548968, -0.0674234644917185, 0.129984492389545, -0.148027265853737, 0.307559668668404, -0.00262167997101521, -0.00282544504740342, 0.0168434509718876}, + {-0.0608171838969239, -0.0608171838969239, 0.0202565508334599, 0.0230536948731185, -0.046107389746237, 0.0230536948731185, -0.0461073897462371, 0.501247265326078, 0.501247265326078, 0.144990676054469}, + {-0.0487833107612748, -0.0487833107612748, 0.0622850658315548, 0.0749232484208884, -0.149846496841777, 0.0749232484208885, -0.149846496841777, 0.289203300009696, 0.289203300009696, 0.60672145251338}, + {-0.0167125477659761, -0.0167125477659761, 0.0323851163046929, 0.0444852621398943, -0.0889705242797887, 0.0444852621398941, -0.0889705242797887, 0.061442405613996, 0.0614424056139963, 0.967125692279056}, + {0.0289180452500466, 0.0289180452500465, -0.0520748014962053, -0.0999422789098743, 0.199884557819749, -0.0999422789098745, 0.199884557819749, -0.0603778494306703, -0.0603778494306701, 0.915109852037704}, + {0.0610889883577043, 0.0610889883577042, -0.0176489825313883, -0.241952607320384, 0.483905214640768, -0.241952607320384, 0.483905214640768, -0.0658956805785703, -0.0658956805785701, 0.543357152332352}, + {0.0568664779664872, 0.0568664779664872, 0.274707138662764, -0.242565894323771, 0.485131788647543, -0.242565894323771, 0.485131788647542, -0.026666513050842, -0.0266665130508418, 0.179761142858403}, + {0.0246703000807061, 0.0246703000807061, 0.718243758548968, -0.109386040264487, 0.218772080528974, -0.109386040264487, 0.218772080528975, -0.0032606201973806, -0.00326062019738041, 0.0201648011554063}, + {0.0211108763763083, 0.0223759175857751, 0.0202565508334599, 0.0737725345196536, -0.0648198503174152, -0.00378368892316169, -0.0273949291750588, -0.11565499294401, 0.953028361840235, 0.121109220204214}, + {0.0335971702606883, -0.0358942747511903, 0.0622850658315548, 0.278414597642436, -0.210660971035901, -0.0286348362908939, -0.0890320226476535, -0.155388486816179, 0.638525569803523, 0.506788188003614}, + {0.050725446767189, -0.0639101497865511, 0.0323851163046929, 0.338438801699255, -0.125078780174246, -0.0901727271791658, -0.0528622683853314, -0.175091373261166, 0.277735791976569, 0.807830142038755}, + {0.0629764585450424, -0.0250300738487932, -0.0520748014962053, 0.120557083126032, 0.281006736446109, -0.169713634674798, 0.118762379193389, -0.144139368149536, 0.0432733750920397, 0.764381845766722}, + {0.0605470656066382, 0.0399235182020918, -0.0176489825313883, -0.185140210770349, 0.680295799728962, -0.209268491422469, 0.287514629552574, -0.0801249870360449, -0.0299589812144171, 0.453860639884402}, + {0.0413342706009022, 0.0636141873018031, 0.274707138662764, -0.289728237600496, 0.682020172849192, -0.165795041633989, 0.288243404445893, -0.0256239169827026, -0.018924611088712, 0.150152633445345}, + {0.0154781884654098, 0.0327882963196601, 0.718243758548968, -0.148027265853737, 0.307559668668404, -0.0674234644917187, 0.129984492389545, -0.0028254450474036, -0.00262167997101501, 0.0168434509718876}, + {0.0635858397592477, 0.366019955489299, 0.0202565508334599, 0.133769185243817, -0.0802974571296575, -0.00793599005513192, -0.0119173223628164, -0.300499563967438, 0.7517539315772, 0.0652648706120206}, + {0.0622463008387585, 0.158234646728241, 0.0622850658315548, 0.522241119924781, -0.260962347302776, -0.038777608547051, -0.0387306463807782, -0.260674724708381, 0.521033755638225, 0.273104437977427}, + {0.0582150166968705, -0.0240696255023904, 0.0323851163046929, 0.701945378409426, -0.15494494263238, -0.0811829011624888, -0.0229961059271972, -0.195275554613315, 0.250589879114876, 0.435333739311907}, + {0.049801839277281, -0.0583655036819059, -0.0520748014962053, 0.416833691765261, 0.348105190962837, -0.113528168626855, 0.0516639246766597, -0.119443708738744, 0.0650877647821211, 0.41191977107955}, + {0.0366518011112075, 0.0130582576350319, -0.0176489825313883, -0.0705223834533175, 0.842736022171066, -0.11460784929594, 0.12507440711047, -0.0543591002641988, -0.00496434292377256, 0.244582170440841}, + {0.0209085718766358, 0.0634982330351343, 0.274707138662764, -0.306364327912917, 0.84487213905531, -0.0799224708936432, 0.125391438239775, -0.0153015931693678, -0.00870528191111163, 0.08091615301742}, + {0.00703488117358859, 0.0387198943189267, 0.718243758548968, -0.177478791461603, 0.380998400779671, -0.0302053001190505, 0.0565457602782777, -0.00156802406648289, -0.00136739165938125, 0.00907681220708495}, + {0.0221590586807319, 0.759259490549808, 0.0202565508334599, 0.179044261105492, -0.089868278171862, -0.00232842517935539, -0.00234650132061204, -0.098675570737028, 0.198117184364796, 0.0143822298745689}, + {0.0202955830318151, 0.403169832432288, 0.0622850658315548, 0.707224672483947, -0.292066992631152, -0.0108399544739676, -0.00762600105240233, -0.0815548866260342, 0.138929449658774, 0.0601832313451773}, + {0.0171413871629327, 0.0601288715882344, 0.0323851163046929, 0.981256130427186, -0.17341315283902, -0.0210931449040642, -0.00452789572055766, -0.0567844308941791, 0.0689738878390521, 0.0959332310357222}, + {0.0130627287158153, -0.0640040756677871, -0.0520748014962053, 0.651638858584826, 0.389596573201605, -0.0271871272651128, 0.0101725424378918, -0.0320130900742903, 0.0200348286650146, 0.0907735628982423}, + {0.00861384643795111, -0.00515429610053724, -0.0176489825313883, 0.0309901900119194, 0.943183482680241, -0.025436114455272, 0.0246269466012944, -0.0135024723402447, 0.000429537561098859, 0.0538978621349367}, + {0.00449218837368868, 0.0611980667541931, 0.274707138662764, -0.306515799699927, 0.94557420778192, -0.0166861035842365, 0.0246893695131651, -0.00357542203927705, -0.001714903257314, 0.0178312574950233}, + {0.00142244936492658, 0.0420437794348033, 0.718243758548968, -0.194553625202202, 0.426410393158711, -0.00605388489987951, 0.0111337678992375, -0.000351729145694105, -0.000295139887384555, 0.00200023072851302}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 100; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 16660 + for (unsigned int ip = 0; ip < 49; ip++) + { + + // Coefficient declarations. + double F0 = 0.0; + double F1 = 0.0; + double F2 = 0.0; + + // Total number of operations to compute function values = 36 + for (unsigned int r = 0; r < 6; r++) + { + F0 += FE0[ip][r]*w[2][r]; + F1 += FE0[ip][r]*w[0][r]; + F2 += FE0[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 4 + double I[1]; + // Number of operations: 4 + I[0] = F0*F1*F2*W49[ip]*det; + + + // Number of operations for primary indices: 300 + for (unsigned int j = 0; j < 10; j++) + { + for (unsigned int k = 0; k < 10; k++) + { + // Number of operations to compute entry: 3 + A[j*10 + k] += FE1[ip][j]*FE1[ip][k]*I[0]; + }// 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 mass_matrix_f3_p2_q3_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f3_p2_q3_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p2_q3_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1)))), 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 3; + } + + /// 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 mass_matrix_f3_p2_q3_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f3_p2_q3_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f3_p2_q3_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p2_q3_quadrature_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p2_q3_quadrature_finite_element_0(); + 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 mass_matrix_f3_p2_q3_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f3_p2_q3_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f3_p2_q3_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p2_q3_quadrature_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p2_q3_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f3_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/mass_matrix_2d/mass_matrix_f3_p2_q3_tensor.h b/mass_matrix_2d/mass_matrix_f3_p2_q3_tensor.h new file mode 100644 index 0000000..ae232b9 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f3_p2_q3_tensor.h @@ -0,0 +1,5598 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F3_P2_Q3_TENSOR_H +#define __MASS_MATRIX_F3_P2_Q3_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p2_q3_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p2_q3_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f3_p2_q3_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f3_p2_q3_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f3_p2_q3_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p2_q3_tensor_finite_element_1() + { + // 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f3_p2_q3_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p2_q3_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p2_q3_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_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 mass_matrix_f3_p2_q3_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f3_p2_q3_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f3_p2_q3_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f3_p2_q3_tensor_dofmap_1() + { + // 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.0*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 mass_matrix_f3_p2_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 mass_matrix_f3_p2_q3_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f3_p2_q3_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 432 + // Number of operations (multiply-add pairs) for tensor contraction: 10827 + // Total number of operations (multiply-add pairs): 11268 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0 = det*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_0_0_1 = det*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_0_0_2 = det*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_0_0_3 = det*w[2][0]*w[0][0]*w[1][3]*(1.0); + const double G0_0_0_4 = det*w[2][0]*w[0][0]*w[1][4]*(1.0); + const double G0_0_0_5 = det*w[2][0]*w[0][0]*w[1][5]*(1.0); + const double G0_0_1_0 = det*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_0_1_1 = det*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_0_1_2 = det*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_0_1_3 = det*w[2][0]*w[0][1]*w[1][3]*(1.0); + const double G0_0_1_4 = det*w[2][0]*w[0][1]*w[1][4]*(1.0); + const double G0_0_1_5 = det*w[2][0]*w[0][1]*w[1][5]*(1.0); + const double G0_0_2_0 = det*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_0_2_1 = det*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_0_2_2 = det*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_0_2_3 = det*w[2][0]*w[0][2]*w[1][3]*(1.0); + const double G0_0_2_4 = det*w[2][0]*w[0][2]*w[1][4]*(1.0); + const double G0_0_2_5 = det*w[2][0]*w[0][2]*w[1][5]*(1.0); + const double G0_0_3_0 = det*w[2][0]*w[0][3]*w[1][0]*(1.0); + const double G0_0_3_1 = det*w[2][0]*w[0][3]*w[1][1]*(1.0); + const double G0_0_3_2 = det*w[2][0]*w[0][3]*w[1][2]*(1.0); + const double G0_0_3_3 = det*w[2][0]*w[0][3]*w[1][3]*(1.0); + const double G0_0_3_4 = det*w[2][0]*w[0][3]*w[1][4]*(1.0); + const double G0_0_3_5 = det*w[2][0]*w[0][3]*w[1][5]*(1.0); + const double G0_0_4_0 = det*w[2][0]*w[0][4]*w[1][0]*(1.0); + const double G0_0_4_1 = det*w[2][0]*w[0][4]*w[1][1]*(1.0); + const double G0_0_4_2 = det*w[2][0]*w[0][4]*w[1][2]*(1.0); + const double G0_0_4_3 = det*w[2][0]*w[0][4]*w[1][3]*(1.0); + const double G0_0_4_4 = det*w[2][0]*w[0][4]*w[1][4]*(1.0); + const double G0_0_4_5 = det*w[2][0]*w[0][4]*w[1][5]*(1.0); + const double G0_0_5_0 = det*w[2][0]*w[0][5]*w[1][0]*(1.0); + const double G0_0_5_1 = det*w[2][0]*w[0][5]*w[1][1]*(1.0); + const double G0_0_5_2 = det*w[2][0]*w[0][5]*w[1][2]*(1.0); + const double G0_0_5_3 = det*w[2][0]*w[0][5]*w[1][3]*(1.0); + const double G0_0_5_4 = det*w[2][0]*w[0][5]*w[1][4]*(1.0); + const double G0_0_5_5 = det*w[2][0]*w[0][5]*w[1][5]*(1.0); + const double G0_1_0_0 = det*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_1_0_1 = det*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_1_0_2 = det*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_1_0_3 = det*w[2][1]*w[0][0]*w[1][3]*(1.0); + const double G0_1_0_4 = det*w[2][1]*w[0][0]*w[1][4]*(1.0); + const double G0_1_0_5 = det*w[2][1]*w[0][0]*w[1][5]*(1.0); + const double G0_1_1_0 = det*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_1_1_1 = det*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_1_1_2 = det*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_1_1_3 = det*w[2][1]*w[0][1]*w[1][3]*(1.0); + const double G0_1_1_4 = det*w[2][1]*w[0][1]*w[1][4]*(1.0); + const double G0_1_1_5 = det*w[2][1]*w[0][1]*w[1][5]*(1.0); + const double G0_1_2_0 = det*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_1_2_1 = det*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_1_2_2 = det*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_1_2_3 = det*w[2][1]*w[0][2]*w[1][3]*(1.0); + const double G0_1_2_4 = det*w[2][1]*w[0][2]*w[1][4]*(1.0); + const double G0_1_2_5 = det*w[2][1]*w[0][2]*w[1][5]*(1.0); + const double G0_1_3_0 = det*w[2][1]*w[0][3]*w[1][0]*(1.0); + const double G0_1_3_1 = det*w[2][1]*w[0][3]*w[1][1]*(1.0); + const double G0_1_3_2 = det*w[2][1]*w[0][3]*w[1][2]*(1.0); + const double G0_1_3_3 = det*w[2][1]*w[0][3]*w[1][3]*(1.0); + const double G0_1_3_4 = det*w[2][1]*w[0][3]*w[1][4]*(1.0); + const double G0_1_3_5 = det*w[2][1]*w[0][3]*w[1][5]*(1.0); + const double G0_1_4_0 = det*w[2][1]*w[0][4]*w[1][0]*(1.0); + const double G0_1_4_1 = det*w[2][1]*w[0][4]*w[1][1]*(1.0); + const double G0_1_4_2 = det*w[2][1]*w[0][4]*w[1][2]*(1.0); + const double G0_1_4_3 = det*w[2][1]*w[0][4]*w[1][3]*(1.0); + const double G0_1_4_4 = det*w[2][1]*w[0][4]*w[1][4]*(1.0); + const double G0_1_4_5 = det*w[2][1]*w[0][4]*w[1][5]*(1.0); + const double G0_1_5_0 = det*w[2][1]*w[0][5]*w[1][0]*(1.0); + const double G0_1_5_1 = det*w[2][1]*w[0][5]*w[1][1]*(1.0); + const double G0_1_5_2 = det*w[2][1]*w[0][5]*w[1][2]*(1.0); + const double G0_1_5_3 = det*w[2][1]*w[0][5]*w[1][3]*(1.0); + const double G0_1_5_4 = det*w[2][1]*w[0][5]*w[1][4]*(1.0); + const double G0_1_5_5 = det*w[2][1]*w[0][5]*w[1][5]*(1.0); + const double G0_2_0_0 = det*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_2_0_1 = det*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_2_0_2 = det*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_2_0_3 = det*w[2][2]*w[0][0]*w[1][3]*(1.0); + const double G0_2_0_4 = det*w[2][2]*w[0][0]*w[1][4]*(1.0); + const double G0_2_0_5 = det*w[2][2]*w[0][0]*w[1][5]*(1.0); + const double G0_2_1_0 = det*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_2_1_1 = det*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_2_1_2 = det*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_2_1_3 = det*w[2][2]*w[0][1]*w[1][3]*(1.0); + const double G0_2_1_4 = det*w[2][2]*w[0][1]*w[1][4]*(1.0); + const double G0_2_1_5 = det*w[2][2]*w[0][1]*w[1][5]*(1.0); + const double G0_2_2_0 = det*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_2_2_1 = det*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_2_2_2 = det*w[2][2]*w[0][2]*w[1][2]*(1.0); + const double G0_2_2_3 = det*w[2][2]*w[0][2]*w[1][3]*(1.0); + const double G0_2_2_4 = det*w[2][2]*w[0][2]*w[1][4]*(1.0); + const double G0_2_2_5 = det*w[2][2]*w[0][2]*w[1][5]*(1.0); + const double G0_2_3_0 = det*w[2][2]*w[0][3]*w[1][0]*(1.0); + const double G0_2_3_1 = det*w[2][2]*w[0][3]*w[1][1]*(1.0); + const double G0_2_3_2 = det*w[2][2]*w[0][3]*w[1][2]*(1.0); + const double G0_2_3_3 = det*w[2][2]*w[0][3]*w[1][3]*(1.0); + const double G0_2_3_4 = det*w[2][2]*w[0][3]*w[1][4]*(1.0); + const double G0_2_3_5 = det*w[2][2]*w[0][3]*w[1][5]*(1.0); + const double G0_2_4_0 = det*w[2][2]*w[0][4]*w[1][0]*(1.0); + const double G0_2_4_1 = det*w[2][2]*w[0][4]*w[1][1]*(1.0); + const double G0_2_4_2 = det*w[2][2]*w[0][4]*w[1][2]*(1.0); + const double G0_2_4_3 = det*w[2][2]*w[0][4]*w[1][3]*(1.0); + const double G0_2_4_4 = det*w[2][2]*w[0][4]*w[1][4]*(1.0); + const double G0_2_4_5 = det*w[2][2]*w[0][4]*w[1][5]*(1.0); + const double G0_2_5_0 = det*w[2][2]*w[0][5]*w[1][0]*(1.0); + const double G0_2_5_1 = det*w[2][2]*w[0][5]*w[1][1]*(1.0); + const double G0_2_5_2 = det*w[2][2]*w[0][5]*w[1][2]*(1.0); + const double G0_2_5_3 = det*w[2][2]*w[0][5]*w[1][3]*(1.0); + const double G0_2_5_4 = det*w[2][2]*w[0][5]*w[1][4]*(1.0); + const double G0_2_5_5 = det*w[2][2]*w[0][5]*w[1][5]*(1.0); + const double G0_3_0_0 = det*w[2][3]*w[0][0]*w[1][0]*(1.0); + const double G0_3_0_1 = det*w[2][3]*w[0][0]*w[1][1]*(1.0); + const double G0_3_0_2 = det*w[2][3]*w[0][0]*w[1][2]*(1.0); + const double G0_3_0_3 = det*w[2][3]*w[0][0]*w[1][3]*(1.0); + const double G0_3_0_4 = det*w[2][3]*w[0][0]*w[1][4]*(1.0); + const double G0_3_0_5 = det*w[2][3]*w[0][0]*w[1][5]*(1.0); + const double G0_3_1_0 = det*w[2][3]*w[0][1]*w[1][0]*(1.0); + const double G0_3_1_1 = det*w[2][3]*w[0][1]*w[1][1]*(1.0); + const double G0_3_1_2 = det*w[2][3]*w[0][1]*w[1][2]*(1.0); + const double G0_3_1_3 = det*w[2][3]*w[0][1]*w[1][3]*(1.0); + const double G0_3_1_4 = det*w[2][3]*w[0][1]*w[1][4]*(1.0); + const double G0_3_1_5 = det*w[2][3]*w[0][1]*w[1][5]*(1.0); + const double G0_3_2_0 = det*w[2][3]*w[0][2]*w[1][0]*(1.0); + const double G0_3_2_1 = det*w[2][3]*w[0][2]*w[1][1]*(1.0); + const double G0_3_2_2 = det*w[2][3]*w[0][2]*w[1][2]*(1.0); + const double G0_3_2_3 = det*w[2][3]*w[0][2]*w[1][3]*(1.0); + const double G0_3_2_4 = det*w[2][3]*w[0][2]*w[1][4]*(1.0); + const double G0_3_2_5 = det*w[2][3]*w[0][2]*w[1][5]*(1.0); + const double G0_3_3_0 = det*w[2][3]*w[0][3]*w[1][0]*(1.0); + const double G0_3_3_1 = det*w[2][3]*w[0][3]*w[1][1]*(1.0); + const double G0_3_3_2 = det*w[2][3]*w[0][3]*w[1][2]*(1.0); + const double G0_3_3_3 = det*w[2][3]*w[0][3]*w[1][3]*(1.0); + const double G0_3_3_4 = det*w[2][3]*w[0][3]*w[1][4]*(1.0); + const double G0_3_3_5 = det*w[2][3]*w[0][3]*w[1][5]*(1.0); + const double G0_3_4_0 = det*w[2][3]*w[0][4]*w[1][0]*(1.0); + const double G0_3_4_1 = det*w[2][3]*w[0][4]*w[1][1]*(1.0); + const double G0_3_4_2 = det*w[2][3]*w[0][4]*w[1][2]*(1.0); + const double G0_3_4_3 = det*w[2][3]*w[0][4]*w[1][3]*(1.0); + const double G0_3_4_4 = det*w[2][3]*w[0][4]*w[1][4]*(1.0); + const double G0_3_4_5 = det*w[2][3]*w[0][4]*w[1][5]*(1.0); + const double G0_3_5_0 = det*w[2][3]*w[0][5]*w[1][0]*(1.0); + const double G0_3_5_1 = det*w[2][3]*w[0][5]*w[1][1]*(1.0); + const double G0_3_5_2 = det*w[2][3]*w[0][5]*w[1][2]*(1.0); + const double G0_3_5_3 = det*w[2][3]*w[0][5]*w[1][3]*(1.0); + const double G0_3_5_4 = det*w[2][3]*w[0][5]*w[1][4]*(1.0); + const double G0_3_5_5 = det*w[2][3]*w[0][5]*w[1][5]*(1.0); + const double G0_4_0_0 = det*w[2][4]*w[0][0]*w[1][0]*(1.0); + const double G0_4_0_1 = det*w[2][4]*w[0][0]*w[1][1]*(1.0); + const double G0_4_0_2 = det*w[2][4]*w[0][0]*w[1][2]*(1.0); + const double G0_4_0_3 = det*w[2][4]*w[0][0]*w[1][3]*(1.0); + const double G0_4_0_4 = det*w[2][4]*w[0][0]*w[1][4]*(1.0); + const double G0_4_0_5 = det*w[2][4]*w[0][0]*w[1][5]*(1.0); + const double G0_4_1_0 = det*w[2][4]*w[0][1]*w[1][0]*(1.0); + const double G0_4_1_1 = det*w[2][4]*w[0][1]*w[1][1]*(1.0); + const double G0_4_1_2 = det*w[2][4]*w[0][1]*w[1][2]*(1.0); + const double G0_4_1_3 = det*w[2][4]*w[0][1]*w[1][3]*(1.0); + const double G0_4_1_4 = det*w[2][4]*w[0][1]*w[1][4]*(1.0); + const double G0_4_1_5 = det*w[2][4]*w[0][1]*w[1][5]*(1.0); + const double G0_4_2_0 = det*w[2][4]*w[0][2]*w[1][0]*(1.0); + const double G0_4_2_1 = det*w[2][4]*w[0][2]*w[1][1]*(1.0); + const double G0_4_2_2 = det*w[2][4]*w[0][2]*w[1][2]*(1.0); + const double G0_4_2_3 = det*w[2][4]*w[0][2]*w[1][3]*(1.0); + const double G0_4_2_4 = det*w[2][4]*w[0][2]*w[1][4]*(1.0); + const double G0_4_2_5 = det*w[2][4]*w[0][2]*w[1][5]*(1.0); + const double G0_4_3_0 = det*w[2][4]*w[0][3]*w[1][0]*(1.0); + const double G0_4_3_1 = det*w[2][4]*w[0][3]*w[1][1]*(1.0); + const double G0_4_3_2 = det*w[2][4]*w[0][3]*w[1][2]*(1.0); + const double G0_4_3_3 = det*w[2][4]*w[0][3]*w[1][3]*(1.0); + const double G0_4_3_4 = det*w[2][4]*w[0][3]*w[1][4]*(1.0); + const double G0_4_3_5 = det*w[2][4]*w[0][3]*w[1][5]*(1.0); + const double G0_4_4_0 = det*w[2][4]*w[0][4]*w[1][0]*(1.0); + const double G0_4_4_1 = det*w[2][4]*w[0][4]*w[1][1]*(1.0); + const double G0_4_4_2 = det*w[2][4]*w[0][4]*w[1][2]*(1.0); + const double G0_4_4_3 = det*w[2][4]*w[0][4]*w[1][3]*(1.0); + const double G0_4_4_4 = det*w[2][4]*w[0][4]*w[1][4]*(1.0); + const double G0_4_4_5 = det*w[2][4]*w[0][4]*w[1][5]*(1.0); + const double G0_4_5_0 = det*w[2][4]*w[0][5]*w[1][0]*(1.0); + const double G0_4_5_1 = det*w[2][4]*w[0][5]*w[1][1]*(1.0); + const double G0_4_5_2 = det*w[2][4]*w[0][5]*w[1][2]*(1.0); + const double G0_4_5_3 = det*w[2][4]*w[0][5]*w[1][3]*(1.0); + const double G0_4_5_4 = det*w[2][4]*w[0][5]*w[1][4]*(1.0); + const double G0_4_5_5 = det*w[2][4]*w[0][5]*w[1][5]*(1.0); + const double G0_5_0_0 = det*w[2][5]*w[0][0]*w[1][0]*(1.0); + const double G0_5_0_1 = det*w[2][5]*w[0][0]*w[1][1]*(1.0); + const double G0_5_0_2 = det*w[2][5]*w[0][0]*w[1][2]*(1.0); + const double G0_5_0_3 = det*w[2][5]*w[0][0]*w[1][3]*(1.0); + const double G0_5_0_4 = det*w[2][5]*w[0][0]*w[1][4]*(1.0); + const double G0_5_0_5 = det*w[2][5]*w[0][0]*w[1][5]*(1.0); + const double G0_5_1_0 = det*w[2][5]*w[0][1]*w[1][0]*(1.0); + const double G0_5_1_1 = det*w[2][5]*w[0][1]*w[1][1]*(1.0); + const double G0_5_1_2 = det*w[2][5]*w[0][1]*w[1][2]*(1.0); + const double G0_5_1_3 = det*w[2][5]*w[0][1]*w[1][3]*(1.0); + const double G0_5_1_4 = det*w[2][5]*w[0][1]*w[1][4]*(1.0); + const double G0_5_1_5 = det*w[2][5]*w[0][1]*w[1][5]*(1.0); + const double G0_5_2_0 = det*w[2][5]*w[0][2]*w[1][0]*(1.0); + const double G0_5_2_1 = det*w[2][5]*w[0][2]*w[1][1]*(1.0); + const double G0_5_2_2 = det*w[2][5]*w[0][2]*w[1][2]*(1.0); + const double G0_5_2_3 = det*w[2][5]*w[0][2]*w[1][3]*(1.0); + const double G0_5_2_4 = det*w[2][5]*w[0][2]*w[1][4]*(1.0); + const double G0_5_2_5 = det*w[2][5]*w[0][2]*w[1][5]*(1.0); + const double G0_5_3_0 = det*w[2][5]*w[0][3]*w[1][0]*(1.0); + const double G0_5_3_1 = det*w[2][5]*w[0][3]*w[1][1]*(1.0); + const double G0_5_3_2 = det*w[2][5]*w[0][3]*w[1][2]*(1.0); + const double G0_5_3_3 = det*w[2][5]*w[0][3]*w[1][3]*(1.0); + const double G0_5_3_4 = det*w[2][5]*w[0][3]*w[1][4]*(1.0); + const double G0_5_3_5 = det*w[2][5]*w[0][3]*w[1][5]*(1.0); + const double G0_5_4_0 = det*w[2][5]*w[0][4]*w[1][0]*(1.0); + const double G0_5_4_1 = det*w[2][5]*w[0][4]*w[1][1]*(1.0); + const double G0_5_4_2 = det*w[2][5]*w[0][4]*w[1][2]*(1.0); + const double G0_5_4_3 = det*w[2][5]*w[0][4]*w[1][3]*(1.0); + const double G0_5_4_4 = det*w[2][5]*w[0][4]*w[1][4]*(1.0); + const double G0_5_4_5 = det*w[2][5]*w[0][4]*w[1][5]*(1.0); + const double G0_5_5_0 = det*w[2][5]*w[0][5]*w[1][0]*(1.0); + const double G0_5_5_1 = det*w[2][5]*w[0][5]*w[1][1]*(1.0); + const double G0_5_5_2 = det*w[2][5]*w[0][5]*w[1][2]*(1.0); + const double G0_5_5_3 = det*w[2][5]*w[0][5]*w[1][3]*(1.0); + const double G0_5_5_4 = det*w[2][5]*w[0][5]*w[1][4]*(1.0); + const double G0_5_5_5 = det*w[2][5]*w[0][5]*w[1][5]*(1.0); + + // Compute element tensor + A[73] = -3.37162837162899e-05*G0_0_0_0 - 5.75317539603344e-06*G0_0_0_1 + 1.67243470814928e-05*G0_0_0_2 - 3.90680747823671e-05*G0_0_0_3 - 4.12087912087982e-05*G0_0_0_4 - 6.74325674325791e-05*G0_0_0_5 - 5.75317539603344e-06*G0_0_1_0 + 5.43206793206885e-05*G0_0_1_1 - 1.53863993149733e-05*G0_0_1_2 + 6.58270301127555e-05*G0_0_1_3 + 2.30127015841341e-05*G0_0_1_4 + 7.27843584986565e-05*G0_0_1_5 + 1.67243470814928e-05*G0_0_2_0 - 1.53863993149733e-05*G0_0_2_1 + 1.47174254317134e-06*G0_0_2_2 - 4.33495076352292e-05*G0_0_2_3 - 2.67589553303885e-06*G0_0_2_4 - 1.76609105180563e-05*G0_0_2_5 - 3.90680747823671e-05*G0_0_3_0 + 6.58270301127555e-05*G0_0_3_1 - 4.33495076352292e-05*G0_0_3_2 + 0.000211930926216676*G0_0_3_3 + 3.2110746396466e-05*G0_0_3_4 + 0.000113457970600847*G0_0_3_5 - 4.12087912087982e-05*G0_0_4_0 + 2.3012701584134e-05*G0_0_4_1 - 2.67589553303885e-06*G0_0_4_2 + 3.2110746396466e-05*G0_0_4_3 - 4.92364778079148e-05*G0_0_4_4 - 1.07035821321555e-05*G0_0_4_5 - 6.74325674325791e-05*G0_0_5_0 + 7.27843584986565e-05*G0_0_5_1 - 1.76609105180563e-05*G0_0_5_2 + 0.000113457970600847*G0_0_5_3 - 1.07035821321554e-05*G0_0_5_4 + 5.56586270872073e-05*G0_0_5_5 - 5.75317539603344e-06*G0_1_0_0 + 5.43206793206885e-05*G0_1_0_1 - 1.53863993149733e-05*G0_1_0_2 + 6.58270301127555e-05*G0_1_0_3 + 2.3012701584134e-05*G0_1_0_4 + 7.27843584986565e-05*G0_1_0_5 + 5.43206793206885e-05*G0_1_1_0 - 0.00039335664335671*G0_1_1_1 + 7.11788211788333e-05*G0_1_1_2 - 0.000299700299700351*G0_1_1_3 - 4.12087912087981e-05*G0_1_1_4 - 0.000243506493506535*G0_1_1_5 - 1.53863993149733e-05*G0_1_2_0 + 7.11788211788333e-05*G0_1_2_1 - 2.22099329242224e-05*G0_1_2_2 + 8.08120450977731e-05*G0_1_2_3 - 2.67589553303886e-06*G0_1_2_4 + 4.65605822748758e-05*G0_1_2_5 + 6.58270301127555e-05*G0_1_3_0 - 0.000299700299700351*G0_1_3_1 + 8.08120450977731e-05*G0_1_3_2 - 0.000449550449550526*G0_1_3_3 - 4.92364778079147e-05*G0_1_3_4 - 0.000224775224775263*G0_1_3_5 + 2.3012701584134e-05*G0_1_4_0 - 4.12087912087981e-05*G0_1_4_1 - 2.67589553303886e-06*G0_1_4_2 - 4.92364778079147e-05*G0_1_4_3 + 3.21107463964661e-05*G0_1_4_4 - 1.07035821321553e-05*G0_1_4_5 + 7.27843584986565e-05*G0_1_5_0 - 0.000243506493506535*G0_1_5_1 + 4.65605822748758e-05*G0_1_5_2 - 0.000224775224775263*G0_1_5_3 - 1.07035821321553e-05*G0_1_5_4 - 0.000224775224775262*G0_1_5_5 + 1.67243470814928e-05*G0_2_0_0 - 1.53863993149733e-05*G0_2_0_1 + 1.47174254317134e-06*G0_2_0_2 - 4.33495076352292e-05*G0_2_0_3 - 2.67589553303885e-06*G0_2_0_4 - 1.76609105180563e-05*G0_2_0_5 - 1.53863993149733e-05*G0_2_1_0 + 7.11788211788333e-05*G0_2_1_1 - 2.22099329242224e-05*G0_2_1_2 + 8.08120450977731e-05*G0_2_1_3 - 2.67589553303886e-06*G0_2_1_4 + 4.65605822748758e-05*G0_2_1_5 + 1.47174254317134e-06*G0_2_2_0 - 2.22099329242224e-05*G0_2_2_1 + 3.37162837162895e-05*G0_2_2_2 - 3.53218210361126e-05*G0_2_2_3 - 5.8869701726854e-06*G0_2_2_4 - 3.26459255030739e-05*G0_2_2_5 - 4.33495076352292e-05*G0_2_3_0 + 8.08120450977731e-05*G0_2_3_1 - 3.53218210361127e-05*G0_2_3_2 + 0.00033823319537611*G0_2_3_3 + 9.20508063365362e-05*G0_2_3_4 + 0.000151990866276606*G0_2_3_5 - 2.67589553303885e-06*G0_2_4_0 - 2.67589553303886e-06*G0_2_4_1 - 5.8869701726854e-06*G0_2_4_2 + 9.20508063365362e-05*G0_2_4_3 + 9.20508063365363e-05*G0_2_4_4 + 7.06436420722255e-05*G0_2_4_5 - 1.76609105180563e-05*G0_2_5_0 + 4.65605822748758e-05*G0_2_5_1 - 3.26459255030739e-05*G0_2_5_2 + 0.000151990866276606*G0_2_5_3 + 7.06436420722255e-05*G0_2_5_4 + 0.000122020836306571*G0_2_5_5 - 3.90680747823671e-05*G0_3_0_0 + 6.58270301127555e-05*G0_3_0_1 - 4.33495076352292e-05*G0_3_0_2 + 0.000211930926216676*G0_3_0_3 + 3.2110746396466e-05*G0_3_0_4 + 0.000113457970600847*G0_3_0_5 + 6.58270301127555e-05*G0_3_1_0 - 0.000299700299700351*G0_3_1_1 + 8.08120450977731e-05*G0_3_1_2 - 0.000449550449550526*G0_3_1_3 - 4.92364778079147e-05*G0_3_1_4 - 0.000224775224775263*G0_3_1_5 - 4.33495076352292e-05*G0_3_2_0 + 8.08120450977731e-05*G0_3_2_1 - 3.53218210361127e-05*G0_3_2_2 + 0.00033823319537611*G0_3_2_3 + 9.20508063365362e-05*G0_3_2_4 + 0.000151990866276606*G0_3_2_5 + 0.000211930926216676*G0_3_3_0 - 0.000449550449550526*G0_3_3_1 + 0.00033823319537611*G0_3_3_2 - 0.00196945911231659*G0_3_3_3 - 0.000325388896817523*G0_3_3_4 - 0.000727843584986565*G0_3_3_5 + 3.2110746396466e-05*G0_3_4_0 - 4.92364778079147e-05*G0_3_4_1 + 9.20508063365362e-05*G0_3_4_2 - 0.000325388896817523*G0_3_4_3 - 0.000128442985585864*G0_3_4_4 - 0.000205508776937383*G0_3_4_5 + 0.000113457970600847*G0_3_5_0 - 0.000224775224775263*G0_3_5_1 + 0.000151990866276606*G0_3_5_2 - 0.000727843584986565*G0_3_5_3 - 0.000205508776937383*G0_3_5_4 - 0.000470957613814836*G0_3_5_5 - 4.12087912087982e-05*G0_4_0_0 + 2.3012701584134e-05*G0_4_0_1 - 2.67589553303886e-06*G0_4_0_2 + 3.2110746396466e-05*G0_4_0_3 - 4.92364778079148e-05*G0_4_0_4 - 1.07035821321554e-05*G0_4_0_5 + 2.3012701584134e-05*G0_4_1_0 - 4.12087912087981e-05*G0_4_1_1 - 2.67589553303886e-06*G0_4_1_2 - 4.92364778079147e-05*G0_4_1_3 + 3.21107463964661e-05*G0_4_1_4 - 1.07035821321553e-05*G0_4_1_5 - 2.67589553303885e-06*G0_4_2_0 - 2.67589553303886e-06*G0_4_2_1 - 5.8869701726854e-06*G0_4_2_2 + 9.20508063365362e-05*G0_4_2_3 + 9.20508063365363e-05*G0_4_2_4 + 7.06436420722255e-05*G0_4_2_5 + 3.2110746396466e-05*G0_4_3_0 - 4.92364778079147e-05*G0_4_3_1 + 9.20508063365362e-05*G0_4_3_2 - 0.000325388896817523*G0_4_3_3 - 0.000128442985585864*G0_4_3_4 - 0.000205508776937383*G0_4_3_5 - 4.92364778079148e-05*G0_4_4_0 + 3.21107463964661e-05*G0_4_4_1 + 9.20508063365363e-05*G0_4_4_2 - 0.000128442985585864*G0_4_4_3 - 0.000325388896817523*G0_4_4_4 - 0.000205508776937383*G0_4_4_5 - 1.07035821321554e-05*G0_4_5_0 - 1.07035821321553e-05*G0_4_5_1 + 7.06436420722255e-05*G0_4_5_2 - 0.000205508776937383*G0_4_5_3 - 0.000205508776937383*G0_4_5_4 - 0.000222634508348832*G0_4_5_5 - 6.74325674325791e-05*G0_5_0_0 + 7.27843584986565e-05*G0_5_0_1 - 1.76609105180563e-05*G0_5_0_2 + 0.000113457970600847*G0_5_0_3 - 1.07035821321554e-05*G0_5_0_4 + 5.56586270872074e-05*G0_5_0_5 + 7.27843584986566e-05*G0_5_1_0 - 0.000243506493506535*G0_5_1_1 + 4.65605822748758e-05*G0_5_1_2 - 0.000224775224775263*G0_5_1_3 - 1.07035821321553e-05*G0_5_1_4 - 0.000224775224775262*G0_5_1_5 - 1.76609105180563e-05*G0_5_2_0 + 4.65605822748758e-05*G0_5_2_1 - 3.26459255030739e-05*G0_5_2_2 + 0.000151990866276606*G0_5_2_3 + 7.06436420722255e-05*G0_5_2_4 + 0.000122020836306571*G0_5_2_5 + 0.000113457970600847*G0_5_3_0 - 0.000224775224775263*G0_5_3_1 + 0.000151990866276606*G0_5_3_2 - 0.000727843584986565*G0_5_3_3 - 0.000205508776937383*G0_5_3_4 - 0.000470957613814836*G0_5_3_5 - 1.07035821321555e-05*G0_5_4_0 - 1.07035821321553e-05*G0_5_4_1 + 7.06436420722255e-05*G0_5_4_2 - 0.000205508776937383*G0_5_4_3 - 0.000205508776937383*G0_5_4_4 - 0.000222634508348832*G0_5_4_5 + 5.56586270872073e-05*G0_5_5_0 - 0.000224775224775262*G0_5_5_1 + 0.000122020836306571*G0_5_5_2 - 0.000470957613814836*G0_5_5_3 - 0.000222634508348832*G0_5_5_4 - 0.000428143285286216*G0_5_5_5; + A[37] = A[73]; + A[11] = 1.17739403453709e-05*G0_0_0_0 + 5.68875568875667e-06*G0_0_0_1 - 2.0085734371452e-06*G0_0_0_2 + 5.41125541125633e-06*G0_0_0_3 + 9.24340210054651e-06*G0_0_0_4 + 1.67887667887696e-05*G0_0_0_5 + 5.68875568875667e-06*G0_0_1_0 - 8.7875087875103e-05*G0_0_1_1 + 5.68875568875666e-06*G0_0_1_2 - 1.89625189625222e-05*G0_0_1_3 - 1.8962518962522e-06*G0_0_1_4 - 3.79250379250444e-05*G0_0_1_5 - 2.0085734371452e-06*G0_0_2_0 + 5.68875568875666e-06*G0_0_2_1 - 2.0085734371452e-06*G0_0_2_2 + 1.6187516187519e-06*G0_0_2_3 - 3.10536024821791e-06*G0_0_2_4 + 1.6187516187519e-06*G0_0_2_5 + 5.41125541125632e-06*G0_0_3_0 - 1.89625189625222e-05*G0_0_3_1 + 1.6187516187519e-06*G0_0_3_2 - 2.10900210900247e-05*G0_0_3_3 - 7.03000703000821e-06*G0_0_3_4 - 1.40600140600164e-05*G0_0_3_5 + 9.24340210054651e-06*G0_0_4_0 - 1.8962518962522e-06*G0_0_4_1 - 3.10536024821791e-06*G0_0_4_2 - 7.03000703000821e-06*G0_0_4_3 - 1.37428708857304e-06*G0_0_4_4 + 5.5500055500065e-07*G0_0_4_5 + 1.67887667887696e-05*G0_0_5_0 - 3.79250379250444e-05*G0_0_5_1 + 1.6187516187519e-06*G0_0_5_2 - 1.40600140600164e-05*G0_0_5_3 + 5.5500055500065e-07*G0_0_5_4 - 2.10900210900247e-05*G0_0_5_5 + 5.68875568875667e-06*G0_1_0_0 - 8.78750878751029e-05*G0_1_0_1 + 5.68875568875666e-06*G0_1_0_2 - 1.89625189625222e-05*G0_1_0_3 - 1.8962518962522e-06*G0_1_0_4 - 3.79250379250444e-05*G0_1_0_5 - 8.78750878751029e-05*G0_1_1_0 + 0.00187798312798345*G0_1_1_1 - 8.78750878751028e-05*G0_1_1_2 + 0.000370462870462934*G0_1_1_3 + 1.89625189625218e-05*G0_1_1_4 + 0.000370462870462934*G0_1_1_5 + 5.68875568875666e-06*G0_1_2_0 - 8.78750878751028e-05*G0_1_2_1 + 5.68875568875666e-06*G0_1_2_2 - 3.79250379250444e-05*G0_1_2_3 - 1.89625189625221e-06*G0_1_2_4 - 1.89625189625222e-05*G0_1_2_5 - 1.89625189625222e-05*G0_1_3_0 + 0.000370462870462934*G0_1_3_1 - 3.79250379250444e-05*G0_1_3_2 + 0.000151700151700178*G0_1_3_3 + 7.58500758500889e-05*G0_1_3_5 - 1.8962518962522e-06*G0_1_4_0 + 1.89625189625218e-05*G0_1_4_1 - 1.89625189625221e-06*G0_1_4_2 - 1.51700151700177e-05*G0_1_4_4 - 3.79250379250444e-05*G0_1_5_0 + 0.000370462870462934*G0_1_5_1 - 1.89625189625222e-05*G0_1_5_2 + 7.58500758500889e-05*G0_1_5_3 + 0.000151700151700178*G0_1_5_5 - 2.0085734371452e-06*G0_2_0_0 + 5.68875568875666e-06*G0_2_0_1 - 2.0085734371452e-06*G0_2_0_2 + 1.6187516187519e-06*G0_2_0_3 - 3.10536024821791e-06*G0_2_0_4 + 1.6187516187519e-06*G0_2_0_5 + 5.68875568875666e-06*G0_2_1_0 - 8.78750878751028e-05*G0_2_1_1 + 5.68875568875666e-06*G0_2_1_2 - 3.79250379250444e-05*G0_2_1_3 - 1.89625189625221e-06*G0_2_1_4 - 1.89625189625222e-05*G0_2_1_5 - 2.0085734371452e-06*G0_2_2_0 + 5.68875568875666e-06*G0_2_2_1 + 1.17739403453709e-05*G0_2_2_2 + 1.67887667887696e-05*G0_2_2_3 + 9.24340210054652e-06*G0_2_2_4 + 5.41125541125633e-06*G0_2_2_5 + 1.6187516187519e-06*G0_2_3_0 - 3.79250379250444e-05*G0_2_3_1 + 1.67887667887696e-05*G0_2_3_2 - 2.10900210900247e-05*G0_2_3_3 + 5.55000555000642e-07*G0_2_3_4 - 1.40600140600165e-05*G0_2_3_5 - 3.10536024821791e-06*G0_2_4_0 - 1.89625189625221e-06*G0_2_4_1 + 9.24340210054652e-06*G0_2_4_2 + 5.55000555000642e-07*G0_2_4_3 - 1.37428708857305e-06*G0_2_4_4 - 7.03000703000822e-06*G0_2_4_5 + 1.6187516187519e-06*G0_2_5_0 - 1.89625189625222e-05*G0_2_5_1 + 5.41125541125633e-06*G0_2_5_2 - 1.40600140600165e-05*G0_2_5_3 - 7.03000703000822e-06*G0_2_5_4 - 2.10900210900247e-05*G0_2_5_5 + 5.41125541125632e-06*G0_3_0_0 - 1.89625189625222e-05*G0_3_0_1 + 1.6187516187519e-06*G0_3_0_2 - 2.10900210900247e-05*G0_3_0_3 - 7.03000703000821e-06*G0_3_0_4 - 1.40600140600164e-05*G0_3_0_5 - 1.89625189625222e-05*G0_3_1_0 + 0.000370462870462934*G0_3_1_1 - 3.79250379250444e-05*G0_3_1_2 + 0.000151700151700178*G0_3_1_3 + 7.58500758500889e-05*G0_3_1_5 + 1.6187516187519e-06*G0_3_2_0 - 3.79250379250444e-05*G0_3_2_1 + 1.67887667887696e-05*G0_3_2_2 - 2.10900210900247e-05*G0_3_2_3 + 5.55000555000643e-07*G0_3_2_4 - 1.40600140600165e-05*G0_3_2_5 - 2.10900210900247e-05*G0_3_3_0 + 0.000151700151700178*G0_3_3_1 - 2.10900210900247e-05*G0_3_3_2 + 0.000210900210900247*G0_3_3_3 + 4.21800421800493e-05*G0_3_3_4 + 7.03000703000823e-05*G0_3_3_5 - 7.03000703000821e-06*G0_3_4_0 + 5.55000555000642e-07*G0_3_4_2 + 4.21800421800493e-05*G0_3_4_3 + 4.44000444000519e-05*G0_3_4_4 + 2.81200281200329e-05*G0_3_4_5 - 1.40600140600164e-05*G0_3_5_0 + 7.58500758500889e-05*G0_3_5_1 - 1.40600140600165e-05*G0_3_5_2 + 7.03000703000823e-05*G0_3_5_3 + 2.81200281200329e-05*G0_3_5_4 + 7.03000703000822e-05*G0_3_5_5 + 9.24340210054651e-06*G0_4_0_0 - 1.8962518962522e-06*G0_4_0_1 - 3.10536024821791e-06*G0_4_0_2 - 7.03000703000821e-06*G0_4_0_3 - 1.37428708857304e-06*G0_4_0_4 + 5.55000555000649e-07*G0_4_0_5 - 1.8962518962522e-06*G0_4_1_0 + 1.89625189625218e-05*G0_4_1_1 - 1.89625189625221e-06*G0_4_1_2 - 1.51700151700177e-05*G0_4_1_4 - 3.10536024821791e-06*G0_4_2_0 - 1.89625189625221e-06*G0_4_2_1 + 9.24340210054652e-06*G0_4_2_2 + 5.55000555000642e-07*G0_4_2_3 - 1.37428708857305e-06*G0_4_2_4 - 7.03000703000822e-06*G0_4_2_5 - 7.03000703000821e-06*G0_4_3_0 + 5.55000555000643e-07*G0_4_3_2 + 4.21800421800493e-05*G0_4_3_3 + 4.44000444000519e-05*G0_4_3_4 + 2.81200281200329e-05*G0_4_3_5 - 1.37428708857304e-06*G0_4_4_0 - 1.51700151700177e-05*G0_4_4_1 - 1.37428708857305e-06*G0_4_4_2 + 4.44000444000519e-05*G0_4_4_3 + 0.000116708688137279*G0_4_4_4 + 4.44000444000519e-05*G0_4_4_5 + 5.55000555000649e-07*G0_4_5_0 - 7.03000703000822e-06*G0_4_5_2 + 2.81200281200329e-05*G0_4_5_3 + 4.44000444000519e-05*G0_4_5_4 + 4.21800421800493e-05*G0_4_5_5 + 1.67887667887696e-05*G0_5_0_0 - 3.79250379250444e-05*G0_5_0_1 + 1.6187516187519e-06*G0_5_0_2 - 1.40600140600164e-05*G0_5_0_3 + 5.55000555000648e-07*G0_5_0_4 - 2.10900210900247e-05*G0_5_0_5 - 3.79250379250444e-05*G0_5_1_0 + 0.000370462870462934*G0_5_1_1 - 1.89625189625222e-05*G0_5_1_2 + 7.58500758500889e-05*G0_5_1_3 + 0.000151700151700178*G0_5_1_5 + 1.6187516187519e-06*G0_5_2_0 - 1.89625189625222e-05*G0_5_2_1 + 5.41125541125633e-06*G0_5_2_2 - 1.40600140600165e-05*G0_5_2_3 - 7.03000703000822e-06*G0_5_2_4 - 2.10900210900247e-05*G0_5_2_5 - 1.40600140600164e-05*G0_5_3_0 + 7.58500758500889e-05*G0_5_3_1 - 1.40600140600165e-05*G0_5_3_2 + 7.03000703000823e-05*G0_5_3_3 + 2.81200281200329e-05*G0_5_3_4 + 7.03000703000822e-05*G0_5_3_5 + 5.55000555000649e-07*G0_5_4_0 - 7.03000703000822e-06*G0_5_4_2 + 2.81200281200329e-05*G0_5_4_3 + 4.44000444000519e-05*G0_5_4_4 + 4.21800421800493e-05*G0_5_4_5 - 2.10900210900247e-05*G0_5_5_0 + 0.000151700151700178*G0_5_5_1 - 2.10900210900247e-05*G0_5_5_2 + 7.03000703000822e-05*G0_5_5_3 + 4.21800421800493e-05*G0_5_5_4 + 0.000210900210900247*G0_5_5_5; + A[1] = 0.000103368853368871*G0_0_0_0 - 8.69500869501015e-06*G0_0_0_1 - 6.19750619750724e-06*G0_0_0_2 + 2.4050024050028e-06*G0_0_0_3 + 2.77037777037824e-05*G0_0_0_4 + 4.37525437525511e-05*G0_0_0_5 - 8.69500869501015e-06*G0_0_1_0 - 8.69500869501019e-06*G0_0_1_1 + 1.82192146477892e-06*G0_0_1_2 - 2.55035969321727e-06*G0_0_1_3 - 2.55035969321726e-06*G0_0_1_4 - 1.22496551068e-05*G0_0_1_5 - 6.19750619750724e-06*G0_0_2_0 + 1.82192146477892e-06*G0_0_2_1 - 7.84598998884846e-07*G0_0_2_2 - 2.33232376089558e-06*G0_0_2_3 - 5.46411260697067e-06*G0_0_2_4 - 3.27714613428954e-06*G0_0_2_5 + 2.4050024050028e-06*G0_0_3_0 - 2.55035969321727e-06*G0_0_3_1 - 2.33232376089558e-06*G0_0_3_2 + 2.24643081785977e-06*G0_0_3_3 + 2.90714576428912e-07*G0_0_3_4 + 1.74428745857346e-06*G0_0_3_5 + 2.77037777037824e-05*G0_0_4_0 - 2.55035969321726e-06*G0_0_4_1 - 5.46411260697067e-06*G0_0_4_2 + 2.90714576428912e-07*G0_0_4_3 + 1.16550116550136e-05*G0_0_4_4 + 1.16550116550136e-05*G0_0_4_5 + 4.37525437525511e-05*G0_0_5_0 - 1.22496551068e-05*G0_0_5_1 - 3.27714613428954e-06*G0_0_5_2 + 1.74428745857346e-06*G0_0_5_3 + 1.16550116550136e-05*G0_0_5_4 + 2.33100233100272e-05*G0_0_5_5 - 8.69500869501015e-06*G0_1_0_0 - 8.69500869501019e-06*G0_1_0_1 + 1.82192146477892e-06*G0_1_0_2 - 2.55035969321727e-06*G0_1_0_3 - 2.55035969321726e-06*G0_1_0_4 - 1.22496551068e-05*G0_1_0_5 - 8.69500869501019e-06*G0_1_1_0 + 0.000103368853368871*G0_1_1_1 - 6.19750619750726e-06*G0_1_1_2 + 2.77037777037825e-05*G0_1_1_3 + 2.4050024050028e-06*G0_1_1_4 + 4.37525437525512e-05*G0_1_1_5 + 1.82192146477892e-06*G0_1_2_0 - 6.19750619750726e-06*G0_1_2_1 - 7.84598998884842e-07*G0_1_2_2 - 5.46411260697068e-06*G0_1_2_3 - 2.33232376089558e-06*G0_1_2_4 - 3.27714613428955e-06*G0_1_2_5 - 2.55035969321727e-06*G0_1_3_0 + 2.77037777037825e-05*G0_1_3_1 - 5.46411260697068e-06*G0_1_3_2 + 1.16550116550137e-05*G0_1_3_3 + 2.90714576428911e-07*G0_1_3_4 + 1.16550116550136e-05*G0_1_3_5 - 2.55035969321726e-06*G0_1_4_0 + 2.4050024050028e-06*G0_1_4_1 - 2.33232376089558e-06*G0_1_4_2 + 2.90714576428911e-07*G0_1_4_3 + 2.24643081785977e-06*G0_1_4_4 + 1.74428745857346e-06*G0_1_4_5 - 1.22496551068e-05*G0_1_5_0 + 4.37525437525512e-05*G0_1_5_1 - 3.27714613428955e-06*G0_1_5_2 + 1.16550116550136e-05*G0_1_5_3 + 1.74428745857346e-06*G0_1_5_4 + 2.33100233100273e-05*G0_1_5_5 - 6.19750619750724e-06*G0_2_0_0 + 1.82192146477892e-06*G0_2_0_1 - 7.84598998884846e-07*G0_2_0_2 - 2.33232376089558e-06*G0_2_0_3 - 5.46411260697067e-06*G0_2_0_4 - 3.27714613428954e-06*G0_2_0_5 + 1.82192146477892e-06*G0_2_1_0 - 6.19750619750726e-06*G0_2_1_1 - 7.84598998884842e-07*G0_2_1_2 - 5.46411260697068e-06*G0_2_1_3 - 2.33232376089558e-06*G0_2_1_4 - 3.27714613428955e-06*G0_2_1_5 - 7.84598998884846e-07*G0_2_2_0 - 7.84598998884842e-07*G0_2_2_1 + 1.03913943199675e-05*G0_2_2_2 + 6.27018484161447e-06*G0_2_2_3 + 6.27018484161447e-06*G0_2_2_4 + 7.33393590536572e-07*G0_2_2_5 - 2.33232376089558e-06*G0_2_3_0 - 5.46411260697068e-06*G0_2_3_1 + 6.27018484161447e-06*G0_2_3_2 + 1.24478695907288e-05*G0_2_3_3 + 9.32929504358233e-06*G0_2_3_4 + 3.19786034071802e-06*G0_2_3_5 - 5.46411260697067e-06*G0_2_4_0 - 2.33232376089558e-06*G0_2_4_1 + 6.27018484161447e-06*G0_2_4_2 + 9.32929504358233e-06*G0_2_4_3 + 1.24478695907288e-05*G0_2_4_4 + 3.19786034071802e-06*G0_2_4_5 - 3.27714613428954e-06*G0_2_5_0 - 3.27714613428955e-06*G0_2_5_1 + 7.33393590536572e-07*G0_2_5_2 + 3.19786034071802e-06*G0_2_5_3 + 3.19786034071802e-06*G0_2_5_4 - 2.37857380714564e-06*G0_2_5_5 + 2.4050024050028e-06*G0_3_0_0 - 2.55035969321727e-06*G0_3_0_1 - 2.33232376089558e-06*G0_3_0_2 + 2.24643081785977e-06*G0_3_0_3 + 2.90714576428913e-07*G0_3_0_4 + 1.74428745857346e-06*G0_3_0_5 - 2.55035969321727e-06*G0_3_1_0 + 2.77037777037825e-05*G0_3_1_1 - 5.46411260697068e-06*G0_3_1_2 + 1.16550116550137e-05*G0_3_1_3 + 2.90714576428912e-07*G0_3_1_4 + 1.16550116550136e-05*G0_3_1_5 - 2.33232376089558e-06*G0_3_2_0 - 5.46411260697068e-06*G0_3_2_1 + 6.27018484161447e-06*G0_3_2_2 + 1.24478695907288e-05*G0_3_2_3 + 9.32929504358233e-06*G0_3_2_4 + 3.19786034071802e-06*G0_3_2_5 + 2.24643081785977e-06*G0_3_3_0 + 1.16550116550137e-05*G0_3_3_1 + 1.24478695907288e-05*G0_3_3_2 - 3.20314606028946e-05*G0_3_3_3 - 5.07429078857737e-06*G0_3_3_4 - 1.08885823171556e-05*G0_3_3_5 + 2.90714576428913e-07*G0_3_4_0 + 2.90714576428912e-07*G0_3_4_1 + 9.32929504358233e-06*G0_3_4_2 - 5.07429078857737e-06*G0_3_4_3 - 5.07429078857737e-06*G0_3_4_4 - 6.97714983429387e-06*G0_3_4_5 + 1.74428745857346e-06*G0_3_5_0 + 1.16550116550136e-05*G0_3_5_1 + 3.19786034071802e-06*G0_3_5_2 - 1.08885823171556e-05*G0_3_5_3 - 6.97714983429387e-06*G0_3_5_4 + 1.26857269714434e-06*G0_3_5_5 + 2.77037777037824e-05*G0_4_0_0 - 2.55035969321726e-06*G0_4_0_1 - 5.46411260697067e-06*G0_4_0_2 + 2.90714576428912e-07*G0_4_0_3 + 1.16550116550136e-05*G0_4_0_4 + 1.16550116550136e-05*G0_4_0_5 - 2.55035969321726e-06*G0_4_1_0 + 2.4050024050028e-06*G0_4_1_1 - 2.33232376089558e-06*G0_4_1_2 + 2.90714576428911e-07*G0_4_1_3 + 2.24643081785977e-06*G0_4_1_4 + 1.74428745857346e-06*G0_4_1_5 - 5.46411260697067e-06*G0_4_2_0 - 2.33232376089558e-06*G0_4_2_1 + 6.27018484161447e-06*G0_4_2_2 + 9.32929504358233e-06*G0_4_2_3 + 1.24478695907288e-05*G0_4_2_4 + 3.19786034071803e-06*G0_4_2_5 + 2.90714576428912e-07*G0_4_3_0 + 2.90714576428911e-07*G0_4_3_1 + 9.32929504358233e-06*G0_4_3_2 - 5.07429078857736e-06*G0_4_3_3 - 5.07429078857737e-06*G0_4_3_4 - 6.97714983429387e-06*G0_4_3_5 + 1.16550116550136e-05*G0_4_4_0 + 2.24643081785977e-06*G0_4_4_1 + 1.24478695907288e-05*G0_4_4_2 - 5.07429078857737e-06*G0_4_4_3 - 3.20314606028946e-05*G0_4_4_4 - 1.08885823171556e-05*G0_4_4_5 + 1.16550116550136e-05*G0_4_5_0 + 1.74428745857346e-06*G0_4_5_1 + 3.19786034071802e-06*G0_4_5_2 - 6.97714983429387e-06*G0_4_5_3 - 1.08885823171556e-05*G0_4_5_4 + 1.26857269714434e-06*G0_4_5_5 + 4.37525437525511e-05*G0_5_0_0 - 1.22496551068e-05*G0_5_0_1 - 3.27714613428954e-06*G0_5_0_2 + 1.74428745857346e-06*G0_5_0_3 + 1.16550116550136e-05*G0_5_0_4 + 2.33100233100272e-05*G0_5_0_5 - 1.22496551068e-05*G0_5_1_0 + 4.37525437525512e-05*G0_5_1_1 - 3.27714613428955e-06*G0_5_1_2 + 1.16550116550136e-05*G0_5_1_3 + 1.74428745857346e-06*G0_5_1_4 + 2.33100233100273e-05*G0_5_1_5 - 3.27714613428954e-06*G0_5_2_0 - 3.27714613428955e-06*G0_5_2_1 + 7.33393590536572e-07*G0_5_2_2 + 3.19786034071802e-06*G0_5_2_3 + 3.19786034071802e-06*G0_5_2_4 - 2.37857380714564e-06*G0_5_2_5 + 1.74428745857346e-06*G0_5_3_0 + 1.16550116550136e-05*G0_5_3_1 + 3.19786034071802e-06*G0_5_3_2 - 1.08885823171556e-05*G0_5_3_3 - 6.97714983429387e-06*G0_5_3_4 + 1.26857269714435e-06*G0_5_3_5 + 1.16550116550136e-05*G0_5_4_0 + 1.74428745857346e-06*G0_5_4_1 + 3.19786034071802e-06*G0_5_4_2 - 6.97714983429387e-06*G0_5_4_3 - 1.08885823171556e-05*G0_5_4_4 + 1.26857269714434e-06*G0_5_4_5 + 2.33100233100272e-05*G0_5_5_0 + 2.33100233100273e-05*G0_5_5_1 - 2.37857380714564e-06*G0_5_5_2 + 1.26857269714435e-06*G0_5_5_3 + 1.26857269714434e-06*G0_5_5_4 + 8.30915116629543e-05*G0_5_5_5; + A[7] = -A[1] + 0.00110861360861379*G0_0_0_0 - 0.00011587949087951*G0_0_0_1 - 6.3431938431949e-05*G0_0_0_2 + 1.69737669737697e-05*G0_0_0_3 + 0.00025664150664155*G0_0_0_4 + 0.000501628001628086*G0_0_0_5 - 0.00011587949087951*G0_0_1_0 + 1.75287675287705e-05*G0_0_1_1 + 6.6088012516595e-06*G0_0_1_2 - 1.30160844446581e-06*G0_0_1_3 - 2.87741359169979e-05*G0_0_1_4 - 7.34384662956215e-05*G0_0_1_5 - 6.3431938431949e-05*G0_0_2_0 + 6.6088012516595e-06*G0_0_2_1 + 7.54040932612488e-06*G0_0_2_2 - 8.15982958840239e-06*G0_0_2_3 - 3.16878888307513e-05*G0_0_2_4 - 3.5328428185577e-05*G0_0_2_5 + 1.69737669737697e-05*G0_0_3_0 - 1.3016084444658e-06*G0_0_3_1 - 8.15982958840239e-06*G0_0_3_2 + 4.22064707779065e-05*G0_0_3_3 + 2.36007378864562e-05*G0_0_3_4 + 3.67093224236143e-05*G0_0_3_5 + 0.00025664150664155*G0_0_4_0 - 2.87741359169979e-05*G0_0_4_1 - 3.16878888307513e-05*G0_0_4_2 + 2.36007378864562e-05*G0_0_4_3 + 0.00012820512820515*G0_0_4_4 + 0.00012820512820515*G0_0_4_5 + 0.000501628001628086*G0_0_5_0 - 7.34384662956215e-05*G0_0_5_1 - 3.5328428185577e-05*G0_0_5_2 + 3.67093224236143e-05*G0_0_5_3 + 0.00012820512820515*G0_0_5_4 + 0.000372960372960436*G0_0_5_5 - 0.00011587949087951*G0_1_0_0 + 1.75287675287705e-05*G0_1_0_1 + 6.6088012516595e-06*G0_1_0_2 - 1.30160844446581e-06*G0_1_0_3 - 2.87741359169979e-05*G0_1_0_4 - 7.34384662956215e-05*G0_1_0_5 + 1.75287675287705e-05*G0_1_1_0 + 4.21800421800495e-05*G0_1_1_1 + 4.47634376205866e-07*G0_1_1_2 - 4.64482607339823e-06*G0_1_1_3 - 4.55232598089819e-06*G0_1_1_4 + 4.50607593464818e-06*G0_1_1_5 + 6.6088012516595e-06*G0_1_2_0 + 4.47634376205866e-07*G0_1_2_1 - 8.14331171474161e-07*G0_1_2_2 + 1.55268012410896e-06*G0_1_2_3 - 2.2133950705383e-06*G0_1_2_4 + 1.18267975410853e-06*G0_1_2_5 - 1.30160844446581e-06*G0_1_3_0 - 4.64482607339823e-06*G0_1_3_1 + 1.55268012410896e-06*G0_1_3_2 - 2.14071642643104e-06*G0_1_3_3 + 1.1707868850728e-05*G0_1_3_4 + 2.37857380714581e-07*G0_1_3_5 - 2.87741359169979e-05*G0_1_4_0 - 4.55232598089819e-06*G0_1_4_1 - 2.2133950705383e-06*G0_1_4_2 + 1.1707868850728e-05*G0_1_4_3 + 1.88964474678792e-05*G0_1_4_4 + 6.73929245357929e-06*G0_1_4_5 - 7.34384662956215e-05*G0_1_5_0 + 4.50607593464817e-06*G0_1_5_1 + 1.18267975410853e-06*G0_1_5_2 + 2.37857380714578e-07*G0_1_5_3 + 6.73929245357929e-06*G0_1_5_4 - 3.66300366300428e-05*G0_1_5_5 - 6.3431938431949e-05*G0_2_0_0 + 6.6088012516595e-06*G0_2_0_1 + 7.54040932612488e-06*G0_2_0_2 - 8.15982958840239e-06*G0_2_0_3 - 3.16878888307513e-05*G0_2_0_4 - 3.5328428185577e-05*G0_2_0_5 + 6.6088012516595e-06*G0_2_1_0 + 4.47634376205866e-07*G0_2_1_1 - 8.14331171474161e-07*G0_2_1_2 + 1.55268012410896e-06*G0_2_1_3 - 2.2133950705383e-06*G0_2_1_4 + 1.18267975410852e-06*G0_2_1_5 + 7.54040932612488e-06*G0_2_2_0 - 8.14331171474161e-07*G0_2_2_1 + 7.22491793920484e-06*G0_2_2_2 - 6.4551850266147e-06*G0_2_2_3 - 6.8714354428654e-07*G0_2_2_4 - 7.71054342483044e-06*G0_2_2_5 - 8.15982958840239e-06*G0_2_3_0 + 1.55268012410896e-06*G0_2_3_1 - 6.4551850266147e-06*G0_2_3_2 + 3.81364667079017e-05*G0_2_3_3 + 2.07464493178814e-05*G0_2_3_4 + 3.17407460264657e-05*G0_2_3_5 - 3.16878888307513e-05*G0_2_4_0 - 2.2133950705383e-06*G0_2_4_1 - 6.8714354428654e-07*G0_2_4_2 + 2.07464493178814e-05*G0_2_4_3 + 1.74428745857346e-05*G0_2_4_4 + 1.98478769907375e-05*G0_2_4_5 - 3.5328428185577e-05*G0_2_5_0 + 1.18267975410853e-06*G0_2_5_1 - 7.71054342483044e-06*G0_2_5_2 + 3.17407460264657e-05*G0_2_5_3 + 1.98478769907375e-05*G0_2_5_4 + 4.25764711479069e-05*G0_2_5_5 + 1.69737669737697e-05*G0_3_0_0 - 1.30160844446581e-06*G0_3_0_1 - 8.15982958840239e-06*G0_3_0_2 + 4.22064707779065e-05*G0_3_0_3 + 2.36007378864562e-05*G0_3_0_4 + 3.67093224236143e-05*G0_3_0_5 - 1.30160844446581e-06*G0_3_1_0 - 4.64482607339824e-06*G0_3_1_1 + 1.55268012410896e-06*G0_3_1_2 - 2.14071642643104e-06*G0_3_1_3 + 1.1707868850728e-05*G0_3_1_4 + 2.37857380714581e-07*G0_3_1_5 - 8.15982958840239e-06*G0_3_2_0 + 1.55268012410896e-06*G0_3_2_1 - 6.4551850266147e-06*G0_3_2_2 + 3.81364667079017e-05*G0_3_2_3 + 2.07464493178814e-05*G0_3_2_4 + 3.17407460264657e-05*G0_3_2_5 + 4.22064707779065e-05*G0_3_3_0 - 2.14071642643104e-06*G0_3_3_1 + 3.81364667079017e-05*G0_3_3_2 - 0.000320314606028946*G0_3_3_3 - 0.000107828679257269*G0_3_3_4 - 0.000147894433608744*G0_3_3_5 + 2.36007378864562e-05*G0_3_4_0 + 1.1707868850728e-05*G0_3_4_1 + 2.07464493178814e-05*G0_3_4_2 - 0.000107828679257269*G0_3_4_3 - 8.49943707086708e-05*G0_3_4_4 - 8.68972297543873e-05*G0_3_4_5 + 3.67093224236143e-05*G0_3_5_0 + 2.37857380714581e-07*G0_3_5_1 + 3.17407460264657e-05*G0_3_5_2 - 0.000147894433608744*G0_3_5_3 - 8.68972297543873e-05*G0_3_5_4 - 0.000158571587143043*G0_3_5_5 + 0.00025664150664155*G0_4_0_0 - 2.87741359169979e-05*G0_4_0_1 - 3.16878888307513e-05*G0_4_0_2 + 2.36007378864562e-05*G0_4_0_3 + 0.00012820512820515*G0_4_0_4 + 0.00012820512820515*G0_4_0_5 - 2.87741359169979e-05*G0_4_1_0 - 4.55232598089819e-06*G0_4_1_1 - 2.2133950705383e-06*G0_4_1_2 + 1.1707868850728e-05*G0_4_1_3 + 1.88964474678792e-05*G0_4_1_4 + 6.73929245357929e-06*G0_4_1_5 - 3.16878888307513e-05*G0_4_2_0 - 2.2133950705383e-06*G0_4_2_1 - 6.8714354428654e-07*G0_4_2_2 + 2.07464493178814e-05*G0_4_2_3 + 1.74428745857347e-05*G0_4_2_4 + 1.98478769907375e-05*G0_4_2_5 + 2.36007378864562e-05*G0_4_3_0 + 1.1707868850728e-05*G0_4_3_1 + 2.07464493178814e-05*G0_4_3_2 - 0.000107828679257269*G0_4_3_3 - 8.49943707086708e-05*G0_4_3_4 - 8.68972297543873e-05*G0_4_3_5 + 0.00012820512820515*G0_4_4_0 + 1.88964474678792e-05*G0_4_4_1 + 1.74428745857347e-05*G0_4_4_2 - 8.49943707086708e-05*G0_4_4_3 - 0.000131931560503011*G0_4_4_4 - 7.74886489172335e-05*G0_4_4_5 + 0.00012820512820515*G0_4_5_0 + 6.73929245357929e-06*G0_4_5_1 + 1.98478769907375e-05*G0_4_5_2 - 8.68972297543873e-05*G0_4_5_3 - 7.74886489172335e-05*G0_4_5_4 - 9.86315272029723e-05*G0_4_5_5 + 0.000501628001628086*G0_5_0_0 - 7.34384662956215e-05*G0_5_0_1 - 3.5328428185577e-05*G0_5_0_2 + 3.67093224236143e-05*G0_5_0_3 + 0.00012820512820515*G0_5_0_4 + 0.000372960372960436*G0_5_0_5 - 7.34384662956215e-05*G0_5_1_0 + 4.50607593464816e-06*G0_5_1_1 + 1.18267975410853e-06*G0_5_1_2 + 2.37857380714581e-07*G0_5_1_3 + 6.73929245357929e-06*G0_5_1_4 - 3.66300366300428e-05*G0_5_1_5 - 3.5328428185577e-05*G0_5_2_0 + 1.18267975410852e-06*G0_5_2_1 - 7.71054342483044e-06*G0_5_2_2 + 3.17407460264657e-05*G0_5_2_3 + 1.98478769907375e-05*G0_5_2_4 + 4.25764711479069e-05*G0_5_2_5 + 3.67093224236143e-05*G0_5_3_0 + 2.37857380714581e-07*G0_5_3_1 + 3.17407460264657e-05*G0_5_3_2 - 0.000147894433608744*G0_5_3_3 - 8.68972297543873e-05*G0_5_3_4 - 0.000158571587143043*G0_5_3_5 + 0.00012820512820515*G0_5_4_0 + 6.73929245357929e-06*G0_5_4_1 + 1.98478769907375e-05*G0_5_4_2 - 8.68972297543873e-05*G0_5_4_3 - 7.74886489172335e-05*G0_5_4_4 - 9.86315272029723e-05*G0_5_4_5 + 0.000372960372960436*G0_5_5_0 - 3.66300366300428e-05*G0_5_5_1 + 4.25764711479069e-05*G0_5_5_2 - 0.000158571587143043*G0_5_5_3 - 9.86315272029723e-05*G0_5_5_4 - 0.000316508887937513*G0_5_5_5; + A[99] = A[73] + 3.37162837162897e-05*G0_0_0_0 - 0.000109845511631245*G0_0_0_1 - 0.000132323034108771*G0_0_0_2 + 0.000674860853432396*G0_0_0_3 + 0.000715534465534586*G0_0_0_4 + 0.000741758241758367*G0_0_0_5 - 0.000109845511631245*G0_0_1_0 - 0.000169919366347966*G0_0_1_1 + 2.98362351933831e-05*G0_0_1_2 + 0.00022316968745544*G0_0_1_3 + 0.000265984015984061*G0_0_1_4 + 4.28143285286215e-06*G0_0_1_5 - 0.000132323034108771*G0_0_2_0 + 2.98362351933831e-05*G0_0_2_1 - 0.000117070429570449*G0_0_2_2 + 0.000332346225203424*G0_0_2_3 + 7.97416868845577e-05*G0_0_2_4 + 0.000306657628086251*G0_0_2_5 + 0.000674860853432396*G0_0_3_0 + 0.00022316968745544*G0_0_3_1 + 0.000332346225203424*G0_0_3_2 - 0.00298629941487135*G0_0_3_3 - 0.00188168973883291*G0_0_3_4 - 0.00196303696303729*G0_0_3_5 + 0.000715534465534586*G0_0_4_0 + 0.000265984015984061*G0_0_4_1 + 7.97416868845577e-05*G0_0_4_2 - 0.00188168973883291*G0_0_4_3 - 0.00149207934922246*G0_0_4_4 - 0.00114528328814062*G0_0_4_5 + 0.000741758241758367*G0_0_5_0 + 4.28143285286218e-06*G0_0_5_1 + 0.000306657628086251*G0_0_5_2 - 0.00196303696303729*G0_0_5_3 - 0.00114528328814062*G0_0_5_4 - 0.00159697445411758*G0_0_5_5 - 0.000109845511631245*G0_1_0_0 - 0.000169919366347966*G0_1_0_1 + 2.9836235193383e-05*G0_1_0_2 + 0.00022316968745544*G0_1_0_3 + 0.000265984015984061*G0_1_0_4 + 4.28143285286218e-06*G0_1_0_5 - 0.000169919366347966*G0_1_1_0 + 0.00039335664335671*G0_1_1_1 - 0.000186777508206111*G0_1_1_2 + 0.000974025974026138*G0_1_1_3 + 0.000677001569858827*G0_1_1_4 + 0.000917832167832322*G0_1_1_5 + 2.98362351933831e-05*G0_1_2_0 - 0.000186777508206111*G0_1_2_1 - 9.33887541030555e-05*G0_1_2_2 - 3.7462537462543e-06*G0_1_2_3 + 0.000291672613101234*G0_1_2_4 + 0.000242436135293319*G0_1_2_5 + 0.00022316968745544*G0_1_3_0 + 0.000974025974026138*G0_1_3_1 - 3.74625374625423e-06*G0_1_3_2 - 0.00109176537747985*G0_1_3_3 - 0.00180034251462853*G0_1_3_4 - 0.000931211645497517*G0_1_3_5 + 0.000265984015984061*G0_1_4_0 + 0.000677001569858827*G0_1_4_1 + 0.000291672613101234*G0_1_4_2 - 0.00180034251462853*G0_1_4_3 - 0.00280647923505114*G0_1_4_4 - 0.00183887541030429*G0_1_4_5 + 4.28143285286215e-06*G0_1_5_0 + 0.000917832167832322*G0_1_5_1 + 0.000242436135293319*G0_1_5_2 - 0.000931211645497517*G0_1_5_3 - 0.00183887541030429*G0_1_5_4 - 0.00131654060225511*G0_1_5_5 - 0.000132323034108771*G0_2_0_0 + 2.9836235193383e-05*G0_2_0_1 - 0.000117070429570449*G0_2_0_2 + 0.000332346225203424*G0_2_0_3 + 7.97416868845577e-05*G0_2_0_4 + 0.000306657628086251*G0_2_0_5 + 2.9836235193383e-05*G0_2_1_0 - 0.000186777508206111*G0_2_1_1 - 9.33887541030555e-05*G0_2_1_2 - 3.7462537462543e-06*G0_2_1_3 + 0.000291672613101234*G0_2_1_4 + 0.000242436135293319*G0_2_1_5 - 0.000117070429570449*G0_2_2_0 - 9.33887541030555e-05*G0_2_2_1 - 3.37162837162896e-05*G0_2_2_2 + 0.000709647495361901*G0_2_2_3 + 0.000680212644498473*G0_2_2_4 + 0.000668438704153103*G0_2_2_5 + 0.000332346225203424*G0_2_3_0 - 3.74625374625425e-06*G0_2_3_1 + 0.000709647495361901*G0_2_3_2 - 0.00187954902240648*G0_2_3_3 - 0.00124803767660932*G0_2_3_4 - 0.00200156985871305*G0_2_3_5 + 7.97416868845577e-05*G0_2_4_0 + 0.000291672613101234*G0_2_4_1 + 0.000680212644498473*G0_2_4_2 - 0.00124803767660932*G0_2_4_3 - 0.00163336663336691*G0_2_4_4 - 0.00192022263450867*G0_2_4_5 + 0.000306657628086251*G0_2_5_0 + 0.000242436135293319*G0_2_5_1 + 0.000668438704153103*G0_2_5_2 - 0.00200156985871305*G0_2_5_3 - 0.00192022263450867*G0_2_5_4 - 0.00289638932496124*G0_2_5_5 + 0.000674860853432396*G0_3_0_0 + 0.00022316968745544*G0_3_0_1 + 0.000332346225203424*G0_3_0_2 - 0.00298629941487135*G0_3_0_3 - 0.00188168973883291*G0_3_0_4 - 0.00196303696303729*G0_3_0_5 + 0.00022316968745544*G0_3_1_0 + 0.000974025974026138*G0_3_1_1 - 3.74625374625432e-06*G0_3_1_2 - 0.00109176537747985*G0_3_1_3 - 0.00180034251462853*G0_3_1_4 - 0.000931211645497517*G0_3_1_5 + 0.000332346225203424*G0_3_2_0 - 3.74625374625432e-06*G0_3_2_1 + 0.000709647495361901*G0_3_2_2 - 0.00187954902240648*G0_3_2_3 - 0.00124803767660932*G0_3_2_4 - 0.00200156985871305*G0_3_2_5 - 0.00298629941487135*G0_3_3_0 - 0.00109176537747985*G0_3_3_1 - 0.00187954902240648*G0_3_3_2 + 0.0173826173826203*G0_3_3_3 + 0.00957328385899976*G0_3_3_4 + 0.0099757385471688*G0_3_3_5 - 0.00188168973883291*G0_3_4_0 - 0.00180034251462853*G0_3_4_1 - 0.00124803767660932*G0_3_4_2 + 0.00957328385899976*G0_3_4_3 + 0.00937633794776811*G0_3_4_4 + 0.00760382474668317*G0_3_4_5 - 0.00196303696303729*G0_3_5_0 - 0.000931211645497517*G0_3_5_1 - 0.00200156985871305*G0_3_5_2 + 0.0099757385471688*G0_3_5_3 + 0.00760382474668317*G0_3_5_4 + 0.00971885257599708*G0_3_5_5 + 0.000715534465534586*G0_4_0_0 + 0.000265984015984061*G0_4_0_1 + 7.97416868845577e-05*G0_4_0_2 - 0.00188168973883291*G0_4_0_3 - 0.00149207934922246*G0_4_0_4 - 0.00114528328814062*G0_4_0_5 + 0.000265984015984061*G0_4_1_0 + 0.000677001569858827*G0_4_1_1 + 0.000291672613101234*G0_4_1_2 - 0.00180034251462853*G0_4_1_3 - 0.00280647923505114*G0_4_1_4 - 0.00183887541030429*G0_4_1_5 + 7.97416868845577e-05*G0_4_2_0 + 0.000291672613101234*G0_4_2_1 + 0.000680212644498473*G0_4_2_2 - 0.00124803767660932*G0_4_2_3 - 0.00163336663336691*G0_4_2_4 - 0.00192022263450867*G0_4_2_5 - 0.00188168973883291*G0_4_3_0 - 0.00180034251462853*G0_4_3_1 - 0.00124803767660932*G0_4_3_2 + 0.00957328385899976*G0_4_3_3 + 0.00937633794776811*G0_4_3_4 + 0.00760382474668318*G0_4_3_5 - 0.00149207934922246*G0_4_4_0 - 0.00280647923505114*G0_4_4_1 - 0.00163336663336691*G0_4_4_2 + 0.00937633794776811*G0_4_4_3 + 0.0157385471671213*G0_4_4_4 + 0.00945340373911962*G0_4_4_5 - 0.00114528328814062*G0_4_5_0 - 0.00183887541030429*G0_4_5_1 - 0.00192022263450867*G0_4_5_2 + 0.00760382474668318*G0_4_5_3 + 0.00945340373911962*G0_4_5_4 + 0.00947052947053107*G0_4_5_5 + 0.000741758241758367*G0_5_0_0 + 4.28143285286218e-06*G0_5_0_1 + 0.000306657628086251*G0_5_0_2 - 0.00196303696303729*G0_5_0_3 - 0.00114528328814062*G0_5_0_4 - 0.00159697445411758*G0_5_0_5 + 4.28143285286215e-06*G0_5_1_0 + 0.000917832167832322*G0_5_1_1 + 0.000242436135293319*G0_5_1_2 - 0.000931211645497517*G0_5_1_3 - 0.00183887541030429*G0_5_1_4 - 0.00131654060225511*G0_5_1_5 + 0.000306657628086251*G0_5_2_0 + 0.000242436135293319*G0_5_2_1 + 0.000668438704153103*G0_5_2_2 - 0.00200156985871305*G0_5_2_3 - 0.00192022263450867*G0_5_2_4 - 0.00289638932496124*G0_5_2_5 - 0.00196303696303729*G0_5_3_0 - 0.000931211645497517*G0_5_3_1 - 0.00200156985871305*G0_5_3_2 + 0.00997573854716881*G0_5_3_3 + 0.00760382474668317*G0_5_3_4 + 0.00971885257599708*G0_5_3_5 - 0.00114528328814062*G0_5_4_0 - 0.00183887541030429*G0_5_4_1 - 0.00192022263450867*G0_5_4_2 + 0.00760382474668318*G0_5_4_3 + 0.00945340373911962*G0_5_4_4 + 0.00947052947053107*G0_5_4_5 - 0.00159697445411758*G0_5_5_0 - 0.00131654060225511*G0_5_5_1 - 0.00289638932496124*G0_5_5_2 + 0.00971885257599708*G0_5_5_3 + 0.00947052947053107*G0_5_5_4 + 0.01584130155559*G0_5_5_5; + A[21] = 1.03913943199675e-05*G0_0_0_0 - 7.84598998884842e-07*G0_0_0_1 - 7.84598998884843e-07*G0_0_0_2 + 7.3339359053657e-07*G0_0_0_3 + 6.27018484161446e-06*G0_0_0_4 + 6.27018484161446e-06*G0_0_0_5 - 7.84598998884842e-07*G0_0_1_0 - 6.19750619750725e-06*G0_0_1_1 + 1.82192146477891e-06*G0_0_1_2 - 3.27714613428955e-06*G0_0_1_3 - 2.33232376089558e-06*G0_0_1_4 - 5.46411260697067e-06*G0_0_1_5 - 7.84598998884844e-07*G0_0_2_0 + 1.82192146477891e-06*G0_0_2_1 - 6.19750619750724e-06*G0_0_2_2 - 3.27714613428954e-06*G0_0_2_3 - 5.46411260697067e-06*G0_0_2_4 - 2.33232376089558e-06*G0_0_2_5 + 7.3339359053657e-07*G0_0_3_0 - 3.27714613428955e-06*G0_0_3_1 - 3.27714613428954e-06*G0_0_3_2 - 2.37857380714564e-06*G0_0_3_3 + 3.19786034071802e-06*G0_0_3_4 + 3.19786034071803e-06*G0_0_3_5 + 6.27018484161446e-06*G0_0_4_0 - 2.33232376089558e-06*G0_0_4_1 - 5.46411260697067e-06*G0_0_4_2 + 3.19786034071802e-06*G0_0_4_3 + 1.24478695907288e-05*G0_0_4_4 + 9.32929504358233e-06*G0_0_4_5 + 6.27018484161446e-06*G0_0_5_0 - 5.46411260697066e-06*G0_0_5_1 - 2.33232376089558e-06*G0_0_5_2 + 3.19786034071803e-06*G0_0_5_3 + 9.32929504358233e-06*G0_0_5_4 + 1.24478695907288e-05*G0_0_5_5 - 7.84598998884842e-07*G0_1_0_0 - 6.19750619750725e-06*G0_1_0_1 + 1.82192146477891e-06*G0_1_0_2 - 3.27714613428955e-06*G0_1_0_3 - 2.33232376089558e-06*G0_1_0_4 - 5.46411260697067e-06*G0_1_0_5 - 6.19750619750725e-06*G0_1_1_0 + 0.000103368853368871*G0_1_1_1 - 8.69500869501018e-06*G0_1_1_2 + 4.37525437525512e-05*G0_1_1_3 + 2.4050024050028e-06*G0_1_1_4 + 2.77037777037824e-05*G0_1_1_5 + 1.82192146477891e-06*G0_1_2_0 - 8.69500869501018e-06*G0_1_2_1 - 8.69500869501015e-06*G0_1_2_2 - 1.22496551068e-05*G0_1_2_3 - 2.55035969321726e-06*G0_1_2_4 - 2.55035969321727e-06*G0_1_2_5 - 3.27714613428955e-06*G0_1_3_0 + 4.37525437525512e-05*G0_1_3_1 - 1.22496551068e-05*G0_1_3_2 + 2.33100233100273e-05*G0_1_3_3 + 1.74428745857347e-06*G0_1_3_4 + 1.16550116550136e-05*G0_1_3_5 - 2.33232376089558e-06*G0_1_4_0 + 2.4050024050028e-06*G0_1_4_1 - 2.55035969321726e-06*G0_1_4_2 + 1.74428745857347e-06*G0_1_4_3 + 2.24643081785977e-06*G0_1_4_4 + 2.90714576428908e-07*G0_1_4_5 - 5.46411260697067e-06*G0_1_5_0 + 2.77037777037824e-05*G0_1_5_1 - 2.55035969321727e-06*G0_1_5_2 + 1.16550116550136e-05*G0_1_5_3 + 2.90714576428908e-07*G0_1_5_4 + 1.16550116550136e-05*G0_1_5_5 - 7.84598998884844e-07*G0_2_0_0 + 1.82192146477891e-06*G0_2_0_1 - 6.19750619750724e-06*G0_2_0_2 - 3.27714613428954e-06*G0_2_0_3 - 5.46411260697067e-06*G0_2_0_4 - 2.33232376089558e-06*G0_2_0_5 + 1.82192146477891e-06*G0_2_1_0 - 8.69500869501017e-06*G0_2_1_1 - 8.69500869501015e-06*G0_2_1_2 - 1.22496551068e-05*G0_2_1_3 - 2.55035969321726e-06*G0_2_1_4 - 2.55035969321727e-06*G0_2_1_5 - 6.19750619750724e-06*G0_2_2_0 - 8.69500869501015e-06*G0_2_2_1 + 0.000103368853368871*G0_2_2_2 + 4.37525437525511e-05*G0_2_2_3 + 2.77037777037824e-05*G0_2_2_4 + 2.40500240500282e-06*G0_2_2_5 - 3.27714613428954e-06*G0_2_3_0 - 1.22496551068e-05*G0_2_3_1 + 4.37525437525511e-05*G0_2_3_2 + 2.33100233100273e-05*G0_2_3_3 + 1.16550116550136e-05*G0_2_3_4 + 1.74428745857347e-06*G0_2_3_5 - 5.46411260697067e-06*G0_2_4_0 - 2.55035969321726e-06*G0_2_4_1 + 2.77037777037824e-05*G0_2_4_2 + 1.16550116550136e-05*G0_2_4_3 + 1.16550116550136e-05*G0_2_4_4 + 2.90714576428917e-07*G0_2_4_5 - 2.33232376089558e-06*G0_2_5_0 - 2.55035969321727e-06*G0_2_5_1 + 2.40500240500282e-06*G0_2_5_2 + 1.74428745857347e-06*G0_2_5_3 + 2.90714576428917e-07*G0_2_5_4 + 2.24643081785978e-06*G0_2_5_5 + 7.3339359053657e-07*G0_3_0_0 - 3.27714613428955e-06*G0_3_0_1 - 3.27714613428954e-06*G0_3_0_2 - 2.37857380714564e-06*G0_3_0_3 + 3.19786034071802e-06*G0_3_0_4 + 3.19786034071803e-06*G0_3_0_5 - 3.27714613428955e-06*G0_3_1_0 + 4.37525437525512e-05*G0_3_1_1 - 1.22496551068e-05*G0_3_1_2 + 2.33100233100273e-05*G0_3_1_3 + 1.74428745857347e-06*G0_3_1_4 + 1.16550116550136e-05*G0_3_1_5 - 3.27714613428954e-06*G0_3_2_0 - 1.22496551068e-05*G0_3_2_1 + 4.37525437525511e-05*G0_3_2_2 + 2.33100233100273e-05*G0_3_2_3 + 1.16550116550136e-05*G0_3_2_4 + 1.74428745857347e-06*G0_3_2_5 - 2.37857380714564e-06*G0_3_3_0 + 2.33100233100273e-05*G0_3_3_1 + 2.33100233100273e-05*G0_3_3_2 + 8.30915116629544e-05*G0_3_3_3 + 1.26857269714434e-06*G0_3_3_4 + 1.26857269714435e-06*G0_3_3_5 + 3.19786034071802e-06*G0_3_4_0 + 1.74428745857347e-06*G0_3_4_1 + 1.16550116550136e-05*G0_3_4_2 + 1.26857269714434e-06*G0_3_4_3 - 1.08885823171556e-05*G0_3_4_4 - 6.97714983429387e-06*G0_3_4_5 + 3.19786034071803e-06*G0_3_5_0 + 1.16550116550136e-05*G0_3_5_1 + 1.74428745857347e-06*G0_3_5_2 + 1.26857269714435e-06*G0_3_5_3 - 6.97714983429388e-06*G0_3_5_4 - 1.08885823171556e-05*G0_3_5_5 + 6.27018484161446e-06*G0_4_0_0 - 2.33232376089558e-06*G0_4_0_1 - 5.46411260697067e-06*G0_4_0_2 + 3.19786034071802e-06*G0_4_0_3 + 1.24478695907288e-05*G0_4_0_4 + 9.32929504358233e-06*G0_4_0_5 - 2.33232376089558e-06*G0_4_1_0 + 2.4050024050028e-06*G0_4_1_1 - 2.55035969321726e-06*G0_4_1_2 + 1.74428745857347e-06*G0_4_1_3 + 2.24643081785977e-06*G0_4_1_4 + 2.90714576428908e-07*G0_4_1_5 - 5.46411260697067e-06*G0_4_2_0 - 2.55035969321726e-06*G0_4_2_1 + 2.77037777037824e-05*G0_4_2_2 + 1.16550116550136e-05*G0_4_2_3 + 1.16550116550136e-05*G0_4_2_4 + 2.90714576428917e-07*G0_4_2_5 + 3.19786034071802e-06*G0_4_3_0 + 1.74428745857347e-06*G0_4_3_1 + 1.16550116550136e-05*G0_4_3_2 + 1.26857269714434e-06*G0_4_3_3 - 1.08885823171556e-05*G0_4_3_4 - 6.97714983429387e-06*G0_4_3_5 + 1.24478695907288e-05*G0_4_4_0 + 2.24643081785977e-06*G0_4_4_1 + 1.16550116550136e-05*G0_4_4_2 - 1.08885823171556e-05*G0_4_4_3 - 3.20314606028946e-05*G0_4_4_4 - 5.07429078857736e-06*G0_4_4_5 + 9.32929504358233e-06*G0_4_5_0 + 2.90714576428908e-07*G0_4_5_1 + 2.90714576428917e-07*G0_4_5_2 - 6.97714983429387e-06*G0_4_5_3 - 5.07429078857736e-06*G0_4_5_4 - 5.07429078857738e-06*G0_4_5_5 + 6.27018484161446e-06*G0_5_0_0 - 5.46411260697066e-06*G0_5_0_1 - 2.33232376089558e-06*G0_5_0_2 + 3.19786034071803e-06*G0_5_0_3 + 9.32929504358233e-06*G0_5_0_4 + 1.24478695907288e-05*G0_5_0_5 - 5.46411260697067e-06*G0_5_1_0 + 2.77037777037824e-05*G0_5_1_1 - 2.55035969321727e-06*G0_5_1_2 + 1.16550116550136e-05*G0_5_1_3 + 2.90714576428908e-07*G0_5_1_4 + 1.16550116550136e-05*G0_5_1_5 - 2.33232376089558e-06*G0_5_2_0 - 2.55035969321727e-06*G0_5_2_1 + 2.40500240500282e-06*G0_5_2_2 + 1.74428745857347e-06*G0_5_2_3 + 2.90714576428917e-07*G0_5_2_4 + 2.24643081785978e-06*G0_5_2_5 + 3.19786034071803e-06*G0_5_3_0 + 1.16550116550136e-05*G0_5_3_1 + 1.74428745857347e-06*G0_5_3_2 + 1.26857269714435e-06*G0_5_3_3 - 6.97714983429387e-06*G0_5_3_4 - 1.08885823171556e-05*G0_5_3_5 + 9.32929504358233e-06*G0_5_4_0 + 2.90714576428908e-07*G0_5_4_1 + 2.90714576428917e-07*G0_5_4_2 - 6.97714983429387e-06*G0_5_4_3 - 5.07429078857736e-06*G0_5_4_4 - 5.07429078857738e-06*G0_5_4_5 + 1.24478695907288e-05*G0_5_5_0 + 1.16550116550136e-05*G0_5_5_1 + 2.24643081785978e-06*G0_5_5_2 - 1.08885823171556e-05*G0_5_5_3 - 5.07429078857738e-06*G0_5_5_4 - 3.20314606028947e-05*G0_5_5_5; + A[90] = A[21] + 0.000139458755530208*G0_0_0_0 - 1.66979184836356e-05*G0_0_0_1 - 1.66979184836356e-05*G0_0_0_2 + 3.42316413745043e-05*G0_0_0_3 + 8.11424025709877e-05*G0_0_0_4 + 8.11424025709877e-05*G0_0_0_5 - 1.66979184836356e-05*G0_0_1_0 - 2.0085734371452e-06*G0_0_1_1 + 4.95701388558615e-06*G0_0_1_2 + 7.20179291607986e-06*G0_0_1_3 + 2.3323237608956e-06*G0_0_1_4 - 1.20184048755498e-05*G0_0_1_5 - 1.66979184836356e-05*G0_0_2_0 + 4.95701388558615e-06*G0_0_2_1 - 2.00857343714521e-06*G0_0_2_2 + 7.20179291607987e-06*G0_0_2_3 - 1.20184048755498e-05*G0_0_2_4 + 2.3323237608956e-06*G0_0_2_5 + 3.42316413745043e-05*G0_0_3_0 + 7.20179291607986e-06*G0_0_3_1 + 7.20179291607987e-06*G0_0_3_2 - 0.000160315874601616*G0_0_3_3 - 7.31279302707998e-05*G0_0_3_4 - 7.31279302707998e-05*G0_0_3_5 + 8.11424025709877e-05*G0_0_4_0 + 2.3323237608956e-06*G0_0_4_1 - 1.20184048755498e-05*G0_0_4_2 - 7.31279302707998e-05*G0_0_4_3 - 1.24478695907289e-05*G0_0_4_4 - 9.32929504358239e-06*G0_0_4_5 + 8.11424025709877e-05*G0_0_5_0 - 1.20184048755498e-05*G0_0_5_1 + 2.3323237608956e-06*G0_0_5_2 - 7.31279302707998e-05*G0_0_5_3 - 9.32929504358239e-06*G0_0_5_4 - 1.24478695907288e-05*G0_0_5_5 - 1.66979184836356e-05*G0_1_0_0 - 2.0085734371452e-06*G0_1_0_1 + 4.95701388558615e-06*G0_1_0_2 + 7.20179291607986e-06*G0_1_0_3 + 2.3323237608956e-06*G0_1_0_4 - 1.20184048755498e-05*G0_1_0_5 - 2.0085734371452e-06*G0_1_1_0 - 6.96525696525814e-05*G0_1_1_1 + 7.17866789295482e-06*G0_1_1_2 - 2.3653595082171e-06*G0_1_1_3 - 2.04821633393095e-06*G0_1_1_4 - 4.15589701304058e-06*G0_1_1_5 + 4.95701388558615e-06*G0_1_2_0 + 7.17866789295482e-06*G0_1_2_1 + 7.17866789295482e-06*G0_1_2_2 - 1.91475191475223e-05*G0_1_2_3 - 2.42085956371711e-05*G0_1_2_4 - 2.42085956371711e-05*G0_1_2_5 + 7.20179291607986e-06*G0_1_3_0 - 2.3653595082171e-06*G0_1_3_1 - 1.91475191475223e-05*G0_1_3_2 - 4.18628990057633e-05*G0_1_3_3 - 1.03071531642978e-05*G0_1_3_4 + 3.40136054421825e-05*G0_1_3_5 + 2.3323237608956e-06*G0_1_4_0 - 2.04821633393095e-06*G0_1_4_1 - 2.42085956371711e-05*G0_1_4_2 - 1.03071531642978e-05*G0_1_4_3 + 4.48493305636238e-05*G0_1_4_4 + 5.25136239422042e-05*G0_1_4_5 - 1.20184048755498e-05*G0_1_5_0 - 4.15589701304058e-06*G0_1_5_1 - 2.42085956371711e-05*G0_1_5_2 + 3.40136054421825e-05*G0_1_5_3 + 5.25136239422042e-05*G0_1_5_4 + 0.000105370819656552*G0_1_5_5 - 1.66979184836356e-05*G0_2_0_0 + 4.95701388558615e-06*G0_2_0_1 - 2.00857343714521e-06*G0_2_0_2 + 7.20179291607987e-06*G0_2_0_3 - 1.20184048755498e-05*G0_2_0_4 + 2.3323237608956e-06*G0_2_0_5 + 4.95701388558615e-06*G0_2_1_0 + 7.17866789295482e-06*G0_2_1_1 + 7.17866789295482e-06*G0_2_1_2 - 1.91475191475224e-05*G0_2_1_3 - 2.42085956371711e-05*G0_2_1_4 - 2.42085956371711e-05*G0_2_1_5 - 2.00857343714521e-06*G0_2_2_0 + 7.17866789295482e-06*G0_2_2_1 - 6.96525696525813e-05*G0_2_2_2 - 2.36535950821707e-06*G0_2_2_3 - 4.15589701304056e-06*G0_2_2_4 - 2.04821633393097e-06*G0_2_2_5 + 7.20179291607986e-06*G0_2_3_0 - 1.91475191475223e-05*G0_2_3_1 - 2.36535950821707e-06*G0_2_3_2 - 4.18628990057633e-05*G0_2_3_3 + 3.40136054421825e-05*G0_2_3_4 - 1.03071531642978e-05*G0_2_3_5 - 1.20184048755498e-05*G0_2_4_0 - 2.42085956371711e-05*G0_2_4_1 - 4.15589701304056e-06*G0_2_4_2 + 3.40136054421825e-05*G0_2_4_3 + 0.000105370819656552*G0_2_4_4 + 5.25136239422042e-05*G0_2_4_5 + 2.3323237608956e-06*G0_2_5_0 - 2.42085956371711e-05*G0_2_5_1 - 2.04821633393097e-06*G0_2_5_2 - 1.03071531642978e-05*G0_2_5_3 + 5.25136239422042e-05*G0_2_5_4 + 4.48493305636238e-05*G0_2_5_5 + 3.42316413745043e-05*G0_3_0_0 + 7.20179291607986e-06*G0_3_0_1 + 7.20179291607987e-06*G0_3_0_2 - 0.000160315874601616*G0_3_0_3 - 7.31279302707998e-05*G0_3_0_4 - 7.31279302707998e-05*G0_3_0_5 + 7.20179291607986e-06*G0_3_1_0 - 2.3653595082171e-06*G0_3_1_1 - 1.91475191475223e-05*G0_3_1_2 - 4.18628990057633e-05*G0_3_1_3 - 1.03071531642978e-05*G0_3_1_4 + 3.40136054421825e-05*G0_3_1_5 + 7.20179291607986e-06*G0_3_2_0 - 1.91475191475223e-05*G0_3_2_1 - 2.36535950821707e-06*G0_3_2_2 - 4.18628990057633e-05*G0_3_2_3 + 3.40136054421825e-05*G0_3_2_4 - 1.03071531642978e-05*G0_3_2_5 - 0.000160315874601616*G0_3_3_0 - 4.18628990057633e-05*G0_3_3_1 - 4.18628990057633e-05*G0_3_3_2 + 0.000990120990121157*G0_3_3_3 + 0.000341246055531828*G0_3_3_4 + 0.000341246055531828*G0_3_3_5 - 7.31279302707998e-05*G0_3_4_0 - 1.03071531642978e-05*G0_3_4_1 + 3.40136054421825e-05*G0_3_4_2 + 0.000341246055531828*G0_3_4_3 + 5.6557199414352e-05*G0_3_4_4 + 4.12286126571912e-05*G0_3_4_5 - 7.31279302707998e-05*G0_3_5_0 + 3.40136054421825e-05*G0_3_5_1 - 1.03071531642978e-05*G0_3_5_2 + 0.000341246055531828*G0_3_5_3 + 4.12286126571912e-05*G0_3_5_4 + 5.65571994143521e-05*G0_3_5_5 + 8.11424025709877e-05*G0_4_0_0 + 2.3323237608956e-06*G0_4_0_1 - 1.20184048755498e-05*G0_4_0_2 - 7.31279302707998e-05*G0_4_0_3 - 1.24478695907289e-05*G0_4_0_4 - 9.32929504358238e-06*G0_4_0_5 + 2.3323237608956e-06*G0_4_1_0 - 2.04821633393094e-06*G0_4_1_1 - 2.42085956371711e-05*G0_4_1_2 - 1.03071531642978e-05*G0_4_1_3 + 4.48493305636238e-05*G0_4_1_4 + 5.25136239422042e-05*G0_4_1_5 - 1.20184048755498e-05*G0_4_2_0 - 2.42085956371711e-05*G0_4_2_1 - 4.15589701304056e-06*G0_4_2_2 + 3.40136054421825e-05*G0_4_2_3 + 0.000105370819656552*G0_4_2_4 + 5.25136239422042e-05*G0_4_2_5 - 7.31279302707998e-05*G0_4_3_0 - 1.03071531642978e-05*G0_4_3_1 + 3.40136054421825e-05*G0_4_3_2 + 0.000341246055531828*G0_4_3_3 + 5.6557199414352e-05*G0_4_3_4 + 4.12286126571912e-05*G0_4_3_5 - 1.24478695907289e-05*G0_4_4_0 + 4.48493305636238e-05*G0_4_4_1 + 0.000105370819656552*G0_4_4_2 + 5.6557199414352e-05*G0_4_4_3 - 0.000367568938997572*G0_4_4_4 - 0.000194725909011656*G0_4_4_5 - 9.32929504358238e-06*G0_4_5_0 + 5.25136239422042e-05*G0_4_5_1 + 5.25136239422042e-05*G0_4_5_2 + 4.12286126571912e-05*G0_4_5_3 - 0.000194725909011656*G0_4_5_4 - 0.000194725909011656*G0_4_5_5 + 8.11424025709877e-05*G0_5_0_0 - 1.20184048755498e-05*G0_5_0_1 + 2.3323237608956e-06*G0_5_0_2 - 7.31279302707998e-05*G0_5_0_3 - 9.32929504358239e-06*G0_5_0_4 - 1.24478695907288e-05*G0_5_0_5 - 1.20184048755498e-05*G0_5_1_0 - 4.15589701304058e-06*G0_5_1_1 - 2.42085956371711e-05*G0_5_1_2 + 3.40136054421825e-05*G0_5_1_3 + 5.25136239422042e-05*G0_5_1_4 + 0.000105370819656552*G0_5_1_5 + 2.3323237608956e-06*G0_5_2_0 - 2.42085956371711e-05*G0_5_2_1 - 2.04821633393097e-06*G0_5_2_2 - 1.03071531642978e-05*G0_5_2_3 + 5.25136239422042e-05*G0_5_2_4 + 4.48493305636238e-05*G0_5_2_5 - 7.31279302707998e-05*G0_5_3_0 + 3.40136054421825e-05*G0_5_3_1 - 1.03071531642978e-05*G0_5_3_2 + 0.000341246055531828*G0_5_3_3 + 4.12286126571913e-05*G0_5_3_4 + 5.6557199414352e-05*G0_5_3_5 - 9.32929504358238e-06*G0_5_4_0 + 5.25136239422042e-05*G0_5_4_1 + 5.25136239422042e-05*G0_5_4_2 + 4.12286126571912e-05*G0_5_4_3 - 0.000194725909011656*G0_5_4_4 - 0.000194725909011656*G0_5_4_5 - 1.24478695907289e-05*G0_5_5_0 + 0.000105370819656552*G0_5_5_1 + 4.48493305636238e-05*G0_5_5_2 + 5.6557199414352e-05*G0_5_5_3 - 0.000194725909011656*G0_5_5_4 - 0.000367568938997572*G0_5_5_5; + A[22] = 1.17739403453709e-05*G0_0_0_0 - 2.0085734371452e-06*G0_0_0_1 + 5.68875568875665e-06*G0_0_0_2 + 5.41125541125632e-06*G0_0_0_3 + 1.67887667887696e-05*G0_0_0_4 + 9.24340210054651e-06*G0_0_0_5 - 2.0085734371452e-06*G0_0_1_0 - 2.0085734371452e-06*G0_0_1_1 + 5.68875568875663e-06*G0_0_1_2 + 1.61875161875189e-06*G0_0_1_3 + 1.61875161875189e-06*G0_0_1_4 - 3.10536024821791e-06*G0_0_1_5 + 5.68875568875665e-06*G0_0_2_0 + 5.68875568875663e-06*G0_0_2_1 - 8.78750878751026e-05*G0_0_2_2 - 1.89625189625221e-05*G0_0_2_3 - 3.79250379250443e-05*G0_0_2_4 - 1.89625189625222e-06*G0_0_2_5 + 5.41125541125632e-06*G0_0_3_0 + 1.61875161875189e-06*G0_0_3_1 - 1.89625189625221e-05*G0_0_3_2 - 2.10900210900246e-05*G0_0_3_3 - 1.40600140600164e-05*G0_0_3_4 - 7.03000703000822e-06*G0_0_3_5 + 1.67887667887696e-05*G0_0_4_0 + 1.61875161875189e-06*G0_0_4_1 - 3.79250379250443e-05*G0_0_4_2 - 1.40600140600164e-05*G0_0_4_3 - 2.10900210900246e-05*G0_0_4_4 + 5.55000555000641e-07*G0_0_4_5 + 9.24340210054651e-06*G0_0_5_0 - 3.10536024821791e-06*G0_0_5_1 - 1.89625189625222e-06*G0_0_5_2 - 7.03000703000822e-06*G0_0_5_3 + 5.55000555000641e-07*G0_0_5_4 - 1.37428708857305e-06*G0_0_5_5 - 2.0085734371452e-06*G0_1_0_0 - 2.0085734371452e-06*G0_1_0_1 + 5.68875568875663e-06*G0_1_0_2 + 1.61875161875189e-06*G0_1_0_3 + 1.61875161875189e-06*G0_1_0_4 - 3.10536024821791e-06*G0_1_0_5 - 2.0085734371452e-06*G0_1_1_0 + 1.17739403453709e-05*G0_1_1_1 + 5.68875568875663e-06*G0_1_1_2 + 1.67887667887696e-05*G0_1_1_3 + 5.41125541125632e-06*G0_1_1_4 + 9.24340210054651e-06*G0_1_1_5 + 5.68875568875663e-06*G0_1_2_0 + 5.68875568875663e-06*G0_1_2_1 - 8.78750878751025e-05*G0_1_2_2 - 3.79250379250443e-05*G0_1_2_3 - 1.89625189625221e-05*G0_1_2_4 - 1.89625189625223e-06*G0_1_2_5 + 1.61875161875189e-06*G0_1_3_0 + 1.67887667887696e-05*G0_1_3_1 - 3.79250379250443e-05*G0_1_3_2 - 2.10900210900246e-05*G0_1_3_3 - 1.40600140600164e-05*G0_1_3_4 + 5.55000555000648e-07*G0_1_3_5 + 1.61875161875189e-06*G0_1_4_0 + 5.41125541125632e-06*G0_1_4_1 - 1.89625189625221e-05*G0_1_4_2 - 1.40600140600164e-05*G0_1_4_3 - 2.10900210900246e-05*G0_1_4_4 - 7.03000703000821e-06*G0_1_4_5 - 3.10536024821791e-06*G0_1_5_0 + 9.24340210054651e-06*G0_1_5_1 - 1.89625189625223e-06*G0_1_5_2 + 5.55000555000648e-07*G0_1_5_3 - 7.03000703000821e-06*G0_1_5_4 - 1.37428708857303e-06*G0_1_5_5 + 5.68875568875665e-06*G0_2_0_0 + 5.68875568875663e-06*G0_2_0_1 - 8.78750878751026e-05*G0_2_0_2 - 1.89625189625221e-05*G0_2_0_3 - 3.79250379250443e-05*G0_2_0_4 - 1.89625189625223e-06*G0_2_0_5 + 5.68875568875663e-06*G0_2_1_0 + 5.68875568875663e-06*G0_2_1_1 - 8.78750878751025e-05*G0_2_1_2 - 3.79250379250443e-05*G0_2_1_3 - 1.89625189625221e-05*G0_2_1_4 - 1.89625189625223e-06*G0_2_1_5 - 8.78750878751026e-05*G0_2_2_0 - 8.78750878751025e-05*G0_2_2_1 + 0.00187798312798344*G0_2_2_2 + 0.000370462870462933*G0_2_2_3 + 0.000370462870462932*G0_2_2_4 + 1.89625189625224e-05*G0_2_2_5 - 1.89625189625221e-05*G0_2_3_0 - 3.79250379250443e-05*G0_2_3_1 + 0.000370462870462933*G0_2_3_2 + 0.000151700151700177*G0_2_3_3 + 7.58500758500885e-05*G0_2_3_4 - 3.79250379250443e-05*G0_2_4_0 - 1.89625189625221e-05*G0_2_4_1 + 0.000370462870462932*G0_2_4_2 + 7.58500758500885e-05*G0_2_4_3 + 0.000151700151700177*G0_2_4_4 - 1.89625189625223e-06*G0_2_5_0 - 1.89625189625223e-06*G0_2_5_1 + 1.89625189625224e-05*G0_2_5_2 - 1.51700151700177e-05*G0_2_5_5 + 5.41125541125632e-06*G0_3_0_0 + 1.61875161875189e-06*G0_3_0_1 - 1.89625189625221e-05*G0_3_0_2 - 2.10900210900246e-05*G0_3_0_3 - 1.40600140600164e-05*G0_3_0_4 - 7.03000703000822e-06*G0_3_0_5 + 1.61875161875189e-06*G0_3_1_0 + 1.67887667887696e-05*G0_3_1_1 - 3.79250379250443e-05*G0_3_1_2 - 2.10900210900246e-05*G0_3_1_3 - 1.40600140600164e-05*G0_3_1_4 + 5.55000555000647e-07*G0_3_1_5 - 1.89625189625221e-05*G0_3_2_0 - 3.79250379250443e-05*G0_3_2_1 + 0.000370462870462933*G0_3_2_2 + 0.000151700151700177*G0_3_2_3 + 7.58500758500885e-05*G0_3_2_4 - 2.10900210900246e-05*G0_3_3_0 - 2.10900210900246e-05*G0_3_3_1 + 0.000151700151700177*G0_3_3_2 + 0.000210900210900247*G0_3_3_3 + 7.03000703000821e-05*G0_3_3_4 + 4.21800421800493e-05*G0_3_3_5 - 1.40600140600164e-05*G0_3_4_0 - 1.40600140600164e-05*G0_3_4_1 + 7.58500758500885e-05*G0_3_4_2 + 7.03000703000821e-05*G0_3_4_3 + 7.03000703000822e-05*G0_3_4_4 + 2.81200281200329e-05*G0_3_4_5 - 7.03000703000822e-06*G0_3_5_0 + 5.55000555000647e-07*G0_3_5_1 + 4.21800421800493e-05*G0_3_5_3 + 2.81200281200329e-05*G0_3_5_4 + 4.44000444000519e-05*G0_3_5_5 + 1.67887667887696e-05*G0_4_0_0 + 1.61875161875189e-06*G0_4_0_1 - 3.79250379250443e-05*G0_4_0_2 - 1.40600140600164e-05*G0_4_0_3 - 2.10900210900246e-05*G0_4_0_4 + 5.55000555000641e-07*G0_4_0_5 + 1.61875161875189e-06*G0_4_1_0 + 5.41125541125632e-06*G0_4_1_1 - 1.89625189625221e-05*G0_4_1_2 - 1.40600140600164e-05*G0_4_1_3 - 2.10900210900246e-05*G0_4_1_4 - 7.03000703000821e-06*G0_4_1_5 - 3.79250379250443e-05*G0_4_2_0 - 1.89625189625221e-05*G0_4_2_1 + 0.000370462870462932*G0_4_2_2 + 7.58500758500885e-05*G0_4_2_3 + 0.000151700151700177*G0_4_2_4 - 1.40600140600164e-05*G0_4_3_0 - 1.40600140600164e-05*G0_4_3_1 + 7.58500758500885e-05*G0_4_3_2 + 7.03000703000821e-05*G0_4_3_3 + 7.03000703000822e-05*G0_4_3_4 + 2.81200281200329e-05*G0_4_3_5 - 2.10900210900246e-05*G0_4_4_0 - 2.10900210900246e-05*G0_4_4_1 + 0.000151700151700177*G0_4_4_2 + 7.03000703000822e-05*G0_4_4_3 + 0.000210900210900246*G0_4_4_4 + 4.21800421800493e-05*G0_4_4_5 + 5.55000555000641e-07*G0_4_5_0 - 7.03000703000821e-06*G0_4_5_1 + 2.81200281200329e-05*G0_4_5_3 + 4.21800421800493e-05*G0_4_5_4 + 4.44000444000519e-05*G0_4_5_5 + 9.24340210054651e-06*G0_5_0_0 - 3.10536024821791e-06*G0_5_0_1 - 1.89625189625223e-06*G0_5_0_2 - 7.03000703000822e-06*G0_5_0_3 + 5.55000555000641e-07*G0_5_0_4 - 1.37428708857305e-06*G0_5_0_5 - 3.10536024821791e-06*G0_5_1_0 + 9.24340210054651e-06*G0_5_1_1 - 1.89625189625223e-06*G0_5_1_2 + 5.55000555000647e-07*G0_5_1_3 - 7.03000703000821e-06*G0_5_1_4 - 1.37428708857303e-06*G0_5_1_5 - 1.89625189625223e-06*G0_5_2_0 - 1.89625189625223e-06*G0_5_2_1 + 1.89625189625224e-05*G0_5_2_2 - 1.51700151700177e-05*G0_5_2_5 - 7.03000703000822e-06*G0_5_3_0 + 5.55000555000648e-07*G0_5_3_1 + 4.21800421800493e-05*G0_5_3_3 + 2.81200281200329e-05*G0_5_3_4 + 4.44000444000519e-05*G0_5_3_5 + 5.55000555000641e-07*G0_5_4_0 - 7.03000703000821e-06*G0_5_4_1 + 2.81200281200329e-05*G0_5_4_3 + 4.21800421800493e-05*G0_5_4_4 + 4.44000444000519e-05*G0_5_4_5 - 1.37428708857305e-06*G0_5_5_0 - 1.37428708857303e-06*G0_5_5_1 - 1.51700151700177e-05*G0_5_5_2 + 4.44000444000519e-05*G0_5_5_3 + 4.44000444000519e-05*G0_5_5_4 + 0.000116708688137279*G0_5_5_5; + A[10] = A[1]; + A[92] = A[1] - 6.96525696525814e-05*G0_0_0_0 + 7.17866789295481e-06*G0_0_0_1 - 2.00857343714521e-06*G0_0_0_2 - 2.04821633393096e-06*G0_0_0_3 - 4.15589701304056e-06*G0_0_0_4 - 2.36535950821704e-06*G0_0_0_5 + 7.17866789295481e-06*G0_0_1_0 + 7.17866789295485e-06*G0_0_1_1 + 4.95701388558615e-06*G0_0_1_2 - 2.42085956371711e-05*G0_0_1_3 - 2.42085956371712e-05*G0_0_1_4 - 1.91475191475224e-05*G0_0_1_5 - 2.00857343714521e-06*G0_0_2_0 + 4.95701388558615e-06*G0_0_2_1 - 1.66979184836356e-05*G0_0_2_2 + 2.33232376089558e-06*G0_0_2_3 - 1.20184048755498e-05*G0_0_2_4 + 7.20179291607984e-06*G0_0_2_5 - 2.04821633393096e-06*G0_0_3_0 - 2.42085956371711e-05*G0_0_3_1 + 2.33232376089557e-06*G0_0_3_2 + 4.48493305636239e-05*G0_0_3_3 + 5.25136239422042e-05*G0_0_3_4 - 1.03071531642978e-05*G0_0_3_5 - 4.15589701304057e-06*G0_0_4_0 - 2.42085956371712e-05*G0_0_4_1 - 1.20184048755498e-05*G0_0_4_2 + 5.25136239422042e-05*G0_0_4_3 + 0.000105370819656552*G0_0_4_4 + 3.40136054421826e-05*G0_0_4_5 - 2.36535950821705e-06*G0_0_5_0 - 1.91475191475224e-05*G0_0_5_1 + 7.20179291607984e-06*G0_0_5_2 - 1.03071531642978e-05*G0_0_5_3 + 3.40136054421826e-05*G0_0_5_4 - 4.18628990057633e-05*G0_0_5_5 + 7.17866789295481e-06*G0_1_0_0 + 7.17866789295485e-06*G0_1_0_1 + 4.95701388558615e-06*G0_1_0_2 - 2.42085956371711e-05*G0_1_0_3 - 2.42085956371712e-05*G0_1_0_4 - 1.91475191475224e-05*G0_1_0_5 + 7.17866789295485e-06*G0_1_1_0 - 6.96525696525818e-05*G0_1_1_1 - 2.00857343714519e-06*G0_1_1_2 - 4.15589701304065e-06*G0_1_1_3 - 2.04821633393097e-06*G0_1_1_4 - 2.36535950821719e-06*G0_1_1_5 + 4.95701388558615e-06*G0_1_2_0 - 2.00857343714519e-06*G0_1_2_1 - 1.66979184836356e-05*G0_1_2_2 - 1.20184048755498e-05*G0_1_2_3 + 2.33232376089559e-06*G0_1_2_4 + 7.20179291607984e-06*G0_1_2_5 - 2.42085956371711e-05*G0_1_3_0 - 4.15589701304065e-06*G0_1_3_1 - 1.20184048755498e-05*G0_1_3_2 + 0.000105370819656552*G0_1_3_3 + 5.25136239422043e-05*G0_1_3_4 + 3.40136054421826e-05*G0_1_3_5 - 2.42085956371712e-05*G0_1_4_0 - 2.04821633393097e-06*G0_1_4_1 + 2.33232376089559e-06*G0_1_4_2 + 5.25136239422043e-05*G0_1_4_3 + 4.48493305636239e-05*G0_1_4_4 - 1.03071531642977e-05*G0_1_4_5 - 1.91475191475224e-05*G0_1_5_0 - 2.3653595082172e-06*G0_1_5_1 + 7.20179291607984e-06*G0_1_5_2 + 3.40136054421826e-05*G0_1_5_3 - 1.03071531642977e-05*G0_1_5_4 - 4.18628990057632e-05*G0_1_5_5 - 2.00857343714521e-06*G0_2_0_0 + 4.95701388558615e-06*G0_2_0_1 - 1.66979184836356e-05*G0_2_0_2 + 2.33232376089558e-06*G0_2_0_3 - 1.20184048755498e-05*G0_2_0_4 + 7.20179291607984e-06*G0_2_0_5 + 4.95701388558615e-06*G0_2_1_0 - 2.00857343714519e-06*G0_2_1_1 - 1.66979184836356e-05*G0_2_1_2 - 1.20184048755498e-05*G0_2_1_3 + 2.33232376089558e-06*G0_2_1_4 + 7.20179291607984e-06*G0_2_1_5 - 1.66979184836356e-05*G0_2_2_0 - 1.66979184836356e-05*G0_2_2_1 + 0.000139458755530207*G0_2_2_2 + 8.11424025709877e-05*G0_2_2_3 + 8.11424025709877e-05*G0_2_2_4 + 3.42316413745043e-05*G0_2_2_5 + 2.33232376089558e-06*G0_2_3_0 - 1.20184048755498e-05*G0_2_3_1 + 8.11424025709877e-05*G0_2_3_2 - 1.24478695907288e-05*G0_2_3_3 - 9.32929504358231e-06*G0_2_3_4 - 7.31279302707997e-05*G0_2_3_5 - 1.20184048755498e-05*G0_2_4_0 + 2.33232376089558e-06*G0_2_4_1 + 8.11424025709877e-05*G0_2_4_2 - 9.32929504358231e-06*G0_2_4_3 - 1.24478695907288e-05*G0_2_4_4 - 7.31279302707998e-05*G0_2_4_5 + 7.20179291607984e-06*G0_2_5_0 + 7.20179291607985e-06*G0_2_5_1 + 3.42316413745043e-05*G0_2_5_2 - 7.31279302707997e-05*G0_2_5_3 - 7.31279302707998e-05*G0_2_5_4 - 0.000160315874601616*G0_2_5_5 - 2.04821633393096e-06*G0_3_0_0 - 2.42085956371711e-05*G0_3_0_1 + 2.33232376089558e-06*G0_3_0_2 + 4.48493305636239e-05*G0_3_0_3 + 5.25136239422042e-05*G0_3_0_4 - 1.03071531642978e-05*G0_3_0_5 - 2.42085956371711e-05*G0_3_1_0 - 4.15589701304065e-06*G0_3_1_1 - 1.20184048755498e-05*G0_3_1_2 + 0.000105370819656552*G0_3_1_3 + 5.25136239422043e-05*G0_3_1_4 + 3.40136054421826e-05*G0_3_1_5 + 2.33232376089558e-06*G0_3_2_0 - 1.20184048755498e-05*G0_3_2_1 + 8.11424025709877e-05*G0_3_2_2 - 1.24478695907288e-05*G0_3_2_3 - 9.32929504358232e-06*G0_3_2_4 - 7.31279302707997e-05*G0_3_2_5 + 4.48493305636239e-05*G0_3_3_0 + 0.000105370819656552*G0_3_3_1 - 1.24478695907288e-05*G0_3_3_2 - 0.000367568938997573*G0_3_3_3 - 0.000194725909011656*G0_3_3_4 + 5.65571994143517e-05*G0_3_3_5 + 5.25136239422042e-05*G0_3_4_0 + 5.25136239422043e-05*G0_3_4_1 - 9.32929504358231e-06*G0_3_4_2 - 0.000194725909011656*G0_3_4_3 - 0.000194725909011656*G0_3_4_4 + 4.1228612657191e-05*G0_3_4_5 - 1.03071531642978e-05*G0_3_5_0 + 3.40136054421826e-05*G0_3_5_1 - 7.31279302707997e-05*G0_3_5_2 + 5.65571994143517e-05*G0_3_5_3 + 4.1228612657191e-05*G0_3_5_4 + 0.000341246055531827*G0_3_5_5 - 4.15589701304058e-06*G0_4_0_0 - 2.42085956371712e-05*G0_4_0_1 - 1.20184048755498e-05*G0_4_0_2 + 5.25136239422043e-05*G0_4_0_3 + 0.000105370819656552*G0_4_0_4 + 3.40136054421826e-05*G0_4_0_5 - 2.42085956371712e-05*G0_4_1_0 - 2.04821633393097e-06*G0_4_1_1 + 2.33232376089559e-06*G0_4_1_2 + 5.25136239422043e-05*G0_4_1_3 + 4.48493305636239e-05*G0_4_1_4 - 1.03071531642977e-05*G0_4_1_5 - 1.20184048755498e-05*G0_4_2_0 + 2.33232376089558e-06*G0_4_2_1 + 8.11424025709877e-05*G0_4_2_2 - 9.32929504358231e-06*G0_4_2_3 - 1.24478695907288e-05*G0_4_2_4 - 7.31279302707998e-05*G0_4_2_5 + 5.25136239422043e-05*G0_4_3_0 + 5.25136239422043e-05*G0_4_3_1 - 9.32929504358231e-06*G0_4_3_2 - 0.000194725909011656*G0_4_3_3 - 0.000194725909011656*G0_4_3_4 + 4.1228612657191e-05*G0_4_3_5 + 0.000105370819656552*G0_4_4_0 + 4.48493305636239e-05*G0_4_4_1 - 1.24478695907288e-05*G0_4_4_2 - 0.000194725909011656*G0_4_4_3 - 0.000367568938997572*G0_4_4_4 + 5.65571994143518e-05*G0_4_4_5 + 3.40136054421826e-05*G0_4_5_0 - 1.03071531642977e-05*G0_4_5_1 - 7.31279302707998e-05*G0_4_5_2 + 4.1228612657191e-05*G0_4_5_3 + 5.65571994143518e-05*G0_4_5_4 + 0.000341246055531827*G0_4_5_5 - 2.36535950821705e-06*G0_5_0_0 - 1.91475191475224e-05*G0_5_0_1 + 7.20179291607984e-06*G0_5_0_2 - 1.03071531642978e-05*G0_5_0_3 + 3.40136054421826e-05*G0_5_0_4 - 4.18628990057633e-05*G0_5_0_5 - 1.91475191475224e-05*G0_5_1_0 - 2.3653595082172e-06*G0_5_1_1 + 7.20179291607984e-06*G0_5_1_2 + 3.40136054421826e-05*G0_5_1_3 - 1.03071531642977e-05*G0_5_1_4 - 4.18628990057632e-05*G0_5_1_5 + 7.20179291607984e-06*G0_5_2_0 + 7.20179291607985e-06*G0_5_2_1 + 3.42316413745043e-05*G0_5_2_2 - 7.31279302707997e-05*G0_5_2_3 - 7.31279302707998e-05*G0_5_2_4 - 0.000160315874601616*G0_5_2_5 - 1.03071531642978e-05*G0_5_3_0 + 3.40136054421826e-05*G0_5_3_1 - 7.31279302707997e-05*G0_5_3_2 + 5.65571994143517e-05*G0_5_3_3 + 4.1228612657191e-05*G0_5_3_4 + 0.000341246055531827*G0_5_3_5 + 3.40136054421826e-05*G0_5_4_0 - 1.03071531642977e-05*G0_5_4_1 - 7.31279302707998e-05*G0_5_4_2 + 4.1228612657191e-05*G0_5_4_3 + 5.65571994143518e-05*G0_5_4_4 + 0.000341246055531827*G0_5_4_5 - 4.18628990057633e-05*G0_5_5_0 - 4.18628990057632e-05*G0_5_5_1 - 0.000160315874601616*G0_5_5_2 + 0.000341246055531827*G0_5_5_3 + 0.000341246055531827*G0_5_5_4 + 0.000990120990121157*G0_5_5_5; + A[2] = 0.000103368853368871*G0_0_0_0 - 6.19750619750723e-06*G0_0_0_1 - 8.69500869501017e-06*G0_0_0_2 + 2.40500240500281e-06*G0_0_0_3 + 4.37525437525512e-05*G0_0_0_4 + 2.77037777037823e-05*G0_0_0_5 - 6.19750619750723e-06*G0_0_1_0 - 7.84598998884847e-07*G0_0_1_1 + 1.82192146477891e-06*G0_0_1_2 - 2.33232376089558e-06*G0_0_1_3 - 3.27714613428954e-06*G0_0_1_4 - 5.46411260697066e-06*G0_0_1_5 - 8.69500869501017e-06*G0_0_2_0 + 1.82192146477891e-06*G0_0_2_1 - 8.69500869501015e-06*G0_0_2_2 - 2.55035969321727e-06*G0_0_2_3 - 1.22496551068e-05*G0_0_2_4 - 2.55035969321727e-06*G0_0_2_5 + 2.40500240500281e-06*G0_0_3_0 - 2.33232376089558e-06*G0_0_3_1 - 2.55035969321727e-06*G0_0_3_2 + 2.24643081785977e-06*G0_0_3_3 + 1.74428745857347e-06*G0_0_3_4 + 2.90714576428911e-07*G0_0_3_5 + 4.37525437525512e-05*G0_0_4_0 - 3.27714613428954e-06*G0_0_4_1 - 1.22496551068e-05*G0_0_4_2 + 1.74428745857347e-06*G0_0_4_3 + 2.33100233100273e-05*G0_0_4_4 + 1.16550116550136e-05*G0_0_4_5 + 2.77037777037823e-05*G0_0_5_0 - 5.46411260697066e-06*G0_0_5_1 - 2.55035969321727e-06*G0_0_5_2 + 2.90714576428911e-07*G0_0_5_3 + 1.16550116550136e-05*G0_0_5_4 + 1.16550116550136e-05*G0_0_5_5 - 6.19750619750723e-06*G0_1_0_0 - 7.84598998884847e-07*G0_1_0_1 + 1.82192146477891e-06*G0_1_0_2 - 2.33232376089558e-06*G0_1_0_3 - 3.27714613428954e-06*G0_1_0_4 - 5.46411260697067e-06*G0_1_0_5 - 7.84598998884847e-07*G0_1_1_0 + 1.03913943199675e-05*G0_1_1_1 - 7.84598998884849e-07*G0_1_1_2 + 6.27018484161448e-06*G0_1_1_3 + 7.33393590536569e-07*G0_1_1_4 + 6.27018484161447e-06*G0_1_1_5 + 1.82192146477891e-06*G0_1_2_0 - 7.84598998884849e-07*G0_1_2_1 - 6.19750619750723e-06*G0_1_2_2 - 5.46411260697067e-06*G0_1_2_3 - 3.27714613428954e-06*G0_1_2_4 - 2.33232376089558e-06*G0_1_2_5 - 2.33232376089558e-06*G0_1_3_0 + 6.27018484161448e-06*G0_1_3_1 - 5.46411260697067e-06*G0_1_3_2 + 1.24478695907288e-05*G0_1_3_3 + 3.19786034071803e-06*G0_1_3_4 + 9.32929504358233e-06*G0_1_3_5 - 3.27714613428954e-06*G0_1_4_0 + 7.33393590536569e-07*G0_1_4_1 - 3.27714613428954e-06*G0_1_4_2 + 3.19786034071803e-06*G0_1_4_3 - 2.37857380714563e-06*G0_1_4_4 + 3.19786034071802e-06*G0_1_4_5 - 5.46411260697066e-06*G0_1_5_0 + 6.27018484161447e-06*G0_1_5_1 - 2.33232376089558e-06*G0_1_5_2 + 9.32929504358233e-06*G0_1_5_3 + 3.19786034071802e-06*G0_1_5_4 + 1.24478695907288e-05*G0_1_5_5 - 8.69500869501017e-06*G0_2_0_0 + 1.82192146477891e-06*G0_2_0_1 - 8.69500869501015e-06*G0_2_0_2 - 2.55035969321727e-06*G0_2_0_3 - 1.22496551068e-05*G0_2_0_4 - 2.55035969321727e-06*G0_2_0_5 + 1.82192146477891e-06*G0_2_1_0 - 7.84598998884849e-07*G0_2_1_1 - 6.19750619750723e-06*G0_2_1_2 - 5.46411260697067e-06*G0_2_1_3 - 3.27714613428954e-06*G0_2_1_4 - 2.33232376089558e-06*G0_2_1_5 - 8.69500869501016e-06*G0_2_2_0 - 6.19750619750723e-06*G0_2_2_1 + 0.000103368853368871*G0_2_2_2 + 2.77037777037824e-05*G0_2_2_3 + 4.37525437525511e-05*G0_2_2_4 + 2.40500240500282e-06*G0_2_2_5 - 2.55035969321727e-06*G0_2_3_0 - 5.46411260697067e-06*G0_2_3_1 + 2.77037777037824e-05*G0_2_3_2 + 1.16550116550136e-05*G0_2_3_3 + 1.16550116550136e-05*G0_2_3_4 + 2.90714576428914e-07*G0_2_3_5 - 1.22496551068e-05*G0_2_4_0 - 3.27714613428954e-06*G0_2_4_1 + 4.37525437525511e-05*G0_2_4_2 + 1.16550116550136e-05*G0_2_4_3 + 2.33100233100272e-05*G0_2_4_4 + 1.74428745857347e-06*G0_2_4_5 - 2.55035969321727e-06*G0_2_5_0 - 2.33232376089558e-06*G0_2_5_1 + 2.40500240500282e-06*G0_2_5_2 + 2.90714576428913e-07*G0_2_5_3 + 1.74428745857347e-06*G0_2_5_4 + 2.24643081785977e-06*G0_2_5_5 + 2.40500240500281e-06*G0_3_0_0 - 2.33232376089558e-06*G0_3_0_1 - 2.55035969321727e-06*G0_3_0_2 + 2.24643081785977e-06*G0_3_0_3 + 1.74428745857347e-06*G0_3_0_4 + 2.90714576428912e-07*G0_3_0_5 - 2.33232376089558e-06*G0_3_1_0 + 6.27018484161448e-06*G0_3_1_1 - 5.46411260697067e-06*G0_3_1_2 + 1.24478695907288e-05*G0_3_1_3 + 3.19786034071803e-06*G0_3_1_4 + 9.32929504358233e-06*G0_3_1_5 - 2.55035969321727e-06*G0_3_2_0 - 5.46411260697067e-06*G0_3_2_1 + 2.77037777037824e-05*G0_3_2_2 + 1.16550116550136e-05*G0_3_2_3 + 1.16550116550136e-05*G0_3_2_4 + 2.90714576428914e-07*G0_3_2_5 + 2.24643081785977e-06*G0_3_3_0 + 1.24478695907288e-05*G0_3_3_1 + 1.16550116550136e-05*G0_3_3_2 - 3.20314606028946e-05*G0_3_3_3 - 1.08885823171556e-05*G0_3_3_4 - 5.07429078857737e-06*G0_3_3_5 + 1.74428745857347e-06*G0_3_4_0 + 3.19786034071803e-06*G0_3_4_1 + 1.16550116550136e-05*G0_3_4_2 - 1.08885823171556e-05*G0_3_4_3 + 1.26857269714433e-06*G0_3_4_4 - 6.97714983429387e-06*G0_3_4_5 + 2.90714576428912e-07*G0_3_5_0 + 9.32929504358233e-06*G0_3_5_1 + 2.90714576428913e-07*G0_3_5_2 - 5.07429078857737e-06*G0_3_5_3 - 6.97714983429387e-06*G0_3_5_4 - 5.07429078857736e-06*G0_3_5_5 + 4.37525437525512e-05*G0_4_0_0 - 3.27714613428954e-06*G0_4_0_1 - 1.22496551068e-05*G0_4_0_2 + 1.74428745857347e-06*G0_4_0_3 + 2.33100233100273e-05*G0_4_0_4 + 1.16550116550136e-05*G0_4_0_5 - 3.27714613428954e-06*G0_4_1_0 + 7.33393590536569e-07*G0_4_1_1 - 3.27714613428954e-06*G0_4_1_2 + 3.19786034071803e-06*G0_4_1_3 - 2.37857380714563e-06*G0_4_1_4 + 3.19786034071802e-06*G0_4_1_5 - 1.22496551068e-05*G0_4_2_0 - 3.27714613428954e-06*G0_4_2_1 + 4.37525437525511e-05*G0_4_2_2 + 1.16550116550136e-05*G0_4_2_3 + 2.33100233100272e-05*G0_4_2_4 + 1.74428745857347e-06*G0_4_2_5 + 1.74428745857347e-06*G0_4_3_0 + 3.19786034071803e-06*G0_4_3_1 + 1.16550116550136e-05*G0_4_3_2 - 1.08885823171556e-05*G0_4_3_3 + 1.26857269714433e-06*G0_4_3_4 - 6.97714983429387e-06*G0_4_3_5 + 2.33100233100273e-05*G0_4_4_0 - 2.37857380714563e-06*G0_4_4_1 + 2.33100233100272e-05*G0_4_4_2 + 1.26857269714433e-06*G0_4_4_3 + 8.30915116629543e-05*G0_4_4_4 + 1.26857269714433e-06*G0_4_4_5 + 1.16550116550136e-05*G0_4_5_0 + 3.19786034071802e-06*G0_4_5_1 + 1.74428745857347e-06*G0_4_5_2 - 6.97714983429387e-06*G0_4_5_3 + 1.26857269714433e-06*G0_4_5_4 - 1.08885823171556e-05*G0_4_5_5 + 2.77037777037823e-05*G0_5_0_0 - 5.46411260697066e-06*G0_5_0_1 - 2.55035969321727e-06*G0_5_0_2 + 2.90714576428911e-07*G0_5_0_3 + 1.16550116550136e-05*G0_5_0_4 + 1.16550116550136e-05*G0_5_0_5 - 5.46411260697066e-06*G0_5_1_0 + 6.27018484161447e-06*G0_5_1_1 - 2.33232376089558e-06*G0_5_1_2 + 9.32929504358233e-06*G0_5_1_3 + 3.19786034071802e-06*G0_5_1_4 + 1.24478695907288e-05*G0_5_1_5 - 2.55035969321727e-06*G0_5_2_0 - 2.33232376089558e-06*G0_5_2_1 + 2.40500240500282e-06*G0_5_2_2 + 2.90714576428914e-07*G0_5_2_3 + 1.74428745857347e-06*G0_5_2_4 + 2.24643081785977e-06*G0_5_2_5 + 2.90714576428912e-07*G0_5_3_0 + 9.32929504358233e-06*G0_5_3_1 + 2.90714576428914e-07*G0_5_3_2 - 5.07429078857737e-06*G0_5_3_3 - 6.97714983429387e-06*G0_5_3_4 - 5.07429078857736e-06*G0_5_3_5 + 1.16550116550136e-05*G0_5_4_0 + 3.19786034071802e-06*G0_5_4_1 + 1.74428745857347e-06*G0_5_4_2 - 6.97714983429387e-06*G0_5_4_3 + 1.26857269714433e-06*G0_5_4_4 - 1.08885823171556e-05*G0_5_4_5 + 1.16550116550136e-05*G0_5_5_0 + 1.24478695907288e-05*G0_5_5_1 + 2.24643081785977e-06*G0_5_5_2 - 5.07429078857736e-06*G0_5_5_3 - 1.08885823171556e-05*G0_5_5_4 - 3.20314606028946e-05*G0_5_5_5; + A[19] = A[2] - 6.96525696525814e-05*G0_0_0_0 - 2.00857343714521e-06*G0_0_0_1 + 7.17866789295483e-06*G0_0_0_2 - 2.04821633393097e-06*G0_0_0_3 - 2.36535950821713e-06*G0_0_0_4 - 4.15589701304058e-06*G0_0_0_5 - 2.00857343714521e-06*G0_0_1_0 - 1.66979184836356e-05*G0_0_1_1 + 4.95701388558615e-06*G0_0_1_2 + 2.33232376089557e-06*G0_0_1_3 + 7.20179291607984e-06*G0_0_1_4 - 1.20184048755498e-05*G0_0_1_5 + 7.17866789295483e-06*G0_0_2_0 + 4.95701388558615e-06*G0_0_2_1 + 7.17866789295482e-06*G0_0_2_2 - 2.42085956371711e-05*G0_0_2_3 - 1.91475191475223e-05*G0_0_2_4 - 2.42085956371712e-05*G0_0_2_5 - 2.04821633393097e-06*G0_0_3_0 + 2.33232376089558e-06*G0_0_3_1 - 2.42085956371711e-05*G0_0_3_2 + 4.48493305636238e-05*G0_0_3_3 - 1.03071531642977e-05*G0_0_3_4 + 5.25136239422043e-05*G0_0_3_5 - 2.36535950821712e-06*G0_0_4_0 + 7.20179291607984e-06*G0_0_4_1 - 1.91475191475223e-05*G0_0_4_2 - 1.03071531642977e-05*G0_0_4_3 - 4.18628990057632e-05*G0_0_4_4 + 3.40136054421826e-05*G0_0_4_5 - 4.15589701304058e-06*G0_0_5_0 - 1.20184048755498e-05*G0_0_5_1 - 2.42085956371712e-05*G0_0_5_2 + 5.25136239422043e-05*G0_0_5_3 + 3.40136054421827e-05*G0_0_5_4 + 0.000105370819656552*G0_0_5_5 - 2.00857343714521e-06*G0_1_0_0 - 1.66979184836356e-05*G0_1_0_1 + 4.95701388558615e-06*G0_1_0_2 + 2.33232376089557e-06*G0_1_0_3 + 7.20179291607984e-06*G0_1_0_4 - 1.20184048755498e-05*G0_1_0_5 - 1.66979184836356e-05*G0_1_1_0 + 0.000139458755530208*G0_1_1_1 - 1.66979184836356e-05*G0_1_1_2 + 8.11424025709878e-05*G0_1_1_3 + 3.42316413745043e-05*G0_1_1_4 + 8.11424025709878e-05*G0_1_1_5 + 4.95701388558615e-06*G0_1_2_0 - 1.66979184836356e-05*G0_1_2_1 - 2.0085734371452e-06*G0_1_2_2 - 1.20184048755498e-05*G0_1_2_3 + 7.20179291607985e-06*G0_1_2_4 + 2.33232376089558e-06*G0_1_2_5 + 2.33232376089557e-06*G0_1_3_0 + 8.11424025709878e-05*G0_1_3_1 - 1.20184048755498e-05*G0_1_3_2 - 1.24478695907287e-05*G0_1_3_3 - 7.31279302707997e-05*G0_1_3_4 - 9.32929504358229e-06*G0_1_3_5 + 7.20179291607984e-06*G0_1_4_0 + 3.42316413745043e-05*G0_1_4_1 + 7.20179291607985e-06*G0_1_4_2 - 7.31279302707997e-05*G0_1_4_3 - 0.000160315874601616*G0_1_4_4 - 7.31279302707997e-05*G0_1_4_5 - 1.20184048755498e-05*G0_1_5_0 + 8.11424025709878e-05*G0_1_5_1 + 2.33232376089558e-06*G0_1_5_2 - 9.3292950435823e-06*G0_1_5_3 - 7.31279302707997e-05*G0_1_5_4 - 1.24478695907288e-05*G0_1_5_5 + 7.17866789295483e-06*G0_2_0_0 + 4.95701388558615e-06*G0_2_0_1 + 7.17866789295482e-06*G0_2_0_2 - 2.42085956371711e-05*G0_2_0_3 - 1.91475191475223e-05*G0_2_0_4 - 2.42085956371712e-05*G0_2_0_5 + 4.95701388558615e-06*G0_2_1_0 - 1.66979184836356e-05*G0_2_1_1 - 2.0085734371452e-06*G0_2_1_2 - 1.20184048755498e-05*G0_2_1_3 + 7.20179291607985e-06*G0_2_1_4 + 2.33232376089558e-06*G0_2_1_5 + 7.17866789295482e-06*G0_2_2_0 - 2.0085734371452e-06*G0_2_2_1 - 6.96525696525813e-05*G0_2_2_2 - 4.15589701304058e-06*G0_2_2_3 - 2.36535950821709e-06*G0_2_2_4 - 2.04821633393099e-06*G0_2_2_5 - 2.42085956371711e-05*G0_2_3_0 - 1.20184048755498e-05*G0_2_3_1 - 4.15589701304058e-06*G0_2_3_2 + 0.000105370819656552*G0_2_3_3 + 3.40136054421826e-05*G0_2_3_4 + 5.25136239422042e-05*G0_2_3_5 - 1.91475191475223e-05*G0_2_4_0 + 7.20179291607985e-06*G0_2_4_1 - 2.3653595082171e-06*G0_2_4_2 + 3.40136054421826e-05*G0_2_4_3 - 4.18628990057633e-05*G0_2_4_4 - 1.03071531642977e-05*G0_2_4_5 - 2.42085956371712e-05*G0_2_5_0 + 2.33232376089557e-06*G0_2_5_1 - 2.04821633393099e-06*G0_2_5_2 + 5.25136239422043e-05*G0_2_5_3 - 1.03071531642977e-05*G0_2_5_4 + 4.4849330563624e-05*G0_2_5_5 - 2.04821633393097e-06*G0_3_0_0 + 2.33232376089558e-06*G0_3_0_1 - 2.42085956371711e-05*G0_3_0_2 + 4.48493305636238e-05*G0_3_0_3 - 1.03071531642977e-05*G0_3_0_4 + 5.25136239422043e-05*G0_3_0_5 + 2.33232376089557e-06*G0_3_1_0 + 8.11424025709878e-05*G0_3_1_1 - 1.20184048755498e-05*G0_3_1_2 - 1.24478695907287e-05*G0_3_1_3 - 7.31279302707997e-05*G0_3_1_4 - 9.32929504358228e-06*G0_3_1_5 - 2.42085956371711e-05*G0_3_2_0 - 1.20184048755498e-05*G0_3_2_1 - 4.15589701304058e-06*G0_3_2_2 + 0.000105370819656552*G0_3_2_3 + 3.40136054421826e-05*G0_3_2_4 + 5.25136239422043e-05*G0_3_2_5 + 4.48493305636238e-05*G0_3_3_0 - 1.24478695907287e-05*G0_3_3_1 + 0.000105370819656552*G0_3_3_2 - 0.000367568938997572*G0_3_3_3 + 5.65571994143518e-05*G0_3_3_4 - 0.000194725909011656*G0_3_3_5 - 1.03071531642977e-05*G0_3_4_0 - 7.31279302707997e-05*G0_3_4_1 + 3.40136054421826e-05*G0_3_4_2 + 5.65571994143517e-05*G0_3_4_3 + 0.000341246055531827*G0_3_4_4 + 4.12286126571909e-05*G0_3_4_5 + 5.25136239422043e-05*G0_3_5_0 - 9.3292950435823e-06*G0_3_5_1 + 5.25136239422043e-05*G0_3_5_2 - 0.000194725909011656*G0_3_5_3 + 4.12286126571909e-05*G0_3_5_4 - 0.000194725909011657*G0_3_5_5 - 2.36535950821712e-06*G0_4_0_0 + 7.20179291607984e-06*G0_4_0_1 - 1.91475191475223e-05*G0_4_0_2 - 1.03071531642977e-05*G0_4_0_3 - 4.18628990057632e-05*G0_4_0_4 + 3.40136054421826e-05*G0_4_0_5 + 7.20179291607984e-06*G0_4_1_0 + 3.42316413745043e-05*G0_4_1_1 + 7.20179291607985e-06*G0_4_1_2 - 7.31279302707997e-05*G0_4_1_3 - 0.000160315874601616*G0_4_1_4 - 7.31279302707997e-05*G0_4_1_5 - 1.91475191475223e-05*G0_4_2_0 + 7.20179291607985e-06*G0_4_2_1 - 2.36535950821708e-06*G0_4_2_2 + 3.40136054421826e-05*G0_4_2_3 - 4.18628990057633e-05*G0_4_2_4 - 1.03071531642977e-05*G0_4_2_5 - 1.03071531642977e-05*G0_4_3_0 - 7.31279302707997e-05*G0_4_3_1 + 3.40136054421826e-05*G0_4_3_2 + 5.65571994143518e-05*G0_4_3_3 + 0.000341246055531827*G0_4_3_4 + 4.12286126571909e-05*G0_4_3_5 - 4.18628990057632e-05*G0_4_4_0 - 0.000160315874601616*G0_4_4_1 - 4.18628990057633e-05*G0_4_4_2 + 0.000341246055531827*G0_4_4_3 + 0.000990120990121157*G0_4_4_4 + 0.000341246055531827*G0_4_4_5 + 3.40136054421826e-05*G0_4_5_0 - 7.31279302707997e-05*G0_4_5_1 - 1.03071531642977e-05*G0_4_5_2 + 4.12286126571909e-05*G0_4_5_3 + 0.000341246055531827*G0_4_5_4 + 5.65571994143515e-05*G0_4_5_5 - 4.15589701304058e-06*G0_5_0_0 - 1.20184048755498e-05*G0_5_0_1 - 2.42085956371712e-05*G0_5_0_2 + 5.25136239422043e-05*G0_5_0_3 + 3.40136054421826e-05*G0_5_0_4 + 0.000105370819656552*G0_5_0_5 - 1.20184048755498e-05*G0_5_1_0 + 8.11424025709878e-05*G0_5_1_1 + 2.33232376089558e-06*G0_5_1_2 - 9.32929504358231e-06*G0_5_1_3 - 7.31279302707997e-05*G0_5_1_4 - 1.24478695907288e-05*G0_5_1_5 - 2.42085956371712e-05*G0_5_2_0 + 2.33232376089557e-06*G0_5_2_1 - 2.04821633393099e-06*G0_5_2_2 + 5.25136239422043e-05*G0_5_2_3 - 1.03071531642977e-05*G0_5_2_4 + 4.4849330563624e-05*G0_5_2_5 + 5.25136239422043e-05*G0_5_3_0 - 9.3292950435823e-06*G0_5_3_1 + 5.25136239422043e-05*G0_5_3_2 - 0.000194725909011656*G0_5_3_3 + 4.12286126571909e-05*G0_5_3_4 - 0.000194725909011657*G0_5_3_5 + 3.40136054421826e-05*G0_5_4_0 - 7.31279302707997e-05*G0_5_4_1 - 1.03071531642977e-05*G0_5_4_2 + 4.12286126571909e-05*G0_5_4_3 + 0.000341246055531827*G0_5_4_4 + 5.65571994143515e-05*G0_5_4_5 + 0.000105370819656552*G0_5_5_0 - 1.24478695907288e-05*G0_5_5_1 + 4.4849330563624e-05*G0_5_5_2 - 0.000194725909011657*G0_5_5_3 + 5.65571994143515e-05*G0_5_5_4 - 0.000367568938997574*G0_5_5_5; + A[42] = A[7] - 0.00100841123162569*G0_0_0_0 + 0.000107154750011911*G0_0_0_1 + 6.55594405594515e-05*G0_0_0_2 - 2.3012701584134e-05*G0_0_0_3 - 0.000235895057323668*G0_0_0_4 - 0.000470600827743764*G0_0_0_5 + 0.000107154750011911*G0_0_1_0 - 1.95786356500675e-05*G0_0_1_1 + 3.2110746396466e-06*G0_0_1_3 + 2.63427049141379e-05*G0_0_1_4 + 6.82056039199011e-05*G0_0_1_5 + 6.55594405594515e-05*G0_0_2_0 - 6.55594405594516e-05*G0_0_2_2 - 2.62237762237806e-05*G0_0_2_3 + 2.62237762237806e-05*G0_0_2_5 - 2.3012701584134e-05*G0_0_3_0 + 3.2110746396466e-06*G0_0_3_1 - 2.62237762237806e-05*G0_0_3_2 + 4.99500499500585e-06*G0_0_3_3 - 6.66000666000777e-06*G0_0_3_4 - 6.42214927929321e-06*G0_0_3_5 - 0.000235895057323668*G0_0_4_0 + 2.63427049141379e-05*G0_0_4_1 - 6.66000666000777e-06*G0_0_4_3 - 0.00011155511155513*G0_0_4_4 - 0.000105132962275837*G0_0_4_5 - 0.000470600827743764*G0_0_5_0 + 6.82056039199011e-05*G0_0_5_1 + 2.62237762237806e-05*G0_0_5_2 - 6.42214927929321e-06*G0_0_5_3 - 0.000105132962275837*G0_0_5_4 - 0.000323961752533236*G0_0_5_5 + 0.000107154750011911*G0_1_0_0 - 1.95786356500675e-05*G0_1_0_1 + 3.2110746396466e-06*G0_1_0_3 + 2.63427049141379e-05*G0_1_0_4 + 6.82056039199011e-05*G0_1_0_5 - 1.95786356500675e-05*G0_1_1_0 + 1.95786356500675e-05*G0_1_1_2 - 6.89786404072237e-06*G0_1_1_3 + 6.89786404072241e-06*G0_1_1_5 + 1.95786356500675e-05*G0_1_2_1 - 0.000107154750011911*G0_1_2_2 - 6.82056039199011e-05*G0_1_2_3 - 2.63427049141379e-05*G0_1_2_4 - 3.21107463964662e-06*G0_1_2_5 + 3.2110746396466e-06*G0_1_3_0 - 6.89786404072237e-06*G0_1_3_1 - 6.82056039199011e-05*G0_1_3_2 - 4.61443318586254e-05*G0_1_3_3 - 6.4221492792932e-06*G0_1_3_4 + 2.63427049141379e-05*G0_1_4_0 - 2.63427049141379e-05*G0_1_4_2 - 6.4221492792932e-06*G0_1_4_3 + 6.42214927929323e-06*G0_1_4_5 + 6.82056039199011e-05*G0_1_5_0 + 6.89786404072241e-06*G0_1_5_1 - 3.21107463964662e-06*G0_1_5_2 + 6.42214927929322e-06*G0_1_5_4 + 4.61443318586254e-05*G0_1_5_5 + 6.55594405594515e-05*G0_2_0_0 - 6.55594405594516e-05*G0_2_0_2 - 2.62237762237806e-05*G0_2_0_3 + 2.62237762237806e-05*G0_2_0_5 + 1.95786356500675e-05*G0_2_1_1 - 0.000107154750011911*G0_2_1_2 - 6.82056039199011e-05*G0_2_1_3 - 2.63427049141379e-05*G0_2_1_4 - 3.21107463964662e-06*G0_2_1_5 - 6.55594405594516e-05*G0_2_2_0 - 0.000107154750011911*G0_2_2_1 + 0.00100841123162569*G0_2_2_2 + 0.000470600827743764*G0_2_2_3 + 0.000235895057323668*G0_2_2_4 + 2.30127015841342e-05*G0_2_2_5 - 2.62237762237806e-05*G0_2_3_0 - 6.82056039199011e-05*G0_2_3_1 + 0.000470600827743764*G0_2_3_2 + 0.000323961752533236*G0_2_3_3 + 0.000105132962275837*G0_2_3_4 + 6.42214927929329e-06*G0_2_3_5 - 2.63427049141379e-05*G0_2_4_1 + 0.000235895057323668*G0_2_4_2 + 0.000105132962275837*G0_2_4_3 + 0.00011155511155513*G0_2_4_4 + 6.66000666000782e-06*G0_2_4_5 + 2.62237762237806e-05*G0_2_5_0 - 3.21107463964662e-06*G0_2_5_1 + 2.30127015841342e-05*G0_2_5_2 + 6.4221492792933e-06*G0_2_5_3 + 6.66000666000782e-06*G0_2_5_4 - 4.99500499500581e-06*G0_2_5_5 - 2.30127015841339e-05*G0_3_0_0 + 3.2110746396466e-06*G0_3_0_1 - 2.62237762237806e-05*G0_3_0_2 + 4.99500499500584e-06*G0_3_0_3 - 6.66000666000777e-06*G0_3_0_4 - 6.4221492792932e-06*G0_3_0_5 + 3.2110746396466e-06*G0_3_1_0 - 6.89786404072236e-06*G0_3_1_1 - 6.82056039199011e-05*G0_3_1_2 - 4.61443318586254e-05*G0_3_1_3 - 6.4221492792932e-06*G0_3_1_4 - 2.62237762237806e-05*G0_3_2_0 - 6.82056039199011e-05*G0_3_2_1 + 0.000470600827743764*G0_3_2_2 + 0.000323961752533236*G0_3_2_3 + 0.000105132962275837*G0_3_2_4 + 6.42214927929329e-06*G0_3_2_5 + 4.99500499500584e-06*G0_3_3_0 - 4.61443318586254e-05*G0_3_3_1 + 0.000323961752533236*G0_3_3_2 - 0.000111317254174416*G0_3_3_3 + 2.85428856857473e-06*G0_3_3_4 - 2.28343085485981e-05*G0_3_3_5 - 6.66000666000776e-06*G0_3_4_0 - 6.4221492792932e-06*G0_3_4_1 + 0.000105132962275837*G0_3_4_2 + 2.85428856857473e-06*G0_3_4_3 + 1.33200133200155e-05*G0_3_4_4 - 6.42214927929319e-06*G0_3_5_0 + 6.42214927929329e-06*G0_3_5_2 - 2.28343085485981e-05*G0_3_5_3 + 2.28343085485981e-05*G0_3_5_5 - 0.000235895057323668*G0_4_0_0 + 2.63427049141379e-05*G0_4_0_1 - 6.66000666000777e-06*G0_4_0_3 - 0.00011155511155513*G0_4_0_4 - 0.000105132962275837*G0_4_0_5 + 2.63427049141379e-05*G0_4_1_0 - 2.63427049141379e-05*G0_4_1_2 - 6.4221492792932e-06*G0_4_1_3 + 6.42214927929323e-06*G0_4_1_5 - 2.63427049141379e-05*G0_4_2_1 + 0.000235895057323668*G0_4_2_2 + 0.000105132962275837*G0_4_2_3 + 0.00011155511155513*G0_4_2_4 + 6.66000666000782e-06*G0_4_2_5 - 6.66000666000777e-06*G0_4_3_0 - 6.4221492792932e-06*G0_4_3_1 + 0.000105132962275837*G0_4_3_2 + 2.85428856857474e-06*G0_4_3_3 + 1.33200133200156e-05*G0_4_3_4 - 0.00011155511155513*G0_4_4_0 + 0.00011155511155513*G0_4_4_2 + 1.33200133200156e-05*G0_4_4_3 - 1.33200133200156e-05*G0_4_4_5 - 0.000105132962275837*G0_4_5_0 + 6.42214927929323e-06*G0_4_5_1 + 6.66000666000782e-06*G0_4_5_2 - 1.33200133200155e-05*G0_4_5_4 - 2.85428856857492e-06*G0_4_5_5 - 0.000470600827743764*G0_5_0_0 + 6.82056039199011e-05*G0_5_0_1 + 2.62237762237806e-05*G0_5_0_2 - 6.42214927929319e-06*G0_5_0_3 - 0.000105132962275837*G0_5_0_4 - 0.000323961752533236*G0_5_0_5 + 6.82056039199011e-05*G0_5_1_0 + 6.89786404072243e-06*G0_5_1_1 - 3.21107463964663e-06*G0_5_1_2 + 6.42214927929322e-06*G0_5_1_4 + 4.61443318586254e-05*G0_5_1_5 + 2.62237762237806e-05*G0_5_2_0 - 3.21107463964662e-06*G0_5_2_1 + 2.30127015841342e-05*G0_5_2_2 + 6.42214927929329e-06*G0_5_2_3 + 6.66000666000782e-06*G0_5_2_4 - 4.99500499500581e-06*G0_5_2_5 - 6.42214927929319e-06*G0_5_3_0 + 6.42214927929329e-06*G0_5_3_2 - 2.28343085485981e-05*G0_5_3_3 + 2.28343085485981e-05*G0_5_3_5 - 0.000105132962275837*G0_5_4_0 + 6.42214927929323e-06*G0_5_4_1 + 6.66000666000782e-06*G0_5_4_2 - 1.33200133200155e-05*G0_5_4_4 - 2.85428856857492e-06*G0_5_4_5 - 0.000323961752533236*G0_5_5_0 + 4.61443318586254e-05*G0_5_5_1 - 4.99500499500581e-06*G0_5_5_2 + 2.28343085485981e-05*G0_5_5_3 - 2.85428856857493e-06*G0_5_5_4 + 0.000111317254174416*G0_5_5_5; + A[26] = A[42] - 5.80223348080589e-05*G0_0_0_0 + 6.67487274630244e-06*G0_0_0_1 + 1.78987678987709e-05*G0_0_0_2 + 1.48660862946602e-06*G0_0_0_3 - 3.2289139432002e-05*G0_0_0_4 - 1.96232339089515e-05*G0_0_0_5 + 6.67487274630244e-06*G0_0_1_0 - 6.67487274630244e-06*G0_0_1_1 - 4.34089719804079e-06*G0_0_1_3 + 4.34089719804078e-06*G0_0_1_4 + 1.78987678987709e-05*G0_0_2_0 - 4.99500499500584e-05*G0_0_2_2 + 5.82750582750679e-06*G0_0_2_3 - 3.49650349650409e-05*G0_0_2_4 + 7.07625707625826e-06*G0_0_2_5 + 1.48660862946602e-06*G0_0_3_0 - 4.34089719804079e-06*G0_0_3_1 + 5.82750582750679e-06*G0_0_3_2 - 2.83050283050331e-05*G0_0_3_3 - 1.16550116550136e-05*G0_0_3_4 - 1.71257314114486e-05*G0_0_3_5 - 3.2289139432002e-05*G0_0_4_0 + 4.34089719804078e-06*G0_0_4_1 - 3.49650349650409e-05*G0_0_4_2 - 1.16550116550136e-05*G0_0_4_3 - 6.4935064935076e-05*G0_0_4_4 - 2.28343085485981e-05*G0_0_4_5 - 1.96232339089515e-05*G0_0_5_0 + 7.07625707625826e-06*G0_0_5_2 - 1.71257314114486e-05*G0_0_5_3 - 2.28343085485981e-05*G0_0_5_4 - 3.94843251986175e-05*G0_0_5_5 + 6.67487274630244e-06*G0_1_0_0 - 6.67487274630244e-06*G0_1_0_1 - 4.34089719804079e-06*G0_1_0_3 + 4.34089719804078e-06*G0_1_0_4 - 6.67487274630244e-06*G0_1_1_0 + 5.80223348080589e-05*G0_1_1_1 - 1.78987678987709e-05*G0_1_1_2 + 3.22891394320021e-05*G0_1_1_3 - 1.48660862946603e-06*G0_1_1_4 + 1.96232339089515e-05*G0_1_1_5 - 1.78987678987709e-05*G0_1_2_1 + 4.99500499500584e-05*G0_1_2_2 + 3.49650349650409e-05*G0_1_2_3 - 5.82750582750677e-06*G0_1_2_4 - 7.07625707625826e-06*G0_1_2_5 - 4.34089719804079e-06*G0_1_3_0 + 3.22891394320021e-05*G0_1_3_1 + 3.49650349650409e-05*G0_1_3_2 + 6.4935064935076e-05*G0_1_3_3 + 1.16550116550136e-05*G0_1_3_4 + 2.28343085485981e-05*G0_1_3_5 + 4.34089719804078e-06*G0_1_4_0 - 1.48660862946603e-06*G0_1_4_1 - 5.82750582750677e-06*G0_1_4_2 + 1.16550116550136e-05*G0_1_4_3 + 2.83050283050331e-05*G0_1_4_4 + 1.71257314114486e-05*G0_1_4_5 + 1.96232339089515e-05*G0_1_5_1 - 7.07625707625826e-06*G0_1_5_2 + 2.28343085485981e-05*G0_1_5_3 + 1.71257314114486e-05*G0_1_5_4 + 3.94843251986175e-05*G0_1_5_5 + 1.78987678987709e-05*G0_2_0_0 - 4.99500499500584e-05*G0_2_0_2 + 5.82750582750679e-06*G0_2_0_3 - 3.49650349650409e-05*G0_2_0_4 + 7.07625707625826e-06*G0_2_0_5 - 1.78987678987709e-05*G0_2_1_1 + 4.99500499500584e-05*G0_2_1_2 + 3.49650349650409e-05*G0_2_1_3 - 5.82750582750677e-06*G0_2_1_4 - 7.07625707625826e-06*G0_2_1_5 - 4.99500499500584e-05*G0_2_2_0 + 4.99500499500584e-05*G0_2_2_1 - 0.000228937728937768*G0_2_2_3 + 0.000228937728937768*G0_2_2_4 + 5.82750582750679e-06*G0_2_3_0 + 3.49650349650409e-05*G0_2_3_1 - 0.000228937728937768*G0_2_3_2 - 0.000233100233100273*G0_2_3_3 - 1.16550116550137e-05*G0_2_3_5 - 3.49650349650409e-05*G0_2_4_0 - 5.82750582750677e-06*G0_2_4_1 + 0.000228937728937768*G0_2_4_2 + 0.000233100233100272*G0_2_4_4 + 1.16550116550137e-05*G0_2_4_5 + 7.07625707625826e-06*G0_2_5_0 - 7.07625707625826e-06*G0_2_5_1 - 1.16550116550137e-05*G0_2_5_3 + 1.16550116550137e-05*G0_2_5_4 + 1.48660862946602e-06*G0_3_0_0 - 4.34089719804079e-06*G0_3_0_1 + 5.82750582750678e-06*G0_3_0_2 - 2.83050283050331e-05*G0_3_0_3 - 1.16550116550136e-05*G0_3_0_4 - 1.71257314114486e-05*G0_3_0_5 - 4.34089719804079e-06*G0_3_1_0 + 3.22891394320021e-05*G0_3_1_1 + 3.49650349650409e-05*G0_3_1_2 + 6.4935064935076e-05*G0_3_1_3 + 1.16550116550136e-05*G0_3_1_4 + 2.28343085485981e-05*G0_3_1_5 + 5.82750582750679e-06*G0_3_2_0 + 3.49650349650409e-05*G0_3_2_1 - 0.000228937728937768*G0_3_2_2 - 0.000233100233100273*G0_3_2_3 - 1.16550116550137e-05*G0_3_2_5 - 2.83050283050331e-05*G0_3_3_0 + 6.4935064935076e-05*G0_3_3_1 - 0.000233100233100273*G0_3_3_2 + 0.00029970029970035*G0_3_3_3 + 3.3300033300039e-05*G0_3_3_4 + 7.99200799200934e-05*G0_3_3_5 - 1.16550116550136e-05*G0_3_4_0 + 1.16550116550136e-05*G0_3_4_1 + 3.3300033300039e-05*G0_3_4_3 - 3.33000333000389e-05*G0_3_4_4 - 1.71257314114486e-05*G0_3_5_0 + 2.28343085485981e-05*G0_3_5_1 - 1.16550116550137e-05*G0_3_5_2 + 7.99200799200934e-05*G0_3_5_3 + 3.42514628228972e-05*G0_3_5_5 - 3.2289139432002e-05*G0_4_0_0 + 4.34089719804078e-06*G0_4_0_1 - 3.49650349650409e-05*G0_4_0_2 - 1.16550116550136e-05*G0_4_0_3 - 6.4935064935076e-05*G0_4_0_4 - 2.28343085485981e-05*G0_4_0_5 + 4.34089719804078e-06*G0_4_1_0 - 1.48660862946602e-06*G0_4_1_1 - 5.82750582750678e-06*G0_4_1_2 + 1.16550116550136e-05*G0_4_1_3 + 2.83050283050331e-05*G0_4_1_4 + 1.71257314114486e-05*G0_4_1_5 - 3.49650349650409e-05*G0_4_2_0 - 5.82750582750677e-06*G0_4_2_1 + 0.000228937728937768*G0_4_2_2 + 0.000233100233100272*G0_4_2_4 + 1.16550116550137e-05*G0_4_2_5 - 1.16550116550136e-05*G0_4_3_0 + 1.16550116550136e-05*G0_4_3_1 + 3.33000333000389e-05*G0_4_3_3 - 3.33000333000389e-05*G0_4_3_4 - 6.4935064935076e-05*G0_4_4_0 + 2.83050283050331e-05*G0_4_4_1 + 0.000233100233100272*G0_4_4_2 - 3.3300033300039e-05*G0_4_4_3 - 0.00029970029970035*G0_4_4_4 - 7.99200799200933e-05*G0_4_4_5 - 2.28343085485981e-05*G0_4_5_0 + 1.71257314114486e-05*G0_4_5_1 + 1.16550116550137e-05*G0_4_5_2 - 7.99200799200933e-05*G0_4_5_4 - 3.42514628228972e-05*G0_4_5_5 - 1.96232339089515e-05*G0_5_0_0 + 7.07625707625826e-06*G0_5_0_2 - 1.71257314114486e-05*G0_5_0_3 - 2.28343085485981e-05*G0_5_0_4 - 3.94843251986175e-05*G0_5_0_5 + 1.96232339089515e-05*G0_5_1_1 - 7.07625707625826e-06*G0_5_1_2 + 2.28343085485981e-05*G0_5_1_3 + 1.71257314114486e-05*G0_5_1_4 + 3.94843251986175e-05*G0_5_1_5 + 7.07625707625826e-06*G0_5_2_0 - 7.07625707625826e-06*G0_5_2_1 - 1.16550116550137e-05*G0_5_2_3 + 1.16550116550137e-05*G0_5_2_4 - 1.71257314114486e-05*G0_5_3_0 + 2.28343085485981e-05*G0_5_3_1 - 1.16550116550137e-05*G0_5_3_2 + 7.99200799200934e-05*G0_5_3_3 + 3.42514628228972e-05*G0_5_3_5 - 2.28343085485981e-05*G0_5_4_0 + 1.71257314114486e-05*G0_5_4_1 + 1.16550116550137e-05*G0_5_4_2 - 7.99200799200933e-05*G0_5_4_4 - 3.42514628228972e-05*G0_5_4_5 - 3.94843251986175e-05*G0_5_5_0 + 3.94843251986175e-05*G0_5_5_1 + 3.42514628228972e-05*G0_5_5_3 - 3.42514628228972e-05*G0_5_5_4; + A[62] = A[26]; + A[70] = A[7]; + A[9] = A[90]; + A[34] = A[73] + 4.85675039246555e-05*G0_0_0_0 - 2.14071642643114e-06*G0_0_0_1 - 2.46182389039573e-05*G0_0_0_2 - 4.28143285286216e-06*G0_0_0_3 + 8.56286570572435e-06*G0_0_0_4 + 3.47866419295053e-05*G0_0_0_5 - 2.14071642643114e-06*G0_0_1_0 + 1.31118881118903e-05*G0_0_1_1 - 1.52526045383214e-05*G0_0_1_2 - 2.62237762237806e-05*G0_0_1_3 - 4.06736121021904e-05*G0_0_1_4 - 2.62237762237807e-05*G0_0_1_5 - 2.46182389039573e-05*G0_0_2_0 - 1.52526045383214e-05*G0_0_2_1 + 6.59608248894074e-05*G0_0_2_2 + 8.2952761524204e-05*G0_0_2_3 + 4.92364778079146e-05*G0_0_2_4 - 4.28143285286216e-06*G0_0_3_0 - 2.62237762237806e-05*G0_0_3_1 + 8.2952761524204e-05*G0_0_3_2 - 5.35179106607768e-05*G0_0_3_3 + 8.99100899101052e-05*G0_0_3_4 + 8.56286570572435e-06*G0_0_3_5 + 8.56286570572435e-06*G0_0_4_0 - 4.06736121021904e-05*G0_0_4_1 + 4.92364778079147e-05*G0_0_4_2 + 8.99100899101052e-05*G0_0_4_3 + 0.000201227344084521*G0_0_4_4 + 8.13472242043809e-05*G0_0_4_5 + 3.47866419295053e-05*G0_0_5_0 - 2.62237762237807e-05*G0_0_5_1 + 8.56286570572435e-06*G0_0_5_3 + 8.13472242043809e-05*G0_0_5_4 + 9.63322391893989e-05*G0_0_5_5 - 2.14071642643114e-06*G0_1_0_0 + 1.31118881118903e-05*G0_1_0_1 - 1.52526045383214e-05*G0_1_0_2 - 2.62237762237806e-05*G0_1_0_3 - 4.06736121021904e-05*G0_1_0_4 - 2.62237762237807e-05*G0_1_0_5 + 1.31118881118903e-05*G0_1_1_0 - 0.000224775224775263*G0_1_1_1 + 1.31118881118904e-05*G0_1_1_2 - 0.000262237762237807*G0_1_1_3 - 2.62237762237806e-05*G0_1_1_4 - 1.52526045383214e-05*G0_1_2_0 + 1.31118881118904e-05*G0_1_2_1 + 0.000106500642214946*G0_1_2_2 + 0.000183566433566465*G0_1_2_3 + 7.54602540316953e-05*G0_1_2_4 + 2.62237762237807e-05*G0_1_2_5 - 2.62237762237806e-05*G0_1_3_0 - 0.000262237762237807*G0_1_3_1 + 0.000183566433566465*G0_1_3_2 + 0.000104895104895123*G0_1_3_4 - 4.06736121021904e-05*G0_1_4_0 - 2.62237762237806e-05*G0_1_4_1 + 7.54602540316953e-05*G0_1_4_2 + 0.000104895104895123*G0_1_4_3 + 8.13472242043808e-05*G0_1_4_4 - 2.62237762237807e-05*G0_1_5_0 + 2.62237762237807e-05*G0_1_5_2 - 2.46182389039573e-05*G0_2_0_0 - 1.52526045383214e-05*G0_2_0_1 + 6.59608248894074e-05*G0_2_0_2 + 8.2952761524204e-05*G0_2_0_3 + 4.92364778079146e-05*G0_2_0_4 - 1.52526045383214e-05*G0_2_1_0 + 1.31118881118904e-05*G0_2_1_1 + 0.000106500642214946*G0_2_1_2 + 0.000183566433566465*G0_2_1_3 + 7.54602540316953e-05*G0_2_1_4 + 2.62237762237807e-05*G0_2_1_5 + 6.59608248894074e-05*G0_2_2_0 + 0.000106500642214946*G0_2_2_1 - 0.000651848151848262*G0_2_2_2 - 0.000526616240902044*G0_2_2_3 - 0.000237619523333849*G0_2_2_4 - 3.4786641929505e-05*G0_2_2_5 + 8.2952761524204e-05*G0_2_3_0 + 0.000183566433566465*G0_2_3_1 - 0.000526616240902044*G0_2_3_2 - 0.000787783644926636*G0_2_3_3 - 0.000316826031111799*G0_2_3_4 - 9.63322391893983e-05*G0_2_3_5 + 4.92364778079146e-05*G0_2_4_0 + 7.54602540316953e-05*G0_2_4_1 - 0.000237619523333849*G0_2_4_2 - 0.000316826031111799*G0_2_4_3 - 0.000316826031111799*G0_2_4_4 - 8.13472242043808e-05*G0_2_4_5 + 2.62237762237807e-05*G0_2_5_1 - 3.4786641929505e-05*G0_2_5_2 - 9.63322391893983e-05*G0_2_5_3 - 8.13472242043808e-05*G0_2_5_4 - 8.56286570572438e-06*G0_2_5_5 - 4.28143285286217e-06*G0_3_0_0 - 2.62237762237806e-05*G0_3_0_1 + 8.2952761524204e-05*G0_3_0_2 - 5.35179106607767e-05*G0_3_0_3 + 8.99100899101052e-05*G0_3_0_4 + 8.56286570572435e-06*G0_3_0_5 - 2.62237762237806e-05*G0_3_1_0 - 0.000262237762237807*G0_3_1_1 + 0.000183566433566465*G0_3_1_2 + 0.000104895104895123*G0_3_1_4 + 8.2952761524204e-05*G0_3_2_0 + 0.000183566433566465*G0_3_2_1 - 0.000526616240902044*G0_3_2_2 - 0.000787783644926636*G0_3_2_3 - 0.000316826031111799*G0_3_2_4 - 9.63322391893983e-05*G0_3_2_5 - 5.35179106607768e-05*G0_3_3_0 - 0.000787783644926635*G0_3_3_2 + 0.0023976023976028*G0_3_3_3 - 0.000102754388468692*G0_3_3_4 + 0.00029970029970035*G0_3_3_5 + 8.99100899101051e-05*G0_3_4_0 + 0.000104895104895123*G0_3_4_1 - 0.000316826031111799*G0_3_4_2 - 0.000102754388468692*G0_3_4_3 - 0.000342514628228972*G0_3_4_4 - 1.71257314114486e-05*G0_3_4_5 + 8.56286570572435e-06*G0_3_5_0 - 9.63322391893983e-05*G0_3_5_2 + 0.00029970029970035*G0_3_5_3 - 1.71257314114487e-05*G0_3_5_4 + 8.56286570572435e-06*G0_4_0_0 - 4.06736121021904e-05*G0_4_0_1 + 4.92364778079146e-05*G0_4_0_2 + 8.99100899101051e-05*G0_4_0_3 + 0.000201227344084521*G0_4_0_4 + 8.13472242043809e-05*G0_4_0_5 - 4.06736121021904e-05*G0_4_1_0 - 2.62237762237806e-05*G0_4_1_1 + 7.54602540316953e-05*G0_4_1_2 + 0.000104895104895123*G0_4_1_3 + 8.13472242043808e-05*G0_4_1_4 + 4.92364778079147e-05*G0_4_2_0 + 7.54602540316953e-05*G0_4_2_1 - 0.000237619523333849*G0_4_2_2 - 0.000316826031111799*G0_4_2_3 - 0.000316826031111799*G0_4_2_4 - 8.13472242043808e-05*G0_4_2_5 + 8.99100899101051e-05*G0_4_3_0 + 0.000104895104895123*G0_4_3_1 - 0.000316826031111799*G0_4_3_2 - 0.000102754388468692*G0_4_3_3 - 0.000342514628228972*G0_4_3_4 - 1.71257314114487e-05*G0_4_3_5 + 0.000201227344084521*G0_4_4_0 + 8.13472242043808e-05*G0_4_4_1 - 0.000316826031111799*G0_4_4_2 - 0.000342514628228972*G0_4_4_3 - 0.000402454688169042*G0_4_4_4 + 8.13472242043809e-05*G0_4_5_0 - 8.13472242043808e-05*G0_4_5_2 - 1.71257314114486e-05*G0_4_5_3 + 1.71257314114488e-05*G0_4_5_5 + 3.47866419295053e-05*G0_5_0_0 - 2.62237762237807e-05*G0_5_0_1 + 8.56286570572438e-06*G0_5_0_3 + 8.13472242043809e-05*G0_5_0_4 + 9.63322391893989e-05*G0_5_0_5 - 2.62237762237808e-05*G0_5_1_0 + 2.62237762237807e-05*G0_5_1_2 + 2.62237762237807e-05*G0_5_2_1 - 3.4786641929505e-05*G0_5_2_2 - 9.63322391893983e-05*G0_5_2_3 - 8.13472242043808e-05*G0_5_2_4 - 8.56286570572438e-06*G0_5_2_5 + 8.56286570572435e-06*G0_5_3_0 - 9.63322391893983e-05*G0_5_3_2 + 0.00029970029970035*G0_5_3_3 - 1.71257314114487e-05*G0_5_3_4 + 8.13472242043809e-05*G0_5_4_0 - 8.13472242043808e-05*G0_5_4_2 - 1.71257314114486e-05*G0_5_4_3 + 1.71257314114488e-05*G0_5_4_5 + 9.63322391893988e-05*G0_5_5_0 - 8.56286570572438e-06*G0_5_5_2 + 1.71257314114487e-05*G0_5_5_4 - 0.000299700299700348*G0_5_5_5; + A[45] = A[34] - 4.8567503924655e-05*G0_0_0_0 + 2.46182389039573e-05*G0_0_0_1 + 2.14071642643108e-06*G0_0_0_2 + 4.28143285286214e-06*G0_0_0_3 - 3.4786641929505e-05*G0_0_0_4 - 8.56286570572431e-06*G0_0_0_5 + 2.46182389039573e-05*G0_0_1_0 - 6.59608248894075e-05*G0_0_1_1 + 1.52526045383214e-05*G0_0_1_2 - 8.29527615242041e-05*G0_0_1_3 - 4.92364778079147e-05*G0_0_1_5 + 2.14071642643108e-06*G0_0_2_0 + 1.52526045383214e-05*G0_0_2_1 - 1.31118881118903e-05*G0_0_2_2 + 2.62237762237807e-05*G0_0_2_3 + 2.62237762237807e-05*G0_0_2_4 + 4.06736121021904e-05*G0_0_2_5 + 4.28143285286214e-06*G0_0_3_0 - 8.29527615242041e-05*G0_0_3_1 + 2.62237762237807e-05*G0_0_3_2 + 5.35179106607769e-05*G0_0_3_3 - 8.5628657057243e-06*G0_0_3_4 - 8.99100899101051e-05*G0_0_3_5 - 3.4786641929505e-05*G0_0_4_0 + 2.62237762237807e-05*G0_0_4_2 - 8.56286570572433e-06*G0_0_4_3 - 9.63322391893983e-05*G0_0_4_4 - 8.13472242043808e-05*G0_0_4_5 - 8.56286570572431e-06*G0_0_5_0 - 4.92364778079147e-05*G0_0_5_1 + 4.06736121021904e-05*G0_0_5_2 - 8.9910089910105e-05*G0_0_5_3 - 8.13472242043808e-05*G0_0_5_4 - 0.000201227344084521*G0_0_5_5 + 2.46182389039573e-05*G0_1_0_0 - 6.59608248894075e-05*G0_1_0_1 + 1.52526045383214e-05*G0_1_0_2 - 8.29527615242041e-05*G0_1_0_3 - 4.92364778079147e-05*G0_1_0_5 - 6.59608248894075e-05*G0_1_1_0 + 0.000651848151848263*G0_1_1_1 - 0.000106500642214946*G0_1_1_2 + 0.000526616240902045*G0_1_1_3 + 3.47866419295049e-05*G0_1_1_4 + 0.000237619523333849*G0_1_1_5 + 1.52526045383214e-05*G0_1_2_0 - 0.000106500642214946*G0_1_2_1 - 1.31118881118903e-05*G0_1_2_2 - 0.000183566433566465*G0_1_2_3 - 2.62237762237806e-05*G0_1_2_4 - 7.54602540316954e-05*G0_1_2_5 - 8.29527615242041e-05*G0_1_3_0 + 0.000526616240902045*G0_1_3_1 - 0.000183566433566465*G0_1_3_2 + 0.000787783644926636*G0_1_3_3 + 9.63322391893983e-05*G0_1_3_4 + 0.000316826031111799*G0_1_3_5 + 3.47866419295049e-05*G0_1_4_1 - 2.62237762237806e-05*G0_1_4_2 + 9.63322391893983e-05*G0_1_4_3 + 8.5628657057244e-06*G0_1_4_4 + 8.13472242043808e-05*G0_1_4_5 - 4.92364778079147e-05*G0_1_5_0 + 0.000237619523333849*G0_1_5_1 - 7.54602540316954e-05*G0_1_5_2 + 0.000316826031111799*G0_1_5_3 + 8.13472242043808e-05*G0_1_5_4 + 0.000316826031111799*G0_1_5_5 + 2.14071642643108e-06*G0_2_0_0 + 1.52526045383214e-05*G0_2_0_1 - 1.31118881118903e-05*G0_2_0_2 + 2.62237762237807e-05*G0_2_0_3 + 2.62237762237807e-05*G0_2_0_4 + 4.06736121021904e-05*G0_2_0_5 + 1.52526045383214e-05*G0_2_1_0 - 0.000106500642214946*G0_2_1_1 - 1.31118881118903e-05*G0_2_1_2 - 0.000183566433566465*G0_2_1_3 - 2.62237762237806e-05*G0_2_1_4 - 7.54602540316954e-05*G0_2_1_5 - 1.31118881118903e-05*G0_2_2_0 - 1.31118881118903e-05*G0_2_2_1 + 0.000224775224775263*G0_2_2_2 + 0.000262237762237807*G0_2_2_3 + 2.62237762237807e-05*G0_2_2_5 + 2.62237762237807e-05*G0_2_3_0 - 0.000183566433566465*G0_2_3_1 + 0.000262237762237807*G0_2_3_2 - 0.000104895104895123*G0_2_3_5 + 2.62237762237807e-05*G0_2_4_0 - 2.62237762237806e-05*G0_2_4_1 + 4.06736121021904e-05*G0_2_5_0 - 7.54602540316954e-05*G0_2_5_1 + 2.62237762237807e-05*G0_2_5_2 - 0.000104895104895123*G0_2_5_3 - 8.13472242043808e-05*G0_2_5_5 + 4.28143285286214e-06*G0_3_0_0 - 8.29527615242041e-05*G0_3_0_1 + 2.62237762237807e-05*G0_3_0_2 + 5.35179106607768e-05*G0_3_0_3 - 8.56286570572433e-06*G0_3_0_4 - 8.99100899101051e-05*G0_3_0_5 - 8.29527615242041e-05*G0_3_1_0 + 0.000526616240902045*G0_3_1_1 - 0.000183566433566465*G0_3_1_2 + 0.000787783644926636*G0_3_1_3 + 9.63322391893983e-05*G0_3_1_4 + 0.000316826031111799*G0_3_1_5 + 2.62237762237807e-05*G0_3_2_0 - 0.000183566433566465*G0_3_2_1 + 0.000262237762237807*G0_3_2_2 - 0.000104895104895123*G0_3_2_5 + 5.35179106607769e-05*G0_3_3_0 + 0.000787783644926636*G0_3_3_1 - 0.0023976023976028*G0_3_3_3 - 0.00029970029970035*G0_3_3_4 + 0.000102754388468692*G0_3_3_5 - 8.5628657057243e-06*G0_3_4_0 + 9.63322391893983e-05*G0_3_4_1 - 0.00029970029970035*G0_3_4_3 + 1.71257314114484e-05*G0_3_4_5 - 8.99100899101051e-05*G0_3_5_0 + 0.000316826031111799*G0_3_5_1 - 0.000104895104895123*G0_3_5_2 + 0.000102754388468691*G0_3_5_3 + 1.71257314114484e-05*G0_3_5_4 + 0.000342514628228972*G0_3_5_5 - 3.4786641929505e-05*G0_4_0_0 + 2.62237762237807e-05*G0_4_0_2 - 8.5628657057243e-06*G0_4_0_3 - 9.63322391893982e-05*G0_4_0_4 - 8.13472242043808e-05*G0_4_0_5 + 3.47866419295049e-05*G0_4_1_1 - 2.62237762237806e-05*G0_4_1_2 + 9.63322391893983e-05*G0_4_1_3 + 8.5628657057244e-06*G0_4_1_4 + 8.13472242043808e-05*G0_4_1_5 + 2.62237762237807e-05*G0_4_2_0 - 2.62237762237806e-05*G0_4_2_1 - 8.56286570572427e-06*G0_4_3_0 + 9.63322391893983e-05*G0_4_3_1 - 0.00029970029970035*G0_4_3_3 + 1.71257314114485e-05*G0_4_3_5 - 9.63322391893983e-05*G0_4_4_0 + 8.56286570572437e-06*G0_4_4_1 + 0.00029970029970035*G0_4_4_4 - 1.71257314114488e-05*G0_4_4_5 - 8.13472242043808e-05*G0_4_5_0 + 8.13472242043808e-05*G0_4_5_1 + 1.71257314114484e-05*G0_4_5_3 - 1.71257314114488e-05*G0_4_5_4 - 8.56286570572432e-06*G0_5_0_0 - 4.92364778079147e-05*G0_5_0_1 + 4.06736121021904e-05*G0_5_0_2 - 8.99100899101051e-05*G0_5_0_3 - 8.13472242043808e-05*G0_5_0_4 - 0.000201227344084521*G0_5_0_5 - 4.92364778079147e-05*G0_5_1_0 + 0.000237619523333849*G0_5_1_1 - 7.54602540316954e-05*G0_5_1_2 + 0.000316826031111799*G0_5_1_3 + 8.13472242043808e-05*G0_5_1_4 + 0.000316826031111799*G0_5_1_5 + 4.06736121021904e-05*G0_5_2_0 - 7.54602540316954e-05*G0_5_2_1 + 2.62237762237807e-05*G0_5_2_2 - 0.000104895104895123*G0_5_2_3 - 8.13472242043808e-05*G0_5_2_5 - 8.99100899101051e-05*G0_5_3_0 + 0.000316826031111799*G0_5_3_1 - 0.000104895104895123*G0_5_3_2 + 0.000102754388468691*G0_5_3_3 + 1.71257314114485e-05*G0_5_3_4 + 0.000342514628228972*G0_5_3_5 - 8.13472242043808e-05*G0_5_4_0 + 8.13472242043808e-05*G0_5_4_1 + 1.71257314114484e-05*G0_5_4_3 - 1.71257314114488e-05*G0_5_4_4 - 0.000201227344084521*G0_5_5_0 + 0.000316826031111799*G0_5_5_1 - 8.13472242043808e-05*G0_5_5_2 + 0.000342514628228972*G0_5_5_3 + 0.000402454688169042*G0_5_5_5; + A[36] = A[45] + 6.74325674325789e-05*G0_0_0_0 - 1.52526045383214e-05*G0_0_0_1 - 1.64567575281889e-05*G0_0_0_2 + 6.42214927929325e-06*G0_0_0_3 + 3.21107463964662e-05*G0_0_0_4 + 3.53218210361128e-05*G0_0_0_5 - 1.52526045383214e-05*G0_0_1_0 + 1.52526045383214e-05*G0_0_1_1 + 2.56885971171729e-05*G0_0_1_3 - 2.56885971171729e-05*G0_0_1_4 - 1.64567575281889e-05*G0_0_2_0 + 1.68581418581447e-05*G0_0_2_2 - 1.92664478378797e-05*G0_0_2_3 + 8.02768659911649e-06*G0_0_2_4 - 2.56885971171729e-05*G0_0_2_5 + 6.42214927929325e-06*G0_0_3_0 + 2.56885971171729e-05*G0_0_3_1 - 1.92664478378797e-05*G0_0_3_2 - 8.99100899101051e-05*G0_0_3_3 + 3.85328956757593e-05*G0_0_3_4 + 3.85328956757593e-05*G0_0_3_5 + 3.21107463964662e-05*G0_0_4_0 - 2.56885971171729e-05*G0_0_4_1 + 8.02768659911647e-06*G0_0_4_2 + 3.85328956757593e-05*G0_0_4_3 + 0.000282574568288901*G0_0_4_4 + 0.000102754388468692*G0_0_4_5 + 3.53218210361128e-05*G0_0_5_0 - 2.56885971171729e-05*G0_0_5_2 + 3.85328956757593e-05*G0_0_5_3 + 0.000102754388468692*G0_0_5_4 + 0.000141287284144451*G0_0_5_5 - 1.52526045383214e-05*G0_1_0_0 + 1.52526045383214e-05*G0_1_0_1 + 2.56885971171729e-05*G0_1_0_3 - 2.56885971171729e-05*G0_1_0_4 + 1.52526045383214e-05*G0_1_1_0 - 6.7432567432579e-05*G0_1_1_1 + 1.64567575281889e-05*G0_1_1_2 - 3.21107463964662e-05*G0_1_1_3 - 6.42214927929321e-06*G0_1_1_4 - 3.53218210361127e-05*G0_1_1_5 + 1.64567575281889e-05*G0_1_2_1 - 1.68581418581448e-05*G0_1_2_2 - 8.02768659911652e-06*G0_1_2_3 + 1.92664478378796e-05*G0_1_2_4 + 2.56885971171729e-05*G0_1_2_5 + 2.56885971171729e-05*G0_1_3_0 - 3.21107463964662e-05*G0_1_3_1 - 8.02768659911653e-06*G0_1_3_2 - 0.000282574568288902*G0_1_3_3 - 3.85328956757593e-05*G0_1_3_4 - 0.000102754388468692*G0_1_3_5 - 2.56885971171729e-05*G0_1_4_0 - 6.42214927929321e-06*G0_1_4_1 + 1.92664478378796e-05*G0_1_4_2 - 3.85328956757593e-05*G0_1_4_3 + 8.99100899101049e-05*G0_1_4_4 - 3.85328956757594e-05*G0_1_4_5 - 3.53218210361127e-05*G0_1_5_1 + 2.56885971171729e-05*G0_1_5_2 - 0.000102754388468692*G0_1_5_3 - 3.85328956757594e-05*G0_1_5_4 - 0.000141287284144451*G0_1_5_5 - 1.64567575281889e-05*G0_2_0_0 + 1.68581418581447e-05*G0_2_0_2 - 1.92664478378797e-05*G0_2_0_3 + 8.02768659911647e-06*G0_2_0_4 - 2.56885971171729e-05*G0_2_0_5 + 1.64567575281889e-05*G0_2_1_1 - 1.68581418581448e-05*G0_2_1_2 - 8.02768659911653e-06*G0_2_1_3 + 1.92664478378796e-05*G0_2_1_4 + 2.56885971171729e-05*G0_2_1_5 + 1.68581418581447e-05*G0_2_2_0 - 1.68581418581448e-05*G0_2_2_1 + 5.61938061938159e-05*G0_2_2_3 - 5.61938061938156e-05*G0_2_2_4 - 1.92664478378797e-05*G0_2_3_0 - 8.02768659911656e-06*G0_2_3_1 + 5.61938061938158e-05*G0_2_3_2 + 0.000224775224775262*G0_2_3_3 + 3.85328956757593e-05*G0_2_3_5 + 8.02768659911647e-06*G0_2_4_0 + 1.92664478378796e-05*G0_2_4_1 - 5.61938061938156e-05*G0_2_4_2 - 0.000224775224775262*G0_2_4_4 - 3.85328956757593e-05*G0_2_4_5 - 2.56885971171729e-05*G0_2_5_0 + 2.56885971171729e-05*G0_2_5_1 + 3.85328956757593e-05*G0_2_5_3 - 3.85328956757593e-05*G0_2_5_4 + 6.42214927929325e-06*G0_3_0_0 + 2.56885971171729e-05*G0_3_0_1 - 1.92664478378797e-05*G0_3_0_2 - 8.99100899101052e-05*G0_3_0_3 + 3.85328956757593e-05*G0_3_0_4 + 3.85328956757593e-05*G0_3_0_5 + 2.56885971171729e-05*G0_3_1_0 - 3.21107463964662e-05*G0_3_1_1 - 8.02768659911653e-06*G0_3_1_2 - 0.000282574568288902*G0_3_1_3 - 3.85328956757593e-05*G0_3_1_4 - 0.000102754388468692*G0_3_1_5 - 1.92664478378797e-05*G0_3_2_0 - 8.02768659911652e-06*G0_3_2_1 + 5.61938061938158e-05*G0_3_2_2 + 0.000224775224775262*G0_3_2_3 + 3.85328956757593e-05*G0_3_2_5 - 8.99100899101052e-05*G0_3_3_0 - 0.000282574568288902*G0_3_3_1 + 0.000224775224775262*G0_3_3_2 + 0.00154131582703037*G0_3_3_3 + 0.000256885971171729*G0_3_3_4 + 0.000102754388468692*G0_3_3_5 + 3.85328956757593e-05*G0_3_4_0 - 3.85328956757593e-05*G0_3_4_1 + 0.000256885971171729*G0_3_4_3 - 0.000256885971171729*G0_3_4_4 + 3.85328956757593e-05*G0_3_5_0 - 0.000102754388468692*G0_3_5_1 + 3.85328956757593e-05*G0_3_5_2 + 0.000102754388468692*G0_3_5_3 - 7.70657913515187e-05*G0_3_5_5 + 3.21107463964662e-05*G0_4_0_0 - 2.56885971171729e-05*G0_4_0_1 + 8.02768659911647e-06*G0_4_0_2 + 3.85328956757593e-05*G0_4_0_3 + 0.000282574568288901*G0_4_0_4 + 0.000102754388468692*G0_4_0_5 - 2.56885971171729e-05*G0_4_1_0 - 6.42214927929321e-06*G0_4_1_1 + 1.92664478378796e-05*G0_4_1_2 - 3.85328956757593e-05*G0_4_1_3 + 8.99100899101049e-05*G0_4_1_4 - 3.85328956757594e-05*G0_4_1_5 + 8.02768659911649e-06*G0_4_2_0 + 1.92664478378796e-05*G0_4_2_1 - 5.61938061938156e-05*G0_4_2_2 - 0.000224775224775262*G0_4_2_4 - 3.85328956757593e-05*G0_4_2_5 + 3.85328956757593e-05*G0_4_3_0 - 3.85328956757593e-05*G0_4_3_1 + 0.000256885971171729*G0_4_3_3 - 0.000256885971171729*G0_4_3_4 + 0.000282574568288901*G0_4_4_0 + 8.99100899101049e-05*G0_4_4_1 - 0.000224775224775262*G0_4_4_2 - 0.000256885971171729*G0_4_4_3 - 0.00154131582703037*G0_4_4_4 - 0.000102754388468691*G0_4_4_5 + 0.000102754388468692*G0_4_5_0 - 3.85328956757594e-05*G0_4_5_1 - 3.85328956757593e-05*G0_4_5_2 - 0.000102754388468691*G0_4_5_4 + 7.70657913515186e-05*G0_4_5_5 + 3.53218210361128e-05*G0_5_0_0 - 2.56885971171729e-05*G0_5_0_2 + 3.85328956757593e-05*G0_5_0_3 + 0.000102754388468692*G0_5_0_4 + 0.000141287284144451*G0_5_0_5 - 3.53218210361127e-05*G0_5_1_1 + 2.56885971171729e-05*G0_5_1_2 - 0.000102754388468692*G0_5_1_3 - 3.85328956757594e-05*G0_5_1_4 - 0.000141287284144451*G0_5_1_5 - 2.56885971171729e-05*G0_5_2_0 + 2.56885971171729e-05*G0_5_2_1 + 3.85328956757593e-05*G0_5_2_3 - 3.85328956757593e-05*G0_5_2_4 + 3.85328956757593e-05*G0_5_3_0 - 0.000102754388468692*G0_5_3_1 + 3.85328956757593e-05*G0_5_3_2 + 0.000102754388468692*G0_5_3_3 - 7.70657913515187e-05*G0_5_3_5 + 0.000102754388468692*G0_5_4_0 - 3.85328956757594e-05*G0_5_4_1 - 3.85328956757593e-05*G0_5_4_2 - 0.000102754388468691*G0_5_4_4 + 7.70657913515186e-05*G0_5_4_5 + 0.000141287284144451*G0_5_5_0 - 0.000141287284144451*G0_5_5_1 - 7.70657913515187e-05*G0_5_5_3 + 7.70657913515187e-05*G0_5_5_4; + A[69] = -A[36] - 0.000134865134865157*G0_0_0_0 + 3.07727986299465e-06*G0_0_0_1 + 4.68281718281797e-05*G0_0_0_2 + 3.15755672898583e-05*G0_0_0_3 - 3.53218210361127e-05*G0_0_0_4 - 0.000118274582560317*G0_0_0_5 + 3.07727986299465e-06*G0_0_1_0 - 1.21753246753267e-05*G0_0_1_1 - 4.95040673612187e-06*G0_0_1_2 + 9.79377765092216e-05*G0_0_1_3 + 0.000123626373626394*G0_0_1_4 + 9.6867418296006e-05*G0_0_1_5 + 4.68281718281797e-05*G0_0_2_0 - 4.95040673612187e-06*G0_0_2_1 - 1.87312687312719e-05*G0_0_2_2 - 4.65605822748758e-05*G0_0_2_3 - 2.83644926502116e-05*G0_0_2_4 - 9.09804481233205e-06*G0_0_2_5 + 3.15755672898583e-05*G0_0_3_0 + 9.79377765092216e-05*G0_0_3_1 - 4.65605822748758e-05*G0_0_3_2 - 0.000263308120451022*G0_0_3_3 - 0.000310403881832506*G0_0_3_4 - 4.49550449550525e-05*G0_0_3_5 - 3.53218210361127e-05*G0_0_4_0 + 0.000123626373626394*G0_0_4_1 - 2.83644926502116e-05*G0_0_4_2 - 0.000310403881832505*G0_0_4_3 - 0.000689310689310806*G0_0_4_4 - 0.000229056657628125*G0_0_4_5 - 0.000118274582560317*G0_0_5_0 + 9.6867418296006e-05*G0_0_5_1 - 9.09804481233205e-06*G0_0_5_2 - 4.49550449550525e-05*G0_0_5_3 - 0.000229056657628125*G0_0_5_4 - 3.63921792493279e-05*G0_0_5_5 + 3.07727986299466e-06*G0_1_0_0 - 1.21753246753267e-05*G0_1_0_1 - 4.95040673612188e-06*G0_1_0_2 + 9.79377765092216e-05*G0_1_0_3 + 0.000123626373626394*G0_1_0_4 + 9.6867418296006e-05*G0_1_0_5 - 1.21753246753267e-05*G0_1_1_0 - 6.74325674325788e-05*G0_1_1_1 + 3.03714142999909e-05*G0_1_1_2 - 3.21107463964663e-06*G0_1_1_3 + 3.79977165691515e-05*G0_1_1_4 - 8.29527615242041e-05*G0_1_1_5 - 4.95040673612188e-06*G0_1_2_0 + 3.03714142999909e-05*G0_1_2_1 - 1.87312687312716e-06*G0_1_2_2 - 2.03368060510951e-05*G0_1_2_3 - 6.58270301127554e-05*G0_1_2_4 - 3.47866419295049e-05*G0_1_2_5 + 9.79377765092216e-05*G0_1_3_0 - 3.21107463964663e-06*G0_1_3_1 - 2.03368060510951e-05*G0_1_3_2 - 0.000406736121021904*G0_1_3_3 - 0.000271870986156746*G0_1_3_4 - 0.000126302269159433*G0_1_3_5 + 0.000123626373626394*G0_1_4_0 + 3.79977165691515e-05*G0_1_4_1 - 6.58270301127554e-05*G0_1_4_2 - 0.000271870986156746*G0_1_4_3 - 0.000353218210361127*G0_1_4_4 - 6.4221492792932e-06*G0_1_4_5 + 9.68674182960061e-05*G0_1_5_0 - 8.2952761524204e-05*G0_1_5_1 - 3.47866419295049e-05*G0_1_5_2 - 0.000126302269159433*G0_1_5_3 - 6.42214927929318e-06*G0_1_5_4 + 0.000104895104895123*G0_1_5_5 + 4.68281718281797e-05*G0_2_0_0 - 4.95040673612187e-06*G0_2_0_1 - 1.87312687312718e-05*G0_2_0_2 - 4.65605822748758e-05*G0_2_0_3 - 2.83644926502116e-05*G0_2_0_4 - 9.09804481233205e-06*G0_2_0_5 - 4.95040673612187e-06*G0_2_1_0 + 3.03714142999909e-05*G0_2_1_1 - 1.87312687312716e-06*G0_2_1_2 - 2.03368060510951e-05*G0_2_1_3 - 6.58270301127555e-05*G0_2_1_4 - 3.47866419295049e-05*G0_2_1_5 - 1.87312687312719e-05*G0_2_2_0 - 1.87312687312717e-06*G0_2_2_1 - 5.61938061938153e-05*G0_2_2_2 - 1.87312687312719e-05*G0_2_2_3 + 3.74625374625438e-05*G0_2_2_4 - 6.36863136863245e-05*G0_2_2_5 - 4.65605822748758e-05*G0_2_3_0 - 2.03368060510952e-05*G0_2_3_1 - 1.8731268731272e-05*G0_2_3_2 + 0.000224775224775262*G0_2_3_3 + 0.000224775224775263*G0_2_3_4 + 0.000220493791922401*G0_2_3_5 - 2.83644926502116e-05*G0_2_4_0 - 6.58270301127555e-05*G0_2_4_1 + 3.74625374625438e-05*G0_2_4_2 + 0.000224775224775263*G0_2_4_3 + 0.000449550449550525*G0_2_4_4 + 0.00025902668759816*G0_2_4_5 - 9.09804481233205e-06*G0_2_5_0 - 3.47866419295049e-05*G0_2_5_1 - 6.36863136863245e-05*G0_2_5_2 + 0.000220493791922401*G0_2_5_3 + 0.00025902668759816*G0_2_5_4 + 0.000455972598829819*G0_2_5_5 + 3.15755672898583e-05*G0_3_0_0 + 9.79377765092216e-05*G0_3_0_1 - 4.65605822748758e-05*G0_3_0_2 - 0.000263308120451022*G0_3_0_3 - 0.000310403881832506*G0_3_0_4 - 4.49550449550525e-05*G0_3_0_5 + 9.79377765092216e-05*G0_3_1_0 - 3.21107463964663e-06*G0_3_1_1 - 2.03368060510951e-05*G0_3_1_2 - 0.000406736121021904*G0_3_1_3 - 0.000271870986156746*G0_3_1_4 - 0.000126302269159433*G0_3_1_5 - 4.65605822748758e-05*G0_3_2_0 - 2.03368060510951e-05*G0_3_2_1 - 1.8731268731272e-05*G0_3_2_2 + 0.000224775224775262*G0_3_2_3 + 0.000224775224775263*G0_3_2_4 + 0.000220493791922401*G0_3_2_5 - 0.000263308120451022*G0_3_3_0 - 0.000406736121021904*G0_3_3_1 + 0.000224775224775262*G0_3_3_2 + 0.00162694448408762*G0_3_3_3 + 0.00107035821321554*G0_3_3_4 + 8.56286570572431e-05*G0_3_3_5 - 0.000310403881832506*G0_3_4_0 - 0.000271870986156746*G0_3_4_1 + 0.000224775224775263*G0_3_4_2 + 0.00107035821321554*G0_3_4_3 + 0.00132724418438726*G0_3_4_4 + 0.000102754388468691*G0_3_4_5 - 4.49550449550525e-05*G0_3_5_0 - 0.000126302269159433*G0_3_5_1 + 0.000220493791922401*G0_3_5_2 + 8.56286570572433e-05*G0_3_5_3 + 0.000102754388468691*G0_3_5_4 - 0.000822035107749533*G0_3_5_5 - 3.53218210361127e-05*G0_4_0_0 + 0.000123626373626394*G0_4_0_1 - 2.83644926502116e-05*G0_4_0_2 - 0.000310403881832506*G0_4_0_3 - 0.000689310689310806*G0_4_0_4 - 0.000229056657628125*G0_4_0_5 + 0.000123626373626394*G0_4_1_0 + 3.79977165691515e-05*G0_4_1_1 - 6.58270301127555e-05*G0_4_1_2 - 0.000271870986156746*G0_4_1_3 - 0.000353218210361127*G0_4_1_4 - 6.4221492792932e-06*G0_4_1_5 - 2.83644926502116e-05*G0_4_2_0 - 6.58270301127554e-05*G0_4_2_1 + 3.74625374625438e-05*G0_4_2_2 + 0.000224775224775263*G0_4_2_3 + 0.000449550449550525*G0_4_2_4 + 0.00025902668759816*G0_4_2_5 - 0.000310403881832506*G0_4_3_0 - 0.000271870986156746*G0_4_3_1 + 0.000224775224775263*G0_4_3_2 + 0.00107035821321554*G0_4_3_3 + 0.00132724418438726*G0_4_3_4 + 0.000102754388468691*G0_4_3_5 - 0.000689310689310806*G0_4_4_0 - 0.000353218210361127*G0_4_4_1 + 0.000449550449550525*G0_4_4_2 + 0.00132724418438726*G0_4_4_3 + 0.00316826031111799*G0_4_4_4 + 0.000188383045525934*G0_4_4_5 - 0.000229056657628125*G0_4_5_0 - 6.42214927929316e-06*G0_4_5_1 + 0.00025902668759816*G0_4_5_2 + 0.000102754388468691*G0_4_5_3 + 0.000188383045525934*G0_4_5_4 - 0.000899100899101051*G0_4_5_5 - 0.000118274582560317*G0_5_0_0 + 9.6867418296006e-05*G0_5_0_1 - 9.09804481233206e-06*G0_5_0_2 - 4.49550449550525e-05*G0_5_0_3 - 0.000229056657628125*G0_5_0_4 - 3.63921792493279e-05*G0_5_0_5 + 9.6867418296006e-05*G0_5_1_0 - 8.2952761524204e-05*G0_5_1_1 - 3.47866419295049e-05*G0_5_1_2 - 0.000126302269159433*G0_5_1_3 - 6.42214927929317e-06*G0_5_1_4 + 0.000104895104895123*G0_5_1_5 - 9.09804481233205e-06*G0_5_2_0 - 3.47866419295049e-05*G0_5_2_1 - 6.36863136863245e-05*G0_5_2_2 + 0.000220493791922401*G0_5_2_3 + 0.00025902668759816*G0_5_2_4 + 0.000455972598829819*G0_5_2_5 - 4.49550449550525e-05*G0_5_3_0 - 0.000126302269159433*G0_5_3_1 + 0.000220493791922401*G0_5_3_2 + 8.56286570572431e-05*G0_5_3_3 + 0.000102754388468691*G0_5_3_4 - 0.000822035107749533*G0_5_3_5 - 0.000229056657628125*G0_5_4_0 - 6.42214927929316e-06*G0_5_4_1 + 0.00025902668759816*G0_5_4_2 + 0.000102754388468691*G0_5_4_3 + 0.000188383045525934*G0_5_4_4 - 0.000899100899101052*G0_5_4_5 - 3.63921792493279e-05*G0_5_5_0 + 0.000104895104895123*G0_5_5_1 + 0.000455972598829819*G0_5_5_2 - 0.000822035107749533*G0_5_5_3 - 0.000899100899101052*G0_5_5_4 - 0.00289424860853481*G0_5_5_5; + A[89] = A[69] + 6.74325674325788e-05*G0_0_0_1 - 6.74325674325788e-05*G0_0_0_2 - 0.000112387612387631*G0_0_0_4 + 0.000112387612387632*G0_0_0_5 + 6.74325674325788e-05*G0_0_1_0 - 6.10104181532855e-05*G0_0_1_1 - 0.00020871985157703*G0_0_1_3 - 0.000173398030540917*G0_0_1_4 - 0.00020871985157703*G0_0_1_5 - 6.74325674325788e-05*G0_0_2_0 + 6.10104181532855e-05*G0_0_2_2 + 0.00020871985157703*G0_0_2_3 + 0.000208719851577029*G0_0_2_4 + 0.000173398030540917*G0_0_2_5 - 0.00020871985157703*G0_0_3_1 + 0.00020871985157703*G0_0_3_2 + 0.000346796061081833*G0_0_3_4 - 0.000346796061081834*G0_0_3_5 - 0.000112387612387631*G0_0_4_0 - 0.000173398030540917*G0_0_4_1 + 0.000208719851577029*G0_0_4_2 + 0.000346796061081833*G0_0_4_3 + 0.00089910089910105*G0_0_4_4 + 0.000112387612387632*G0_0_5_0 - 0.00020871985157703*G0_0_5_1 + 0.000173398030540917*G0_0_5_2 - 0.000346796061081834*G0_0_5_3 - 0.000899100899101052*G0_0_5_5 + 6.74325674325788e-05*G0_1_0_0 - 6.10104181532856e-05*G0_1_0_1 - 0.00020871985157703*G0_1_0_3 - 0.000173398030540917*G0_1_0_4 - 0.00020871985157703*G0_1_0_5 - 6.10104181532856e-05*G0_1_1_0 + 0.000370879120879184*G0_1_1_1 - 9.231839588984e-05*G0_1_1_2 + 0.00016055373198233*G0_1_1_3 - 9.95433138290449e-05*G0_1_1_4 + 0.0003789068074783*G0_1_1_5 - 9.231839588984e-05*G0_1_2_1 + 9.23183958898399e-05*G0_1_2_2 + 7.38547167118719e-05*G0_1_2_4 - 7.3854716711872e-05*G0_1_2_5 - 0.00020871985157703*G0_1_3_0 + 0.00016055373198233*G0_1_3_1 + 0.000911945197659637*G0_1_3_3 + 0.000616526330812149*G0_1_3_4 + 0.000565149136577803*G0_1_3_5 - 0.000173398030540917*G0_1_4_0 - 9.95433138290449e-05*G0_1_4_1 + 7.38547167118719e-05*G0_1_4_2 + 0.000616526330812149*G0_1_4_3 + 0.000989010989011155*G0_1_4_4 + 0.000346796061081834*G0_1_4_5 - 0.00020871985157703*G0_1_5_0 + 0.0003789068074783*G0_1_5_1 - 7.3854716711872e-05*G0_1_5_2 + 0.000565149136577803*G0_1_5_3 + 0.000346796061081834*G0_1_5_4 + 0.000744969316398013*G0_1_5_5 - 6.74325674325788e-05*G0_2_0_0 + 6.10104181532855e-05*G0_2_0_2 + 0.00020871985157703*G0_2_0_3 + 0.000208719851577029*G0_2_0_4 + 0.000173398030540917*G0_2_0_5 - 9.231839588984e-05*G0_2_1_1 + 9.23183958898399e-05*G0_2_1_2 + 7.38547167118719e-05*G0_2_1_4 - 7.3854716711872e-05*G0_2_1_5 + 6.10104181532855e-05*G0_2_2_0 + 9.23183958898399e-05*G0_2_2_1 - 0.000370879120879183*G0_2_2_2 - 0.00016055373198233*G0_2_2_3 - 0.0003789068074783*G0_2_2_4 + 9.95433138290451e-05*G0_2_2_5 + 0.00020871985157703*G0_2_3_0 - 0.00016055373198233*G0_2_3_2 - 0.000911945197659637*G0_2_3_3 - 0.000565149136577803*G0_2_3_4 - 0.000616526330812149*G0_2_3_5 + 0.000208719851577029*G0_2_4_0 + 7.38547167118719e-05*G0_2_4_1 - 0.0003789068074783*G0_2_4_2 - 0.000565149136577803*G0_2_4_3 - 0.000744969316398012*G0_2_4_4 - 0.000346796061081834*G0_2_4_5 + 0.000173398030540917*G0_2_5_0 - 7.3854716711872e-05*G0_2_5_1 + 9.95433138290451e-05*G0_2_5_2 - 0.000616526330812149*G0_2_5_3 - 0.000346796061081834*G0_2_5_4 - 0.000989010989011157*G0_2_5_5 - 0.00020871985157703*G0_3_0_1 + 0.00020871985157703*G0_3_0_2 + 0.000346796061081834*G0_3_0_4 - 0.000346796061081834*G0_3_0_5 - 0.00020871985157703*G0_3_1_0 + 0.00016055373198233*G0_3_1_1 + 0.000911945197659637*G0_3_1_3 + 0.000616526330812149*G0_3_1_4 + 0.000565149136577803*G0_3_1_5 + 0.00020871985157703*G0_3_2_0 - 0.00016055373198233*G0_3_2_2 - 0.000911945197659637*G0_3_2_3 - 0.000565149136577803*G0_3_2_4 - 0.000616526330812149*G0_3_2_5 + 0.000911945197659637*G0_3_3_1 - 0.000911945197659637*G0_3_3_2 - 0.0012330526616243*G0_3_3_4 + 0.0012330526616243*G0_3_3_5 + 0.000346796061081834*G0_3_4_0 + 0.000616526330812149*G0_3_4_1 - 0.000565149136577803*G0_3_4_2 - 0.0012330526616243*G0_3_4_3 - 0.00267161410018598*G0_3_4_4 - 0.000346796061081834*G0_3_5_0 + 0.000565149136577803*G0_3_5_1 - 0.000616526330812149*G0_3_5_2 + 0.0012330526616243*G0_3_5_3 + 0.00267161410018598*G0_3_5_5 - 0.000112387612387631*G0_4_0_0 - 0.000173398030540917*G0_4_0_1 + 0.000208719851577029*G0_4_0_2 + 0.000346796061081834*G0_4_0_3 + 0.00089910089910105*G0_4_0_4 - 0.000173398030540917*G0_4_1_0 - 9.95433138290449e-05*G0_4_1_1 + 7.38547167118719e-05*G0_4_1_2 + 0.000616526330812149*G0_4_1_3 + 0.000989010989011155*G0_4_1_4 + 0.000346796061081834*G0_4_1_5 + 0.000208719851577029*G0_4_2_0 + 7.38547167118719e-05*G0_4_2_1 - 0.0003789068074783*G0_4_2_2 - 0.000565149136577803*G0_4_2_3 - 0.000744969316398012*G0_4_2_4 - 0.000346796061081834*G0_4_2_5 + 0.000346796061081834*G0_4_3_0 + 0.000616526330812149*G0_4_3_1 - 0.000565149136577803*G0_4_3_2 - 0.0012330526616243*G0_4_3_3 - 0.00267161410018598*G0_4_3_4 + 0.00089910089910105*G0_4_4_0 + 0.000989010989011155*G0_4_4_1 - 0.000744969316398012*G0_4_4_2 - 0.00267161410018598*G0_4_4_3 - 0.00770657913515186*G0_4_4_4 - 0.00128442985585864*G0_4_4_5 + 0.000346796061081834*G0_4_5_1 - 0.000346796061081834*G0_4_5_2 - 0.00128442985585864*G0_4_5_4 + 0.00128442985585865*G0_4_5_5 + 0.000112387612387632*G0_5_0_0 - 0.00020871985157703*G0_5_0_1 + 0.000173398030540917*G0_5_0_2 - 0.000346796061081834*G0_5_0_3 - 0.000899100899101051*G0_5_0_5 - 0.00020871985157703*G0_5_1_0 + 0.0003789068074783*G0_5_1_1 - 7.3854716711872e-05*G0_5_1_2 + 0.000565149136577803*G0_5_1_3 + 0.000346796061081834*G0_5_1_4 + 0.000744969316398013*G0_5_1_5 + 0.000173398030540917*G0_5_2_0 - 7.3854716711872e-05*G0_5_2_1 + 9.95433138290451e-05*G0_5_2_2 - 0.000616526330812149*G0_5_2_3 - 0.000346796061081834*G0_5_2_4 - 0.000989010989011157*G0_5_2_5 - 0.000346796061081834*G0_5_3_0 + 0.000565149136577803*G0_5_3_1 - 0.000616526330812149*G0_5_3_2 + 0.0012330526616243*G0_5_3_3 + 0.00267161410018598*G0_5_3_5 + 0.000346796061081834*G0_5_4_1 - 0.000346796061081834*G0_5_4_2 - 0.00128442985585864*G0_5_4_4 + 0.00128442985585865*G0_5_4_5 - 0.000899100899101051*G0_5_5_0 + 0.000744969316398013*G0_5_5_1 - 0.000989010989011157*G0_5_5_2 + 0.00267161410018598*G0_5_5_3 + 0.00128442985585865*G0_5_5_4 + 0.00770657913515187*G0_5_5_5; + A[93] = A[89] + 0.000134865134865157*G0_0_0_0 - 3.29135150563777e-05*G0_0_0_1 - 3.05052090766427e-05*G0_0_0_2 + 1.28442985585863e-05*G0_0_0_3 + 7.06436420722253e-05*G0_0_0_4 + 6.42214927929319e-05*G0_0_0_5 - 3.29135150563777e-05*G0_0_1_0 + 3.37162837162894e-05*G0_0_1_1 - 3.85328956757593e-05*G0_0_1_3 - 5.13771942343458e-05*G0_0_1_4 + 1.60553731982331e-05*G0_0_1_5 - 3.05052090766427e-05*G0_0_2_0 + 3.05052090766428e-05*G0_0_2_2 + 5.13771942343456e-05*G0_0_2_3 - 5.13771942343458e-05*G0_0_2_5 + 1.28442985585863e-05*G0_0_3_0 - 3.85328956757593e-05*G0_0_3_1 + 5.13771942343456e-05*G0_0_3_2 - 0.000179820179820209*G0_0_3_3 + 7.70657913515191e-05*G0_0_3_4 + 7.70657913515192e-05*G0_0_3_5 + 7.06436420722253e-05*G0_0_4_0 - 5.13771942343458e-05*G0_0_4_1 + 7.70657913515191e-05*G0_0_4_3 + 0.000282574568288902*G0_0_4_4 + 0.000205508776937383*G0_0_4_5 + 6.42214927929319e-05*G0_0_5_0 + 1.60553731982331e-05*G0_0_5_1 - 5.13771942343458e-05*G0_0_5_2 + 7.70657913515192e-05*G0_0_5_3 + 0.000205508776937383*G0_0_5_4 + 0.000565149136577804*G0_0_5_5 - 3.29135150563777e-05*G0_1_0_0 + 3.37162837162894e-05*G0_1_0_1 - 3.85328956757593e-05*G0_1_0_3 - 5.13771942343458e-05*G0_1_0_4 + 1.60553731982331e-05*G0_1_0_5 + 3.37162837162894e-05*G0_1_1_0 - 3.37162837162895e-05*G0_1_1_2 + 0.000112387612387632*G0_1_1_3 - 0.000112387612387631*G0_1_1_5 - 3.37162837162894e-05*G0_1_2_1 + 3.29135150563778e-05*G0_1_2_2 - 1.60553731982331e-05*G0_1_2_3 + 5.13771942343457e-05*G0_1_2_4 + 3.85328956757593e-05*G0_1_2_5 - 3.85328956757593e-05*G0_1_3_0 + 0.000112387612387632*G0_1_3_1 - 1.60553731982332e-05*G0_1_3_2 + 0.000449550449550526*G0_1_3_3 + 7.70657913515189e-05*G0_1_3_4 - 5.13771942343458e-05*G0_1_4_0 + 5.13771942343457e-05*G0_1_4_2 + 7.70657913515189e-05*G0_1_4_3 - 7.70657913515184e-05*G0_1_4_5 + 1.60553731982331e-05*G0_1_5_0 - 0.000112387612387631*G0_1_5_1 + 3.85328956757593e-05*G0_1_5_2 - 7.70657913515184e-05*G0_1_5_4 - 0.000449550449550525*G0_1_5_5 - 3.05052090766427e-05*G0_2_0_0 + 3.05052090766428e-05*G0_2_0_2 + 5.13771942343456e-05*G0_2_0_3 - 5.13771942343458e-05*G0_2_0_5 - 3.37162837162894e-05*G0_2_1_1 + 3.29135150563778e-05*G0_2_1_2 - 1.60553731982331e-05*G0_2_1_3 + 5.13771942343457e-05*G0_2_1_4 + 3.85328956757593e-05*G0_2_1_5 + 3.05052090766428e-05*G0_2_2_0 + 3.29135150563778e-05*G0_2_2_1 - 0.000134865134865158*G0_2_2_2 - 6.42214927929323e-05*G0_2_2_3 - 7.06436420722255e-05*G0_2_2_4 - 1.28442985585866e-05*G0_2_2_5 + 5.13771942343456e-05*G0_2_3_0 - 1.60553731982331e-05*G0_2_3_1 - 6.42214927929323e-05*G0_2_3_2 - 0.000565149136577803*G0_2_3_3 - 0.000205508776937383*G0_2_3_4 - 7.7065791351518e-05*G0_2_3_5 + 5.13771942343457e-05*G0_2_4_1 - 7.06436420722255e-05*G0_2_4_2 - 0.000205508776937383*G0_2_4_3 - 0.000282574568288901*G0_2_4_4 - 7.70657913515182e-05*G0_2_4_5 - 5.13771942343458e-05*G0_2_5_0 + 3.85328956757593e-05*G0_2_5_1 - 1.28442985585866e-05*G0_2_5_2 - 7.7065791351518e-05*G0_2_5_3 - 7.70657913515183e-05*G0_2_5_4 + 0.000179820179820211*G0_2_5_5 + 1.28442985585863e-05*G0_3_0_0 - 3.85328956757593e-05*G0_3_0_1 + 5.13771942343456e-05*G0_3_0_2 - 0.000179820179820209*G0_3_0_3 + 7.70657913515191e-05*G0_3_0_4 + 7.70657913515191e-05*G0_3_0_5 - 3.85328956757593e-05*G0_3_1_0 + 0.000112387612387632*G0_3_1_1 - 1.60553731982331e-05*G0_3_1_2 + 0.000449550449550526*G0_3_1_3 + 7.70657913515189e-05*G0_3_1_4 + 5.13771942343456e-05*G0_3_2_0 - 1.60553731982331e-05*G0_3_2_1 - 6.42214927929323e-05*G0_3_2_2 - 0.000565149136577803*G0_3_2_3 - 0.000205508776937383*G0_3_2_4 - 7.7065791351518e-05*G0_3_2_5 - 0.000179820179820209*G0_3_3_0 + 0.000449550449550526*G0_3_3_1 - 0.000565149136577803*G0_3_3_2 + 0.00308263165406074*G0_3_3_3 + 0.000205508776937381*G0_3_3_4 + 0.000513771942343456*G0_3_3_5 + 7.70657913515191e-05*G0_3_4_0 + 7.70657913515189e-05*G0_3_4_1 - 0.000205508776937383*G0_3_4_2 + 0.000205508776937381*G0_3_4_3 - 0.000154131582703039*G0_3_4_4 + 7.70657913515192e-05*G0_3_5_0 - 7.7065791351518e-05*G0_3_5_2 + 0.000513771942343456*G0_3_5_3 - 0.000513771942343461*G0_3_5_5 + 7.06436420722253e-05*G0_4_0_0 - 5.13771942343458e-05*G0_4_0_1 + 7.70657913515191e-05*G0_4_0_3 + 0.000282574568288902*G0_4_0_4 + 0.000205508776937383*G0_4_0_5 - 5.13771942343458e-05*G0_4_1_0 + 5.13771942343457e-05*G0_4_1_2 + 7.70657913515189e-05*G0_4_1_3 - 7.70657913515184e-05*G0_4_1_5 + 5.13771942343457e-05*G0_4_2_1 - 7.06436420722255e-05*G0_4_2_2 - 0.000205508776937383*G0_4_2_3 - 0.000282574568288901*G0_4_2_4 - 7.70657913515183e-05*G0_4_2_5 + 7.70657913515191e-05*G0_4_3_0 + 7.7065791351519e-05*G0_4_3_1 - 0.000205508776937383*G0_4_3_2 + 0.000205508776937381*G0_4_3_3 - 0.000154131582703039*G0_4_3_4 + 0.000282574568288902*G0_4_4_0 - 0.000282574568288901*G0_4_4_2 - 0.000154131582703039*G0_4_4_3 + 0.000154131582703036*G0_4_4_5 + 0.000205508776937383*G0_4_5_0 - 7.70657913515184e-05*G0_4_5_1 - 7.70657913515182e-05*G0_4_5_2 + 0.000154131582703036*G0_4_5_4 - 0.000205508776937385*G0_4_5_5 + 6.42214927929319e-05*G0_5_0_0 + 1.60553731982331e-05*G0_5_0_1 - 5.13771942343458e-05*G0_5_0_2 + 7.70657913515192e-05*G0_5_0_3 + 0.000205508776937383*G0_5_0_4 + 0.000565149136577804*G0_5_0_5 + 1.60553731982331e-05*G0_5_1_0 - 0.000112387612387631*G0_5_1_1 + 3.85328956757593e-05*G0_5_1_2 - 7.70657913515184e-05*G0_5_1_4 - 0.000449550449550525*G0_5_1_5 - 5.13771942343458e-05*G0_5_2_0 + 3.85328956757593e-05*G0_5_2_1 - 1.28442985585866e-05*G0_5_2_2 - 7.7065791351518e-05*G0_5_2_3 - 7.70657913515183e-05*G0_5_2_4 + 0.000179820179820211*G0_5_2_5 + 7.70657913515192e-05*G0_5_3_0 - 7.70657913515179e-05*G0_5_3_2 + 0.000513771942343455*G0_5_3_3 - 0.000513771942343461*G0_5_3_5 + 0.000205508776937383*G0_5_4_0 - 7.70657913515184e-05*G0_5_4_1 - 7.70657913515182e-05*G0_5_4_2 + 0.000154131582703036*G0_5_4_4 - 0.000205508776937385*G0_5_4_5 + 0.000565149136577804*G0_5_5_0 - 0.000449550449550525*G0_5_5_1 + 0.000179820179820211*G0_5_5_2 - 0.000513771942343461*G0_5_5_3 - 0.000205508776937385*G0_5_5_4 - 0.00308263165406075*G0_5_5_5; + A[94] = A[69] + 0.000134865134865158*G0_0_0_0 - 3.05052090766428e-05*G0_0_0_1 - 3.29135150563777e-05*G0_0_0_2 + 1.28442985585865e-05*G0_0_0_3 + 6.42214927929322e-05*G0_0_0_4 + 7.06436420722254e-05*G0_0_0_5 - 3.05052090766428e-05*G0_0_1_0 + 3.05052090766428e-05*G0_0_1_1 + 5.13771942343457e-05*G0_0_1_3 - 5.13771942343458e-05*G0_0_1_4 - 3.29135150563777e-05*G0_0_2_0 + 3.37162837162894e-05*G0_0_2_2 - 3.85328956757593e-05*G0_0_2_3 + 1.60553731982329e-05*G0_0_2_4 - 5.13771942343458e-05*G0_0_2_5 + 1.28442985585865e-05*G0_0_3_0 + 5.13771942343457e-05*G0_0_3_1 - 3.85328956757593e-05*G0_0_3_2 - 0.00017982017982021*G0_0_3_3 + 7.70657913515185e-05*G0_0_3_4 + 7.70657913515187e-05*G0_0_3_5 + 6.42214927929322e-05*G0_0_4_0 - 5.13771942343458e-05*G0_0_4_1 + 1.6055373198233e-05*G0_0_4_2 + 7.70657913515185e-05*G0_0_4_3 + 0.000565149136577803*G0_0_4_4 + 0.000205508776937383*G0_0_4_5 + 7.06436420722254e-05*G0_0_5_0 - 5.13771942343458e-05*G0_0_5_2 + 7.70657913515187e-05*G0_0_5_3 + 0.000205508776937383*G0_0_5_4 + 0.000282574568288902*G0_0_5_5 - 3.05052090766428e-05*G0_1_0_0 + 3.05052090766428e-05*G0_1_0_1 + 5.13771942343457e-05*G0_1_0_3 - 5.13771942343458e-05*G0_1_0_4 + 3.05052090766428e-05*G0_1_1_0 - 0.000134865134865158*G0_1_1_1 + 3.29135150563778e-05*G0_1_1_2 - 6.42214927929323e-05*G0_1_1_3 - 1.28442985585864e-05*G0_1_1_4 - 7.06436420722254e-05*G0_1_1_5 + 3.29135150563777e-05*G0_1_2_1 - 3.37162837162894e-05*G0_1_2_2 - 1.60553731982329e-05*G0_1_2_3 + 3.85328956757593e-05*G0_1_2_4 + 5.13771942343458e-05*G0_1_2_5 + 5.13771942343457e-05*G0_1_3_0 - 6.42214927929323e-05*G0_1_3_1 - 1.60553731982329e-05*G0_1_3_2 - 0.000565149136577803*G0_1_3_3 - 7.70657913515188e-05*G0_1_3_4 - 0.000205508776937383*G0_1_3_5 - 5.13771942343458e-05*G0_1_4_0 - 1.28442985585864e-05*G0_1_4_1 + 3.85328956757593e-05*G0_1_4_2 - 7.70657913515187e-05*G0_1_4_3 + 0.00017982017982021*G0_1_4_4 - 7.70657913515187e-05*G0_1_4_5 - 7.06436420722254e-05*G0_1_5_1 + 5.13771942343458e-05*G0_1_5_2 - 0.000205508776937383*G0_1_5_3 - 7.70657913515187e-05*G0_1_5_4 - 0.000282574568288902*G0_1_5_5 - 3.29135150563777e-05*G0_2_0_0 + 3.37162837162894e-05*G0_2_0_2 - 3.85328956757593e-05*G0_2_0_3 + 1.60553731982329e-05*G0_2_0_4 - 5.13771942343458e-05*G0_2_0_5 + 3.29135150563778e-05*G0_2_1_1 - 3.37162837162894e-05*G0_2_1_2 - 1.60553731982329e-05*G0_2_1_3 + 3.85328956757593e-05*G0_2_1_4 + 5.13771942343458e-05*G0_2_1_5 + 3.37162837162894e-05*G0_2_2_0 - 3.37162837162894e-05*G0_2_2_1 + 0.000112387612387631*G0_2_2_3 - 0.000112387612387631*G0_2_2_4 - 3.85328956757593e-05*G0_2_3_0 - 1.6055373198233e-05*G0_2_3_1 + 0.000112387612387631*G0_2_3_2 + 0.000449550449550525*G0_2_3_3 + 7.70657913515186e-05*G0_2_3_5 + 1.60553731982329e-05*G0_2_4_0 + 3.85328956757593e-05*G0_2_4_1 - 0.000112387612387631*G0_2_4_2 - 0.000449550449550525*G0_2_4_4 - 7.70657913515187e-05*G0_2_4_5 - 5.13771942343458e-05*G0_2_5_0 + 5.13771942343458e-05*G0_2_5_1 + 7.70657913515185e-05*G0_2_5_3 - 7.70657913515187e-05*G0_2_5_4 + 1.28442985585864e-05*G0_3_0_0 + 5.13771942343457e-05*G0_3_0_1 - 3.85328956757593e-05*G0_3_0_2 - 0.00017982017982021*G0_3_0_3 + 7.70657913515185e-05*G0_3_0_4 + 7.70657913515187e-05*G0_3_0_5 + 5.13771942343457e-05*G0_3_1_0 - 6.42214927929323e-05*G0_3_1_1 - 1.6055373198233e-05*G0_3_1_2 - 0.000565149136577803*G0_3_1_3 - 7.70657913515187e-05*G0_3_1_4 - 0.000205508776937383*G0_3_1_5 - 3.85328956757593e-05*G0_3_2_0 - 1.6055373198233e-05*G0_3_2_1 + 0.000112387612387631*G0_3_2_2 + 0.000449550449550525*G0_3_2_3 + 7.70657913515186e-05*G0_3_2_5 - 0.00017982017982021*G0_3_3_0 - 0.000565149136577803*G0_3_3_1 + 0.000449550449550525*G0_3_3_2 + 0.00308263165406074*G0_3_3_3 + 0.000513771942343456*G0_3_3_4 + 0.000205508776937383*G0_3_3_5 + 7.70657913515185e-05*G0_3_4_0 - 7.70657913515187e-05*G0_3_4_1 + 0.000513771942343457*G0_3_4_3 - 0.000513771942343457*G0_3_4_4 + 7.70657913515187e-05*G0_3_5_0 - 0.000205508776937383*G0_3_5_1 + 7.70657913515186e-05*G0_3_5_2 + 0.000205508776937383*G0_3_5_3 - 0.000154131582703037*G0_3_5_5 + 6.42214927929322e-05*G0_4_0_0 - 5.13771942343458e-05*G0_4_0_1 + 1.60553731982329e-05*G0_4_0_2 + 7.70657913515185e-05*G0_4_0_3 + 0.000565149136577803*G0_4_0_4 + 0.000205508776937383*G0_4_0_5 - 5.13771942343458e-05*G0_4_1_0 - 1.28442985585864e-05*G0_4_1_1 + 3.85328956757593e-05*G0_4_1_2 - 7.70657913515187e-05*G0_4_1_3 + 0.00017982017982021*G0_4_1_4 - 7.70657913515187e-05*G0_4_1_5 + 1.60553731982329e-05*G0_4_2_0 + 3.85328956757593e-05*G0_4_2_1 - 0.000112387612387631*G0_4_2_2 - 0.000449550449550525*G0_4_2_4 - 7.70657913515186e-05*G0_4_2_5 + 7.70657913515185e-05*G0_4_3_0 - 7.70657913515187e-05*G0_4_3_1 + 0.000513771942343457*G0_4_3_3 - 0.000513771942343456*G0_4_3_4 + 0.000565149136577803*G0_4_4_0 + 0.00017982017982021*G0_4_4_1 - 0.000449550449550525*G0_4_4_2 - 0.000513771942343456*G0_4_4_3 - 0.00308263165406074*G0_4_4_4 - 0.000205508776937383*G0_4_4_5 + 0.000205508776937383*G0_4_5_0 - 7.70657913515187e-05*G0_4_5_1 - 7.70657913515187e-05*G0_4_5_2 - 0.000205508776937383*G0_4_5_4 + 0.000154131582703037*G0_4_5_5 + 7.06436420722254e-05*G0_5_0_0 - 5.13771942343458e-05*G0_5_0_2 + 7.70657913515187e-05*G0_5_0_3 + 0.000205508776937383*G0_5_0_4 + 0.000282574568288902*G0_5_0_5 - 7.06436420722254e-05*G0_5_1_1 + 5.13771942343458e-05*G0_5_1_2 - 0.000205508776937383*G0_5_1_3 - 7.70657913515187e-05*G0_5_1_4 - 0.000282574568288902*G0_5_1_5 - 5.13771942343458e-05*G0_5_2_0 + 5.13771942343458e-05*G0_5_2_1 + 7.70657913515186e-05*G0_5_2_3 - 7.70657913515187e-05*G0_5_2_4 + 7.70657913515187e-05*G0_5_3_0 - 0.000205508776937383*G0_5_3_1 + 7.70657913515186e-05*G0_5_3_2 + 0.000205508776937383*G0_5_3_3 - 0.000154131582703037*G0_5_3_5 + 0.000205508776937383*G0_5_4_0 - 7.70657913515187e-05*G0_5_4_1 - 7.70657913515187e-05*G0_5_4_2 - 0.000205508776937382*G0_5_4_4 + 0.000154131582703037*G0_5_4_5 + 0.000282574568288902*G0_5_5_0 - 0.000282574568288902*G0_5_5_1 - 0.000154131582703037*G0_5_5_3 + 0.000154131582703037*G0_5_5_4; + A[97] = A[89] + 0.000505744255744341*G0_0_0_0 - 0.000158948194662507*G0_0_0_1 - 5.77993435136389e-05*G0_0_0_2 - 8.66990152704586e-05*G0_0_0_3 + 0.000337162837162894*G0_0_0_4 + 0.000337162837162894*G0_0_0_5 - 0.000158948194662507*G0_0_1_0 + 0.000158948194662507*G0_0_1_1 + 8.66990152704584e-05*G0_0_1_3 - 8.66990152704585e-05*G0_0_1_4 - 5.77993435136389e-05*G0_0_2_0 + 6.50242614528439e-05*G0_0_2_2 - 0.000173398030540917*G0_0_2_3 - 0.000192664478378796*G0_0_2_4 - 0.000298629941487135*G0_0_2_5 - 8.66990152704586e-05*G0_0_3_0 + 8.66990152704584e-05*G0_0_3_1 - 0.000173398030540917*G0_0_3_2 + 0.000809190809190946*G0_0_3_3 + 0.000346796061081834*G0_0_3_4 + 0.000770657913515187*G0_0_3_5 + 0.000337162837162894*G0_0_4_0 - 8.66990152704585e-05*G0_0_4_1 - 0.000192664478378796*G0_0_4_2 + 0.000346796061081834*G0_0_4_3 + 0.00057799343513639*G0_0_4_4 + 0.000770657913515187*G0_0_4_5 + 0.000337162837162894*G0_0_5_0 - 0.000298629941487135*G0_0_5_2 + 0.000770657913515187*G0_0_5_3 + 0.000770657913515187*G0_0_5_4 + 0.00192664478378797*G0_0_5_5 - 0.000158948194662507*G0_1_0_0 + 0.000158948194662507*G0_1_0_1 + 8.66990152704584e-05*G0_1_0_3 - 8.66990152704585e-05*G0_1_0_4 + 0.000158948194662507*G0_1_1_0 - 0.000505744255744341*G0_1_1_1 + 5.7799343513639e-05*G0_1_1_2 - 0.000337162837162894*G0_1_1_3 + 8.66990152704584e-05*G0_1_1_4 - 0.000337162837162894*G0_1_1_5 + 5.7799343513639e-05*G0_1_2_1 - 6.50242614528438e-05*G0_1_2_2 + 0.000192664478378797*G0_1_2_3 + 0.000173398030540917*G0_1_2_4 + 0.000298629941487135*G0_1_2_5 + 8.66990152704584e-05*G0_1_3_0 - 0.000337162837162894*G0_1_3_1 + 0.000192664478378797*G0_1_3_2 - 0.000577993435136389*G0_1_3_3 - 0.000346796061081833*G0_1_3_4 - 0.000770657913515186*G0_1_3_5 - 8.66990152704585e-05*G0_1_4_0 + 8.66990152704584e-05*G0_1_4_1 + 0.000173398030540917*G0_1_4_2 - 0.000346796061081833*G0_1_4_3 - 0.000809190809190945*G0_1_4_4 - 0.000770657913515186*G0_1_4_5 - 0.000337162837162894*G0_1_5_1 + 0.000298629941487135*G0_1_5_2 - 0.000770657913515186*G0_1_5_3 - 0.000770657913515186*G0_1_5_4 - 0.00192664478378797*G0_1_5_5 - 5.77993435136389e-05*G0_2_0_0 + 6.50242614528439e-05*G0_2_0_2 - 0.000173398030540917*G0_2_0_3 - 0.000192664478378796*G0_2_0_4 - 0.000298629941487135*G0_2_0_5 + 5.7799343513639e-05*G0_2_1_1 - 6.50242614528438e-05*G0_2_1_2 + 0.000192664478378797*G0_2_1_3 + 0.000173398030540917*G0_2_1_4 + 0.000298629941487135*G0_2_1_5 + 6.50242614528439e-05*G0_2_2_0 - 6.50242614528438e-05*G0_2_2_1 - 0.000105965463108338*G0_2_2_3 + 0.000105965463108338*G0_2_2_4 - 0.000173398030540917*G0_2_3_0 + 0.000192664478378797*G0_2_3_1 - 0.000105965463108338*G0_2_3_2 + 0.000616526330812149*G0_2_3_3 + 0.000346796061081834*G0_2_3_5 - 0.000192664478378796*G0_2_4_0 + 0.000173398030540917*G0_2_4_1 + 0.000105965463108338*G0_2_4_2 - 0.000616526330812149*G0_2_4_4 - 0.000346796061081834*G0_2_4_5 - 0.000298629941487135*G0_2_5_0 + 0.000298629941487135*G0_2_5_1 + 0.000346796061081834*G0_2_5_3 - 0.000346796061081834*G0_2_5_4 - 8.66990152704586e-05*G0_3_0_0 + 8.66990152704584e-05*G0_3_0_1 - 0.000173398030540917*G0_3_0_2 + 0.000809190809190946*G0_3_0_3 + 0.000346796061081834*G0_3_0_4 + 0.000770657913515187*G0_3_0_5 + 8.66990152704584e-05*G0_3_1_0 - 0.000337162837162894*G0_3_1_1 + 0.000192664478378797*G0_3_1_2 - 0.000577993435136389*G0_3_1_3 - 0.000346796061081833*G0_3_1_4 - 0.000770657913515186*G0_3_1_5 - 0.000173398030540917*G0_3_2_0 + 0.000192664478378797*G0_3_2_1 - 0.000105965463108338*G0_3_2_2 + 0.000616526330812149*G0_3_2_3 + 0.000346796061081834*G0_3_2_5 + 0.000809190809190946*G0_3_3_0 - 0.000577993435136389*G0_3_3_1 + 0.000616526330812149*G0_3_3_2 - 0.00462394748109112*G0_3_3_3 - 0.000924789496218226*G0_3_3_4 - 0.00231197374054556*G0_3_3_5 + 0.000346796061081834*G0_3_4_0 - 0.000346796061081833*G0_3_4_1 - 0.000924789496218226*G0_3_4_3 + 0.000924789496218222*G0_3_4_4 + 0.000770657913515187*G0_3_5_0 - 0.000770657913515186*G0_3_5_1 + 0.000346796061081834*G0_3_5_2 - 0.00231197374054556*G0_3_5_3 - 0.00154131582703038*G0_3_5_5 + 0.000337162837162894*G0_4_0_0 - 8.66990152704585e-05*G0_4_0_1 - 0.000192664478378796*G0_4_0_2 + 0.000346796061081834*G0_4_0_3 + 0.00057799343513639*G0_4_0_4 + 0.000770657913515187*G0_4_0_5 - 8.66990152704585e-05*G0_4_1_0 + 8.66990152704584e-05*G0_4_1_1 + 0.000173398030540917*G0_4_1_2 - 0.000346796061081833*G0_4_1_3 - 0.000809190809190945*G0_4_1_4 - 0.000770657913515186*G0_4_1_5 - 0.000192664478378796*G0_4_2_0 + 0.000173398030540917*G0_4_2_1 + 0.000105965463108338*G0_4_2_2 - 0.000616526330812149*G0_4_2_4 - 0.000346796061081834*G0_4_2_5 + 0.000346796061081834*G0_4_3_0 - 0.000346796061081833*G0_4_3_1 - 0.000924789496218226*G0_4_3_3 + 0.000924789496218222*G0_4_3_4 + 0.00057799343513639*G0_4_4_0 - 0.000809190809190945*G0_4_4_1 - 0.000616526330812149*G0_4_4_2 + 0.000924789496218222*G0_4_4_3 + 0.00462394748109111*G0_4_4_4 + 0.00231197374054556*G0_4_4_5 + 0.000770657913515187*G0_4_5_0 - 0.000770657913515186*G0_4_5_1 - 0.000346796061081834*G0_4_5_2 + 0.00231197374054556*G0_4_5_4 + 0.00154131582703037*G0_4_5_5 + 0.000337162837162894*G0_5_0_0 - 0.000298629941487135*G0_5_0_2 + 0.000770657913515187*G0_5_0_3 + 0.000770657913515187*G0_5_0_4 + 0.00192664478378797*G0_5_0_5 - 0.000337162837162894*G0_5_1_1 + 0.000298629941487135*G0_5_1_2 - 0.000770657913515186*G0_5_1_3 - 0.000770657913515186*G0_5_1_4 - 0.00192664478378796*G0_5_1_5 - 0.000298629941487135*G0_5_2_0 + 0.000298629941487135*G0_5_2_1 + 0.000346796061081834*G0_5_2_3 - 0.000346796061081834*G0_5_2_4 + 0.000770657913515187*G0_5_3_0 - 0.000770657913515186*G0_5_3_1 + 0.000346796061081834*G0_5_3_2 - 0.00231197374054556*G0_5_3_3 - 0.00154131582703038*G0_5_3_5 + 0.000770657913515187*G0_5_4_0 - 0.000770657913515186*G0_5_4_1 - 0.000346796061081834*G0_5_4_2 + 0.00231197374054556*G0_5_4_4 + 0.00154131582703037*G0_5_4_5 + 0.00192664478378797*G0_5_5_0 - 0.00192664478378796*G0_5_5_1 - 0.00154131582703038*G0_5_5_3 + 0.00154131582703037*G0_5_5_4; + A[55] = A[97] + 0.00123626373626395*G0_0_0_0 - 5.61938061938156e-05*G0_0_0_1 - 0.000258491508491552*G0_0_0_2 + 0.000146103896103921*G0_0_0_3 + 0.00140484515484539*G0_0_0_4 + 0.00020604395604399*G0_0_0_5 - 5.61938061938156e-05*G0_0_1_0 - 4.36170971885331e-05*G0_0_1_1 + 3.83991008991074e-05*G0_0_1_2 - 3.21107463964655e-06*G0_0_1_3 - 9.04452690167127e-05*G0_0_1_4 - 3.21107463964651e-06*G0_0_1_5 - 0.000258491508491552*G0_0_2_0 + 3.83991008991074e-05*G0_0_2_1 + 1.36470672184981e-05*G0_0_2_2 - 4.28143285286214e-06*G0_0_2_3 - 0.000461324389895896*G0_0_2_4 - 2.19423433709184e-05*G0_0_2_5 + 0.000146103896103921*G0_0_3_0 - 3.21107463964655e-06*G0_0_3_1 - 4.28143285286214e-06*G0_0_3_2 - 0.000509490509490596*G0_0_3_3 - 0.000111317254174416*G0_0_3_4 - 0.000248323105466005*G0_0_3_5 + 0.00140484515484539*G0_0_4_0 - 9.04452690167127e-05*G0_0_4_1 - 0.000461324389895896*G0_0_4_2 - 0.000111317254174416*G0_0_4_3 + 0.00224775224775262*G0_0_4_4 + 0.000224775224775262*G0_0_4_5 + 0.00020604395604399*G0_0_5_0 - 3.21107463964651e-06*G0_0_5_1 - 2.19423433709184e-05*G0_0_5_2 - 0.000248323105466005*G0_0_5_3 + 0.000224775224775262*G0_0_5_4 - 0.000449550449550525*G0_0_5_5 - 5.61938061938156e-05*G0_1_0_0 - 4.36170971885331e-05*G0_1_0_1 + 3.83991008991074e-05*G0_1_0_2 - 3.21107463964655e-06*G0_1_0_3 - 9.04452690167127e-05*G0_1_0_4 - 3.21107463964649e-06*G0_1_0_5 - 4.36170971885331e-05*G0_1_1_0 + 0.000150920508063391*G0_1_1_1 - 1.3914656771802e-05*G0_1_1_2 + 0.000158413015555899*G0_1_1_3 + 4.17439703154059e-05*G0_1_1_4 + 7.17140002854411e-05*G0_1_1_5 + 3.83991008991074e-05*G0_1_2_0 - 1.3914656771802e-05*G0_1_2_1 - 2.24775224775263e-05*G0_1_2_2 - 0.000105965463108338*G0_1_2_3 - 2.14071642643108e-05*G0_1_2_4 - 0.000105965463108338*G0_1_2_5 - 3.21107463964655e-06*G0_1_3_0 + 0.000158413015555899*G0_1_3_1 - 0.000105965463108338*G0_1_3_2 + 4.28143285286176e-06*G0_1_3_3 - 7.70657913515189e-05*G0_1_3_4 + 0.000218353075495969*G0_1_3_5 - 9.04452690167127e-05*G0_1_4_0 + 4.17439703154059e-05*G0_1_4_1 - 2.14071642643108e-05*G0_1_4_2 - 7.70657913515189e-05*G0_1_4_3 - 0.00041958041958049*G0_1_4_4 + 0.000128442985585864*G0_1_4_5 - 3.21107463964651e-06*G0_1_5_0 + 7.1714000285441e-05*G0_1_5_1 - 0.000105965463108338*G0_1_5_2 + 0.000218353075495969*G0_1_5_3 + 0.000128442985585864*G0_1_5_4 + 0.000762095047809461*G0_1_5_5 - 0.000258491508491552*G0_2_0_0 + 3.83991008991074e-05*G0_2_0_1 + 1.3647067218498e-05*G0_2_0_2 - 4.28143285286216e-06*G0_2_0_3 - 0.000461324389895896*G0_2_0_4 - 2.19423433709184e-05*G0_2_0_5 + 3.83991008991074e-05*G0_2_1_0 - 1.3914656771802e-05*G0_2_1_1 - 2.24775224775263e-05*G0_2_1_2 - 0.000105965463108338*G0_2_1_3 - 2.14071642643108e-05*G0_2_1_4 - 0.000105965463108338*G0_2_1_5 + 1.3647067218498e-05*G0_2_2_0 - 2.24775224775263e-05*G0_2_2_1 + 0.000258491508491552*G0_2_2_2 + 0.000191594120165581*G0_2_2_3 + 0.000385328956757593*G0_2_2_4 + 2.56885971171729e-05*G0_2_2_5 - 4.28143285286216e-06*G0_2_3_0 - 0.000105965463108338*G0_2_3_1 + 0.000191594120165581*G0_2_3_2 - 8.99100899101052e-05*G0_2_3_3 + 5.13771942343456e-05*G0_2_3_4 - 4.28143285286216e-05*G0_2_3_5 - 0.000461324389895896*G0_2_4_0 - 2.14071642643108e-05*G0_2_4_1 + 0.000385328956757593*G0_2_4_2 + 5.13771942343456e-05*G0_2_4_3 - 0.000822035107749532*G0_2_4_4 - 8.56286570572422e-06*G0_2_4_5 - 2.19423433709184e-05*G0_2_5_0 - 0.000105965463108338*G0_2_5_1 + 2.56885971171729e-05*G0_2_5_2 - 4.28143285286216e-05*G0_2_5_3 - 8.56286570572427e-06*G0_2_5_4 + 0.00029970029970035*G0_2_5_5 + 0.000146103896103921*G0_3_0_0 - 3.21107463964655e-06*G0_3_0_1 - 4.28143285286215e-06*G0_3_0_2 - 0.000509490509490596*G0_3_0_3 - 0.000111317254174416*G0_3_0_4 - 0.000248323105466005*G0_3_0_5 - 3.21107463964655e-06*G0_3_1_0 + 0.000158413015555899*G0_3_1_1 - 0.000105965463108338*G0_3_1_2 + 4.28143285286178e-06*G0_3_1_3 - 7.70657913515189e-05*G0_3_1_4 + 0.000218353075495969*G0_3_1_5 - 4.28143285286215e-06*G0_3_2_0 - 0.000105965463108338*G0_3_2_1 + 0.000191594120165581*G0_3_2_2 - 8.99100899101052e-05*G0_3_2_3 + 5.13771942343456e-05*G0_3_2_4 - 4.28143285286216e-05*G0_3_2_5 - 0.000509490509490596*G0_3_3_0 + 4.28143285286178e-06*G0_3_3_1 - 8.99100899101052e-05*G0_3_3_2 + 0.0033823319537611*G0_3_3_3 + 0.00117311260168423*G0_3_3_4 + 0.00110460967603843*G0_3_3_5 - 0.000111317254174416*G0_3_4_0 - 7.70657913515188e-05*G0_3_4_1 + 5.13771942343456e-05*G0_3_4_2 + 0.00117311260168423*G0_3_4_3 + 0.00106179534750981*G0_3_4_4 + 0.000239760239760281*G0_3_4_5 - 0.000248323105466005*G0_3_5_0 + 0.000218353075495969*G0_3_5_1 - 4.28143285286216e-05*G0_3_5_2 + 0.00110460967603843*G0_3_5_3 + 0.000239760239760281*G0_3_5_4 - 0.000102754388468691*G0_3_5_5 + 0.00140484515484539*G0_4_0_0 - 9.04452690167127e-05*G0_4_0_1 - 0.000461324389895896*G0_4_0_2 - 0.000111317254174416*G0_4_0_3 + 0.00224775224775262*G0_4_0_4 + 0.000224775224775262*G0_4_0_5 - 9.04452690167127e-05*G0_4_1_0 + 4.17439703154059e-05*G0_4_1_1 - 2.14071642643108e-05*G0_4_1_2 - 7.70657913515189e-05*G0_4_1_3 - 0.00041958041958049*G0_4_1_4 + 0.000128442985585864*G0_4_1_5 - 0.000461324389895896*G0_4_2_0 - 2.14071642643108e-05*G0_4_2_1 + 0.000385328956757593*G0_4_2_2 + 5.13771942343456e-05*G0_4_2_3 - 0.000822035107749531*G0_4_2_4 - 8.56286570572427e-06*G0_4_2_5 - 0.000111317254174416*G0_4_3_0 - 7.70657913515189e-05*G0_4_3_1 + 5.13771942343456e-05*G0_4_3_2 + 0.00117311260168423*G0_4_3_3 + 0.00106179534750981*G0_4_3_4 + 0.000239760239760281*G0_4_3_5 + 0.00224775224775262*G0_4_4_0 - 0.00041958041958049*G0_4_4_1 - 0.000822035107749531*G0_4_4_2 + 0.00106179534750981*G0_4_4_3 + 0.00993292421864018*G0_4_4_4 + 0.000856286570572428*G0_4_4_5 + 0.000224775224775262*G0_4_5_0 + 0.000128442985585864*G0_4_5_1 - 8.56286570572417e-06*G0_4_5_2 + 0.000239760239760281*G0_4_5_3 + 0.000856286570572428*G0_4_5_4 - 0.000856286570572429*G0_4_5_5 + 0.00020604395604399*G0_5_0_0 - 3.21107463964651e-06*G0_5_0_1 - 2.19423433709184e-05*G0_5_0_2 - 0.000248323105466005*G0_5_0_3 + 0.000224775224775262*G0_5_0_4 - 0.000449550449550525*G0_5_0_5 - 3.21107463964651e-06*G0_5_1_0 + 7.1714000285441e-05*G0_5_1_1 - 0.000105965463108338*G0_5_1_2 + 0.000218353075495969*G0_5_1_3 + 0.000128442985585864*G0_5_1_4 + 0.000762095047809461*G0_5_1_5 - 2.19423433709184e-05*G0_5_2_0 - 0.000105965463108338*G0_5_2_1 + 2.56885971171729e-05*G0_5_2_2 - 4.28143285286216e-05*G0_5_2_3 - 8.56286570572417e-06*G0_5_2_4 + 0.00029970029970035*G0_5_2_5 - 0.000248323105466005*G0_5_3_0 + 0.000218353075495969*G0_5_3_1 - 4.28143285286216e-05*G0_5_3_2 + 0.00110460967603843*G0_5_3_3 + 0.000239760239760281*G0_5_3_4 - 0.000102754388468691*G0_5_3_5 + 0.000224775224775262*G0_5_4_0 + 0.000128442985585864*G0_5_4_1 - 8.56286570572422e-06*G0_5_4_2 + 0.000239760239760281*G0_5_4_3 + 0.000856286570572429*G0_5_4_4 - 0.000856286570572429*G0_5_4_5 - 0.000449550449550525*G0_5_5_0 + 0.000762095047809461*G0_5_5_1 + 0.00029970029970035*G0_5_5_2 - 0.000102754388468691*G0_5_5_3 - 0.00085628657057243*G0_5_5_4 - 0.00393891822463317*G0_5_5_5; + A[75] = A[55] - 0.000786713286713422*G0_0_0_0 + 2.06043956043993e-05*G0_0_0_1 + 0.000189185814185846*G0_0_0_2 - 4.12087912087983e-05*G0_0_0_3 - 0.00108641358641377*G0_0_0_4 + 2.06043956043992e-05*G0_0_1_0 + 2.54210075638686e-06*G0_0_1_1 - 1.80622948480122e-05*G0_0_1_2 - 1.07035821321553e-05*G0_0_1_3 + 7.11788211788332e-05*G0_0_1_4 - 4.12087912087982e-05*G0_0_1_5 + 0.000189185814185846*G0_0_2_0 - 1.80622948480122e-05*G0_0_2_1 - 2.18085485942666e-05*G0_0_2_2 + 4.17439703154059e-05*G0_0_2_3 + 0.000400849150849219*G0_0_2_4 + 4.12087912087981e-05*G0_0_2_5 - 4.12087912087983e-05*G0_0_3_0 - 1.07035821321553e-05*G0_0_3_1 + 4.17439703154059e-05*G0_0_3_2 + 2.14071642643107e-05*G0_0_3_3 - 5.99400599400703e-05*G0_0_3_4 - 0.00108641358641377*G0_0_4_0 + 7.11788211788332e-05*G0_0_4_1 + 0.000400849150849219*G0_0_4_2 - 5.99400599400703e-05*G0_0_4_3 - 0.00202297702297736*G0_0_4_4 - 0.000224775224775263*G0_0_4_5 - 4.12087912087982e-05*G0_0_5_1 + 4.12087912087981e-05*G0_0_5_2 - 0.000224775224775263*G0_0_5_4 + 0.000224775224775262*G0_0_5_5 + 2.06043956043992e-05*G0_1_0_0 + 2.54210075638686e-06*G0_1_0_1 - 1.80622948480122e-05*G0_1_0_2 - 1.07035821321553e-05*G0_1_0_3 + 7.11788211788332e-05*G0_1_0_4 - 4.12087912087982e-05*G0_1_0_5 + 2.54210075638686e-06*G0_1_1_0 + 1.76609105180566e-05*G0_1_1_1 - 5.88697017268544e-06*G0_1_1_2 + 1.07035821321561e-06*G0_1_1_3 - 3.42514628228972e-05*G0_1_1_4 + 3.10403881832507e-05*G0_1_1_5 - 1.80622948480122e-05*G0_1_2_0 - 5.88697017268544e-06*G0_1_2_1 + 3.31811046096816e-05*G0_1_2_2 + 1.17739403453709e-05*G0_1_2_3 - 3.31811046096816e-05*G0_1_2_4 - 1.07035821321554e-05*G0_1_3_0 + 1.0703582132156e-06*G0_1_3_1 + 1.17739403453709e-05*G0_1_3_2 + 8.13472242043809e-05*G0_1_3_3 + 8.9910089910105e-05*G0_1_3_4 + 2.14071642643109e-05*G0_1_3_5 + 7.11788211788332e-05*G0_1_4_0 - 3.42514628228972e-05*G0_1_4_1 - 3.31811046096816e-05*G0_1_4_2 + 8.9910089910105e-05*G0_1_4_3 + 0.000470957613814835*G0_1_4_4 + 6.85029256457943e-05*G0_1_4_5 - 4.12087912087982e-05*G0_1_5_0 + 3.10403881832507e-05*G0_1_5_1 + 2.14071642643109e-05*G0_1_5_3 + 6.85029256457943e-05*G0_1_5_4 - 0.000128442985585864*G0_1_5_5 + 0.000189185814185846*G0_2_0_0 - 1.80622948480122e-05*G0_2_0_1 - 2.18085485942666e-05*G0_2_0_2 + 4.1743970315406e-05*G0_2_0_3 + 0.000400849150849219*G0_2_0_4 + 4.12087912087981e-05*G0_2_0_5 - 1.80622948480122e-05*G0_2_1_0 - 5.88697017268544e-06*G0_2_1_1 + 3.31811046096816e-05*G0_2_1_2 + 1.17739403453709e-05*G0_2_1_3 - 3.31811046096816e-05*G0_2_1_4 - 2.18085485942666e-05*G0_2_2_0 + 3.31811046096816e-05*G0_2_2_1 - 0.000224775224775263*G0_2_2_2 - 0.000102754388468692*G0_2_2_3 - 0.000346796061081834*G0_2_2_4 - 3.10403881832506e-05*G0_2_2_5 + 4.1743970315406e-05*G0_2_3_0 + 1.17739403453709e-05*G0_2_3_1 - 0.000102754388468692*G0_2_3_2 - 0.000107035821321554*G0_2_3_3 - 1.71257314114484e-05*G0_2_3_4 - 2.14071642643108e-05*G0_2_3_5 + 0.000400849150849219*G0_2_4_0 - 3.31811046096816e-05*G0_2_4_1 - 0.000346796061081834*G0_2_4_2 - 1.71257314114484e-05*G0_2_4_3 + 0.000890538033395326*G0_2_4_4 + 0.000128442985585864*G0_2_4_5 + 4.12087912087981e-05*G0_2_5_0 - 3.10403881832506e-05*G0_2_5_2 - 2.14071642643108e-05*G0_2_5_3 + 0.000128442985585864*G0_2_5_4 - 6.85029256457943e-05*G0_2_5_5 - 4.12087912087983e-05*G0_3_0_0 - 1.07035821321553e-05*G0_3_0_1 + 4.1743970315406e-05*G0_3_0_2 + 2.14071642643107e-05*G0_3_0_3 - 5.99400599400703e-05*G0_3_0_4 - 1.07035821321553e-05*G0_3_1_0 + 1.0703582132156e-06*G0_3_1_1 + 1.17739403453709e-05*G0_3_1_2 + 8.13472242043809e-05*G0_3_1_3 + 8.9910089910105e-05*G0_3_1_4 + 2.14071642643109e-05*G0_3_1_5 + 4.1743970315406e-05*G0_3_2_0 + 1.17739403453709e-05*G0_3_2_1 - 0.000102754388468692*G0_3_2_2 - 0.000107035821321554*G0_3_2_3 - 1.71257314114484e-05*G0_3_2_4 - 2.14071642643108e-05*G0_3_2_5 + 2.14071642643107e-05*G0_3_3_0 + 8.13472242043809e-05*G0_3_3_1 - 0.000107035821321554*G0_3_3_2 - 0.000162694448408762*G0_3_3_3 - 0.000222634508348832*G0_3_3_4 - 5.99400599400703e-05*G0_3_4_0 + 8.9910089910105e-05*G0_3_4_1 - 1.71257314114484e-05*G0_3_4_2 - 0.000222634508348832*G0_3_4_3 - 0.000822035107749533*G0_3_4_4 - 0.000137005851291589*G0_3_4_5 + 2.14071642643109e-05*G0_3_5_1 - 2.14071642643108e-05*G0_3_5_2 - 0.000137005851291589*G0_3_5_4 + 0.000137005851291589*G0_3_5_5 - 0.00108641358641377*G0_4_0_0 + 7.11788211788332e-05*G0_4_0_1 + 0.000400849150849219*G0_4_0_2 - 5.99400599400703e-05*G0_4_0_3 - 0.00202297702297736*G0_4_0_4 - 0.000224775224775263*G0_4_0_5 + 7.11788211788332e-05*G0_4_1_0 - 3.42514628228971e-05*G0_4_1_1 - 3.31811046096816e-05*G0_4_1_2 + 8.9910089910105e-05*G0_4_1_3 + 0.000470957613814835*G0_4_1_4 + 6.85029256457944e-05*G0_4_1_5 + 0.000400849150849219*G0_4_2_0 - 3.31811046096816e-05*G0_4_2_1 - 0.000346796061081834*G0_4_2_2 - 1.71257314114484e-05*G0_4_2_3 + 0.000890538033395326*G0_4_2_4 + 0.000128442985585864*G0_4_2_5 - 5.99400599400703e-05*G0_4_3_0 + 8.9910089910105e-05*G0_4_3_1 - 1.71257314114484e-05*G0_4_3_2 - 0.000222634508348832*G0_4_3_3 - 0.000822035107749533*G0_4_3_4 - 0.000137005851291589*G0_4_3_5 - 0.00202297702297736*G0_4_4_0 + 0.000470957613814835*G0_4_4_1 + 0.000890538033395326*G0_4_4_2 - 0.000822035107749533*G0_4_4_3 - 0.00959040959041121*G0_4_4_4 - 0.0011988011988014*G0_4_4_5 - 0.000224775224775263*G0_4_5_0 + 6.85029256457943e-05*G0_4_5_1 + 0.000128442985585864*G0_4_5_2 - 0.000137005851291589*G0_4_5_3 - 0.0011988011988014*G0_4_5_4 - 4.12087912087981e-05*G0_5_0_1 + 4.12087912087981e-05*G0_5_0_2 - 0.000224775224775263*G0_5_0_4 + 0.000224775224775262*G0_5_0_5 - 4.12087912087982e-05*G0_5_1_0 + 3.10403881832507e-05*G0_5_1_1 + 2.14071642643109e-05*G0_5_1_3 + 6.85029256457943e-05*G0_5_1_4 - 0.000128442985585864*G0_5_1_5 + 4.12087912087981e-05*G0_5_2_0 - 3.10403881832506e-05*G0_5_2_2 - 2.14071642643108e-05*G0_5_2_3 + 0.000128442985585864*G0_5_2_4 - 6.85029256457944e-05*G0_5_2_5 + 2.14071642643109e-05*G0_5_3_1 - 2.14071642643108e-05*G0_5_3_2 - 0.000137005851291589*G0_5_3_4 + 0.000137005851291588*G0_5_3_5 - 0.000224775224775263*G0_5_4_0 + 6.85029256457943e-05*G0_5_4_1 + 0.000128442985585864*G0_5_4_2 - 0.000137005851291589*G0_5_4_3 - 0.0011988011988014*G0_5_4_4 + 0.000224775224775262*G0_5_5_0 - 0.000128442985585864*G0_5_5_1 - 6.85029256457944e-05*G0_5_5_2 + 0.000137005851291589*G0_5_5_3 + 0.0011988011988014*G0_5_5_5; + A[64] = A[75] - 0.000786713286713418*G0_0_0_0 + 0.000107303410874857*G0_0_0_1 + 0.000153462608819777*G0_0_0_2 - 1.07035821321553e-05*G0_0_0_3 - 0.000440452404738193*G0_0_0_4 - 0.000496111031825401*G0_0_0_5 + 0.000107303410874857*G0_0_1_0 - 4.61591979449199e-05*G0_0_1_1 + 8.13472242043807e-05*G0_0_1_3 + 0.000173398030540917*G0_0_1_4 + 0.000158948194662507*G0_0_1_5 + 0.000153462608819777*G0_0_2_0 - 0.000153462608819777*G0_0_2_2 - 9.2050806336536e-05*G0_0_2_3 + 9.20508063365361e-05*G0_0_2_5 - 1.07035821321553e-05*G0_0_3_0 + 8.13472242043807e-05*G0_0_3_1 - 9.2050806336536e-05*G0_0_3_2 - 0.000269730269730315*G0_0_3_3 - 0.000325388896817523*G0_0_3_4 - 0.000162694448408762*G0_0_3_5 - 0.000440452404738193*G0_0_4_0 + 0.000173398030540917*G0_0_4_1 - 0.000325388896817523*G0_0_4_3 - 0.0010682174967891*G0_0_4_4 - 0.000530897673754906*G0_0_4_5 - 0.000496111031825401*G0_0_5_0 + 0.000158948194662507*G0_0_5_1 + 9.20508063365361e-05*G0_0_5_2 - 0.000162694448408762*G0_0_5_3 - 0.000530897673754906*G0_0_5_4 - 0.000717140002854409*G0_0_5_5 + 0.000107303410874857*G0_1_0_0 - 4.61591979449199e-05*G0_1_0_1 + 8.13472242043807e-05*G0_1_0_3 + 0.000173398030540917*G0_1_0_4 + 0.000158948194662507*G0_1_0_5 - 4.61591979449199e-05*G0_1_1_0 + 4.615919794492e-05*G0_1_1_2 + 5.56586270872079e-05*G0_1_1_3 - 5.5658627087208e-05*G0_1_1_5 + 4.615919794492e-05*G0_1_2_1 - 0.000107303410874857*G0_1_2_2 - 0.000158948194662507*G0_1_2_3 - 0.000173398030540917*G0_1_2_4 - 8.13472242043808e-05*G0_1_2_5 + 8.13472242043807e-05*G0_1_3_0 + 5.56586270872078e-05*G0_1_3_1 - 0.000158948194662507*G0_1_3_2 - 0.000351077493934696*G0_1_3_3 - 0.000162694448408761*G0_1_3_4 + 0.000173398030540917*G0_1_4_0 - 0.000173398030540917*G0_1_4_2 - 0.000162694448408761*G0_1_4_3 + 0.000162694448408762*G0_1_4_5 + 0.000158948194662507*G0_1_5_0 - 5.5658627087208e-05*G0_1_5_1 - 8.13472242043808e-05*G0_1_5_2 + 0.000162694448408762*G0_1_5_4 + 0.000351077493934696*G0_1_5_5 + 0.000153462608819777*G0_2_0_0 - 0.000153462608819777*G0_2_0_2 - 9.2050806336536e-05*G0_2_0_3 + 9.20508063365361e-05*G0_2_0_5 + 4.615919794492e-05*G0_2_1_1 - 0.000107303410874857*G0_2_1_2 - 0.000158948194662507*G0_2_1_3 - 0.000173398030540917*G0_2_1_4 - 8.13472242043808e-05*G0_2_1_5 - 0.000153462608819777*G0_2_2_0 - 0.000107303410874857*G0_2_2_1 + 0.000786713286713418*G0_2_2_2 + 0.000496111031825401*G0_2_2_3 + 0.000440452404738193*G0_2_2_4 + 1.07035821321554e-05*G0_2_2_5 - 9.2050806336536e-05*G0_2_3_0 - 0.000158948194662507*G0_2_3_1 + 0.000496111031825401*G0_2_3_2 + 0.000717140002854409*G0_2_3_3 + 0.000530897673754906*G0_2_3_4 + 0.000162694448408762*G0_2_3_5 - 0.000173398030540917*G0_2_4_1 + 0.000440452404738193*G0_2_4_2 + 0.000530897673754906*G0_2_4_3 + 0.0010682174967891*G0_2_4_4 + 0.000325388896817523*G0_2_4_5 + 9.20508063365361e-05*G0_2_5_0 - 8.13472242043808e-05*G0_2_5_1 + 1.07035821321554e-05*G0_2_5_2 + 0.000162694448408762*G0_2_5_3 + 0.000325388896817523*G0_2_5_4 + 0.000269730269730315*G0_2_5_5 - 1.07035821321553e-05*G0_3_0_0 + 8.13472242043807e-05*G0_3_0_1 - 9.2050806336536e-05*G0_3_0_2 - 0.000269730269730315*G0_3_0_3 - 0.000325388896817523*G0_3_0_4 - 0.000162694448408762*G0_3_0_5 + 8.13472242043807e-05*G0_3_1_0 + 5.56586270872079e-05*G0_3_1_1 - 0.000158948194662507*G0_3_1_2 - 0.000351077493934696*G0_3_1_3 - 0.000162694448408761*G0_3_1_4 - 9.2050806336536e-05*G0_3_2_0 - 0.000158948194662507*G0_3_2_1 + 0.000496111031825401*G0_3_2_2 + 0.000717140002854409*G0_3_2_3 + 0.000530897673754906*G0_3_2_4 + 0.000162694448408762*G0_3_2_5 - 0.000269730269730315*G0_3_3_0 - 0.000351077493934696*G0_3_3_1 + 0.000717140002854409*G0_3_3_2 + 0.00174682460396776*G0_3_3_3 + 0.000864849436278153*G0_3_3_4 + 0.000214071642643108*G0_3_3_5 - 0.000325388896817523*G0_3_4_0 - 0.000162694448408761*G0_3_4_1 + 0.000530897673754906*G0_3_4_2 + 0.000864849436278153*G0_3_4_3 + 0.000650777793635046*G0_3_4_4 - 0.000162694448408762*G0_3_5_0 + 0.000162694448408762*G0_3_5_2 + 0.000214071642643108*G0_3_5_3 - 0.000214071642643107*G0_3_5_5 - 0.000440452404738193*G0_4_0_0 + 0.000173398030540917*G0_4_0_1 - 0.000325388896817523*G0_4_0_3 - 0.0010682174967891*G0_4_0_4 - 0.000530897673754906*G0_4_0_5 + 0.000173398030540917*G0_4_1_0 - 0.000173398030540917*G0_4_1_2 - 0.000162694448408761*G0_4_1_3 + 0.000162694448408761*G0_4_1_5 - 0.000173398030540917*G0_4_2_1 + 0.000440452404738193*G0_4_2_2 + 0.000530897673754906*G0_4_2_3 + 0.0010682174967891*G0_4_2_4 + 0.000325388896817523*G0_4_2_5 - 0.000325388896817523*G0_4_3_0 - 0.000162694448408761*G0_4_3_1 + 0.000530897673754906*G0_4_3_2 + 0.000864849436278153*G0_4_3_3 + 0.000650777793635046*G0_4_3_4 - 0.0010682174967891*G0_4_4_0 + 0.0010682174967891*G0_4_4_2 + 0.000650777793635046*G0_4_4_3 - 0.000650777793635045*G0_4_4_5 - 0.000530897673754906*G0_4_5_0 + 0.000162694448408762*G0_4_5_1 + 0.000325388896817523*G0_4_5_2 - 0.000650777793635045*G0_4_5_4 - 0.000864849436278153*G0_4_5_5 - 0.000496111031825401*G0_5_0_0 + 0.000158948194662507*G0_5_0_1 + 9.20508063365361e-05*G0_5_0_2 - 0.000162694448408762*G0_5_0_3 - 0.000530897673754906*G0_5_0_4 - 0.000717140002854409*G0_5_0_5 + 0.000158948194662507*G0_5_1_0 - 5.5658627087208e-05*G0_5_1_1 - 8.13472242043808e-05*G0_5_1_2 + 0.000162694448408762*G0_5_1_4 + 0.000351077493934696*G0_5_1_5 + 9.20508063365361e-05*G0_5_2_0 - 8.13472242043807e-05*G0_5_2_1 + 1.07035821321554e-05*G0_5_2_2 + 0.000162694448408762*G0_5_2_3 + 0.000325388896817523*G0_5_2_4 + 0.000269730269730315*G0_5_2_5 - 0.000162694448408762*G0_5_3_0 + 0.000162694448408762*G0_5_3_2 + 0.000214071642643108*G0_5_3_3 - 0.000214071642643107*G0_5_3_5 - 0.000530897673754906*G0_5_4_0 + 0.000162694448408762*G0_5_4_1 + 0.000325388896817523*G0_5_4_2 - 0.000650777793635045*G0_5_4_4 - 0.000864849436278153*G0_5_4_5 - 0.000717140002854409*G0_5_5_0 + 0.000351077493934696*G0_5_5_1 + 0.000269730269730315*G0_5_5_2 - 0.000214071642643107*G0_5_5_3 - 0.000864849436278153*G0_5_5_4 - 0.00174682460396775*G0_5_5_5; + A[54] = A[45]; + A[83] = A[75] - 0.000786713286713418*G0_0_0_0 + 0.000153462608819777*G0_0_0_1 + 0.000107303410874857*G0_0_0_2 - 1.07035821321554e-05*G0_0_0_3 - 0.000496111031825401*G0_0_0_4 - 0.000440452404738193*G0_0_0_5 + 0.000153462608819777*G0_0_1_0 - 0.000153462608819777*G0_0_1_1 - 9.20508063365361e-05*G0_0_1_3 + 9.2050806336536e-05*G0_0_1_4 + 0.000107303410874857*G0_0_2_0 - 4.615919794492e-05*G0_0_2_2 + 8.13472242043808e-05*G0_0_2_3 + 0.000158948194662507*G0_0_2_4 + 0.000173398030540917*G0_0_2_5 - 1.07035821321554e-05*G0_0_3_0 - 9.20508063365361e-05*G0_0_3_1 + 8.13472242043808e-05*G0_0_3_2 - 0.000269730269730315*G0_0_3_3 - 0.000162694448408761*G0_0_3_4 - 0.000325388896817523*G0_0_3_5 - 0.000496111031825401*G0_0_4_0 + 9.2050806336536e-05*G0_0_4_1 + 0.000158948194662507*G0_0_4_2 - 0.000162694448408761*G0_0_4_3 - 0.000717140002854409*G0_0_4_4 - 0.000530897673754906*G0_0_4_5 - 0.000440452404738193*G0_0_5_0 + 0.000173398030540917*G0_0_5_2 - 0.000325388896817523*G0_0_5_3 - 0.000530897673754906*G0_0_5_4 - 0.0010682174967891*G0_0_5_5 + 0.000153462608819777*G0_1_0_0 - 0.000153462608819778*G0_1_0_1 - 9.20508063365361e-05*G0_1_0_3 + 9.2050806336536e-05*G0_1_0_4 - 0.000153462608819778*G0_1_1_0 + 0.00078671328671342*G0_1_1_1 - 0.000107303410874858*G0_1_1_2 + 0.000496111031825401*G0_1_1_3 + 1.07035821321553e-05*G0_1_1_4 + 0.000440452404738193*G0_1_1_5 - 0.000107303410874858*G0_1_2_1 + 4.61591979449201e-05*G0_1_2_2 - 0.000158948194662507*G0_1_2_3 - 8.13472242043807e-05*G0_1_2_4 - 0.000173398030540917*G0_1_2_5 - 9.20508063365361e-05*G0_1_3_0 + 0.000496111031825401*G0_1_3_1 - 0.000158948194662507*G0_1_3_2 + 0.00071714000285441*G0_1_3_3 + 0.000162694448408762*G0_1_3_4 + 0.000530897673754906*G0_1_3_5 + 9.2050806336536e-05*G0_1_4_0 + 1.07035821321553e-05*G0_1_4_1 - 8.13472242043807e-05*G0_1_4_2 + 0.000162694448408762*G0_1_4_3 + 0.000269730269730315*G0_1_4_4 + 0.000325388896817523*G0_1_4_5 + 0.000440452404738193*G0_1_5_1 - 0.000173398030540917*G0_1_5_2 + 0.000530897673754906*G0_1_5_3 + 0.000325388896817523*G0_1_5_4 + 0.0010682174967891*G0_1_5_5 + 0.000107303410874857*G0_2_0_0 - 4.615919794492e-05*G0_2_0_2 + 8.13472242043808e-05*G0_2_0_3 + 0.000158948194662507*G0_2_0_4 + 0.000173398030540917*G0_2_0_5 - 0.000107303410874858*G0_2_1_1 + 4.61591979449201e-05*G0_2_1_2 - 0.000158948194662507*G0_2_1_3 - 8.13472242043807e-05*G0_2_1_4 - 0.000173398030540917*G0_2_1_5 - 4.615919794492e-05*G0_2_2_0 + 4.61591979449201e-05*G0_2_2_1 + 5.56586270872078e-05*G0_2_2_3 - 5.56586270872081e-05*G0_2_2_4 + 8.13472242043808e-05*G0_2_3_0 - 0.000158948194662507*G0_2_3_1 + 5.56586270872078e-05*G0_2_3_2 - 0.000351077493934696*G0_2_3_3 - 0.000162694448408762*G0_2_3_5 + 0.000158948194662507*G0_2_4_0 - 8.13472242043807e-05*G0_2_4_1 - 5.56586270872081e-05*G0_2_4_2 + 0.000351077493934696*G0_2_4_4 + 0.000162694448408761*G0_2_4_5 + 0.000173398030540917*G0_2_5_0 - 0.000173398030540917*G0_2_5_1 - 0.000162694448408762*G0_2_5_3 + 0.000162694448408761*G0_2_5_4 - 1.07035821321554e-05*G0_3_0_0 - 9.20508063365361e-05*G0_3_0_1 + 8.13472242043808e-05*G0_3_0_2 - 0.000269730269730315*G0_3_0_3 - 0.000162694448408761*G0_3_0_4 - 0.000325388896817523*G0_3_0_5 - 9.20508063365361e-05*G0_3_1_0 + 0.000496111031825401*G0_3_1_1 - 0.000158948194662507*G0_3_1_2 + 0.00071714000285441*G0_3_1_3 + 0.000162694448408762*G0_3_1_4 + 0.000530897673754906*G0_3_1_5 + 8.13472242043808e-05*G0_3_2_0 - 0.000158948194662507*G0_3_2_1 + 5.56586270872078e-05*G0_3_2_2 - 0.000351077493934696*G0_3_2_3 - 0.000162694448408761*G0_3_2_5 - 0.000269730269730315*G0_3_3_0 + 0.00071714000285441*G0_3_3_1 - 0.000351077493934696*G0_3_3_2 + 0.00174682460396776*G0_3_3_3 + 0.000214071642643107*G0_3_3_4 + 0.000864849436278154*G0_3_3_5 - 0.000162694448408761*G0_3_4_0 + 0.000162694448408762*G0_3_4_1 + 0.000214071642643107*G0_3_4_3 - 0.000214071642643108*G0_3_4_4 - 0.000325388896817523*G0_3_5_0 + 0.000530897673754906*G0_3_5_1 - 0.000162694448408761*G0_3_5_2 + 0.000864849436278154*G0_3_5_3 + 0.000650777793635046*G0_3_5_5 - 0.000496111031825401*G0_4_0_0 + 9.2050806336536e-05*G0_4_0_1 + 0.000158948194662507*G0_4_0_2 - 0.000162694448408761*G0_4_0_3 - 0.000717140002854409*G0_4_0_4 - 0.000530897673754906*G0_4_0_5 + 9.2050806336536e-05*G0_4_1_0 + 1.07035821321553e-05*G0_4_1_1 - 8.13472242043807e-05*G0_4_1_2 + 0.000162694448408762*G0_4_1_3 + 0.000269730269730315*G0_4_1_4 + 0.000325388896817523*G0_4_1_5 + 0.000158948194662507*G0_4_2_0 - 8.13472242043807e-05*G0_4_2_1 - 5.56586270872081e-05*G0_4_2_2 + 0.000351077493934695*G0_4_2_4 + 0.000162694448408761*G0_4_2_5 - 0.000162694448408761*G0_4_3_0 + 0.000162694448408762*G0_4_3_1 + 0.000214071642643107*G0_4_3_3 - 0.000214071642643108*G0_4_3_4 - 0.000717140002854409*G0_4_4_0 + 0.000269730269730315*G0_4_4_1 + 0.000351077493934696*G0_4_4_2 - 0.000214071642643108*G0_4_4_3 - 0.00174682460396775*G0_4_4_4 - 0.000864849436278153*G0_4_4_5 - 0.000530897673754906*G0_4_5_0 + 0.000325388896817523*G0_4_5_1 + 0.000162694448408761*G0_4_5_2 - 0.000864849436278153*G0_4_5_4 - 0.000650777793635046*G0_4_5_5 - 0.000440452404738193*G0_5_0_0 + 0.000173398030540917*G0_5_0_2 - 0.000325388896817523*G0_5_0_3 - 0.000530897673754906*G0_5_0_4 - 0.0010682174967891*G0_5_0_5 + 0.000440452404738193*G0_5_1_1 - 0.000173398030540917*G0_5_1_2 + 0.000530897673754906*G0_5_1_3 + 0.000325388896817523*G0_5_1_4 + 0.0010682174967891*G0_5_1_5 + 0.000173398030540917*G0_5_2_0 - 0.000173398030540917*G0_5_2_1 - 0.000162694448408762*G0_5_2_3 + 0.000162694448408761*G0_5_2_4 - 0.000325388896817523*G0_5_3_0 + 0.000530897673754906*G0_5_3_1 - 0.000162694448408762*G0_5_3_2 + 0.000864849436278154*G0_5_3_3 + 0.000650777793635046*G0_5_3_5 - 0.000530897673754906*G0_5_4_0 + 0.000325388896817523*G0_5_4_1 + 0.000162694448408761*G0_5_4_2 - 0.000864849436278153*G0_5_4_4 - 0.000650777793635046*G0_5_4_5 - 0.0010682174967891*G0_5_5_0 + 0.0010682174967891*G0_5_5_1 + 0.000650777793635046*G0_5_5_3 - 0.000650777793635046*G0_5_5_4; + A[46] = A[64]; + A[57] = A[75]; + A[98] = A[89]; + A[39] = A[93]; + A[96] = A[69]; + A[65] = A[36] - 0.000651848151848262*G0_0_0_0 + 6.59608248894074e-05*G0_0_0_1 + 0.000106500642214946*G0_0_0_2 - 3.4786641929505e-05*G0_0_0_3 - 0.000526616240902045*G0_0_0_4 - 0.000237619523333849*G0_0_0_5 + 6.59608248894074e-05*G0_0_1_0 - 2.46182389039573e-05*G0_0_1_1 - 1.52526045383214e-05*G0_0_1_2 + 8.29527615242041e-05*G0_0_1_4 + 4.92364778079146e-05*G0_0_1_5 + 0.000106500642214946*G0_0_2_0 - 1.52526045383214e-05*G0_0_2_1 + 1.31118881118904e-05*G0_0_2_2 + 2.62237762237807e-05*G0_0_2_3 + 0.000183566433566465*G0_0_2_4 + 7.54602540316953e-05*G0_0_2_5 - 3.4786641929505e-05*G0_0_3_0 + 2.62237762237807e-05*G0_0_3_2 - 8.56286570572422e-06*G0_0_3_3 - 9.63322391893983e-05*G0_0_3_4 - 8.13472242043808e-05*G0_0_3_5 - 0.000526616240902045*G0_0_4_0 + 8.29527615242041e-05*G0_0_4_1 + 0.000183566433566465*G0_0_4_2 - 9.63322391893983e-05*G0_0_4_3 - 0.000787783644926635*G0_0_4_4 - 0.000316826031111799*G0_0_4_5 - 0.000237619523333849*G0_0_5_0 + 4.92364778079147e-05*G0_0_5_1 + 7.54602540316953e-05*G0_0_5_2 - 8.13472242043808e-05*G0_0_5_3 - 0.000316826031111799*G0_0_5_4 - 0.000316826031111799*G0_0_5_5 + 6.59608248894074e-05*G0_1_0_0 - 2.46182389039573e-05*G0_1_0_1 - 1.52526045383214e-05*G0_1_0_2 + 8.29527615242041e-05*G0_1_0_4 + 4.92364778079146e-05*G0_1_0_5 - 2.46182389039573e-05*G0_1_1_0 + 4.8567503924655e-05*G0_1_1_1 - 2.14071642643108e-06*G0_1_1_2 + 3.47866419295049e-05*G0_1_1_3 - 4.28143285286221e-06*G0_1_1_4 + 8.56286570572429e-06*G0_1_1_5 - 1.52526045383214e-05*G0_1_2_0 - 2.14071642643108e-06*G0_1_2_1 + 1.31118881118903e-05*G0_1_2_2 - 2.62237762237806e-05*G0_1_2_3 - 2.62237762237807e-05*G0_1_2_4 - 4.06736121021904e-05*G0_1_2_5 + 3.47866419295049e-05*G0_1_3_1 - 2.62237762237806e-05*G0_1_3_2 + 9.63322391893983e-05*G0_1_3_3 + 8.56286570572441e-06*G0_1_3_4 + 8.13472242043808e-05*G0_1_3_5 + 8.29527615242041e-05*G0_1_4_0 - 4.28143285286221e-06*G0_1_4_1 - 2.62237762237807e-05*G0_1_4_2 + 8.5628657057244e-06*G0_1_4_3 - 5.35179106607764e-05*G0_1_4_4 + 8.99100899101052e-05*G0_1_4_5 + 4.92364778079146e-05*G0_1_5_0 + 8.56286570572429e-06*G0_1_5_1 - 4.06736121021904e-05*G0_1_5_2 + 8.13472242043808e-05*G0_1_5_3 + 8.99100899101052e-05*G0_1_5_4 + 0.000201227344084521*G0_1_5_5 + 0.000106500642214946*G0_2_0_0 - 1.52526045383214e-05*G0_2_0_1 + 1.31118881118904e-05*G0_2_0_2 + 2.62237762237807e-05*G0_2_0_3 + 0.000183566433566465*G0_2_0_4 + 7.54602540316954e-05*G0_2_0_5 - 1.52526045383214e-05*G0_2_1_0 - 2.14071642643108e-06*G0_2_1_1 + 1.31118881118903e-05*G0_2_1_2 - 2.62237762237806e-05*G0_2_1_3 - 2.62237762237807e-05*G0_2_1_4 - 4.06736121021904e-05*G0_2_1_5 + 1.31118881118904e-05*G0_2_2_0 + 1.31118881118903e-05*G0_2_2_1 - 0.000224775224775263*G0_2_2_2 - 0.000262237762237807*G0_2_2_4 - 2.62237762237807e-05*G0_2_2_5 + 2.62237762237807e-05*G0_2_3_0 - 2.62237762237806e-05*G0_2_3_1 + 0.000183566433566465*G0_2_4_0 - 2.62237762237807e-05*G0_2_4_1 - 0.000262237762237807*G0_2_4_2 + 0.000104895104895123*G0_2_4_5 + 7.54602540316953e-05*G0_2_5_0 - 4.06736121021904e-05*G0_2_5_1 - 2.62237762237807e-05*G0_2_5_2 + 0.000104895104895123*G0_2_5_4 + 8.13472242043808e-05*G0_2_5_5 - 3.4786641929505e-05*G0_3_0_0 + 2.62237762237807e-05*G0_3_0_2 - 8.56286570572419e-06*G0_3_0_3 - 9.63322391893983e-05*G0_3_0_4 - 8.13472242043808e-05*G0_3_0_5 + 3.4786641929505e-05*G0_3_1_1 - 2.62237762237806e-05*G0_3_1_2 + 9.63322391893983e-05*G0_3_1_3 + 8.56286570572441e-06*G0_3_1_4 + 8.13472242043808e-05*G0_3_1_5 + 2.62237762237807e-05*G0_3_2_0 - 2.62237762237807e-05*G0_3_2_1 - 8.56286570572419e-06*G0_3_3_0 + 9.63322391893982e-05*G0_3_3_1 - 0.000299700299700352*G0_3_3_3 + 1.71257314114483e-05*G0_3_3_5 - 9.63322391893983e-05*G0_3_4_0 + 8.56286570572441e-06*G0_3_4_1 + 0.00029970029970035*G0_3_4_4 - 1.71257314114488e-05*G0_3_4_5 - 8.13472242043808e-05*G0_3_5_0 + 8.13472242043808e-05*G0_3_5_1 + 1.71257314114483e-05*G0_3_5_3 - 1.71257314114488e-05*G0_3_5_4 - 0.000526616240902045*G0_4_0_0 + 8.29527615242041e-05*G0_4_0_1 + 0.000183566433566465*G0_4_0_2 - 9.63322391893983e-05*G0_4_0_3 - 0.000787783644926635*G0_4_0_4 - 0.000316826031111799*G0_4_0_5 + 8.29527615242041e-05*G0_4_1_0 - 4.28143285286221e-06*G0_4_1_1 - 2.62237762237807e-05*G0_4_1_2 + 8.56286570572441e-06*G0_4_1_3 - 5.35179106607764e-05*G0_4_1_4 + 8.99100899101052e-05*G0_4_1_5 + 0.000183566433566465*G0_4_2_0 - 2.62237762237807e-05*G0_4_2_1 - 0.000262237762237807*G0_4_2_2 + 0.000104895104895123*G0_4_2_5 - 9.63322391893983e-05*G0_4_3_0 + 8.5628657057244e-06*G0_4_3_1 + 0.00029970029970035*G0_4_3_4 - 1.71257314114488e-05*G0_4_3_5 - 0.000787783644926635*G0_4_4_0 - 5.35179106607764e-05*G0_4_4_1 + 0.00029970029970035*G0_4_4_3 + 0.0023976023976028*G0_4_4_4 - 0.000102754388468692*G0_4_4_5 - 0.000316826031111799*G0_4_5_0 + 8.99100899101052e-05*G0_4_5_1 + 0.000104895104895123*G0_4_5_2 - 1.71257314114488e-05*G0_4_5_3 - 0.000102754388468692*G0_4_5_4 - 0.000342514628228972*G0_4_5_5 - 0.000237619523333849*G0_5_0_0 + 4.92364778079147e-05*G0_5_0_1 + 7.54602540316954e-05*G0_5_0_2 - 8.13472242043808e-05*G0_5_0_3 - 0.000316826031111799*G0_5_0_4 - 0.000316826031111799*G0_5_0_5 + 4.92364778079147e-05*G0_5_1_0 + 8.56286570572429e-06*G0_5_1_1 - 4.06736121021904e-05*G0_5_1_2 + 8.13472242043808e-05*G0_5_1_3 + 8.99100899101052e-05*G0_5_1_4 + 0.000201227344084521*G0_5_1_5 + 7.54602540316953e-05*G0_5_2_0 - 4.06736121021904e-05*G0_5_2_1 - 2.62237762237807e-05*G0_5_2_2 + 0.000104895104895123*G0_5_2_4 + 8.13472242043808e-05*G0_5_2_5 - 8.13472242043808e-05*G0_5_3_0 + 8.13472242043808e-05*G0_5_3_1 + 1.71257314114483e-05*G0_5_3_3 - 1.71257314114488e-05*G0_5_3_4 - 0.000316826031111799*G0_5_4_0 + 8.99100899101052e-05*G0_5_4_1 + 0.000104895104895123*G0_5_4_2 - 1.71257314114488e-05*G0_5_4_3 - 0.000102754388468692*G0_5_4_4 - 0.000342514628228972*G0_5_4_5 - 0.000316826031111799*G0_5_5_0 + 0.000201227344084521*G0_5_5_1 + 8.13472242043808e-05*G0_5_5_2 - 0.000342514628228972*G0_5_5_4 - 0.000402454688169042*G0_5_5_5; + A[85] = A[65] + 0.000224775224775264*G0_0_0_0 - 1.31118881118904e-05*G0_0_0_1 - 1.31118881118905e-05*G0_0_0_2 + 2.62237762237807e-05*G0_0_0_3 + 0.000262237762237807*G0_0_0_4 - 1.31118881118904e-05*G0_0_1_0 + 2.14071642643117e-06*G0_0_1_1 + 1.52526045383214e-05*G0_0_1_2 + 4.06736121021904e-05*G0_0_1_3 + 2.62237762237806e-05*G0_0_1_4 + 2.62237762237807e-05*G0_0_1_5 - 1.31118881118905e-05*G0_0_2_0 + 1.52526045383214e-05*G0_0_2_1 - 0.000106500642214946*G0_0_2_2 - 7.54602540316953e-05*G0_0_2_3 - 0.000183566433566465*G0_0_2_4 - 2.62237762237807e-05*G0_0_2_5 + 2.62237762237807e-05*G0_0_3_0 + 4.06736121021904e-05*G0_0_3_1 - 7.54602540316953e-05*G0_0_3_2 - 8.13472242043808e-05*G0_0_3_3 - 0.000104895104895123*G0_0_3_4 + 0.000262237762237807*G0_0_4_0 + 2.62237762237806e-05*G0_0_4_1 - 0.000183566433566465*G0_0_4_2 - 0.000104895104895123*G0_0_4_3 + 2.62237762237807e-05*G0_0_5_1 - 2.62237762237807e-05*G0_0_5_2 - 1.31118881118904e-05*G0_1_0_0 + 2.14071642643117e-06*G0_1_0_1 + 1.52526045383214e-05*G0_1_0_2 + 4.06736121021904e-05*G0_1_0_3 + 2.62237762237806e-05*G0_1_0_4 + 2.62237762237807e-05*G0_1_0_5 + 2.14071642643116e-06*G0_1_1_0 - 4.85675039246556e-05*G0_1_1_1 + 2.46182389039574e-05*G0_1_1_2 - 8.56286570572439e-06*G0_1_1_3 + 4.28143285286221e-06*G0_1_1_4 - 3.47866419295053e-05*G0_1_1_5 + 1.52526045383214e-05*G0_1_2_0 + 2.46182389039574e-05*G0_1_2_1 - 6.59608248894073e-05*G0_1_2_2 - 4.92364778079146e-05*G0_1_2_3 - 8.2952761524204e-05*G0_1_2_4 + 4.06736121021904e-05*G0_1_3_0 - 8.5628657057244e-06*G0_1_3_1 - 4.92364778079146e-05*G0_1_3_2 - 0.000201227344084521*G0_1_3_3 - 8.99100899101052e-05*G0_1_3_4 - 8.13472242043809e-05*G0_1_3_5 + 2.62237762237806e-05*G0_1_4_0 + 4.28143285286221e-06*G0_1_4_1 - 8.2952761524204e-05*G0_1_4_2 - 8.99100899101051e-05*G0_1_4_3 + 5.35179106607763e-05*G0_1_4_4 - 8.56286570572454e-06*G0_1_4_5 + 2.62237762237807e-05*G0_1_5_0 - 3.47866419295053e-05*G0_1_5_1 - 8.13472242043809e-05*G0_1_5_3 - 8.56286570572454e-06*G0_1_5_4 - 9.63322391893989e-05*G0_1_5_5 - 1.31118881118905e-05*G0_2_0_0 + 1.52526045383214e-05*G0_2_0_1 - 0.000106500642214946*G0_2_0_2 - 7.54602540316953e-05*G0_2_0_3 - 0.000183566433566465*G0_2_0_4 - 2.62237762237807e-05*G0_2_0_5 + 1.52526045383214e-05*G0_2_1_0 + 2.46182389039573e-05*G0_2_1_1 - 6.59608248894073e-05*G0_2_1_2 - 4.92364778079146e-05*G0_2_1_3 - 8.2952761524204e-05*G0_2_1_4 - 0.000106500642214946*G0_2_2_0 - 6.59608248894073e-05*G0_2_2_1 + 0.000651848151848262*G0_2_2_2 + 0.000237619523333849*G0_2_2_3 + 0.000526616240902044*G0_2_2_4 + 3.4786641929505e-05*G0_2_2_5 - 7.54602540316953e-05*G0_2_3_0 - 4.92364778079146e-05*G0_2_3_1 + 0.000237619523333849*G0_2_3_2 + 0.000316826031111799*G0_2_3_3 + 0.000316826031111799*G0_2_3_4 + 8.13472242043808e-05*G0_2_3_5 - 0.000183566433566465*G0_2_4_0 - 8.2952761524204e-05*G0_2_4_1 + 0.000526616240902044*G0_2_4_2 + 0.000316826031111799*G0_2_4_3 + 0.000787783644926635*G0_2_4_4 + 9.63322391893982e-05*G0_2_4_5 - 2.62237762237807e-05*G0_2_5_0 + 3.4786641929505e-05*G0_2_5_2 + 8.13472242043808e-05*G0_2_5_3 + 9.63322391893982e-05*G0_2_5_4 + 8.56286570572426e-06*G0_2_5_5 + 2.62237762237807e-05*G0_3_0_0 + 4.06736121021904e-05*G0_3_0_1 - 7.54602540316953e-05*G0_3_0_2 - 8.13472242043808e-05*G0_3_0_3 - 0.000104895104895123*G0_3_0_4 + 4.06736121021904e-05*G0_3_1_0 - 8.5628657057244e-06*G0_3_1_1 - 4.92364778079146e-05*G0_3_1_2 - 0.000201227344084521*G0_3_1_3 - 8.99100899101052e-05*G0_3_1_4 - 8.13472242043809e-05*G0_3_1_5 - 7.54602540316953e-05*G0_3_2_0 - 4.92364778079146e-05*G0_3_2_1 + 0.000237619523333849*G0_3_2_2 + 0.000316826031111799*G0_3_2_3 + 0.000316826031111799*G0_3_2_4 + 8.13472242043808e-05*G0_3_2_5 - 8.13472242043808e-05*G0_3_3_0 - 0.000201227344084521*G0_3_3_1 + 0.000316826031111799*G0_3_3_2 + 0.000402454688169042*G0_3_3_3 + 0.000342514628228972*G0_3_3_4 - 0.000104895104895123*G0_3_4_0 - 8.99100899101052e-05*G0_3_4_1 + 0.000316826031111799*G0_3_4_2 + 0.000342514628228972*G0_3_4_3 + 0.000102754388468692*G0_3_4_4 + 1.7125731411449e-05*G0_3_4_5 - 8.13472242043809e-05*G0_3_5_1 + 8.13472242043808e-05*G0_3_5_2 + 1.7125731411449e-05*G0_3_5_4 - 1.71257314114487e-05*G0_3_5_5 + 0.000262237762237807*G0_4_0_0 + 2.62237762237806e-05*G0_4_0_1 - 0.000183566433566465*G0_4_0_2 - 0.000104895104895123*G0_4_0_3 + 2.62237762237806e-05*G0_4_1_0 + 4.28143285286221e-06*G0_4_1_1 - 8.2952761524204e-05*G0_4_1_2 - 8.99100899101052e-05*G0_4_1_3 + 5.35179106607762e-05*G0_4_1_4 - 8.56286570572454e-06*G0_4_1_5 - 0.000183566433566465*G0_4_2_0 - 8.2952761524204e-05*G0_4_2_1 + 0.000526616240902044*G0_4_2_2 + 0.000316826031111799*G0_4_2_3 + 0.000787783644926635*G0_4_2_4 + 9.63322391893982e-05*G0_4_2_5 - 0.000104895104895123*G0_4_3_0 - 8.99100899101052e-05*G0_4_3_1 + 0.000316826031111799*G0_4_3_2 + 0.000342514628228972*G0_4_3_3 + 0.000102754388468692*G0_4_3_4 + 1.7125731411449e-05*G0_4_3_5 + 5.35179106607763e-05*G0_4_4_1 + 0.000787783644926635*G0_4_4_2 + 0.000102754388468692*G0_4_4_3 - 0.0023976023976028*G0_4_4_4 - 0.000299700299700349*G0_4_4_5 - 8.56286570572454e-06*G0_4_5_1 + 9.63322391893982e-05*G0_4_5_2 + 1.7125731411449e-05*G0_4_5_3 - 0.000299700299700349*G0_4_5_4 + 2.62237762237807e-05*G0_5_0_1 - 2.62237762237807e-05*G0_5_0_2 + 2.62237762237807e-05*G0_5_1_0 - 3.47866419295053e-05*G0_5_1_1 - 8.13472242043809e-05*G0_5_1_3 - 8.56286570572454e-06*G0_5_1_4 - 9.63322391893989e-05*G0_5_1_5 - 2.62237762237807e-05*G0_5_2_0 + 3.4786641929505e-05*G0_5_2_2 + 8.13472242043808e-05*G0_5_2_3 + 9.63322391893982e-05*G0_5_2_4 + 8.56286570572425e-06*G0_5_2_5 - 8.13472242043809e-05*G0_5_3_1 + 8.13472242043808e-05*G0_5_3_2 + 1.7125731411449e-05*G0_5_3_4 - 1.71257314114487e-05*G0_5_3_5 - 8.56286570572454e-06*G0_5_4_1 + 9.63322391893982e-05*G0_5_4_2 + 1.7125731411449e-05*G0_5_4_3 - 0.000299700299700349*G0_5_4_4 - 9.63322391893989e-05*G0_5_5_1 + 8.56286570572425e-06*G0_5_5_2 - 1.71257314114487e-05*G0_5_5_3 + 0.000299700299700349*G0_5_5_5; + A[58] = A[85]; + A[67] = A[85] + 1.68581418581448e-05*G0_0_0_1 - 1.68581418581446e-05*G0_0_0_2 + 5.61938061938154e-05*G0_0_0_4 - 5.61938061938157e-05*G0_0_0_5 + 1.68581418581448e-05*G0_0_1_0 - 1.64567575281889e-05*G0_0_1_1 - 2.56885971171729e-05*G0_0_1_3 - 1.92664478378796e-05*G0_0_1_4 + 8.0276865991164e-06*G0_0_1_5 - 1.68581418581446e-05*G0_0_2_0 + 1.64567575281889e-05*G0_0_2_2 + 2.56885971171729e-05*G0_0_2_3 - 8.02768659911633e-06*G0_0_2_4 + 1.92664478378797e-05*G0_0_2_5 - 2.56885971171729e-05*G0_0_3_1 + 2.56885971171729e-05*G0_0_3_2 + 3.85328956757594e-05*G0_0_3_4 - 3.85328956757594e-05*G0_0_3_5 + 5.61938061938154e-05*G0_0_4_0 - 1.92664478378796e-05*G0_0_4_1 - 8.02768659911634e-06*G0_0_4_2 + 3.85328956757594e-05*G0_0_4_3 + 0.000224775224775263*G0_0_4_4 - 5.61938061938157e-05*G0_0_5_0 + 8.02768659911641e-06*G0_0_5_1 + 1.92664478378797e-05*G0_0_5_2 - 3.85328956757594e-05*G0_0_5_3 - 0.000224775224775263*G0_0_5_5 + 1.68581418581448e-05*G0_1_0_0 - 1.64567575281889e-05*G0_1_0_1 - 2.56885971171729e-05*G0_1_0_3 - 1.92664478378796e-05*G0_1_0_4 + 8.0276865991164e-06*G0_1_0_5 - 1.64567575281889e-05*G0_1_1_0 + 6.74325674325794e-05*G0_1_1_1 - 1.52526045383214e-05*G0_1_1_2 + 3.53218210361128e-05*G0_1_1_3 + 6.42214927929318e-06*G0_1_1_4 + 3.21107463964665e-05*G0_1_1_5 - 1.52526045383214e-05*G0_1_2_1 + 1.52526045383214e-05*G0_1_2_2 + 2.56885971171729e-05*G0_1_2_4 - 2.56885971171729e-05*G0_1_2_5 - 2.56885971171729e-05*G0_1_3_0 + 3.53218210361128e-05*G0_1_3_1 + 0.000141287284144451*G0_1_3_3 + 3.85328956757594e-05*G0_1_3_4 + 0.000102754388468692*G0_1_3_5 - 1.92664478378796e-05*G0_1_4_0 + 6.42214927929318e-06*G0_1_4_1 + 2.56885971171729e-05*G0_1_4_2 + 3.85328956757594e-05*G0_1_4_3 - 8.99100899101046e-05*G0_1_4_4 + 3.85328956757595e-05*G0_1_4_5 + 8.02768659911638e-06*G0_1_5_0 + 3.21107463964665e-05*G0_1_5_1 - 2.56885971171729e-05*G0_1_5_2 + 0.000102754388468692*G0_1_5_3 + 3.85328956757595e-05*G0_1_5_4 + 0.000282574568288902*G0_1_5_5 - 1.68581418581446e-05*G0_2_0_0 + 1.64567575281889e-05*G0_2_0_2 + 2.56885971171729e-05*G0_2_0_3 - 8.02768659911632e-06*G0_2_0_4 + 1.92664478378797e-05*G0_2_0_5 - 1.52526045383214e-05*G0_2_1_1 + 1.52526045383214e-05*G0_2_1_2 + 2.56885971171729e-05*G0_2_1_4 - 2.56885971171729e-05*G0_2_1_5 + 1.64567575281889e-05*G0_2_2_0 + 1.52526045383214e-05*G0_2_2_1 - 6.7432567432579e-05*G0_2_2_2 - 3.53218210361128e-05*G0_2_2_3 - 3.21107463964664e-05*G0_2_2_4 - 6.42214927929327e-06*G0_2_2_5 + 2.56885971171729e-05*G0_2_3_0 - 3.53218210361128e-05*G0_2_3_2 - 0.000141287284144451*G0_2_3_3 - 0.000102754388468692*G0_2_3_4 - 3.85328956757593e-05*G0_2_3_5 - 8.02768659911632e-06*G0_2_4_0 + 2.56885971171729e-05*G0_2_4_1 - 3.21107463964663e-05*G0_2_4_2 - 0.000102754388468692*G0_2_4_3 - 0.000282574568288902*G0_2_4_4 - 3.85328956757592e-05*G0_2_4_5 + 1.92664478378797e-05*G0_2_5_0 - 2.56885971171729e-05*G0_2_5_1 - 6.42214927929326e-06*G0_2_5_2 - 3.85328956757594e-05*G0_2_5_3 - 3.85328956757592e-05*G0_2_5_4 + 8.9910089910105e-05*G0_2_5_5 - 2.56885971171729e-05*G0_3_0_1 + 2.56885971171729e-05*G0_3_0_2 + 3.85328956757594e-05*G0_3_0_4 - 3.85328956757594e-05*G0_3_0_5 - 2.56885971171729e-05*G0_3_1_0 + 3.53218210361128e-05*G0_3_1_1 + 0.000141287284144451*G0_3_1_3 + 3.85328956757594e-05*G0_3_1_4 + 0.000102754388468692*G0_3_1_5 + 2.56885971171729e-05*G0_3_2_0 - 3.53218210361128e-05*G0_3_2_2 - 0.000141287284144451*G0_3_2_3 - 0.000102754388468692*G0_3_2_4 - 3.85328956757593e-05*G0_3_2_5 + 0.000141287284144451*G0_3_3_1 - 0.000141287284144451*G0_3_3_2 - 7.70657913515189e-05*G0_3_3_4 + 7.70657913515186e-05*G0_3_3_5 + 3.85328956757594e-05*G0_3_4_0 + 3.85328956757594e-05*G0_3_4_1 - 0.000102754388468692*G0_3_4_2 - 7.70657913515189e-05*G0_3_4_3 + 0.000102754388468691*G0_3_4_4 - 3.85328956757594e-05*G0_3_5_0 + 0.000102754388468692*G0_3_5_1 - 3.85328956757593e-05*G0_3_5_2 + 7.70657913515186e-05*G0_3_5_3 - 0.000102754388468691*G0_3_5_5 + 5.61938061938153e-05*G0_4_0_0 - 1.92664478378796e-05*G0_4_0_1 - 8.02768659911632e-06*G0_4_0_2 + 3.85328956757594e-05*G0_4_0_3 + 0.000224775224775263*G0_4_0_4 - 1.92664478378796e-05*G0_4_1_0 + 6.42214927929318e-06*G0_4_1_1 + 2.56885971171729e-05*G0_4_1_2 + 3.85328956757594e-05*G0_4_1_3 - 8.99100899101046e-05*G0_4_1_4 + 3.85328956757596e-05*G0_4_1_5 - 8.02768659911632e-06*G0_4_2_0 + 2.56885971171729e-05*G0_4_2_1 - 3.21107463964663e-05*G0_4_2_2 - 0.000102754388468692*G0_4_2_3 - 0.000282574568288902*G0_4_2_4 - 3.85328956757592e-05*G0_4_2_5 + 3.85328956757594e-05*G0_4_3_0 + 3.85328956757594e-05*G0_4_3_1 - 0.000102754388468692*G0_4_3_2 - 7.70657913515189e-05*G0_4_3_3 + 0.000102754388468691*G0_4_3_4 + 0.000224775224775263*G0_4_4_0 - 8.99100899101046e-05*G0_4_4_1 - 0.000282574568288902*G0_4_4_2 + 0.000102754388468691*G0_4_4_3 + 0.00154131582703037*G0_4_4_4 + 0.000256885971171728*G0_4_4_5 + 3.85328956757595e-05*G0_4_5_1 - 3.85328956757592e-05*G0_4_5_2 + 0.000256885971171728*G0_4_5_4 - 0.000256885971171729*G0_4_5_5 - 5.61938061938158e-05*G0_5_0_0 + 8.02768659911641e-06*G0_5_0_1 + 1.92664478378797e-05*G0_5_0_2 - 3.85328956757594e-05*G0_5_0_3 - 0.000224775224775263*G0_5_0_5 + 8.02768659911641e-06*G0_5_1_0 + 3.21107463964665e-05*G0_5_1_1 - 2.56885971171729e-05*G0_5_1_2 + 0.000102754388468692*G0_5_1_3 + 3.85328956757595e-05*G0_5_1_4 + 0.000282574568288902*G0_5_1_5 + 1.92664478378797e-05*G0_5_2_0 - 2.56885971171729e-05*G0_5_2_1 - 6.42214927929327e-06*G0_5_2_2 - 3.85328956757593e-05*G0_5_2_3 - 3.85328956757592e-05*G0_5_2_4 + 8.9910089910105e-05*G0_5_2_5 - 3.85328956757594e-05*G0_5_3_0 + 0.000102754388468692*G0_5_3_1 - 3.85328956757593e-05*G0_5_3_2 + 7.70657913515186e-05*G0_5_3_3 - 0.000102754388468691*G0_5_3_5 + 3.85328956757595e-05*G0_5_4_1 - 3.85328956757592e-05*G0_5_4_2 + 0.000256885971171728*G0_5_4_4 - 0.000256885971171729*G0_5_4_5 - 0.000224775224775263*G0_5_5_0 + 0.000282574568288902*G0_5_5_1 + 8.9910089910105e-05*G0_5_5_2 - 0.000102754388468691*G0_5_5_3 - 0.000256885971171729*G0_5_5_4 - 0.00154131582703037*G0_5_5_5; + A[76] = A[67]; + A[78] = A[67] - 0.000224775224775262*G0_0_0_0 + 1.31118881118902e-05*G0_0_0_1 + 1.31118881118903e-05*G0_0_0_2 - 2.62237762237806e-05*G0_0_0_3 - 0.000262237762237806*G0_0_0_5 + 1.31118881118903e-05*G0_0_1_0 + 0.000106500642214946*G0_0_1_1 - 1.52526045383214e-05*G0_0_1_2 + 7.54602540316953e-05*G0_0_1_3 + 2.62237762237806e-05*G0_0_1_4 + 0.000183566433566464*G0_0_1_5 + 1.31118881118903e-05*G0_0_2_0 - 1.52526045383214e-05*G0_0_2_1 - 2.14071642643112e-06*G0_0_2_2 - 4.06736121021904e-05*G0_0_2_3 - 2.62237762237808e-05*G0_0_2_4 - 2.62237762237807e-05*G0_0_2_5 - 2.62237762237806e-05*G0_0_3_0 + 7.54602540316953e-05*G0_0_3_1 - 4.06736121021904e-05*G0_0_3_2 + 8.13472242043807e-05*G0_0_3_3 + 0.000104895104895123*G0_0_3_5 + 2.62237762237806e-05*G0_0_4_1 - 2.62237762237808e-05*G0_0_4_2 - 0.000262237762237806*G0_0_5_0 + 0.000183566433566464*G0_0_5_1 - 2.62237762237807e-05*G0_0_5_2 + 0.000104895104895123*G0_0_5_3 + 1.31118881118902e-05*G0_1_0_0 + 0.000106500642214946*G0_1_0_1 - 1.52526045383214e-05*G0_1_0_2 + 7.54602540316953e-05*G0_1_0_3 + 2.62237762237806e-05*G0_1_0_4 + 0.000183566433566464*G0_1_0_5 + 0.000106500642214946*G0_1_1_0 - 0.000651848151848262*G0_1_1_1 + 6.59608248894074e-05*G0_1_1_2 - 0.000237619523333849*G0_1_1_3 - 3.47866419295048e-05*G0_1_1_4 - 0.000526616240902044*G0_1_1_5 - 1.52526045383214e-05*G0_1_2_0 + 6.59608248894074e-05*G0_1_2_1 - 2.46182389039574e-05*G0_1_2_2 + 4.92364778079147e-05*G0_1_2_3 + 8.29527615242041e-05*G0_1_2_5 + 7.54602540316953e-05*G0_1_3_0 - 0.000237619523333849*G0_1_3_1 + 4.92364778079147e-05*G0_1_3_2 - 0.000316826031111799*G0_1_3_3 - 8.13472242043808e-05*G0_1_3_4 - 0.000316826031111799*G0_1_3_5 + 2.62237762237806e-05*G0_1_4_0 - 3.47866419295048e-05*G0_1_4_1 - 8.13472242043808e-05*G0_1_4_3 - 8.56286570572463e-06*G0_1_4_4 - 9.63322391893983e-05*G0_1_4_5 + 0.000183566433566464*G0_1_5_0 - 0.000526616240902044*G0_1_5_1 + 8.29527615242041e-05*G0_1_5_2 - 0.000316826031111799*G0_1_5_3 - 9.63322391893983e-05*G0_1_5_4 - 0.000787783644926635*G0_1_5_5 + 1.31118881118903e-05*G0_2_0_0 - 1.52526045383214e-05*G0_2_0_1 - 2.14071642643112e-06*G0_2_0_2 - 4.06736121021904e-05*G0_2_0_3 - 2.62237762237808e-05*G0_2_0_4 - 2.62237762237807e-05*G0_2_0_5 - 1.52526045383214e-05*G0_2_1_0 + 6.59608248894074e-05*G0_2_1_1 - 2.46182389039574e-05*G0_2_1_2 + 4.92364778079147e-05*G0_2_1_3 + 8.29527615242041e-05*G0_2_1_5 - 2.14071642643113e-06*G0_2_2_0 - 2.46182389039574e-05*G0_2_2_1 + 4.85675039246553e-05*G0_2_2_2 + 8.56286570572439e-06*G0_2_2_3 + 3.47866419295053e-05*G0_2_2_4 - 4.28143285286209e-06*G0_2_2_5 - 4.06736121021904e-05*G0_2_3_0 + 4.92364778079147e-05*G0_2_3_1 + 8.56286570572439e-06*G0_2_3_2 + 0.000201227344084521*G0_2_3_3 + 8.13472242043809e-05*G0_2_3_4 + 8.99100899101051e-05*G0_2_3_5 - 2.62237762237808e-05*G0_2_4_0 + 3.47866419295052e-05*G0_2_4_2 + 8.13472242043809e-05*G0_2_4_3 + 9.63322391893987e-05*G0_2_4_4 + 8.56286570572419e-06*G0_2_4_5 - 2.62237762237807e-05*G0_2_5_0 + 8.29527615242041e-05*G0_2_5_1 - 4.28143285286209e-06*G0_2_5_2 + 8.99100899101051e-05*G0_2_5_3 + 8.56286570572423e-06*G0_2_5_4 - 5.35179106607768e-05*G0_2_5_5 - 2.62237762237806e-05*G0_3_0_0 + 7.54602540316953e-05*G0_3_0_1 - 4.06736121021904e-05*G0_3_0_2 + 8.13472242043807e-05*G0_3_0_3 + 0.000104895104895123*G0_3_0_5 + 7.54602540316953e-05*G0_3_1_0 - 0.000237619523333849*G0_3_1_1 + 4.92364778079147e-05*G0_3_1_2 - 0.000316826031111799*G0_3_1_3 - 8.13472242043808e-05*G0_3_1_4 - 0.000316826031111799*G0_3_1_5 - 4.06736121021904e-05*G0_3_2_0 + 4.92364778079147e-05*G0_3_2_1 + 8.56286570572438e-06*G0_3_2_2 + 0.000201227344084521*G0_3_2_3 + 8.13472242043809e-05*G0_3_2_4 + 8.99100899101051e-05*G0_3_2_5 + 8.13472242043807e-05*G0_3_3_0 - 0.000316826031111799*G0_3_3_1 + 0.000201227344084521*G0_3_3_2 - 0.000402454688169042*G0_3_3_3 - 0.000342514628228972*G0_3_3_5 - 8.13472242043808e-05*G0_3_4_1 + 8.13472242043809e-05*G0_3_4_2 + 1.71257314114493e-05*G0_3_4_4 - 1.71257314114484e-05*G0_3_4_5 + 0.000104895104895123*G0_3_5_0 - 0.000316826031111799*G0_3_5_1 + 8.99100899101051e-05*G0_3_5_2 - 0.000342514628228972*G0_3_5_3 - 1.71257314114484e-05*G0_3_5_4 - 0.000102754388468691*G0_3_5_5 + 2.62237762237806e-05*G0_4_0_1 - 2.62237762237808e-05*G0_4_0_2 + 2.62237762237806e-05*G0_4_1_0 - 3.47866419295048e-05*G0_4_1_1 - 8.13472242043808e-05*G0_4_1_3 - 8.56286570572467e-06*G0_4_1_4 - 9.63322391893984e-05*G0_4_1_5 - 2.62237762237808e-05*G0_4_2_0 + 3.47866419295052e-05*G0_4_2_2 + 8.13472242043809e-05*G0_4_2_3 + 9.63322391893987e-05*G0_4_2_4 + 8.56286570572419e-06*G0_4_2_5 - 8.13472242043809e-05*G0_4_3_1 + 8.13472242043809e-05*G0_4_3_2 + 1.71257314114493e-05*G0_4_3_4 - 1.71257314114484e-05*G0_4_3_5 - 8.56286570572463e-06*G0_4_4_1 + 9.63322391893987e-05*G0_4_4_2 + 1.71257314114493e-05*G0_4_4_3 - 0.000299700299700347*G0_4_4_4 - 9.63322391893983e-05*G0_4_5_1 + 8.56286570572422e-06*G0_4_5_2 - 1.71257314114484e-05*G0_4_5_3 + 0.000299700299700351*G0_4_5_5 - 0.000262237762237806*G0_5_0_0 + 0.000183566433566464*G0_5_0_1 - 2.62237762237807e-05*G0_5_0_2 + 0.000104895104895123*G0_5_0_3 + 0.000183566433566464*G0_5_1_0 - 0.000526616240902044*G0_5_1_1 + 8.29527615242041e-05*G0_5_1_2 - 0.000316826031111799*G0_5_1_3 - 9.63322391893984e-05*G0_5_1_4 - 0.000787783644926635*G0_5_1_5 - 2.62237762237807e-05*G0_5_2_0 + 8.29527615242041e-05*G0_5_2_1 - 4.28143285286208e-06*G0_5_2_2 + 8.99100899101051e-05*G0_5_2_3 + 8.56286570572422e-06*G0_5_2_4 - 5.35179106607768e-05*G0_5_2_5 + 0.000104895104895123*G0_5_3_0 - 0.000316826031111799*G0_5_3_1 + 8.99100899101051e-05*G0_5_3_2 - 0.000342514628228972*G0_5_3_3 - 1.71257314114484e-05*G0_5_3_4 - 0.000102754388468691*G0_5_3_5 - 9.63322391893983e-05*G0_5_4_1 + 8.56286570572422e-06*G0_5_4_2 - 1.71257314114484e-05*G0_5_4_3 + 0.000299700299700351*G0_5_4_5 - 0.000787783644926635*G0_5_5_1 - 5.35179106607768e-05*G0_5_5_2 - 0.000102754388468691*G0_5_5_3 + 0.000299700299700351*G0_5_5_4 + 0.0023976023976028*G0_5_5_5; + A[48] = A[78] + 0.000651848151848261*G0_0_0_0 - 0.000106500642214946*G0_0_0_1 - 6.59608248894073e-05*G0_0_0_2 + 3.47866419295049e-05*G0_0_0_3 + 0.000237619523333849*G0_0_0_4 + 0.000526616240902044*G0_0_0_5 - 0.000106500642214946*G0_0_1_0 - 1.31118881118905e-05*G0_0_1_1 + 1.52526045383214e-05*G0_0_1_2 - 2.62237762237806e-05*G0_0_1_3 - 7.54602540316953e-05*G0_0_1_4 - 0.000183566433566464*G0_0_1_5 - 6.59608248894073e-05*G0_0_2_0 + 1.52526045383214e-05*G0_0_2_1 + 2.46182389039573e-05*G0_0_2_2 - 4.92364778079147e-05*G0_0_2_4 - 8.2952761524204e-05*G0_0_2_5 + 3.47866419295049e-05*G0_0_3_0 - 2.62237762237806e-05*G0_0_3_1 + 8.56286570572419e-06*G0_0_3_3 + 8.13472242043807e-05*G0_0_3_4 + 9.63322391893982e-05*G0_0_3_5 + 0.000237619523333849*G0_0_4_0 - 7.54602540316953e-05*G0_0_4_1 - 4.92364778079147e-05*G0_0_4_2 + 8.13472242043807e-05*G0_0_4_3 + 0.000316826031111798*G0_0_4_4 + 0.000316826031111799*G0_0_4_5 + 0.000526616240902044*G0_0_5_0 - 0.000183566433566464*G0_0_5_1 - 8.2952761524204e-05*G0_0_5_2 + 9.63322391893982e-05*G0_0_5_3 + 0.000316826031111799*G0_0_5_4 + 0.000787783644926634*G0_0_5_5 - 0.000106500642214946*G0_1_0_0 - 1.31118881118905e-05*G0_1_0_1 + 1.52526045383214e-05*G0_1_0_2 - 2.62237762237806e-05*G0_1_0_3 - 7.54602540316953e-05*G0_1_0_4 - 0.000183566433566464*G0_1_0_5 - 1.31118881118905e-05*G0_1_1_0 + 0.000224775224775263*G0_1_1_1 - 1.31118881118903e-05*G0_1_1_2 + 2.62237762237806e-05*G0_1_1_4 + 0.000262237762237807*G0_1_1_5 + 1.52526045383214e-05*G0_1_2_0 - 1.31118881118903e-05*G0_1_2_1 + 2.14071642643103e-06*G0_1_2_2 + 2.62237762237806e-05*G0_1_2_3 + 4.06736121021904e-05*G0_1_2_4 + 2.62237762237806e-05*G0_1_2_5 - 2.62237762237806e-05*G0_1_3_0 + 2.62237762237806e-05*G0_1_3_2 - 7.54602540316952e-05*G0_1_4_0 + 2.62237762237806e-05*G0_1_4_1 + 4.06736121021904e-05*G0_1_4_2 - 8.13472242043808e-05*G0_1_4_4 - 0.000104895104895123*G0_1_4_5 - 0.000183566433566464*G0_1_5_0 + 0.000262237762237807*G0_1_5_1 + 2.62237762237806e-05*G0_1_5_2 - 0.000104895104895123*G0_1_5_4 - 6.59608248894073e-05*G0_2_0_0 + 1.52526045383214e-05*G0_2_0_1 + 2.46182389039573e-05*G0_2_0_2 - 4.92364778079147e-05*G0_2_0_4 - 8.2952761524204e-05*G0_2_0_5 + 1.52526045383214e-05*G0_2_1_0 - 1.31118881118903e-05*G0_2_1_1 + 2.14071642643103e-06*G0_2_1_2 + 2.62237762237806e-05*G0_2_1_3 + 4.06736121021904e-05*G0_2_1_4 + 2.62237762237806e-05*G0_2_1_5 + 2.46182389039573e-05*G0_2_2_0 + 2.14071642643102e-06*G0_2_2_1 - 4.85675039246547e-05*G0_2_2_2 - 3.47866419295047e-05*G0_2_2_3 - 8.56286570572419e-06*G0_2_2_4 + 4.28143285286212e-06*G0_2_2_5 + 2.62237762237806e-05*G0_2_3_1 - 3.47866419295048e-05*G0_2_3_2 - 9.6332239189398e-05*G0_2_3_3 - 8.13472242043807e-05*G0_2_3_4 - 8.56286570572421e-06*G0_2_3_5 - 4.92364778079147e-05*G0_2_4_0 + 4.06736121021904e-05*G0_2_4_1 - 8.56286570572417e-06*G0_2_4_2 - 8.13472242043807e-05*G0_2_4_3 - 0.000201227344084521*G0_2_4_4 - 8.9910089910105e-05*G0_2_4_5 - 8.2952761524204e-05*G0_2_5_0 + 2.62237762237806e-05*G0_2_5_1 + 4.28143285286212e-06*G0_2_5_2 - 8.56286570572419e-06*G0_2_5_3 - 8.9910089910105e-05*G0_2_5_4 + 5.35179106607771e-05*G0_2_5_5 + 3.47866419295049e-05*G0_3_0_0 - 2.62237762237806e-05*G0_3_0_1 + 8.56286570572419e-06*G0_3_0_3 + 8.13472242043807e-05*G0_3_0_4 + 9.63322391893983e-05*G0_3_0_5 - 2.62237762237806e-05*G0_3_1_0 + 2.62237762237806e-05*G0_3_1_2 + 2.62237762237806e-05*G0_3_2_1 - 3.47866419295047e-05*G0_3_2_2 - 9.6332239189398e-05*G0_3_2_3 - 8.13472242043807e-05*G0_3_2_4 - 8.56286570572422e-06*G0_3_2_5 + 8.56286570572419e-06*G0_3_3_0 - 9.6332239189398e-05*G0_3_3_2 + 0.000299700299700351*G0_3_3_3 - 1.71257314114482e-05*G0_3_3_4 + 8.13472242043807e-05*G0_3_4_0 - 8.13472242043807e-05*G0_3_4_2 - 1.71257314114483e-05*G0_3_4_3 + 1.71257314114485e-05*G0_3_4_5 + 9.63322391893982e-05*G0_3_5_0 - 8.56286570572422e-06*G0_3_5_2 + 1.71257314114485e-05*G0_3_5_4 - 0.000299700299700351*G0_3_5_5 + 0.000237619523333849*G0_4_0_0 - 7.54602540316952e-05*G0_4_0_1 - 4.92364778079147e-05*G0_4_0_2 + 8.13472242043807e-05*G0_4_0_3 + 0.000316826031111798*G0_4_0_4 + 0.000316826031111799*G0_4_0_5 - 7.54602540316952e-05*G0_4_1_0 + 2.62237762237806e-05*G0_4_1_1 + 4.06736121021904e-05*G0_4_1_2 - 8.13472242043807e-05*G0_4_1_4 - 0.000104895104895123*G0_4_1_5 - 4.92364778079147e-05*G0_4_2_0 + 4.06736121021904e-05*G0_4_2_1 - 8.56286570572419e-06*G0_4_2_2 - 8.13472242043807e-05*G0_4_2_3 - 0.000201227344084521*G0_4_2_4 - 8.9910089910105e-05*G0_4_2_5 + 8.13472242043807e-05*G0_4_3_0 - 8.13472242043807e-05*G0_4_3_2 - 1.71257314114482e-05*G0_4_3_3 + 1.71257314114485e-05*G0_4_3_5 + 0.000316826031111798*G0_4_4_0 - 8.13472242043808e-05*G0_4_4_1 - 0.000201227344084521*G0_4_4_2 + 0.000402454688169042*G0_4_4_4 + 0.000342514628228971*G0_4_4_5 + 0.000316826031111799*G0_4_5_0 - 0.000104895104895123*G0_4_5_1 - 8.9910089910105e-05*G0_4_5_2 + 1.71257314114485e-05*G0_4_5_3 + 0.000342514628228971*G0_4_5_4 + 0.000102754388468691*G0_4_5_5 + 0.000526616240902044*G0_5_0_0 - 0.000183566433566464*G0_5_0_1 - 8.2952761524204e-05*G0_5_0_2 + 9.63322391893983e-05*G0_5_0_3 + 0.000316826031111799*G0_5_0_4 + 0.000787783644926634*G0_5_0_5 - 0.000183566433566464*G0_5_1_0 + 0.000262237762237807*G0_5_1_1 + 2.62237762237806e-05*G0_5_1_2 - 0.000104895104895123*G0_5_1_4 - 8.2952761524204e-05*G0_5_2_0 + 2.62237762237806e-05*G0_5_2_1 + 4.28143285286212e-06*G0_5_2_2 - 8.56286570572421e-06*G0_5_2_3 - 8.9910089910105e-05*G0_5_2_4 + 5.35179106607771e-05*G0_5_2_5 + 9.63322391893982e-05*G0_5_3_0 - 8.56286570572423e-06*G0_5_3_2 + 1.71257314114485e-05*G0_5_3_4 - 0.000299700299700351*G0_5_3_5 + 0.000316826031111799*G0_5_4_0 - 0.000104895104895123*G0_5_4_1 - 8.9910089910105e-05*G0_5_4_2 + 1.71257314114485e-05*G0_5_4_3 + 0.000342514628228971*G0_5_4_4 + 0.000102754388468691*G0_5_4_5 + 0.000787783644926634*G0_5_5_0 + 5.35179106607771e-05*G0_5_5_2 - 0.000299700299700351*G0_5_5_3 + 0.000102754388468691*G0_5_5_4 - 0.0023976023976028*G0_5_5_5; + A[87] = A[78]; + A[24] = A[42]; + A[84] = A[48]; + A[59] = A[69] + 0.00050574425574434*G0_0_0_0 - 5.77993435136389e-05*G0_0_0_1 - 0.000158948194662507*G0_0_0_2 - 8.66990152704585e-05*G0_0_0_3 + 0.000337162837162894*G0_0_0_4 + 0.000337162837162894*G0_0_0_5 - 5.77993435136389e-05*G0_0_1_0 + 6.50242614528439e-05*G0_0_1_1 - 0.000173398030540917*G0_0_1_3 - 0.000298629941487135*G0_0_1_4 - 0.000192664478378797*G0_0_1_5 - 0.000158948194662507*G0_0_2_0 + 0.000158948194662507*G0_0_2_2 + 8.66990152704583e-05*G0_0_2_3 - 8.66990152704585e-05*G0_0_2_5 - 8.66990152704585e-05*G0_0_3_0 - 0.000173398030540917*G0_0_3_1 + 8.66990152704583e-05*G0_0_3_2 + 0.000809190809190946*G0_0_3_3 + 0.000770657913515187*G0_0_3_4 + 0.000346796061081834*G0_0_3_5 + 0.000337162837162894*G0_0_4_0 - 0.000298629941487135*G0_0_4_1 + 0.000770657913515187*G0_0_4_3 + 0.00192664478378797*G0_0_4_4 + 0.000770657913515187*G0_0_4_5 + 0.000337162837162894*G0_0_5_0 - 0.000192664478378797*G0_0_5_1 - 8.66990152704585e-05*G0_0_5_2 + 0.000346796061081834*G0_0_5_3 + 0.000770657913515187*G0_0_5_4 + 0.00057799343513639*G0_0_5_5 - 5.77993435136389e-05*G0_1_0_0 + 6.50242614528439e-05*G0_1_0_1 - 0.000173398030540917*G0_1_0_3 - 0.000298629941487135*G0_1_0_4 - 0.000192664478378797*G0_1_0_5 + 6.50242614528439e-05*G0_1_1_0 - 6.50242614528438e-05*G0_1_1_2 - 0.000105965463108338*G0_1_1_3 + 0.000105965463108338*G0_1_1_5 - 6.50242614528438e-05*G0_1_2_1 + 5.77993435136389e-05*G0_1_2_2 + 0.000192664478378796*G0_1_2_3 + 0.000298629941487134*G0_1_2_4 + 0.000173398030540917*G0_1_2_5 - 0.000173398030540917*G0_1_3_0 - 0.000105965463108338*G0_1_3_1 + 0.000192664478378796*G0_1_3_2 + 0.000616526330812149*G0_1_3_3 + 0.000346796061081834*G0_1_3_4 - 0.000298629941487135*G0_1_4_0 + 0.000298629941487134*G0_1_4_2 + 0.000346796061081834*G0_1_4_3 - 0.000346796061081834*G0_1_4_5 - 0.000192664478378797*G0_1_5_0 + 0.000105965463108338*G0_1_5_1 + 0.000173398030540917*G0_1_5_2 - 0.000346796061081834*G0_1_5_4 - 0.000616526330812149*G0_1_5_5 - 0.000158948194662507*G0_2_0_0 + 0.000158948194662507*G0_2_0_2 + 8.66990152704583e-05*G0_2_0_3 - 8.66990152704585e-05*G0_2_0_5 - 6.50242614528438e-05*G0_2_1_1 + 5.77993435136389e-05*G0_2_1_2 + 0.000192664478378796*G0_2_1_3 + 0.000298629941487134*G0_2_1_4 + 0.000173398030540917*G0_2_1_5 + 0.000158948194662507*G0_2_2_0 + 5.77993435136389e-05*G0_2_2_1 - 0.000505744255744341*G0_2_2_2 - 0.000337162837162894*G0_2_2_3 - 0.000337162837162894*G0_2_2_4 + 8.66990152704585e-05*G0_2_2_5 + 8.66990152704583e-05*G0_2_3_0 + 0.000192664478378796*G0_2_3_1 - 0.000337162837162894*G0_2_3_2 - 0.000577993435136389*G0_2_3_3 - 0.000770657913515186*G0_2_3_4 - 0.000346796061081834*G0_2_3_5 + 0.000298629941487134*G0_2_4_1 - 0.000337162837162894*G0_2_4_2 - 0.000770657913515186*G0_2_4_3 - 0.00192664478378796*G0_2_4_4 - 0.000770657913515186*G0_2_4_5 - 8.66990152704585e-05*G0_2_5_0 + 0.000173398030540917*G0_2_5_1 + 8.66990152704584e-05*G0_2_5_2 - 0.000346796061081834*G0_2_5_3 - 0.000770657913515186*G0_2_5_4 - 0.000809190809190946*G0_2_5_5 - 8.66990152704585e-05*G0_3_0_0 - 0.000173398030540917*G0_3_0_1 + 8.66990152704583e-05*G0_3_0_2 + 0.000809190809190946*G0_3_0_3 + 0.000770657913515187*G0_3_0_4 + 0.000346796061081834*G0_3_0_5 - 0.000173398030540917*G0_3_1_0 - 0.000105965463108338*G0_3_1_1 + 0.000192664478378796*G0_3_1_2 + 0.000616526330812149*G0_3_1_3 + 0.000346796061081834*G0_3_1_4 + 8.66990152704583e-05*G0_3_2_0 + 0.000192664478378796*G0_3_2_1 - 0.000337162837162894*G0_3_2_2 - 0.000577993435136389*G0_3_2_3 - 0.000770657913515186*G0_3_2_4 - 0.000346796061081834*G0_3_2_5 + 0.000809190809190946*G0_3_3_0 + 0.000616526330812149*G0_3_3_1 - 0.000577993435136389*G0_3_3_2 - 0.00462394748109112*G0_3_3_3 - 0.00231197374054556*G0_3_3_4 - 0.000924789496218225*G0_3_3_5 + 0.000770657913515187*G0_3_4_0 + 0.000346796061081834*G0_3_4_1 - 0.000770657913515186*G0_3_4_2 - 0.00231197374054556*G0_3_4_3 - 0.00154131582703037*G0_3_4_4 + 0.000346796061081834*G0_3_5_0 - 0.000346796061081834*G0_3_5_2 - 0.000924789496218225*G0_3_5_3 + 0.000924789496218223*G0_3_5_5 + 0.000337162837162894*G0_4_0_0 - 0.000298629941487135*G0_4_0_1 + 0.000770657913515187*G0_4_0_3 + 0.00192664478378797*G0_4_0_4 + 0.000770657913515187*G0_4_0_5 - 0.000298629941487135*G0_4_1_0 + 0.000298629941487134*G0_4_1_2 + 0.000346796061081834*G0_4_1_3 - 0.000346796061081834*G0_4_1_5 + 0.000298629941487134*G0_4_2_1 - 0.000337162837162894*G0_4_2_2 - 0.000770657913515186*G0_4_2_3 - 0.00192664478378796*G0_4_2_4 - 0.000770657913515186*G0_4_2_5 + 0.000770657913515187*G0_4_3_0 + 0.000346796061081834*G0_4_3_1 - 0.000770657913515186*G0_4_3_2 - 0.00231197374054556*G0_4_3_3 - 0.00154131582703037*G0_4_3_4 + 0.00192664478378797*G0_4_4_0 - 0.00192664478378796*G0_4_4_2 - 0.00154131582703037*G0_4_4_3 + 0.00154131582703037*G0_4_4_5 + 0.000770657913515187*G0_4_5_0 - 0.000346796061081834*G0_4_5_1 - 0.000770657913515186*G0_4_5_2 + 0.00154131582703037*G0_4_5_4 + 0.00231197374054556*G0_4_5_5 + 0.000337162837162894*G0_5_0_0 - 0.000192664478378797*G0_5_0_1 - 8.66990152704585e-05*G0_5_0_2 + 0.000346796061081834*G0_5_0_3 + 0.000770657913515186*G0_5_0_4 + 0.00057799343513639*G0_5_0_5 - 0.000192664478378797*G0_5_1_0 + 0.000105965463108338*G0_5_1_1 + 0.000173398030540917*G0_5_1_2 - 0.000346796061081834*G0_5_1_4 - 0.000616526330812149*G0_5_1_5 - 8.66990152704585e-05*G0_5_2_0 + 0.000173398030540917*G0_5_2_1 + 8.66990152704584e-05*G0_5_2_2 - 0.000346796061081834*G0_5_2_3 - 0.000770657913515186*G0_5_2_4 - 0.000809190809190946*G0_5_2_5 + 0.000346796061081834*G0_5_3_0 - 0.000346796061081834*G0_5_3_2 - 0.000924789496218225*G0_5_3_3 + 0.000924789496218223*G0_5_3_5 + 0.000770657913515186*G0_5_4_0 - 0.000346796061081834*G0_5_4_1 - 0.000770657913515186*G0_5_4_2 + 0.00154131582703037*G0_5_4_4 + 0.00231197374054556*G0_5_4_5 + 0.00057799343513639*G0_5_5_0 - 0.000616526330812149*G0_5_5_1 - 0.000809190809190946*G0_5_5_2 + 0.000924789496218223*G0_5_5_3 + 0.00231197374054556*G0_5_5_4 + 0.00462394748109112*G0_5_5_5; + A[91] = A[19]; + A[66] = A[64] + 0.000224775224775263*G0_0_0_0 - 3.31811046096816e-05*G0_0_0_1 + 2.18085485942665e-05*G0_0_0_2 + 3.10403881832505e-05*G0_0_0_3 + 0.000346796061081834*G0_0_0_4 + 0.000102754388468691*G0_0_0_5 - 3.31811046096816e-05*G0_0_1_0 + 5.88697017268545e-06*G0_0_1_1 + 1.80622948480121e-05*G0_0_1_2 + 3.31811046096816e-05*G0_0_1_4 - 1.17739403453709e-05*G0_0_1_5 + 2.18085485942665e-05*G0_0_2_0 + 1.80622948480122e-05*G0_0_2_1 - 0.000189185814185846*G0_0_2_2 - 4.12087912087982e-05*G0_0_2_3 - 0.000400849150849218*G0_0_2_4 - 4.17439703154059e-05*G0_0_2_5 + 3.10403881832505e-05*G0_0_3_0 - 4.12087912087982e-05*G0_0_3_2 + 6.85029256457946e-05*G0_0_3_3 - 0.000128442985585864*G0_0_3_4 + 2.14071642643108e-05*G0_0_3_5 + 0.000346796061081834*G0_0_4_0 + 3.31811046096816e-05*G0_0_4_1 - 0.000400849150849218*G0_0_4_2 - 0.000128442985585864*G0_0_4_3 - 0.000890538033395325*G0_0_4_4 + 1.71257314114487e-05*G0_0_4_5 + 0.000102754388468691*G0_0_5_0 - 1.17739403453709e-05*G0_0_5_1 - 4.17439703154059e-05*G0_0_5_2 + 2.14071642643108e-05*G0_0_5_3 + 1.71257314114486e-05*G0_0_5_4 + 0.000107035821321554*G0_0_5_5 - 3.31811046096816e-05*G0_1_0_0 + 5.88697017268545e-06*G0_1_0_1 + 1.80622948480121e-05*G0_1_0_2 + 3.31811046096816e-05*G0_1_0_4 - 1.17739403453709e-05*G0_1_0_5 + 5.88697017268545e-06*G0_1_1_0 - 1.76609105180564e-05*G0_1_1_1 - 2.54210075638691e-06*G0_1_1_2 - 3.10403881832506e-05*G0_1_1_3 + 3.42514628228971e-05*G0_1_1_4 - 1.07035821321555e-06*G0_1_1_5 + 1.80622948480121e-05*G0_1_2_0 - 2.54210075638691e-06*G0_1_2_1 - 2.06043956043989e-05*G0_1_2_2 + 4.12087912087982e-05*G0_1_2_3 - 7.1178821178833e-05*G0_1_2_4 + 1.07035821321554e-05*G0_1_2_5 - 3.10403881832506e-05*G0_1_3_1 + 4.12087912087982e-05*G0_1_3_2 + 0.000128442985585864*G0_1_3_3 - 6.85029256457944e-05*G0_1_3_4 - 2.14071642643108e-05*G0_1_3_5 + 3.31811046096816e-05*G0_1_4_0 + 3.42514628228971e-05*G0_1_4_1 - 7.1178821178833e-05*G0_1_4_2 - 6.85029256457944e-05*G0_1_4_3 - 0.000470957613814836*G0_1_4_4 - 8.9910089910105e-05*G0_1_4_5 - 1.17739403453709e-05*G0_1_5_0 - 1.07035821321555e-06*G0_1_5_1 + 1.07035821321554e-05*G0_1_5_2 - 2.14071642643108e-05*G0_1_5_3 - 8.9910089910105e-05*G0_1_5_4 - 8.13472242043807e-05*G0_1_5_5 + 2.18085485942665e-05*G0_2_0_0 + 1.80622948480121e-05*G0_2_0_1 - 0.000189185814185846*G0_2_0_2 - 4.12087912087982e-05*G0_2_0_3 - 0.000400849150849218*G0_2_0_4 - 4.17439703154059e-05*G0_2_0_5 + 1.80622948480121e-05*G0_2_1_0 - 2.54210075638691e-06*G0_2_1_1 - 2.06043956043989e-05*G0_2_1_2 + 4.12087912087982e-05*G0_2_1_3 - 7.11788211788329e-05*G0_2_1_4 + 1.07035821321554e-05*G0_2_1_5 - 0.000189185814185846*G0_2_2_0 - 2.06043956043989e-05*G0_2_2_1 + 0.00078671328671342*G0_2_2_2 + 0.00108641358641377*G0_2_2_4 + 4.12087912087983e-05*G0_2_2_5 - 4.12087912087982e-05*G0_2_3_0 + 4.12087912087982e-05*G0_2_3_1 - 0.000224775224775263*G0_2_3_3 + 0.000224775224775262*G0_2_3_4 - 0.000400849150849218*G0_2_4_0 - 7.11788211788329e-05*G0_2_4_1 + 0.00108641358641377*G0_2_4_2 + 0.000224775224775262*G0_2_4_3 + 0.00202297702297736*G0_2_4_4 + 5.99400599400699e-05*G0_2_4_5 - 4.17439703154059e-05*G0_2_5_0 + 1.07035821321554e-05*G0_2_5_1 + 4.12087912087983e-05*G0_2_5_2 + 5.99400599400699e-05*G0_2_5_4 - 2.14071642643108e-05*G0_2_5_5 + 3.10403881832505e-05*G0_3_0_0 - 4.12087912087982e-05*G0_3_0_2 + 6.85029256457946e-05*G0_3_0_3 - 0.000128442985585864*G0_3_0_4 + 2.14071642643108e-05*G0_3_0_5 - 3.10403881832506e-05*G0_3_1_1 + 4.12087912087982e-05*G0_3_1_2 + 0.000128442985585865*G0_3_1_3 - 6.85029256457944e-05*G0_3_1_4 - 2.14071642643108e-05*G0_3_1_5 - 4.12087912087982e-05*G0_3_2_0 + 4.12087912087982e-05*G0_3_2_1 - 0.000224775224775263*G0_3_2_3 + 0.000224775224775262*G0_3_2_4 + 6.85029256457946e-05*G0_3_3_0 + 0.000128442985585865*G0_3_3_1 - 0.000224775224775263*G0_3_3_2 - 0.0011988011988014*G0_3_3_3 - 0.000137005851291589*G0_3_3_5 - 0.000128442985585864*G0_3_4_0 - 6.85029256457944e-05*G0_3_4_1 + 0.000224775224775262*G0_3_4_2 + 0.0011988011988014*G0_3_4_4 + 0.000137005851291589*G0_3_4_5 + 2.14071642643108e-05*G0_3_5_0 - 2.14071642643107e-05*G0_3_5_1 - 0.000137005851291589*G0_3_5_3 + 0.000137005851291589*G0_3_5_4 + 0.000346796061081834*G0_4_0_0 + 3.31811046096816e-05*G0_4_0_1 - 0.000400849150849218*G0_4_0_2 - 0.000128442985585864*G0_4_0_3 - 0.000890538033395325*G0_4_0_4 + 1.71257314114486e-05*G0_4_0_5 + 3.31811046096816e-05*G0_4_1_0 + 3.42514628228971e-05*G0_4_1_1 - 7.11788211788329e-05*G0_4_1_2 - 6.85029256457944e-05*G0_4_1_3 - 0.000470957613814836*G0_4_1_4 - 8.9910089910105e-05*G0_4_1_5 - 0.000400849150849218*G0_4_2_0 - 7.11788211788329e-05*G0_4_2_1 + 0.00108641358641377*G0_4_2_2 + 0.000224775224775262*G0_4_2_3 + 0.00202297702297736*G0_4_2_4 + 5.99400599400699e-05*G0_4_2_5 - 0.000128442985585864*G0_4_3_0 - 6.85029256457944e-05*G0_4_3_1 + 0.000224775224775262*G0_4_3_2 + 0.0011988011988014*G0_4_3_4 + 0.000137005851291589*G0_4_3_5 - 0.000890538033395326*G0_4_4_0 - 0.000470957613814836*G0_4_4_1 + 0.00202297702297736*G0_4_4_2 + 0.0011988011988014*G0_4_4_3 + 0.00959040959041121*G0_4_4_4 + 0.000822035107749532*G0_4_4_5 + 1.71257314114486e-05*G0_4_5_0 - 8.9910089910105e-05*G0_4_5_1 + 5.99400599400699e-05*G0_4_5_2 + 0.000137005851291589*G0_4_5_3 + 0.000822035107749532*G0_4_5_4 + 0.000222634508348832*G0_4_5_5 + 0.000102754388468691*G0_5_0_0 - 1.17739403453709e-05*G0_5_0_1 - 4.17439703154059e-05*G0_5_0_2 + 2.14071642643108e-05*G0_5_0_3 + 1.71257314114486e-05*G0_5_0_4 + 0.000107035821321554*G0_5_0_5 - 1.17739403453709e-05*G0_5_1_0 - 1.07035821321553e-06*G0_5_1_1 + 1.07035821321554e-05*G0_5_1_2 - 2.14071642643108e-05*G0_5_1_3 - 8.9910089910105e-05*G0_5_1_4 - 8.13472242043807e-05*G0_5_1_5 - 4.17439703154059e-05*G0_5_2_0 + 1.07035821321554e-05*G0_5_2_1 + 4.12087912087983e-05*G0_5_2_2 + 5.99400599400699e-05*G0_5_2_4 - 2.14071642643108e-05*G0_5_2_5 + 2.14071642643108e-05*G0_5_3_0 - 2.14071642643108e-05*G0_5_3_1 - 0.000137005851291589*G0_5_3_3 + 0.000137005851291589*G0_5_3_4 + 1.71257314114486e-05*G0_5_4_0 - 8.9910089910105e-05*G0_5_4_1 + 5.99400599400699e-05*G0_5_4_2 + 0.000137005851291589*G0_5_4_3 + 0.000822035107749532*G0_5_4_4 + 0.000222634508348832*G0_5_4_5 + 0.000107035821321554*G0_5_5_0 - 8.13472242043807e-05*G0_5_5_1 - 2.14071642643108e-05*G0_5_5_2 + 0.000222634508348832*G0_5_5_4 + 0.000162694448408762*G0_5_5_5; + A[56] = A[65]; + A[77] = A[55] - 0.000168581418581447*G0_0_0_1 + 0.000168581418581447*G0_0_0_2 - 0.00108641358641377*G0_0_0_4 + 0.00108641358641377*G0_0_0_5 - 0.000168581418581447*G0_0_1_0 + 2.43506493506533e-05*G0_0_1_1 - 5.24475524475612e-05*G0_0_1_3 + 2.99700299700351e-05*G0_0_1_4 - 0.000442057942058016*G0_0_1_5 + 0.000168581418581447*G0_0_2_0 - 2.43506493506535e-05*G0_0_2_2 + 5.24475524475613e-05*G0_0_2_3 + 0.000442057942058017*G0_0_2_4 - 2.9970029970035e-05*G0_0_2_5 - 5.24475524475612e-05*G0_0_3_1 + 5.24475524475613e-05*G0_0_3_2 - 5.99400599400704e-05*G0_0_3_4 + 5.994005994007e-05*G0_0_3_5 - 0.00108641358641377*G0_0_4_0 + 2.9970029970035e-05*G0_0_4_1 + 0.000442057942058017*G0_0_4_2 - 5.99400599400704e-05*G0_0_4_3 - 0.00224775224775262*G0_0_4_4 + 0.00108641358641377*G0_0_5_0 - 0.000442057942058016*G0_0_5_1 - 2.9970029970035e-05*G0_0_5_2 + 5.994005994007e-05*G0_0_5_3 + 0.00224775224775263*G0_0_5_5 - 0.000168581418581447*G0_1_0_0 + 2.43506493506533e-05*G0_1_0_1 - 5.24475524475612e-05*G0_1_0_3 + 2.99700299700351e-05*G0_1_0_4 - 0.000442057942058016*G0_1_0_5 + 2.43506493506533e-05*G0_1_1_0 + 0.000242436135293319*G0_1_1_1 - 3.90680747823671e-05*G0_1_1_2 + 0.000103824746681907*G0_1_1_3 - 3.21107463964667e-06*G0_1_1_4 + 0.000377836449265084*G0_1_1_5 - 3.90680747823671e-05*G0_1_2_1 + 3.90680747823671e-05*G0_1_2_2 - 3.31811046096816e-05*G0_1_2_4 + 3.31811046096815e-05*G0_1_2_5 - 5.24475524475612e-05*G0_1_3_0 + 0.000103824746681907*G0_1_3_1 + 0.000188383045525935*G0_1_3_3 + 0.000111317254174416*G0_1_3_4 + 3.85328956757596e-05*G0_1_3_5 + 2.99700299700351e-05*G0_1_4_0 - 3.21107463964667e-06*G0_1_4_1 - 3.31811046096816e-05*G0_1_4_2 + 0.000111317254174416*G0_1_4_3 + 0.00053946053946063*G0_1_4_4 - 5.99400599400699e-05*G0_1_4_5 - 0.000442057942058016*G0_1_5_0 + 0.000377836449265084*G0_1_5_1 + 3.31811046096815e-05*G0_1_5_2 + 3.85328956757596e-05*G0_1_5_3 - 5.99400599400699e-05*G0_1_5_4 - 0.00101898101898119*G0_1_5_5 + 0.000168581418581447*G0_2_0_0 - 2.43506493506535e-05*G0_2_0_2 + 5.24475524475613e-05*G0_2_0_3 + 0.000442057942058017*G0_2_0_4 - 2.9970029970035e-05*G0_2_0_5 - 3.90680747823671e-05*G0_2_1_1 + 3.90680747823671e-05*G0_2_1_2 - 3.31811046096816e-05*G0_2_1_4 + 3.31811046096815e-05*G0_2_1_5 - 2.43506493506534e-05*G0_2_2_0 + 3.90680747823671e-05*G0_2_2_1 - 0.000242436135293319*G0_2_2_2 - 0.000103824746681907*G0_2_2_3 - 0.000377836449265085*G0_2_2_4 + 3.21107463964658e-06*G0_2_2_5 + 5.24475524475613e-05*G0_2_3_0 - 0.000103824746681907*G0_2_3_2 - 0.000188383045525935*G0_2_3_3 - 3.85328956757592e-05*G0_2_3_4 - 0.000111317254174416*G0_2_3_5 + 0.000442057942058017*G0_2_4_0 - 3.31811046096816e-05*G0_2_4_1 - 0.000377836449265085*G0_2_4_2 - 3.85328956757592e-05*G0_2_4_3 + 0.00101898101898119*G0_2_4_4 + 5.99400599400701e-05*G0_2_4_5 - 2.99700299700349e-05*G0_2_5_0 + 3.31811046096815e-05*G0_2_5_1 + 3.21107463964655e-06*G0_2_5_2 - 0.000111317254174416*G0_2_5_3 + 5.99400599400701e-05*G0_2_5_4 - 0.00053946053946063*G0_2_5_5 - 5.24475524475612e-05*G0_3_0_1 + 5.24475524475613e-05*G0_3_0_2 - 5.99400599400704e-05*G0_3_0_4 + 5.994005994007e-05*G0_3_0_5 - 5.24475524475612e-05*G0_3_1_0 + 0.000103824746681907*G0_3_1_1 + 0.000188383045525935*G0_3_1_3 + 0.000111317254174416*G0_3_1_4 + 3.85328956757596e-05*G0_3_1_5 + 5.24475524475613e-05*G0_3_2_0 - 0.000103824746681907*G0_3_2_2 - 0.000188383045525935*G0_3_2_3 - 3.85328956757592e-05*G0_3_2_4 - 0.000111317254174416*G0_3_2_5 + 0.000188383045525935*G0_3_3_1 - 0.000188383045525935*G0_3_3_2 - 0.000222634508348832*G0_3_3_4 + 0.000222634508348832*G0_3_3_5 - 5.99400599400704e-05*G0_3_4_0 + 0.000111317254174416*G0_3_4_1 - 3.85328956757592e-05*G0_3_4_2 - 0.000222634508348832*G0_3_4_3 - 0.000959040959041122*G0_3_4_4 + 5.994005994007e-05*G0_3_5_0 + 3.85328956757596e-05*G0_3_5_1 - 0.000111317254174416*G0_3_5_2 + 0.000222634508348832*G0_3_5_3 + 0.00095904095904112*G0_3_5_5 - 0.00108641358641377*G0_4_0_0 + 2.9970029970035e-05*G0_4_0_1 + 0.000442057942058017*G0_4_0_2 - 5.99400599400704e-05*G0_4_0_3 - 0.00224775224775262*G0_4_0_4 + 2.99700299700351e-05*G0_4_1_0 - 3.21107463964666e-06*G0_4_1_1 - 3.31811046096816e-05*G0_4_1_2 + 0.000111317254174416*G0_4_1_3 + 0.00053946053946063*G0_4_1_4 - 5.99400599400699e-05*G0_4_1_5 + 0.000442057942058017*G0_4_2_0 - 3.31811046096816e-05*G0_4_2_1 - 0.000377836449265085*G0_4_2_2 - 3.85328956757591e-05*G0_4_2_3 + 0.00101898101898119*G0_4_2_4 + 5.99400599400701e-05*G0_4_2_5 - 5.99400599400704e-05*G0_4_3_0 + 0.000111317254174416*G0_4_3_1 - 3.85328956757592e-05*G0_4_3_2 - 0.000222634508348832*G0_4_3_3 - 0.000959040959041122*G0_4_3_4 - 0.00224775224775262*G0_4_4_0 + 0.00053946053946063*G0_4_4_1 + 0.00101898101898119*G0_4_4_2 - 0.000959040959041122*G0_4_4_3 - 0.0107892107892126*G0_4_4_4 - 0.0011988011988014*G0_4_4_5 - 5.99400599400699e-05*G0_4_5_1 + 5.994005994007e-05*G0_4_5_2 - 0.0011988011988014*G0_4_5_4 + 0.0011988011988014*G0_4_5_5 + 0.00108641358641377*G0_5_0_0 - 0.000442057942058016*G0_5_0_1 - 2.99700299700349e-05*G0_5_0_2 + 5.994005994007e-05*G0_5_0_3 + 0.00224775224775263*G0_5_0_5 - 0.000442057942058016*G0_5_1_0 + 0.000377836449265084*G0_5_1_1 + 3.31811046096815e-05*G0_5_1_2 + 3.85328956757596e-05*G0_5_1_3 - 5.99400599400699e-05*G0_5_1_4 - 0.00101898101898119*G0_5_1_5 - 2.99700299700349e-05*G0_5_2_0 + 3.31811046096815e-05*G0_5_2_1 + 3.21107463964653e-06*G0_5_2_2 - 0.000111317254174416*G0_5_2_3 + 5.99400599400699e-05*G0_5_2_4 - 0.00053946053946063*G0_5_2_5 + 5.994005994007e-05*G0_5_3_0 + 3.85328956757596e-05*G0_5_3_1 - 0.000111317254174416*G0_5_3_2 + 0.000222634508348832*G0_5_3_3 + 0.00095904095904112*G0_5_3_5 - 5.99400599400699e-05*G0_5_4_1 + 5.994005994007e-05*G0_5_4_2 - 0.0011988011988014*G0_5_4_4 + 0.0011988011988014*G0_5_4_5 + 0.00224775224775263*G0_5_5_0 - 0.00101898101898119*G0_5_5_1 - 0.00053946053946063*G0_5_5_2 + 0.00095904095904112*G0_5_5_3 + 0.0011988011988014*G0_5_5_4 + 0.0107892107892126*G0_5_5_5; + A[12] = A[21]; + A[49] = A[94]; + A[33] = A[83] - 1.76609105180565e-05*G0_0_0_0 - 2.54210075638687e-06*G0_0_0_1 + 5.88697017268547e-06*G0_0_0_2 + 3.42514628228971e-05*G0_0_0_3 - 1.07035821321557e-06*G0_0_0_4 - 3.10403881832507e-05*G0_0_0_5 - 2.54210075638687e-06*G0_0_1_0 - 2.06043956043991e-05*G0_0_1_1 + 1.80622948480122e-05*G0_0_1_2 - 7.11788211788334e-05*G0_0_1_3 + 1.07035821321554e-05*G0_0_1_4 + 4.12087912087981e-05*G0_0_1_5 + 5.88697017268547e-06*G0_0_2_0 + 1.80622948480122e-05*G0_0_2_1 - 3.31811046096816e-05*G0_0_2_2 + 3.31811046096816e-05*G0_0_2_3 - 1.17739403453709e-05*G0_0_2_4 + 3.42514628228971e-05*G0_0_3_0 - 7.11788211788334e-05*G0_0_3_1 + 3.31811046096816e-05*G0_0_3_2 - 0.000470957613814836*G0_0_3_3 - 8.9910089910105e-05*G0_0_3_4 - 6.85029256457942e-05*G0_0_3_5 - 1.07035821321557e-06*G0_0_4_0 + 1.07035821321553e-05*G0_0_4_1 - 1.17739403453709e-05*G0_0_4_2 - 8.9910089910105e-05*G0_0_4_3 - 8.13472242043808e-05*G0_0_4_4 - 2.14071642643107e-05*G0_0_4_5 - 3.10403881832507e-05*G0_0_5_0 + 4.12087912087981e-05*G0_0_5_1 - 6.85029256457942e-05*G0_0_5_3 - 2.14071642643108e-05*G0_0_5_4 + 0.000128442985585864*G0_0_5_5 - 2.54210075638687e-06*G0_1_0_0 - 2.06043956043991e-05*G0_1_0_1 + 1.80622948480122e-05*G0_1_0_2 - 7.11788211788334e-05*G0_1_0_3 + 1.07035821321554e-05*G0_1_0_4 + 4.12087912087981e-05*G0_1_0_5 - 2.06043956043991e-05*G0_1_1_0 + 0.000786713286713421*G0_1_1_1 - 0.000189185814185847*G0_1_1_2 + 0.00108641358641377*G0_1_1_3 + 4.12087912087983e-05*G0_1_1_4 + 1.80622948480122e-05*G0_1_2_0 - 0.000189185814185847*G0_1_2_1 + 2.18085485942667e-05*G0_1_2_2 - 0.000400849150849219*G0_1_2_3 - 4.17439703154059e-05*G0_1_2_4 - 4.12087912087983e-05*G0_1_2_5 - 7.11788211788334e-05*G0_1_3_0 + 0.00108641358641377*G0_1_3_1 - 0.000400849150849219*G0_1_3_2 + 0.00202297702297737*G0_1_3_3 + 5.99400599400702e-05*G0_1_3_4 + 0.000224775224775263*G0_1_3_5 + 1.07035821321554e-05*G0_1_4_0 + 4.12087912087983e-05*G0_1_4_1 - 4.1743970315406e-05*G0_1_4_2 + 5.99400599400702e-05*G0_1_4_3 - 2.14071642643108e-05*G0_1_4_4 + 4.12087912087981e-05*G0_1_5_0 - 4.12087912087983e-05*G0_1_5_2 + 0.000224775224775263*G0_1_5_3 - 0.000224775224775262*G0_1_5_5 + 5.88697017268547e-06*G0_2_0_0 + 1.80622948480122e-05*G0_2_0_1 - 3.31811046096816e-05*G0_2_0_2 + 3.31811046096816e-05*G0_2_0_3 - 1.17739403453709e-05*G0_2_0_4 + 1.80622948480122e-05*G0_2_1_0 - 0.000189185814185847*G0_2_1_1 + 2.18085485942667e-05*G0_2_1_2 - 0.000400849150849219*G0_2_1_3 - 4.1743970315406e-05*G0_2_1_4 - 4.12087912087983e-05*G0_2_1_5 - 3.31811046096816e-05*G0_2_2_0 + 2.18085485942667e-05*G0_2_2_1 + 0.000224775224775263*G0_2_2_2 + 0.000346796061081834*G0_2_2_3 + 0.000102754388468692*G0_2_2_4 + 3.10403881832506e-05*G0_2_2_5 + 3.31811046096817e-05*G0_2_3_0 - 0.000400849150849219*G0_2_3_1 + 0.000346796061081834*G0_2_3_2 - 0.000890538033395328*G0_2_3_3 + 1.71257314114486e-05*G0_2_3_4 - 0.000128442985585864*G0_2_3_5 - 1.17739403453709e-05*G0_2_4_0 - 4.1743970315406e-05*G0_2_4_1 + 0.000102754388468692*G0_2_4_2 + 1.71257314114486e-05*G0_2_4_3 + 0.000107035821321554*G0_2_4_4 + 2.14071642643108e-05*G0_2_4_5 - 4.12087912087983e-05*G0_2_5_1 + 3.10403881832506e-05*G0_2_5_2 - 0.000128442985585864*G0_2_5_3 + 2.14071642643108e-05*G0_2_5_4 + 6.85029256457945e-05*G0_2_5_5 + 3.42514628228971e-05*G0_3_0_0 - 7.11788211788334e-05*G0_3_0_1 + 3.31811046096816e-05*G0_3_0_2 - 0.000470957613814836*G0_3_0_3 - 8.9910089910105e-05*G0_3_0_4 - 6.85029256457942e-05*G0_3_0_5 - 7.11788211788334e-05*G0_3_1_0 + 0.00108641358641377*G0_3_1_1 - 0.000400849150849219*G0_3_1_2 + 0.00202297702297737*G0_3_1_3 + 5.99400599400702e-05*G0_3_1_4 + 0.000224775224775263*G0_3_1_5 + 3.31811046096816e-05*G0_3_2_0 - 0.000400849150849219*G0_3_2_1 + 0.000346796061081834*G0_3_2_2 - 0.000890538033395327*G0_3_2_3 + 1.71257314114486e-05*G0_3_2_4 - 0.000128442985585864*G0_3_2_5 - 0.000470957613814836*G0_3_3_0 + 0.00202297702297737*G0_3_3_1 - 0.000890538033395328*G0_3_3_2 + 0.00959040959041121*G0_3_3_3 + 0.000822035107749532*G0_3_3_4 + 0.0011988011988014*G0_3_3_5 - 8.9910089910105e-05*G0_3_4_0 + 5.99400599400702e-05*G0_3_4_1 + 1.71257314114486e-05*G0_3_4_2 + 0.000822035107749532*G0_3_4_3 + 0.000222634508348832*G0_3_4_4 + 0.000137005851291588*G0_3_4_5 - 6.85029256457942e-05*G0_3_5_0 + 0.000224775224775263*G0_3_5_1 - 0.000128442985585864*G0_3_5_2 + 0.0011988011988014*G0_3_5_3 + 0.000137005851291588*G0_3_5_4 - 1.07035821321558e-06*G0_4_0_0 + 1.07035821321554e-05*G0_4_0_1 - 1.17739403453709e-05*G0_4_0_2 - 8.9910089910105e-05*G0_4_0_3 - 8.13472242043808e-05*G0_4_0_4 - 2.14071642643108e-05*G0_4_0_5 + 1.07035821321553e-05*G0_4_1_0 + 4.12087912087983e-05*G0_4_1_1 - 4.1743970315406e-05*G0_4_1_2 + 5.99400599400702e-05*G0_4_1_3 - 2.14071642643107e-05*G0_4_1_4 - 1.17739403453709e-05*G0_4_2_0 - 4.1743970315406e-05*G0_4_2_1 + 0.000102754388468692*G0_4_2_2 + 1.71257314114486e-05*G0_4_2_3 + 0.000107035821321554*G0_4_2_4 + 2.14071642643108e-05*G0_4_2_5 - 8.9910089910105e-05*G0_4_3_0 + 5.99400599400702e-05*G0_4_3_1 + 1.71257314114486e-05*G0_4_3_2 + 0.000822035107749532*G0_4_3_3 + 0.000222634508348832*G0_4_3_4 + 0.000137005851291588*G0_4_3_5 - 8.13472242043808e-05*G0_4_4_0 - 2.14071642643108e-05*G0_4_4_1 + 0.000107035821321554*G0_4_4_2 + 0.000222634508348832*G0_4_4_3 + 0.000162694448408762*G0_4_4_4 - 2.14071642643108e-05*G0_4_5_0 + 2.14071642643108e-05*G0_4_5_2 + 0.000137005851291588*G0_4_5_3 - 0.000137005851291589*G0_4_5_5 - 3.10403881832507e-05*G0_5_0_0 + 4.12087912087981e-05*G0_5_0_1 - 6.85029256457942e-05*G0_5_0_3 - 2.14071642643108e-05*G0_5_0_4 + 0.000128442985585864*G0_5_0_5 + 4.12087912087981e-05*G0_5_1_0 - 4.12087912087983e-05*G0_5_1_2 + 0.000224775224775263*G0_5_1_3 - 0.000224775224775262*G0_5_1_5 - 4.12087912087983e-05*G0_5_2_1 + 3.10403881832506e-05*G0_5_2_2 - 0.000128442985585864*G0_5_2_3 + 2.14071642643108e-05*G0_5_2_4 + 6.85029256457944e-05*G0_5_2_5 - 6.85029256457942e-05*G0_5_3_0 + 0.000224775224775263*G0_5_3_1 - 0.000128442985585864*G0_5_3_2 + 0.0011988011988014*G0_5_3_3 + 0.000137005851291588*G0_5_3_4 - 2.14071642643108e-05*G0_5_4_0 + 2.14071642643108e-05*G0_5_4_2 + 0.000137005851291588*G0_5_4_3 - 0.000137005851291589*G0_5_4_5 + 0.000128442985585864*G0_5_5_0 - 0.000224775224775262*G0_5_5_1 + 6.85029256457944e-05*G0_5_5_2 - 0.000137005851291589*G0_5_5_4 - 0.0011988011988014*G0_5_5_5; + A[29] = A[92]; + A[81] = A[26] + 1.95786356500675e-05*G0_0_0_1 - 1.95786356500675e-05*G0_0_0_2 + 6.8978640407224e-06*G0_0_0_4 - 6.89786404072234e-06*G0_0_0_5 + 1.95786356500675e-05*G0_0_1_0 - 0.000107154750011911*G0_0_1_1 - 2.63427049141379e-05*G0_0_1_3 - 3.21107463964658e-06*G0_0_1_4 - 6.82056039199012e-05*G0_0_1_5 - 1.95786356500675e-05*G0_0_2_0 + 0.000107154750011911*G0_0_2_2 + 2.63427049141379e-05*G0_0_2_3 + 6.82056039199011e-05*G0_0_2_4 + 3.21107463964661e-06*G0_0_2_5 - 2.63427049141379e-05*G0_0_3_1 + 2.63427049141379e-05*G0_0_3_2 + 6.42214927929322e-06*G0_0_3_4 - 6.42214927929319e-06*G0_0_3_5 + 6.89786404072239e-06*G0_0_4_0 - 3.21107463964658e-06*G0_0_4_1 + 6.82056039199011e-05*G0_0_4_2 + 6.42214927929322e-06*G0_0_4_3 + 4.61443318586255e-05*G0_0_4_4 - 6.89786404072235e-06*G0_0_5_0 - 6.82056039199012e-05*G0_0_5_1 + 3.21107463964661e-06*G0_0_5_2 - 6.42214927929319e-06*G0_0_5_3 - 4.61443318586252e-05*G0_0_5_5 + 1.95786356500675e-05*G0_1_0_0 - 0.000107154750011911*G0_1_0_1 - 2.63427049141379e-05*G0_1_0_3 - 3.21107463964658e-06*G0_1_0_4 - 6.82056039199012e-05*G0_1_0_5 - 0.000107154750011911*G0_1_1_0 + 0.00100841123162569*G0_1_1_1 - 6.55594405594517e-05*G0_1_1_2 + 0.000235895057323669*G0_1_1_3 + 2.30127015841339e-05*G0_1_1_4 + 0.000470600827743765*G0_1_1_5 - 6.55594405594517e-05*G0_1_2_1 + 6.55594405594515e-05*G0_1_2_2 + 2.62237762237806e-05*G0_1_2_4 - 2.62237762237807e-05*G0_1_2_5 - 2.63427049141379e-05*G0_1_3_0 + 0.000235895057323669*G0_1_3_1 + 0.000111555111555131*G0_1_3_3 + 6.66000666000771e-06*G0_1_3_4 + 0.000105132962275837*G0_1_3_5 - 3.21107463964658e-06*G0_1_4_0 + 2.30127015841339e-05*G0_1_4_1 + 2.62237762237806e-05*G0_1_4_2 + 6.66000666000771e-06*G0_1_4_3 - 4.99500499500595e-06*G0_1_4_4 + 6.42214927929314e-06*G0_1_4_5 - 6.82056039199012e-05*G0_1_5_0 + 0.000470600827743765*G0_1_5_1 - 2.62237762237807e-05*G0_1_5_2 + 0.000105132962275837*G0_1_5_3 + 6.42214927929314e-06*G0_1_5_4 + 0.000323961752533236*G0_1_5_5 - 1.95786356500675e-05*G0_2_0_0 + 0.000107154750011911*G0_2_0_2 + 2.63427049141379e-05*G0_2_0_3 + 6.82056039199011e-05*G0_2_0_4 + 3.21107463964661e-06*G0_2_0_5 - 6.55594405594517e-05*G0_2_1_1 + 6.55594405594515e-05*G0_2_1_2 + 2.62237762237806e-05*G0_2_1_4 - 2.62237762237807e-05*G0_2_1_5 + 0.000107154750011911*G0_2_2_0 + 6.55594405594515e-05*G0_2_2_1 - 0.00100841123162569*G0_2_2_2 - 0.000235895057323668*G0_2_2_3 - 0.000470600827743764*G0_2_2_4 - 2.30127015841342e-05*G0_2_2_5 + 2.63427049141379e-05*G0_2_3_0 - 0.000235895057323668*G0_2_3_2 - 0.00011155511155513*G0_2_3_3 - 0.000105132962275837*G0_2_3_4 - 6.66000666000781e-06*G0_2_3_5 + 6.82056039199011e-05*G0_2_4_0 + 2.62237762237806e-05*G0_2_4_1 - 0.000470600827743764*G0_2_4_2 - 0.000105132962275837*G0_2_4_3 - 0.000323961752533236*G0_2_4_4 - 6.42214927929328e-06*G0_2_4_5 + 3.21107463964661e-06*G0_2_5_0 - 2.62237762237807e-05*G0_2_5_1 - 2.30127015841342e-05*G0_2_5_2 - 6.66000666000781e-06*G0_2_5_3 - 6.42214927929328e-06*G0_2_5_4 + 4.99500499500585e-06*G0_2_5_5 - 2.63427049141379e-05*G0_3_0_1 + 2.63427049141379e-05*G0_3_0_2 + 6.42214927929322e-06*G0_3_0_4 - 6.42214927929319e-06*G0_3_0_5 - 2.63427049141379e-05*G0_3_1_0 + 0.000235895057323669*G0_3_1_1 + 0.000111555111555131*G0_3_1_3 + 6.66000666000771e-06*G0_3_1_4 + 0.000105132962275837*G0_3_1_5 + 2.63427049141379e-05*G0_3_2_0 - 0.000235895057323668*G0_3_2_2 - 0.00011155511155513*G0_3_2_3 - 0.000105132962275837*G0_3_2_4 - 6.66000666000781e-06*G0_3_2_5 + 0.000111555111555131*G0_3_3_1 - 0.00011155511155513*G0_3_3_2 - 1.33200133200155e-05*G0_3_3_4 + 1.33200133200155e-05*G0_3_3_5 + 6.42214927929322e-06*G0_3_4_0 + 6.66000666000771e-06*G0_3_4_1 - 0.000105132962275837*G0_3_4_2 - 1.33200133200155e-05*G0_3_4_3 - 2.85428856857462e-06*G0_3_4_4 - 6.42214927929319e-06*G0_3_5_0 + 0.000105132962275837*G0_3_5_1 - 6.6600066600078e-06*G0_3_5_2 + 1.33200133200155e-05*G0_3_5_3 + 2.85428856857458e-06*G0_3_5_5 + 6.89786404072239e-06*G0_4_0_0 - 3.21107463964658e-06*G0_4_0_1 + 6.82056039199011e-05*G0_4_0_2 + 6.42214927929322e-06*G0_4_0_3 + 4.61443318586255e-05*G0_4_0_4 - 3.21107463964658e-06*G0_4_1_0 + 2.30127015841339e-05*G0_4_1_1 + 2.62237762237806e-05*G0_4_1_2 + 6.66000666000771e-06*G0_4_1_3 - 4.99500499500595e-06*G0_4_1_4 + 6.42214927929313e-06*G0_4_1_5 + 6.82056039199011e-05*G0_4_2_0 + 2.62237762237806e-05*G0_4_2_1 - 0.000470600827743764*G0_4_2_2 - 0.000105132962275837*G0_4_2_3 - 0.000323961752533236*G0_4_2_4 - 6.42214927929328e-06*G0_4_2_5 + 6.42214927929322e-06*G0_4_3_0 + 6.66000666000771e-06*G0_4_3_1 - 0.000105132962275837*G0_4_3_2 - 1.33200133200155e-05*G0_4_3_3 - 2.8542885685746e-06*G0_4_3_4 + 4.61443318586255e-05*G0_4_4_0 - 4.99500499500594e-06*G0_4_4_1 - 0.000323961752533236*G0_4_4_2 - 2.8542885685746e-06*G0_4_4_3 + 0.000111317254174416*G0_4_4_4 + 2.2834308548598e-05*G0_4_4_5 + 6.42214927929313e-06*G0_4_5_1 - 6.42214927929328e-06*G0_4_5_2 + 2.28343085485981e-05*G0_4_5_4 - 2.28343085485982e-05*G0_4_5_5 - 6.89786404072235e-06*G0_5_0_0 - 6.82056039199012e-05*G0_5_0_1 + 3.21107463964661e-06*G0_5_0_2 - 6.42214927929319e-06*G0_5_0_3 - 4.61443318586252e-05*G0_5_0_5 - 6.82056039199012e-05*G0_5_1_0 + 0.000470600827743765*G0_5_1_1 - 2.62237762237807e-05*G0_5_1_2 + 0.000105132962275837*G0_5_1_3 + 6.42214927929314e-06*G0_5_1_4 + 0.000323961752533236*G0_5_1_5 + 3.21107463964661e-06*G0_5_2_0 - 2.62237762237807e-05*G0_5_2_1 - 2.30127015841342e-05*G0_5_2_2 - 6.66000666000781e-06*G0_5_2_3 - 6.42214927929328e-06*G0_5_2_4 + 4.99500499500584e-06*G0_5_2_5 - 6.42214927929319e-06*G0_5_3_0 + 0.000105132962275837*G0_5_3_1 - 6.66000666000781e-06*G0_5_3_2 + 1.33200133200155e-05*G0_5_3_3 + 2.85428856857456e-06*G0_5_3_5 + 6.42214927929313e-06*G0_5_4_1 - 6.42214927929328e-06*G0_5_4_2 + 2.2834308548598e-05*G0_5_4_4 - 2.28343085485982e-05*G0_5_4_5 - 4.61443318586252e-05*G0_5_5_0 + 0.000323961752533236*G0_5_5_1 + 4.99500499500584e-06*G0_5_5_2 + 2.85428856857459e-06*G0_5_5_3 - 2.28343085485982e-05*G0_5_5_4 - 0.000111317254174416*G0_5_5_5; + A[31] = A[81] + 5.80223348080587e-05*G0_0_0_0 - 1.78987678987709e-05*G0_0_0_1 - 6.67487274630243e-06*G0_0_0_2 - 1.48660862946602e-06*G0_0_0_3 + 1.96232339089515e-05*G0_0_0_4 + 3.2289139432002e-05*G0_0_0_5 - 1.78987678987709e-05*G0_0_1_0 + 4.99500499500584e-05*G0_0_1_1 - 5.82750582750684e-06*G0_0_1_3 - 7.07625707625828e-06*G0_0_1_4 + 3.49650349650409e-05*G0_0_1_5 - 6.67487274630243e-06*G0_0_2_0 + 6.67487274630244e-06*G0_0_2_2 + 4.34089719804081e-06*G0_0_2_3 - 4.34089719804076e-06*G0_0_2_5 - 1.48660862946602e-06*G0_0_3_0 - 5.82750582750683e-06*G0_0_3_1 + 4.34089719804081e-06*G0_0_3_2 + 2.8305028305033e-05*G0_0_3_3 + 1.71257314114486e-05*G0_0_3_4 + 1.16550116550136e-05*G0_0_3_5 + 1.96232339089515e-05*G0_0_4_0 - 7.07625707625828e-06*G0_0_4_1 + 1.71257314114486e-05*G0_0_4_3 + 3.94843251986175e-05*G0_0_4_4 + 2.28343085485981e-05*G0_0_4_5 + 3.2289139432002e-05*G0_0_5_0 + 3.49650349650409e-05*G0_0_5_1 - 4.34089719804076e-06*G0_0_5_2 + 1.16550116550136e-05*G0_0_5_3 + 2.28343085485981e-05*G0_0_5_4 + 6.49350649350757e-05*G0_0_5_5 - 1.78987678987709e-05*G0_1_0_0 + 4.99500499500584e-05*G0_1_0_1 - 5.82750582750684e-06*G0_1_0_3 - 7.07625707625828e-06*G0_1_0_4 + 3.49650349650409e-05*G0_1_0_5 + 4.99500499500584e-05*G0_1_1_0 - 4.99500499500584e-05*G0_1_1_2 + 0.000228937728937768*G0_1_1_3 - 0.000228937728937768*G0_1_1_5 - 4.99500499500584e-05*G0_1_2_1 + 1.78987678987709e-05*G0_1_2_2 - 3.4965034965041e-05*G0_1_2_3 + 7.07625707625826e-06*G0_1_2_4 + 5.82750582750677e-06*G0_1_2_5 - 5.82750582750683e-06*G0_1_3_0 + 0.000228937728937768*G0_1_3_1 - 3.4965034965041e-05*G0_1_3_2 + 0.000233100233100273*G0_1_3_3 + 1.16550116550137e-05*G0_1_3_4 - 7.07625707625828e-06*G0_1_4_0 + 7.07625707625826e-06*G0_1_4_2 + 1.16550116550137e-05*G0_1_4_3 - 1.16550116550135e-05*G0_1_4_5 + 3.49650349650409e-05*G0_1_5_0 - 0.000228937728937767*G0_1_5_1 + 5.82750582750676e-06*G0_1_5_2 - 1.16550116550135e-05*G0_1_5_4 - 0.000233100233100272*G0_1_5_5 - 6.67487274630243e-06*G0_2_0_0 + 6.67487274630244e-06*G0_2_0_2 + 4.34089719804081e-06*G0_2_0_3 - 4.34089719804076e-06*G0_2_0_5 - 4.99500499500584e-05*G0_2_1_1 + 1.78987678987709e-05*G0_2_1_2 - 3.4965034965041e-05*G0_2_1_3 + 7.07625707625826e-06*G0_2_1_4 + 5.82750582750677e-06*G0_2_1_5 + 6.67487274630244e-06*G0_2_2_0 + 1.78987678987709e-05*G0_2_2_1 - 5.80223348080589e-05*G0_2_2_2 - 3.2289139432002e-05*G0_2_2_3 - 1.96232339089515e-05*G0_2_2_4 + 1.48660862946604e-06*G0_2_2_5 + 4.34089719804081e-06*G0_2_3_0 - 3.4965034965041e-05*G0_2_3_1 - 3.2289139432002e-05*G0_2_3_2 - 6.49350649350761e-05*G0_2_3_3 - 2.28343085485981e-05*G0_2_3_4 - 1.16550116550137e-05*G0_2_3_5 + 7.07625707625826e-06*G0_2_4_1 - 1.96232339089515e-05*G0_2_4_2 - 2.28343085485981e-05*G0_2_4_3 - 3.94843251986176e-05*G0_2_4_4 - 1.71257314114486e-05*G0_2_4_5 - 4.34089719804076e-06*G0_2_5_0 + 5.82750582750676e-06*G0_2_5_1 + 1.48660862946604e-06*G0_2_5_2 - 1.16550116550137e-05*G0_2_5_3 - 1.71257314114486e-05*G0_2_5_4 - 2.83050283050331e-05*G0_2_5_5 - 1.48660862946602e-06*G0_3_0_0 - 5.82750582750683e-06*G0_3_0_1 + 4.34089719804081e-06*G0_3_0_2 + 2.8305028305033e-05*G0_3_0_3 + 1.71257314114486e-05*G0_3_0_4 + 1.16550116550136e-05*G0_3_0_5 - 5.82750582750683e-06*G0_3_1_0 + 0.000228937728937768*G0_3_1_1 - 3.4965034965041e-05*G0_3_1_2 + 0.000233100233100273*G0_3_1_3 + 1.16550116550137e-05*G0_3_1_4 + 4.34089719804081e-06*G0_3_2_0 - 3.4965034965041e-05*G0_3_2_1 - 3.2289139432002e-05*G0_3_2_2 - 6.49350649350761e-05*G0_3_2_3 - 2.28343085485981e-05*G0_3_2_4 - 1.16550116550137e-05*G0_3_2_5 + 2.8305028305033e-05*G0_3_3_0 + 0.000233100233100273*G0_3_3_1 - 6.49350649350761e-05*G0_3_3_2 - 0.000299700299700349*G0_3_3_3 - 7.99200799200933e-05*G0_3_3_4 - 3.33000333000386e-05*G0_3_3_5 + 1.71257314114486e-05*G0_3_4_0 + 1.16550116550137e-05*G0_3_4_1 - 2.28343085485981e-05*G0_3_4_2 - 7.99200799200933e-05*G0_3_4_3 - 3.42514628228972e-05*G0_3_4_4 + 1.16550116550136e-05*G0_3_5_0 - 1.16550116550137e-05*G0_3_5_2 - 3.33000333000385e-05*G0_3_5_3 + 3.33000333000392e-05*G0_3_5_5 + 1.96232339089515e-05*G0_4_0_0 - 7.07625707625828e-06*G0_4_0_1 + 1.71257314114486e-05*G0_4_0_3 + 3.94843251986175e-05*G0_4_0_4 + 2.28343085485981e-05*G0_4_0_5 - 7.07625707625828e-06*G0_4_1_0 + 7.07625707625826e-06*G0_4_1_2 + 1.16550116550137e-05*G0_4_1_3 - 1.16550116550135e-05*G0_4_1_5 + 7.07625707625826e-06*G0_4_2_1 - 1.96232339089515e-05*G0_4_2_2 - 2.28343085485981e-05*G0_4_2_3 - 3.94843251986176e-05*G0_4_2_4 - 1.71257314114486e-05*G0_4_2_5 + 1.71257314114486e-05*G0_4_3_0 + 1.16550116550137e-05*G0_4_3_1 - 2.28343085485981e-05*G0_4_3_2 - 7.99200799200933e-05*G0_4_3_3 - 3.42514628228972e-05*G0_4_3_4 + 3.94843251986175e-05*G0_4_4_0 - 3.94843251986176e-05*G0_4_4_2 - 3.42514628228972e-05*G0_4_4_3 + 3.42514628228971e-05*G0_4_4_5 + 2.28343085485981e-05*G0_4_5_0 - 1.16550116550135e-05*G0_4_5_1 - 1.71257314114486e-05*G0_4_5_2 + 3.42514628228971e-05*G0_4_5_4 + 7.99200799200935e-05*G0_4_5_5 + 3.2289139432002e-05*G0_5_0_0 + 3.49650349650409e-05*G0_5_0_1 - 4.34089719804076e-06*G0_5_0_2 + 1.16550116550136e-05*G0_5_0_3 + 2.28343085485981e-05*G0_5_0_4 + 6.49350649350757e-05*G0_5_0_5 + 3.49650349650409e-05*G0_5_1_0 - 0.000228937728937768*G0_5_1_1 + 5.82750582750677e-06*G0_5_1_2 - 1.16550116550135e-05*G0_5_1_4 - 0.000233100233100272*G0_5_1_5 - 4.34089719804076e-06*G0_5_2_0 + 5.82750582750677e-06*G0_5_2_1 + 1.48660862946604e-06*G0_5_2_2 - 1.16550116550137e-05*G0_5_2_3 - 1.71257314114486e-05*G0_5_2_4 - 2.83050283050331e-05*G0_5_2_5 + 1.16550116550136e-05*G0_5_3_0 - 1.16550116550137e-05*G0_5_3_2 - 3.33000333000385e-05*G0_5_3_3 + 3.33000333000392e-05*G0_5_3_5 + 2.28343085485981e-05*G0_5_4_0 - 1.16550116550135e-05*G0_5_4_1 - 1.71257314114486e-05*G0_5_4_2 + 3.42514628228971e-05*G0_5_4_4 + 7.99200799200935e-05*G0_5_4_5 + 6.49350649350757e-05*G0_5_5_0 - 0.000233100233100272*G0_5_5_1 - 2.83050283050331e-05*G0_5_5_2 + 3.33000333000392e-05*G0_5_5_3 + 7.99200799200935e-05*G0_5_5_4 + 0.000299700299700351*G0_5_5_5; + A[5] = A[31] + 0.00100841123162569*G0_0_0_0 - 6.55594405594516e-05*G0_0_0_1 - 0.000107154750011911*G0_0_0_2 + 2.3012701584134e-05*G0_0_0_3 + 0.000470600827743765*G0_0_0_4 + 0.000235895057323668*G0_0_0_5 - 6.55594405594516e-05*G0_0_1_0 + 6.55594405594517e-05*G0_0_1_1 + 2.62237762237807e-05*G0_0_1_3 - 2.62237762237806e-05*G0_0_1_4 - 0.000107154750011911*G0_0_2_0 + 1.95786356500676e-05*G0_0_2_2 - 3.21107463964663e-06*G0_0_2_3 - 6.82056039199012e-05*G0_0_2_4 - 2.63427049141379e-05*G0_0_2_5 + 2.3012701584134e-05*G0_0_3_0 + 2.62237762237807e-05*G0_0_3_1 - 3.21107463964663e-06*G0_0_3_2 - 4.99500499500569e-06*G0_0_3_3 + 6.42214927929329e-06*G0_0_3_4 + 6.66000666000781e-06*G0_0_3_5 + 0.000470600827743765*G0_0_4_0 - 2.62237762237806e-05*G0_0_4_1 - 6.82056039199012e-05*G0_0_4_2 + 6.42214927929329e-06*G0_0_4_3 + 0.000323961752533236*G0_0_4_4 + 0.000105132962275837*G0_0_4_5 + 0.000235895057323668*G0_0_5_0 - 2.63427049141379e-05*G0_0_5_2 + 6.66000666000781e-06*G0_0_5_3 + 0.000105132962275837*G0_0_5_4 + 0.00011155511155513*G0_0_5_5 - 6.55594405594516e-05*G0_1_0_0 + 6.55594405594517e-05*G0_1_0_1 + 2.62237762237807e-05*G0_1_0_3 - 2.62237762237806e-05*G0_1_0_4 + 6.55594405594517e-05*G0_1_1_0 - 0.00100841123162569*G0_1_1_1 + 0.000107154750011911*G0_1_1_2 - 0.000470600827743765*G0_1_1_3 - 2.3012701584134e-05*G0_1_1_4 - 0.000235895057323669*G0_1_1_5 + 0.000107154750011911*G0_1_2_1 - 1.95786356500676e-05*G0_1_2_2 + 6.82056039199013e-05*G0_1_2_3 + 3.21107463964662e-06*G0_1_2_4 + 2.6342704914138e-05*G0_1_2_5 + 2.62237762237807e-05*G0_1_3_0 - 0.000470600827743765*G0_1_3_1 + 6.82056039199013e-05*G0_1_3_2 - 0.000323961752533237*G0_1_3_3 - 6.42214927929323e-06*G0_1_3_4 - 0.000105132962275837*G0_1_3_5 - 2.62237762237806e-05*G0_1_4_0 - 2.3012701584134e-05*G0_1_4_1 + 3.21107463964662e-06*G0_1_4_2 - 6.42214927929323e-06*G0_1_4_3 + 4.99500499500579e-06*G0_1_4_4 - 6.66000666000777e-06*G0_1_4_5 - 0.000235895057323669*G0_1_5_1 + 2.6342704914138e-05*G0_1_5_2 - 0.000105132962275837*G0_1_5_3 - 6.66000666000776e-06*G0_1_5_4 - 0.00011155511155513*G0_1_5_5 - 0.000107154750011911*G0_2_0_0 + 1.95786356500676e-05*G0_2_0_2 - 3.21107463964663e-06*G0_2_0_3 - 6.82056039199012e-05*G0_2_0_4 - 2.63427049141379e-05*G0_2_0_5 + 0.000107154750011911*G0_2_1_1 - 1.95786356500676e-05*G0_2_1_2 + 6.82056039199013e-05*G0_2_1_3 + 3.21107463964662e-06*G0_2_1_4 + 2.6342704914138e-05*G0_2_1_5 + 1.95786356500676e-05*G0_2_2_0 - 1.95786356500676e-05*G0_2_2_1 + 6.89786404072234e-06*G0_2_2_3 - 6.89786404072237e-06*G0_2_2_4 - 3.21107463964663e-06*G0_2_3_0 + 6.82056039199013e-05*G0_2_3_1 + 6.89786404072236e-06*G0_2_3_2 + 4.61443318586256e-05*G0_2_3_3 + 6.42214927929328e-06*G0_2_3_5 - 6.82056039199013e-05*G0_2_4_0 + 3.21107463964661e-06*G0_2_4_1 - 6.89786404072237e-06*G0_2_4_2 - 4.61443318586255e-05*G0_2_4_4 - 6.42214927929323e-06*G0_2_4_5 - 2.63427049141379e-05*G0_2_5_0 + 2.6342704914138e-05*G0_2_5_1 + 6.42214927929328e-06*G0_2_5_3 - 6.42214927929324e-06*G0_2_5_4 + 2.3012701584134e-05*G0_3_0_0 + 2.62237762237807e-05*G0_3_0_1 - 3.21107463964663e-06*G0_3_0_2 - 4.99500499500569e-06*G0_3_0_3 + 6.42214927929329e-06*G0_3_0_4 + 6.6600066600078e-06*G0_3_0_5 + 2.62237762237807e-05*G0_3_1_0 - 0.000470600827743765*G0_3_1_1 + 6.82056039199013e-05*G0_3_1_2 - 0.000323961752533237*G0_3_1_3 - 6.42214927929323e-06*G0_3_1_4 - 0.000105132962275837*G0_3_1_5 - 3.21107463964663e-06*G0_3_2_0 + 6.82056039199013e-05*G0_3_2_1 + 6.89786404072236e-06*G0_3_2_2 + 4.61443318586256e-05*G0_3_2_3 + 6.42214927929328e-06*G0_3_2_5 - 4.99500499500569e-06*G0_3_3_0 - 0.000323961752533236*G0_3_3_1 + 4.61443318586256e-05*G0_3_3_2 + 0.000111317254174414*G0_3_3_3 + 2.2834308548598e-05*G0_3_3_4 - 2.85428856857513e-06*G0_3_3_5 + 6.42214927929329e-06*G0_3_4_0 - 6.42214927929323e-06*G0_3_4_1 + 2.2834308548598e-05*G0_3_4_3 - 2.28343085485981e-05*G0_3_4_4 + 6.6600066600078e-06*G0_3_5_0 - 0.000105132962275837*G0_3_5_1 + 6.42214927929328e-06*G0_3_5_2 - 2.85428856857516e-06*G0_3_5_3 - 1.33200133200156e-05*G0_3_5_5 + 0.000470600827743765*G0_4_0_0 - 2.62237762237806e-05*G0_4_0_1 - 6.82056039199012e-05*G0_4_0_2 + 6.42214927929329e-06*G0_4_0_3 + 0.000323961752533236*G0_4_0_4 + 0.000105132962275837*G0_4_0_5 - 2.62237762237806e-05*G0_4_1_0 - 2.3012701584134e-05*G0_4_1_1 + 3.21107463964661e-06*G0_4_1_2 - 6.42214927929323e-06*G0_4_1_3 + 4.99500499500579e-06*G0_4_1_4 - 6.66000666000776e-06*G0_4_1_5 - 6.82056039199013e-05*G0_4_2_0 + 3.21107463964662e-06*G0_4_2_1 - 6.89786404072237e-06*G0_4_2_2 - 4.61443318586255e-05*G0_4_2_4 - 6.42214927929323e-06*G0_4_2_5 + 6.42214927929329e-06*G0_4_3_0 - 6.42214927929323e-06*G0_4_3_1 + 2.2834308548598e-05*G0_4_3_3 - 2.28343085485981e-05*G0_4_3_4 + 0.000323961752533236*G0_4_4_0 + 4.99500499500579e-06*G0_4_4_1 - 4.61443318586255e-05*G0_4_4_2 - 2.28343085485981e-05*G0_4_4_3 - 0.000111317254174415*G0_4_4_4 + 2.85428856857485e-06*G0_4_4_5 + 0.000105132962275837*G0_4_5_0 - 6.66000666000776e-06*G0_4_5_1 - 6.42214927929323e-06*G0_4_5_2 + 2.85428856857485e-06*G0_4_5_4 + 1.33200133200156e-05*G0_4_5_5 + 0.000235895057323668*G0_5_0_0 - 2.63427049141379e-05*G0_5_0_2 + 6.66000666000781e-06*G0_5_0_3 + 0.000105132962275837*G0_5_0_4 + 0.00011155511155513*G0_5_0_5 - 0.000235895057323669*G0_5_1_1 + 2.6342704914138e-05*G0_5_1_2 - 0.000105132962275837*G0_5_1_3 - 6.66000666000776e-06*G0_5_1_4 - 0.00011155511155513*G0_5_1_5 - 2.63427049141379e-05*G0_5_2_0 + 2.6342704914138e-05*G0_5_2_1 + 6.42214927929328e-06*G0_5_2_3 - 6.42214927929323e-06*G0_5_2_4 + 6.6600066600078e-06*G0_5_3_0 - 0.000105132962275837*G0_5_3_1 + 6.42214927929328e-06*G0_5_3_2 - 2.85428856857516e-06*G0_5_3_3 - 1.33200133200157e-05*G0_5_3_5 + 0.000105132962275837*G0_5_4_0 - 6.66000666000776e-06*G0_5_4_1 - 6.42214927929323e-06*G0_5_4_2 + 2.85428856857482e-06*G0_5_4_4 + 1.33200133200156e-05*G0_5_4_5 + 0.00011155511155513*G0_5_5_0 - 0.00011155511155513*G0_5_5_1 - 1.33200133200157e-05*G0_5_5_3 + 1.33200133200156e-05*G0_5_5_4; + A[13] = A[31]; + A[50] = A[5]; + A[44] = A[66] - 0.000242436135293319*G0_0_0_0 + 3.90680747823671e-05*G0_0_0_1 - 2.43506493506534e-05*G0_0_0_2 + 3.21107463964655e-06*G0_0_0_3 - 0.000377836449265085*G0_0_0_4 - 0.000103824746681907*G0_0_0_5 + 3.90680747823671e-05*G0_0_1_0 - 3.90680747823671e-05*G0_0_1_1 + 3.31811046096815e-05*G0_0_1_3 - 3.31811046096816e-05*G0_0_1_4 - 2.43506493506534e-05*G0_0_2_0 + 0.000168581418581447*G0_0_2_2 - 2.99700299700348e-05*G0_0_2_3 + 0.000442057942058017*G0_0_2_4 + 5.24475524475613e-05*G0_0_2_5 + 3.21107463964656e-06*G0_0_3_0 + 3.31811046096816e-05*G0_0_3_1 - 2.99700299700348e-05*G0_0_3_2 - 0.00053946053946063*G0_0_3_3 + 5.994005994007e-05*G0_0_3_4 - 0.000111317254174416*G0_0_3_5 - 0.000377836449265085*G0_0_4_0 - 3.31811046096816e-05*G0_0_4_1 + 0.000442057942058017*G0_0_4_2 + 5.994005994007e-05*G0_0_4_3 + 0.00101898101898119*G0_0_4_4 - 3.85328956757595e-05*G0_0_4_5 - 0.000103824746681907*G0_0_5_0 + 5.24475524475613e-05*G0_0_5_2 - 0.000111317254174416*G0_0_5_3 - 3.85328956757594e-05*G0_0_5_4 - 0.000188383045525934*G0_0_5_5 + 3.90680747823671e-05*G0_1_0_0 - 3.90680747823671e-05*G0_1_0_1 + 3.31811046096815e-05*G0_1_0_3 - 3.31811046096816e-05*G0_1_0_4 - 3.90680747823671e-05*G0_1_1_0 + 0.000242436135293319*G0_1_1_1 + 2.43506493506534e-05*G0_1_1_2 + 0.000377836449265084*G0_1_1_3 - 3.2110746396466e-06*G0_1_1_4 + 0.000103824746681907*G0_1_1_5 + 2.43506493506534e-05*G0_1_2_1 - 0.000168581418581447*G0_1_2_2 - 0.000442057942058016*G0_1_2_3 + 2.99700299700349e-05*G0_1_2_4 - 5.24475524475613e-05*G0_1_2_5 + 3.31811046096815e-05*G0_1_3_0 + 0.000377836449265084*G0_1_3_1 - 0.000442057942058016*G0_1_3_2 - 0.00101898101898119*G0_1_3_3 - 5.99400599400698e-05*G0_1_3_4 + 3.85328956757594e-05*G0_1_3_5 - 3.31811046096816e-05*G0_1_4_0 - 3.2110746396466e-06*G0_1_4_1 + 2.99700299700348e-05*G0_1_4_2 - 5.99400599400698e-05*G0_1_4_3 + 0.00053946053946063*G0_1_4_4 + 0.000111317254174416*G0_1_4_5 + 0.000103824746681907*G0_1_5_1 - 5.24475524475613e-05*G0_1_5_2 + 3.85328956757594e-05*G0_1_5_3 + 0.000111317254174416*G0_1_5_4 + 0.000188383045525934*G0_1_5_5 - 2.43506493506534e-05*G0_2_0_0 + 0.000168581418581447*G0_2_0_2 - 2.99700299700348e-05*G0_2_0_3 + 0.000442057942058017*G0_2_0_4 + 5.24475524475613e-05*G0_2_0_5 + 2.43506493506534e-05*G0_2_1_1 - 0.000168581418581447*G0_2_1_2 - 0.000442057942058016*G0_2_1_3 + 2.99700299700349e-05*G0_2_1_4 - 5.24475524475613e-05*G0_2_1_5 + 0.000168581418581447*G0_2_2_0 - 0.000168581418581447*G0_2_2_1 + 0.00108641358641377*G0_2_2_3 - 0.00108641358641377*G0_2_2_4 - 2.99700299700348e-05*G0_2_3_0 - 0.000442057942058016*G0_2_3_1 + 0.00108641358641377*G0_2_3_2 + 0.00224775224775263*G0_2_3_3 + 5.994005994007e-05*G0_2_3_5 + 0.000442057942058017*G0_2_4_0 + 2.99700299700349e-05*G0_2_4_1 - 0.00108641358641377*G0_2_4_2 - 0.00224775224775263*G0_2_4_4 - 5.99400599400699e-05*G0_2_4_5 + 5.24475524475613e-05*G0_2_5_0 - 5.24475524475613e-05*G0_2_5_1 + 5.99400599400701e-05*G0_2_5_3 - 5.99400599400699e-05*G0_2_5_4 + 3.21107463964655e-06*G0_3_0_0 + 3.31811046096815e-05*G0_3_0_1 - 2.99700299700348e-05*G0_3_0_2 - 0.00053946053946063*G0_3_0_3 + 5.99400599400699e-05*G0_3_0_4 - 0.000111317254174416*G0_3_0_5 + 3.31811046096815e-05*G0_3_1_0 + 0.000377836449265084*G0_3_1_1 - 0.000442057942058016*G0_3_1_2 - 0.00101898101898119*G0_3_1_3 - 5.99400599400698e-05*G0_3_1_4 + 3.85328956757594e-05*G0_3_1_5 - 2.99700299700348e-05*G0_3_2_0 - 0.000442057942058016*G0_3_2_1 + 0.00108641358641377*G0_3_2_2 + 0.00224775224775263*G0_3_2_3 + 5.994005994007e-05*G0_3_2_5 - 0.00053946053946063*G0_3_3_0 - 0.00101898101898119*G0_3_3_1 + 0.00224775224775263*G0_3_3_2 + 0.0107892107892126*G0_3_3_3 + 0.0011988011988014*G0_3_3_4 + 0.000959040959041121*G0_3_3_5 + 5.99400599400699e-05*G0_3_4_0 - 5.99400599400698e-05*G0_3_4_1 + 0.0011988011988014*G0_3_4_3 - 0.0011988011988014*G0_3_4_4 - 0.000111317254174416*G0_3_5_0 + 3.85328956757594e-05*G0_3_5_1 + 5.994005994007e-05*G0_3_5_2 + 0.000959040959041121*G0_3_5_3 + 0.000222634508348832*G0_3_5_5 - 0.000377836449265085*G0_4_0_0 - 3.31811046096816e-05*G0_4_0_1 + 0.000442057942058017*G0_4_0_2 + 5.99400599400699e-05*G0_4_0_3 + 0.00101898101898119*G0_4_0_4 - 3.85328956757594e-05*G0_4_0_5 - 3.31811046096816e-05*G0_4_1_0 - 3.21107463964662e-06*G0_4_1_1 + 2.99700299700348e-05*G0_4_1_2 - 5.99400599400698e-05*G0_4_1_3 + 0.00053946053946063*G0_4_1_4 + 0.000111317254174416*G0_4_1_5 + 0.000442057942058017*G0_4_2_0 + 2.99700299700348e-05*G0_4_2_1 - 0.00108641358641377*G0_4_2_2 - 0.00224775224775263*G0_4_2_4 - 5.99400599400699e-05*G0_4_2_5 + 5.99400599400699e-05*G0_4_3_0 - 5.99400599400698e-05*G0_4_3_1 + 0.0011988011988014*G0_4_3_3 - 0.0011988011988014*G0_4_3_4 + 0.00101898101898119*G0_4_4_0 + 0.00053946053946063*G0_4_4_1 - 0.00224775224775263*G0_4_4_2 - 0.0011988011988014*G0_4_4_3 - 0.0107892107892126*G0_4_4_4 - 0.000959040959041121*G0_4_4_5 - 3.85328956757594e-05*G0_4_5_0 + 0.000111317254174416*G0_4_5_1 - 5.99400599400699e-05*G0_4_5_2 - 0.000959040959041121*G0_4_5_4 - 0.000222634508348832*G0_4_5_5 - 0.000103824746681907*G0_5_0_0 + 5.24475524475613e-05*G0_5_0_2 - 0.000111317254174416*G0_5_0_3 - 3.85328956757594e-05*G0_5_0_4 - 0.000188383045525934*G0_5_0_5 + 0.000103824746681907*G0_5_1_1 - 5.24475524475613e-05*G0_5_1_2 + 3.85328956757594e-05*G0_5_1_3 + 0.000111317254174416*G0_5_1_4 + 0.000188383045525934*G0_5_1_5 + 5.24475524475613e-05*G0_5_2_0 - 5.24475524475613e-05*G0_5_2_1 + 5.99400599400701e-05*G0_5_2_3 - 5.99400599400699e-05*G0_5_2_4 - 0.000111317254174416*G0_5_3_0 + 3.85328956757594e-05*G0_5_3_1 + 5.99400599400701e-05*G0_5_3_2 + 0.000959040959041121*G0_5_3_3 + 0.000222634508348832*G0_5_3_5 - 3.85328956757595e-05*G0_5_4_0 + 0.000111317254174416*G0_5_4_1 - 5.99400599400699e-05*G0_5_4_2 - 0.000959040959041121*G0_5_4_4 - 0.000222634508348832*G0_5_4_5 - 0.000188383045525934*G0_5_5_0 + 0.000188383045525934*G0_5_5_1 + 0.000222634508348832*G0_5_5_3 - 0.000222634508348832*G0_5_5_4; + A[63] = A[36]; + A[0] = 0.00187798312798345*G0_0_0_0 - 8.78750878751026e-05*G0_0_0_1 - 8.78750878751028e-05*G0_0_0_2 + 1.8962518962522e-05*G0_0_0_3 + 0.000370462870462934*G0_0_0_4 + 0.000370462870462933*G0_0_0_5 - 8.78750878751026e-05*G0_0_1_0 + 5.68875568875663e-06*G0_0_1_1 + 5.68875568875664e-06*G0_0_1_2 - 1.89625189625221e-06*G0_0_1_3 - 1.89625189625222e-05*G0_0_1_4 - 3.79250379250443e-05*G0_0_1_5 - 8.78750878751028e-05*G0_0_2_0 + 5.68875568875664e-06*G0_0_2_1 + 5.68875568875666e-06*G0_0_2_2 - 1.89625189625221e-06*G0_0_2_3 - 3.79250379250444e-05*G0_0_2_4 - 1.89625189625222e-05*G0_0_2_5 + 1.8962518962522e-05*G0_0_3_0 - 1.89625189625221e-06*G0_0_3_1 - 1.89625189625221e-06*G0_0_3_2 - 1.51700151700177e-05*G0_0_3_3 + 0.000370462870462934*G0_0_4_0 - 1.89625189625222e-05*G0_0_4_1 - 3.79250379250444e-05*G0_0_4_2 + 0.000151700151700178*G0_0_4_4 + 7.58500758500887e-05*G0_0_4_5 + 0.000370462870462933*G0_0_5_0 - 3.79250379250443e-05*G0_0_5_1 - 1.89625189625222e-05*G0_0_5_2 + 7.58500758500887e-05*G0_0_5_4 + 0.000151700151700177*G0_0_5_5 - 8.78750878751026e-05*G0_1_0_0 + 5.68875568875663e-06*G0_1_0_1 + 5.68875568875664e-06*G0_1_0_2 - 1.89625189625221e-06*G0_1_0_3 - 1.89625189625222e-05*G0_1_0_4 - 3.79250379250443e-05*G0_1_0_5 + 5.68875568875663e-06*G0_1_1_0 + 1.17739403453709e-05*G0_1_1_1 - 2.00857343714521e-06*G0_1_1_2 + 9.24340210054652e-06*G0_1_1_3 + 5.41125541125632e-06*G0_1_1_4 + 1.67887667887696e-05*G0_1_1_5 + 5.68875568875664e-06*G0_1_2_0 - 2.00857343714521e-06*G0_1_2_1 - 2.0085734371452e-06*G0_1_2_2 - 3.10536024821792e-06*G0_1_2_3 + 1.61875161875189e-06*G0_1_2_4 + 1.61875161875189e-06*G0_1_2_5 - 1.89625189625221e-06*G0_1_3_0 + 9.24340210054652e-06*G0_1_3_1 - 3.10536024821792e-06*G0_1_3_2 - 1.37428708857303e-06*G0_1_3_3 - 7.03000703000822e-06*G0_1_3_4 + 5.55000555000655e-07*G0_1_3_5 - 1.89625189625222e-05*G0_1_4_0 + 5.41125541125632e-06*G0_1_4_1 + 1.61875161875189e-06*G0_1_4_2 - 7.03000703000822e-06*G0_1_4_3 - 2.10900210900246e-05*G0_1_4_4 - 1.40600140600164e-05*G0_1_4_5 - 3.79250379250443e-05*G0_1_5_0 + 1.67887667887696e-05*G0_1_5_1 + 1.61875161875189e-06*G0_1_5_2 + 5.55000555000655e-07*G0_1_5_3 - 1.40600140600164e-05*G0_1_5_4 - 2.10900210900246e-05*G0_1_5_5 - 8.78750878751028e-05*G0_2_0_0 + 5.68875568875664e-06*G0_2_0_1 + 5.68875568875666e-06*G0_2_0_2 - 1.89625189625221e-06*G0_2_0_3 - 3.79250379250444e-05*G0_2_0_4 - 1.89625189625222e-05*G0_2_0_5 + 5.68875568875664e-06*G0_2_1_0 - 2.00857343714521e-06*G0_2_1_1 - 2.0085734371452e-06*G0_2_1_2 - 3.10536024821792e-06*G0_2_1_3 + 1.61875161875189e-06*G0_2_1_4 + 1.61875161875189e-06*G0_2_1_5 + 5.68875568875666e-06*G0_2_2_0 - 2.0085734371452e-06*G0_2_2_1 + 1.17739403453709e-05*G0_2_2_2 + 9.24340210054652e-06*G0_2_2_3 + 1.67887667887696e-05*G0_2_2_4 + 5.41125541125633e-06*G0_2_2_5 - 1.89625189625221e-06*G0_2_3_0 - 3.10536024821792e-06*G0_2_3_1 + 9.24340210054652e-06*G0_2_3_2 - 1.37428708857305e-06*G0_2_3_3 + 5.5500055500064e-07*G0_2_3_4 - 7.03000703000822e-06*G0_2_3_5 - 3.79250379250444e-05*G0_2_4_0 + 1.61875161875189e-06*G0_2_4_1 + 1.67887667887696e-05*G0_2_4_2 + 5.5500055500064e-07*G0_2_4_3 - 2.10900210900247e-05*G0_2_4_4 - 1.40600140600164e-05*G0_2_4_5 - 1.89625189625222e-05*G0_2_5_0 + 1.61875161875189e-06*G0_2_5_1 + 5.41125541125633e-06*G0_2_5_2 - 7.03000703000822e-06*G0_2_5_3 - 1.40600140600164e-05*G0_2_5_4 - 2.10900210900246e-05*G0_2_5_5 + 1.8962518962522e-05*G0_3_0_0 - 1.89625189625221e-06*G0_3_0_1 - 1.89625189625221e-06*G0_3_0_2 - 1.51700151700177e-05*G0_3_0_3 - 1.89625189625221e-06*G0_3_1_0 + 9.24340210054652e-06*G0_3_1_1 - 3.10536024821792e-06*G0_3_1_2 - 1.37428708857303e-06*G0_3_1_3 - 7.03000703000822e-06*G0_3_1_4 + 5.55000555000655e-07*G0_3_1_5 - 1.89625189625221e-06*G0_3_2_0 - 3.10536024821792e-06*G0_3_2_1 + 9.24340210054652e-06*G0_3_2_2 - 1.37428708857305e-06*G0_3_2_3 + 5.5500055500064e-07*G0_3_2_4 - 7.03000703000822e-06*G0_3_2_5 - 1.51700151700177e-05*G0_3_3_0 - 1.37428708857303e-06*G0_3_3_1 - 1.37428708857305e-06*G0_3_3_2 + 0.000116708688137279*G0_3_3_3 + 4.44000444000519e-05*G0_3_3_4 + 4.44000444000519e-05*G0_3_3_5 - 7.03000703000822e-06*G0_3_4_1 + 5.5500055500064e-07*G0_3_4_2 + 4.44000444000519e-05*G0_3_4_3 + 4.21800421800493e-05*G0_3_4_4 + 2.81200281200329e-05*G0_3_4_5 + 5.55000555000655e-07*G0_3_5_1 - 7.03000703000822e-06*G0_3_5_2 + 4.44000444000519e-05*G0_3_5_3 + 2.81200281200329e-05*G0_3_5_4 + 4.21800421800493e-05*G0_3_5_5 + 0.000370462870462934*G0_4_0_0 - 1.89625189625222e-05*G0_4_0_1 - 3.79250379250444e-05*G0_4_0_2 + 0.000151700151700178*G0_4_0_4 + 7.58500758500886e-05*G0_4_0_5 - 1.89625189625222e-05*G0_4_1_0 + 5.41125541125632e-06*G0_4_1_1 + 1.61875161875189e-06*G0_4_1_2 - 7.03000703000822e-06*G0_4_1_3 - 2.10900210900246e-05*G0_4_1_4 - 1.40600140600164e-05*G0_4_1_5 - 3.79250379250444e-05*G0_4_2_0 + 1.61875161875189e-06*G0_4_2_1 + 1.67887667887696e-05*G0_4_2_2 + 5.55000555000639e-07*G0_4_2_3 - 2.10900210900247e-05*G0_4_2_4 - 1.40600140600164e-05*G0_4_2_5 - 7.03000703000822e-06*G0_4_3_1 + 5.55000555000639e-07*G0_4_3_2 + 4.44000444000519e-05*G0_4_3_3 + 4.21800421800493e-05*G0_4_3_4 + 2.81200281200329e-05*G0_4_3_5 + 0.000151700151700178*G0_4_4_0 - 2.10900210900246e-05*G0_4_4_1 - 2.10900210900247e-05*G0_4_4_2 + 4.21800421800493e-05*G0_4_4_3 + 0.000210900210900247*G0_4_4_4 + 7.03000703000821e-05*G0_4_4_5 + 7.58500758500887e-05*G0_4_5_0 - 1.40600140600164e-05*G0_4_5_1 - 1.40600140600164e-05*G0_4_5_2 + 2.81200281200329e-05*G0_4_5_3 + 7.03000703000821e-05*G0_4_5_4 + 7.03000703000822e-05*G0_4_5_5 + 0.000370462870462933*G0_5_0_0 - 3.79250379250443e-05*G0_5_0_1 - 1.89625189625222e-05*G0_5_0_2 + 7.58500758500887e-05*G0_5_0_4 + 0.000151700151700177*G0_5_0_5 - 3.79250379250443e-05*G0_5_1_0 + 1.67887667887696e-05*G0_5_1_1 + 1.61875161875189e-06*G0_5_1_2 + 5.55000555000655e-07*G0_5_1_3 - 1.40600140600164e-05*G0_5_1_4 - 2.10900210900246e-05*G0_5_1_5 - 1.89625189625222e-05*G0_5_2_0 + 1.61875161875189e-06*G0_5_2_1 + 5.41125541125633e-06*G0_5_2_2 - 7.03000703000822e-06*G0_5_2_3 - 1.40600140600164e-05*G0_5_2_4 - 2.10900210900246e-05*G0_5_2_5 + 5.55000555000655e-07*G0_5_3_1 - 7.03000703000822e-06*G0_5_3_2 + 4.44000444000519e-05*G0_5_3_3 + 2.81200281200329e-05*G0_5_3_4 + 4.21800421800493e-05*G0_5_3_5 + 7.58500758500887e-05*G0_5_4_0 - 1.40600140600164e-05*G0_5_4_1 - 1.40600140600164e-05*G0_5_4_2 + 2.81200281200329e-05*G0_5_4_3 + 7.03000703000821e-05*G0_5_4_4 + 7.03000703000822e-05*G0_5_4_5 + 0.000151700151700177*G0_5_5_0 - 2.10900210900246e-05*G0_5_5_1 - 2.10900210900246e-05*G0_5_5_2 + 4.21800421800493e-05*G0_5_5_3 + 7.03000703000822e-05*G0_5_5_4 + 0.000210900210900247*G0_5_5_5; + A[25] = A[0] - 0.00173874736374766*G0_0_0_0 + 7.35590467733448e-05*G0_0_0_1 + 5.70130927273881e-05*G0_0_0_2 - 9.68608111465401e-06*G0_0_0_3 - 0.000263070263070308*G0_0_0_4 - 0.000314685314685368*G0_0_0_5 + 7.35590467733449e-05*G0_0_1_0 - 1.57084978513575e-06*G0_0_1_1 - 5.54009482581003e-06*G0_0_1_2 + 1.83678755107357e-06*G0_0_1_3 + 2.90714576428912e-06*G0_0_1_4 + 2.62105619248521e-05*G0_0_1_5 + 5.70130927273881e-05*G0_0_2_0 - 5.54009482581003e-06*G0_0_2_1 + 4.57181707181784e-05*G0_0_2_2 + 1.06375106375124e-05*G0_0_2_3 + 3.79250379250444e-05*G0_0_2_4 + 5.76143433286388e-06*G0_0_2_5 - 9.68608111465401e-06*G0_0_3_0 + 1.83678755107357e-06*G0_0_3_1 + 1.06375106375124e-05*G0_0_3_2 + 8.27215112929538e-06*G0_0_3_3 + 1.35578707007301e-05*G0_0_3_4 + 7.84929356358063e-06*G0_0_3_5 - 0.000263070263070308*G0_0_4_0 + 2.90714576428912e-06*G0_0_4_1 + 3.79250379250444e-05*G0_0_4_2 + 1.35578707007301e-05*G0_0_4_3 + 9.56715242429653e-06*G0_0_4_4 - 1.7337160194306e-05*G0_0_4_5 - 0.000314685314685368*G0_0_5_0 + 2.62105619248521e-05*G0_0_5_1 + 5.76143433286388e-06*G0_0_5_2 + 7.84929356358063e-06*G0_0_5_3 - 1.7337160194306e-05*G0_0_5_4 - 9.19979491408218e-05*G0_0_5_5 + 7.35590467733449e-05*G0_1_0_0 - 1.57084978513575e-06*G0_1_0_1 - 5.54009482581003e-06*G0_1_0_2 + 1.83678755107357e-06*G0_1_0_3 + 2.90714576428912e-06*G0_1_0_4 + 2.62105619248521e-05*G0_1_0_5 - 1.57084978513575e-06*G0_1_1_0 - 1.82852861424322e-05*G0_1_1_1 - 1.7971446542878e-06*G0_1_1_2 - 1.15625115625135e-05*G0_1_1_3 - 4.75714761429116e-07*G0_1_1_4 - 1.18532261389425e-05*G0_1_1_5 - 5.54009482581004e-06*G0_1_2_0 - 1.7971446542878e-06*G0_1_2_1 + 2.8440474869051e-05*G0_1_2_2 + 2.05878777307383e-05*G0_1_2_3 + 1.87775187775219e-05*G0_1_2_4 + 8.07393664536658e-06*G0_1_2_5 + 1.83678755107357e-06*G0_1_3_0 - 1.15625115625135e-05*G0_1_3_1 + 2.05878777307383e-05*G0_1_3_2 - 1.7178588607163e-05*G0_1_3_3 - 2.72214557928892e-06*G0_1_3_4 - 1.98214483928803e-05*G0_1_3_5 + 2.90714576428912e-06*G0_1_4_0 - 4.75714761429117e-07*G0_1_4_1 + 1.87775187775219e-05*G0_1_4_2 - 2.72214557928892e-06*G0_1_4_3 + 7.53215038929443e-06*G0_1_4_4 - 1.51964437678749e-05*G0_1_4_5 + 2.62105619248521e-05*G0_1_5_0 - 1.18532261389425e-05*G0_1_5_1 + 8.07393664536658e-06*G0_1_5_2 - 1.98214483928803e-05*G0_1_5_3 - 1.51964437678749e-05*G0_1_5_4 - 2.52921681493153e-05*G0_1_5_5 + 5.70130927273881e-05*G0_2_0_0 - 5.54009482581003e-06*G0_2_0_1 + 4.57181707181784e-05*G0_2_0_2 + 1.06375106375124e-05*G0_2_0_3 + 3.79250379250444e-05*G0_2_0_4 + 5.76143433286388e-06*G0_2_0_5 - 5.54009482581004e-06*G0_2_1_0 - 1.7971446542878e-06*G0_2_1_1 + 2.84404748690511e-05*G0_2_1_2 + 2.05878777307383e-05*G0_2_1_3 + 1.87775187775219e-05*G0_2_1_4 + 8.07393664536658e-06*G0_2_1_5 + 4.57181707181784e-05*G0_2_2_0 + 2.84404748690511e-05*G0_2_2_1 - 0.000476933780505289*G0_2_2_2 - 0.00012371226656943*G0_2_2_3 - 0.000202020202020236*G0_2_2_4 - 8.32500832500979e-06*G0_2_2_5 + 1.06375106375124e-05*G0_2_3_0 + 2.05878777307383e-05*G0_2_3_1 - 0.00012371226656943*G0_2_3_2 - 5.69007711864951e-05*G0_2_3_3 - 5.88300588300688e-05*G0_2_3_4 - 4.62500462500542e-06*G0_2_3_5 + 3.79250379250444e-05*G0_2_4_0 + 1.87775187775219e-05*G0_2_4_1 - 0.000202020202020236*G0_2_4_2 - 5.88300588300688e-05*G0_2_4_3 - 0.00015373515373518*G0_2_4_4 - 2.09050209050245e-05*G0_2_4_5 + 5.76143433286388e-06*G0_2_5_0 + 8.07393664536658e-06*G0_2_5_1 - 8.32500832500979e-06*G0_2_5_2 - 4.62500462500542e-06*G0_2_5_3 - 2.09050209050245e-05*G0_2_5_4 - 1.24478695907288e-05*G0_2_5_5 - 9.68608111465401e-06*G0_3_0_0 + 1.83678755107358e-06*G0_3_0_1 + 1.06375106375124e-05*G0_3_0_2 + 8.27215112929538e-06*G0_3_0_3 + 1.35578707007301e-05*G0_3_0_4 + 7.84929356358063e-06*G0_3_0_5 + 1.83678755107357e-06*G0_3_1_0 - 1.15625115625135e-05*G0_3_1_1 + 2.05878777307383e-05*G0_3_1_2 - 1.7178588607163e-05*G0_3_1_3 - 2.72214557928892e-06*G0_3_1_4 - 1.98214483928803e-05*G0_3_1_5 + 1.06375106375124e-05*G0_3_2_0 + 2.05878777307383e-05*G0_3_2_1 - 0.00012371226656943*G0_3_2_2 - 5.69007711864951e-05*G0_3_2_3 - 5.88300588300688e-05*G0_3_2_4 - 4.62500462500542e-06*G0_3_2_5 + 8.27215112929538e-06*G0_3_3_0 - 1.7178588607163e-05*G0_3_3_1 - 5.69007711864951e-05*G0_3_3_2 - 1.68085882371625e-05*G0_3_3_3 - 1.11000111000129e-05*G0_3_3_4 - 7.29429300857995e-06*G0_3_3_5 + 1.35578707007301e-05*G0_3_4_0 - 2.72214557928892e-06*G0_3_4_1 - 5.88300588300688e-05*G0_3_4_2 - 1.11000111000129e-05*G0_3_4_3 - 4.21800421800492e-05*G0_3_4_4 + 1.46943004085886e-05*G0_3_4_5 + 7.84929356358063e-06*G0_3_5_0 - 1.98214483928803e-05*G0_3_5_1 - 4.62500462500542e-06*G0_3_5_2 - 7.29429300857995e-06*G0_3_5_3 + 1.46943004085886e-05*G0_3_5_4 + 9.19715205429644e-06*G0_3_5_5 - 0.000263070263070308*G0_4_0_0 + 2.90714576428912e-06*G0_4_0_1 + 3.79250379250444e-05*G0_4_0_2 + 1.35578707007301e-05*G0_4_0_3 + 9.56715242429656e-06*G0_4_0_4 - 1.7337160194306e-05*G0_4_0_5 + 2.90714576428912e-06*G0_4_1_0 - 4.75714761429116e-07*G0_4_1_1 + 1.87775187775219e-05*G0_4_1_2 - 2.72214557928892e-06*G0_4_1_3 + 7.53215038929443e-06*G0_4_1_4 - 1.51964437678749e-05*G0_4_1_5 + 3.79250379250444e-05*G0_4_2_0 + 1.87775187775219e-05*G0_4_2_1 - 0.000202020202020236*G0_4_2_2 - 5.88300588300687e-05*G0_4_2_3 - 0.00015373515373518*G0_4_2_4 - 2.09050209050245e-05*G0_4_2_5 + 1.35578707007301e-05*G0_4_3_0 - 2.72214557928892e-06*G0_4_3_1 - 5.88300588300687e-05*G0_4_3_2 - 1.11000111000129e-05*G0_4_3_3 - 4.21800421800492e-05*G0_4_3_4 + 1.46943004085886e-05*G0_4_3_5 + 9.56715242429653e-06*G0_4_4_0 + 7.53215038929443e-06*G0_4_4_1 - 0.00015373515373518*G0_4_4_2 - 4.21800421800492e-05*G0_4_4_3 - 0.00041070041070048*G0_4_4_4 + 2.67457410314599e-05*G0_4_4_5 - 1.7337160194306e-05*G0_4_5_0 - 1.51964437678749e-05*G0_4_5_1 - 2.09050209050245e-05*G0_4_5_2 + 1.46943004085886e-05*G0_4_5_3 + 2.674574103146e-05*G0_4_5_4 + 5.52886267172074e-05*G0_4_5_5 - 0.000314685314685368*G0_5_0_0 + 2.62105619248521e-05*G0_5_0_1 + 5.76143433286388e-06*G0_5_0_2 + 7.84929356358063e-06*G0_5_0_3 - 1.7337160194306e-05*G0_5_0_4 - 9.19979491408218e-05*G0_5_0_5 + 2.62105619248521e-05*G0_5_1_0 - 1.18532261389425e-05*G0_5_1_1 + 8.07393664536658e-06*G0_5_1_2 - 1.98214483928803e-05*G0_5_1_3 - 1.51964437678749e-05*G0_5_1_4 - 2.52921681493153e-05*G0_5_1_5 + 5.76143433286388e-06*G0_5_2_0 + 8.07393664536658e-06*G0_5_2_1 - 8.32500832500979e-06*G0_5_2_2 - 4.62500462500542e-06*G0_5_2_3 - 2.09050209050245e-05*G0_5_2_4 - 1.24478695907288e-05*G0_5_2_5 + 7.84929356358063e-06*G0_5_3_0 - 1.98214483928803e-05*G0_5_3_1 - 4.62500462500542e-06*G0_5_3_2 - 7.29429300857995e-06*G0_5_3_3 + 1.46943004085886e-05*G0_5_3_4 + 9.19715205429644e-06*G0_5_3_5 - 1.7337160194306e-05*G0_5_4_0 - 1.51964437678749e-05*G0_5_4_1 - 2.09050209050244e-05*G0_5_4_2 + 1.46943004085886e-05*G0_5_4_3 + 2.67457410314599e-05*G0_5_4_4 + 5.52886267172074e-05*G0_5_4_5 - 9.19979491408218e-05*G0_5_5_0 - 2.52921681493153e-05*G0_5_5_1 - 1.24478695907288e-05*G0_5_5_2 + 9.19715205429644e-06*G0_5_5_3 + 5.52886267172074e-05*G0_5_5_4 + 3.17143174285799e-07*G0_5_5_5; + A[60] = -A[25] - 0.000325924075924131*G0_0_0_0 + 1.21158603301481e-05*G0_0_0_1 + 2.05449312592204e-05*G0_0_0_2 + 6.3626849341146e-06*G0_0_0_3 - 7.78388278388412e-05*G0_0_0_4 - 5.86913086913185e-05*G0_0_0_5 + 1.21158603301481e-05*G0_0_1_0 + 3.12187812187868e-07*G0_0_1_1 + 2.97321725893207e-07*G0_0_1_2 + 9.63322391893983e-06*G0_0_1_3 + 4.34089719804078e-06*G0_0_1_4 + 5.76804148232817e-06*G0_0_1_5 + 2.05449312592204e-05*G0_0_2_0 + 2.97321725893207e-07*G0_0_2_1 + 2.05449312592205e-05*G0_0_2_2 - 4.45982588839806e-06*G0_0_2_3 - 4.45982588839807e-06*G0_0_2_5 + 6.3626849341146e-06*G0_0_3_0 + 9.63322391893983e-06*G0_0_3_1 - 4.45982588839806e-06*G0_0_3_2 - 4.04357547214759e-05*G0_0_3_3 - 2.14071642643107e-05*G0_0_3_4 - 3.80571809143302e-06*G0_0_3_5 - 7.78388278388412e-05*G0_0_4_0 + 4.34089719804079e-06*G0_0_4_1 - 2.14071642643107e-05*G0_0_4_3 - 1.35578707007304e-05*G0_0_4_4 + 2.37857380714573e-07*G0_0_4_5 - 5.86913086913185e-05*G0_0_5_0 + 5.76804148232817e-06*G0_0_5_1 - 4.45982588839807e-06*G0_0_5_2 - 3.80571809143302e-06*G0_0_5_3 + 2.37857380714566e-07*G0_0_5_4 + 1.42714428428736e-06*G0_0_5_5 + 1.21158603301481e-05*G0_1_0_0 + 3.12187812187867e-07*G0_1_0_1 + 2.97321725893207e-07*G0_1_0_2 + 9.63322391893984e-06*G0_1_0_3 + 4.34089719804078e-06*G0_1_0_4 + 5.76804148232817e-06*G0_1_0_5 + 3.12187812187866e-07*G0_1_1_0 - 1.30226915941224e-05*G0_1_1_1 + 3.12187812187868e-07*G0_1_1_2 + 2.61643118786019e-06*G0_1_1_3 + 9.8710812996544e-06*G0_1_1_4 + 2.61643118786019e-06*G0_1_1_5 + 2.97321725893206e-07*G0_1_2_0 + 3.12187812187867e-07*G0_1_2_1 + 1.21158603301481e-05*G0_1_2_2 + 5.76804148232817e-06*G0_1_2_3 + 4.3408971980408e-06*G0_1_2_4 + 9.63322391893983e-06*G0_1_2_5 + 9.63322391893984e-06*G0_1_3_0 + 2.6164311878602e-06*G0_1_3_1 + 5.76804148232817e-06*G0_1_3_2 - 6.49350649350759e-05*G0_1_3_3 - 3.90086104371885e-05*G0_1_3_4 - 3.85328956757593e-05*G0_1_3_5 + 4.34089719804078e-06*G0_1_4_0 + 9.8710812996544e-06*G0_1_4_1 + 4.3408971980408e-06*G0_1_4_2 - 3.90086104371885e-05*G0_1_4_3 - 2.71157414014603e-05*G0_1_4_4 - 3.90086104371885e-05*G0_1_4_5 + 5.76804148232817e-06*G0_1_5_0 + 2.61643118786019e-06*G0_1_5_1 + 9.63322391893983e-06*G0_1_5_2 - 3.85328956757593e-05*G0_1_5_3 - 3.90086104371885e-05*G0_1_5_4 - 6.49350649350759e-05*G0_1_5_5 + 2.05449312592204e-05*G0_2_0_0 + 2.97321725893207e-07*G0_2_0_1 + 2.05449312592205e-05*G0_2_0_2 - 4.45982588839806e-06*G0_2_0_3 - 4.45982588839807e-06*G0_2_0_5 + 2.97321725893207e-07*G0_2_1_0 + 3.12187812187868e-07*G0_2_1_1 + 1.21158603301481e-05*G0_2_1_2 + 5.76804148232818e-06*G0_2_1_3 + 4.3408971980408e-06*G0_2_1_4 + 9.63322391893983e-06*G0_2_1_5 + 2.05449312592205e-05*G0_2_2_0 + 1.21158603301481e-05*G0_2_2_1 - 0.000325924075924131*G0_2_2_2 - 5.86913086913186e-05*G0_2_2_3 - 7.78388278388409e-05*G0_2_2_4 + 6.36268493411453e-06*G0_2_2_5 - 4.45982588839806e-06*G0_2_3_0 + 5.76804148232818e-06*G0_2_3_1 - 5.86913086913186e-05*G0_2_3_2 + 1.42714428428732e-06*G0_2_3_3 + 2.37857380714532e-07*G0_2_3_4 - 3.80571809143304e-06*G0_2_3_5 + 4.3408971980408e-06*G0_2_4_1 - 7.78388278388409e-05*G0_2_4_2 + 2.37857380714532e-07*G0_2_4_3 - 1.35578707007301e-05*G0_2_4_4 - 2.14071642643108e-05*G0_2_4_5 - 4.45982588839806e-06*G0_2_5_0 + 9.63322391893983e-06*G0_2_5_1 + 6.36268493411453e-06*G0_2_5_2 - 3.80571809143304e-06*G0_2_5_3 - 2.14071642643108e-05*G0_2_5_4 - 4.04357547214758e-05*G0_2_5_5 + 6.3626849341146e-06*G0_3_0_0 + 9.63322391893983e-06*G0_3_0_1 - 4.45982588839806e-06*G0_3_0_2 - 4.04357547214759e-05*G0_3_0_3 - 2.14071642643107e-05*G0_3_0_4 - 3.80571809143303e-06*G0_3_0_5 + 9.63322391893983e-06*G0_3_1_0 + 2.6164311878602e-06*G0_3_1_1 + 5.76804148232817e-06*G0_3_1_2 - 6.49350649350759e-05*G0_3_1_3 - 3.90086104371885e-05*G0_3_1_4 - 3.85328956757593e-05*G0_3_1_5 - 4.45982588839806e-06*G0_3_2_0 + 5.76804148232818e-06*G0_3_2_1 - 5.86913086913186e-05*G0_3_2_2 + 1.42714428428732e-06*G0_3_2_3 + 2.37857380714532e-07*G0_3_2_4 - 3.80571809143304e-06*G0_3_2_5 - 4.04357547214759e-05*G0_3_3_0 - 6.49350649350759e-05*G0_3_3_1 + 1.42714428428732e-06*G0_3_3_2 + 0.00031111745397465*G0_3_3_3 + 0.000158888730317329*G0_3_3_4 + 8.84829456258178e-05*G0_3_3_5 - 2.14071642643107e-05*G0_3_4_0 - 3.90086104371885e-05*G0_3_4_1 + 2.37857380714532e-07*G0_3_4_2 + 0.000158888730317329*G0_3_4_3 + 9.70458113315421e-05*G0_3_4_4 + 8.5628657057243e-05*G0_3_4_5 - 3.80571809143303e-06*G0_3_5_0 - 3.85328956757593e-05*G0_3_5_1 - 3.80571809143304e-06*G0_3_5_2 + 8.84829456258178e-05*G0_3_5_3 + 8.5628657057243e-05*G0_3_5_4 + 8.84829456258177e-05*G0_3_5_5 - 7.78388278388412e-05*G0_4_0_0 + 4.34089719804078e-06*G0_4_0_1 - 2.14071642643107e-05*G0_4_0_3 - 1.35578707007304e-05*G0_4_0_4 + 2.37857380714566e-07*G0_4_0_5 + 4.34089719804078e-06*G0_4_1_0 + 9.8710812996544e-06*G0_4_1_1 + 4.3408971980408e-06*G0_4_1_2 - 3.90086104371885e-05*G0_4_1_3 - 2.71157414014604e-05*G0_4_1_4 - 3.90086104371885e-05*G0_4_1_5 + 4.3408971980408e-06*G0_4_2_1 - 7.78388278388409e-05*G0_4_2_2 + 2.37857380714532e-07*G0_4_2_3 - 1.35578707007301e-05*G0_4_2_4 - 2.14071642643108e-05*G0_4_2_5 - 2.14071642643107e-05*G0_4_3_0 - 3.90086104371885e-05*G0_4_3_1 + 2.37857380714532e-07*G0_4_3_2 + 0.000158888730317329*G0_4_3_3 + 9.70458113315421e-05*G0_4_3_4 + 8.5628657057243e-05*G0_4_3_5 - 1.35578707007304e-05*G0_4_4_0 - 2.71157414014604e-05*G0_4_4_1 - 1.35578707007301e-05*G0_4_4_2 + 9.70458113315421e-05*G0_4_4_3 - 0.000399600399600466*G0_4_4_4 + 9.70458113315421e-05*G0_4_4_5 + 2.37857380714566e-07*G0_4_5_0 - 3.90086104371885e-05*G0_4_5_1 - 2.14071642643108e-05*G0_4_5_2 + 8.5628657057243e-05*G0_4_5_3 + 9.70458113315422e-05*G0_4_5_4 + 0.000158888730317329*G0_4_5_5 - 5.86913086913185e-05*G0_5_0_0 + 5.76804148232818e-06*G0_5_0_1 - 4.45982588839806e-06*G0_5_0_2 - 3.80571809143302e-06*G0_5_0_3 + 2.37857380714539e-07*G0_5_0_4 + 1.42714428428736e-06*G0_5_0_5 + 5.76804148232817e-06*G0_5_1_0 + 2.61643118786019e-06*G0_5_1_1 + 9.63322391893983e-06*G0_5_1_2 - 3.85328956757593e-05*G0_5_1_3 - 3.90086104371885e-05*G0_5_1_4 - 6.49350649350759e-05*G0_5_1_5 - 4.45982588839807e-06*G0_5_2_0 + 9.63322391893983e-06*G0_5_2_1 + 6.36268493411453e-06*G0_5_2_2 - 3.80571809143304e-06*G0_5_2_3 - 2.14071642643108e-05*G0_5_2_4 - 4.04357547214758e-05*G0_5_2_5 - 3.80571809143303e-06*G0_5_3_0 - 3.85328956757593e-05*G0_5_3_1 - 3.80571809143304e-06*G0_5_3_2 + 8.84829456258178e-05*G0_5_3_3 + 8.5628657057243e-05*G0_5_3_4 + 8.84829456258177e-05*G0_5_3_5 + 2.37857380714553e-07*G0_5_4_0 - 3.90086104371885e-05*G0_5_4_1 - 2.14071642643107e-05*G0_5_4_2 + 8.5628657057243e-05*G0_5_4_3 + 9.70458113315422e-05*G0_5_4_4 + 0.000158888730317329*G0_5_4_5 + 1.42714428428736e-06*G0_5_5_0 - 6.49350649350759e-05*G0_5_5_1 - 4.04357547214758e-05*G0_5_5_2 + 8.84829456258177e-05*G0_5_5_3 + 0.000158888730317329*G0_5_5_4 + 0.000311117453974649*G0_5_5_5; + A[16] = A[60] + 0.000417707292707364*G0_0_0_0 - 2.23883259597583e-05*G0_0_0_1 - 3.94694591123229e-05*G0_0_0_2 + 7.84929356358059e-06*G0_0_0_3 + 0.000171614100185558*G0_0_0_4 + 9.10399124684992e-05*G0_0_0_5 - 2.23883259597583e-05*G0_0_1_0 + 2.76509205080679e-06*G0_0_1_1 + 1.59067123352864e-06*G0_0_1_2 - 2.14071642643107e-06*G0_0_1_4 - 5.53018410161361e-06*G0_0_1_5 - 3.9469459112323e-05*G0_0_2_0 + 1.59067123352864e-06*G0_0_2_1 + 1.16698777413083e-05*G0_0_2_2 + 1.48660862946602e-06*G0_0_2_3 - 1.58769801626971e-05*G0_0_2_4 - 4.04357547214757e-06*G0_0_2_5 + 7.84929356358059e-06*G0_0_3_0 + 1.48660862946602e-06*G0_0_3_2 + 4.28143285286217e-06*G0_0_3_3 - 1.1417154274299e-05*G0_0_3_4 - 7.61143618286605e-06*G0_0_3_5 + 0.000171614100185558*G0_0_4_0 - 2.14071642643107e-06*G0_0_4_1 - 1.58769801626971e-05*G0_0_4_2 - 1.1417154274299e-05*G0_0_4_3 + 4.56686170971965e-05*G0_0_4_4 + 1.23685837971573e-05*G0_0_4_5 + 9.10399124684991e-05*G0_0_5_0 - 5.53018410161361e-06*G0_0_5_1 - 4.04357547214757e-06*G0_0_5_2 - 7.61143618286605e-06*G0_0_5_3 + 1.23685837971573e-05*G0_0_5_4 + 1.11792968935845e-05*G0_0_5_5 - 2.23883259597583e-05*G0_1_0_0 + 2.76509205080679e-06*G0_1_0_1 + 1.59067123352864e-06*G0_1_0_2 - 2.14071642643107e-06*G0_1_0_4 - 5.53018410161361e-06*G0_1_0_5 + 2.76509205080679e-06*G0_1_1_0 - 1.84636791779679e-05*G0_1_1_1 + 2.33397554826166e-06*G0_1_1_2 - 7.84929356358062e-06*G0_1_1_3 + 2.14071642643107e-06*G0_1_1_4 - 9.33590219304659e-06*G0_1_1_5 + 1.59067123352864e-06*G0_1_2_0 + 2.33397554826166e-06*G0_1_2_1 + 7.43304314733012e-07*G0_1_2_2 - 1.48660862946602e-06*G0_1_2_3 - 2.08125208125243e-06*G0_1_2_4 - 3.80571809143302e-06*G0_1_2_5 - 7.84929356358063e-06*G0_1_3_1 - 1.48660862946602e-06*G0_1_3_2 + 1.14171542742991e-05*G0_1_3_3 - 4.28143285286214e-06*G0_1_3_4 + 7.61143618286604e-06*G0_1_3_5 - 2.14071642643107e-06*G0_1_4_0 + 2.14071642643107e-06*G0_1_4_1 - 2.08125208125243e-06*G0_1_4_2 - 4.28143285286215e-06*G0_1_4_3 - 4.56686170971962e-05*G0_1_4_4 + 3.33000333000391e-06*G0_1_4_5 - 5.53018410161361e-06*G0_1_5_0 - 9.33590219304659e-06*G0_1_5_1 - 3.80571809143302e-06*G0_1_5_2 + 7.61143618286604e-06*G0_1_5_3 + 3.33000333000391e-06*G0_1_5_4 + 1.8552875695736e-05*G0_1_5_5 - 3.9469459112323e-05*G0_2_0_0 + 1.59067123352864e-06*G0_2_0_1 + 1.16698777413083e-05*G0_2_0_2 + 1.48660862946602e-06*G0_2_0_3 - 1.58769801626971e-05*G0_2_0_4 - 4.04357547214757e-06*G0_2_0_5 + 1.59067123352864e-06*G0_2_1_0 + 2.33397554826166e-06*G0_2_1_1 + 7.43304314733011e-07*G0_2_1_2 - 1.48660862946602e-06*G0_2_1_3 - 2.08125208125243e-06*G0_2_1_4 - 3.80571809143302e-06*G0_2_1_5 + 1.16698777413083e-05*G0_2_2_0 + 7.43304314733012e-07*G0_2_2_1 - 4.43306693306768e-05*G0_2_2_2 - 3.28837828837885e-05*G0_2_2_4 - 1.48660862946603e-06*G0_2_2_5 + 1.48660862946602e-06*G0_2_3_0 - 1.48660862946602e-06*G0_2_3_1 - 1.1892869035728e-06*G0_2_3_3 + 1.18928690357279e-06*G0_2_3_4 - 1.58769801626971e-05*G0_2_4_0 - 2.08125208125243e-06*G0_2_4_1 - 3.28837828837885e-05*G0_2_4_2 + 1.18928690357279e-06*G0_2_4_3 - 2.78293135436042e-05*G0_2_4_4 + 7.1357214214369e-06*G0_2_4_5 - 4.04357547214757e-06*G0_2_5_0 - 3.80571809143302e-06*G0_2_5_1 - 1.48660862946603e-06*G0_2_5_2 + 7.1357214214369e-06*G0_2_5_4 + 7.61143618286602e-06*G0_2_5_5 + 7.84929356358059e-06*G0_3_0_0 + 1.48660862946602e-06*G0_3_0_2 + 4.28143285286217e-06*G0_3_0_3 - 1.1417154274299e-05*G0_3_0_4 - 7.61143618286605e-06*G0_3_0_5 - 7.84929356358062e-06*G0_3_1_1 - 1.48660862946602e-06*G0_3_1_2 + 1.1417154274299e-05*G0_3_1_3 - 4.28143285286213e-06*G0_3_1_4 + 7.61143618286604e-06*G0_3_1_5 + 1.48660862946602e-06*G0_3_2_0 - 1.48660862946602e-06*G0_3_2_1 - 1.1892869035728e-06*G0_3_2_3 + 1.18928690357279e-06*G0_3_2_4 + 4.28143285286217e-06*G0_3_3_0 + 1.1417154274299e-05*G0_3_3_1 - 1.18928690357281e-06*G0_3_3_2 - 0.000114171542742991*G0_3_3_3 - 8.56286570572435e-06*G0_3_3_5 - 1.1417154274299e-05*G0_3_4_0 - 4.28143285286214e-06*G0_3_4_1 + 1.1892869035728e-06*G0_3_4_2 + 0.00011417154274299*G0_3_4_4 + 8.56286570572427e-06*G0_3_4_5 - 7.61143618286605e-06*G0_3_5_0 + 7.61143618286604e-06*G0_3_5_1 - 8.56286570572437e-06*G0_3_5_3 + 8.56286570572428e-06*G0_3_5_4 + 0.000171614100185558*G0_4_0_0 - 2.14071642643107e-06*G0_4_0_1 - 1.58769801626971e-05*G0_4_0_2 - 1.1417154274299e-05*G0_4_0_3 + 4.56686170971965e-05*G0_4_0_4 + 1.23685837971573e-05*G0_4_0_5 - 2.14071642643107e-06*G0_4_1_0 + 2.14071642643107e-06*G0_4_1_1 - 2.08125208125243e-06*G0_4_1_2 - 4.28143285286215e-06*G0_4_1_3 - 4.56686170971962e-05*G0_4_1_4 + 3.33000333000391e-06*G0_4_1_5 - 1.58769801626971e-05*G0_4_2_0 - 2.08125208125243e-06*G0_4_2_1 - 3.28837828837885e-05*G0_4_2_2 + 1.18928690357279e-06*G0_4_2_3 - 2.78293135436042e-05*G0_4_2_4 + 7.13572142143689e-06*G0_4_2_5 - 1.1417154274299e-05*G0_4_3_0 - 4.28143285286215e-06*G0_4_3_1 + 1.1892869035728e-06*G0_4_3_2 + 0.00011417154274299*G0_4_3_4 + 8.56286570572427e-06*G0_4_3_5 + 4.56686170971966e-05*G0_4_4_0 - 4.56686170971962e-05*G0_4_4_1 - 2.78293135436042e-05*G0_4_4_2 + 0.000114171542742991*G0_4_4_3 + 0.000810617953475233*G0_4_4_4 + 7.70657913515186e-05*G0_4_4_5 + 1.23685837971573e-05*G0_4_5_0 + 3.33000333000391e-06*G0_4_5_1 + 7.1357214214369e-06*G0_4_5_2 + 8.56286570572427e-06*G0_4_5_3 + 7.70657913515186e-05*G0_4_5_4 - 2.18828790257398e-05*G0_4_5_5 + 9.10399124684992e-05*G0_5_0_0 - 5.53018410161361e-06*G0_5_0_1 - 4.04357547214757e-06*G0_5_0_2 - 7.61143618286605e-06*G0_5_0_3 + 1.23685837971573e-05*G0_5_0_4 + 1.11792968935845e-05*G0_5_0_5 - 5.53018410161361e-06*G0_5_1_0 - 9.33590219304659e-06*G0_5_1_1 - 3.80571809143302e-06*G0_5_1_2 + 7.61143618286604e-06*G0_5_1_3 + 3.33000333000391e-06*G0_5_1_4 + 1.8552875695736e-05*G0_5_1_5 - 4.04357547214757e-06*G0_5_2_0 - 3.80571809143302e-06*G0_5_2_1 - 1.48660862946603e-06*G0_5_2_2 + 7.1357214214369e-06*G0_5_2_4 + 7.61143618286602e-06*G0_5_2_5 - 7.61143618286605e-06*G0_5_3_0 + 7.61143618286604e-06*G0_5_3_1 - 8.56286570572435e-06*G0_5_3_3 + 8.56286570572429e-06*G0_5_3_4 + 1.23685837971573e-05*G0_5_4_0 + 3.33000333000391e-06*G0_5_4_1 + 7.13572142143689e-06*G0_5_4_2 + 8.56286570572427e-06*G0_5_4_3 + 7.70657913515185e-05*G0_5_4_4 - 2.18828790257398e-05*G0_5_4_5 + 1.11792968935845e-05*G0_5_5_0 + 1.8552875695736e-05*G0_5_5_1 + 7.61143618286602e-06*G0_5_5_2 - 2.18828790257398e-05*G0_5_5_4 - 3.71057513914716e-05*G0_5_5_5; + A[40] = A[16] + 2.24775224775263e-05*G0_0_0_0 - 5.0842015127738e-06*G0_0_0_1 - 5.48558584272962e-06*G0_0_0_2 + 2.14071642643107e-06*G0_0_0_3 + 1.07035821321553e-05*G0_0_0_4 + 1.17739403453709e-05*G0_0_0_5 - 5.0842015127738e-06*G0_0_1_0 + 5.08420151277381e-06*G0_0_1_1 + 8.5628657057243e-06*G0_0_1_3 - 8.56286570572428e-06*G0_0_1_4 - 5.48558584272962e-06*G0_0_2_0 + 5.61938061938157e-06*G0_0_2_2 - 6.42214927929322e-06*G0_0_2_3 + 2.67589553303883e-06*G0_0_2_4 - 8.5628657057243e-06*G0_0_2_5 + 2.14071642643107e-06*G0_0_3_0 + 8.5628657057243e-06*G0_0_3_1 - 6.42214927929322e-06*G0_0_3_2 - 2.9970029970035e-05*G0_0_3_3 + 1.28442985585864e-05*G0_0_3_4 + 1.28442985585865e-05*G0_0_3_5 + 1.07035821321553e-05*G0_0_4_0 - 8.56286570572429e-06*G0_0_4_1 + 2.67589553303883e-06*G0_0_4_2 + 1.28442985585864e-05*G0_0_4_3 + 9.41915227629672e-05*G0_0_4_4 + 3.42514628228972e-05*G0_0_4_5 + 1.17739403453709e-05*G0_0_5_0 - 8.5628657057243e-06*G0_0_5_2 + 1.28442985585865e-05*G0_0_5_3 + 3.42514628228972e-05*G0_0_5_4 + 4.70957613814836e-05*G0_0_5_5 - 5.0842015127738e-06*G0_1_0_0 + 5.08420151277381e-06*G0_1_0_1 + 8.56286570572429e-06*G0_1_0_3 - 8.56286570572428e-06*G0_1_0_4 + 5.08420151277381e-06*G0_1_1_0 - 2.24775224775264e-05*G0_1_1_1 + 5.48558584272963e-06*G0_1_1_2 - 1.07035821321554e-05*G0_1_1_3 - 2.14071642643107e-06*G0_1_1_4 - 1.1773940345371e-05*G0_1_1_5 + 5.48558584272963e-06*G0_1_2_1 - 5.61938061938158e-06*G0_1_2_2 - 2.67589553303883e-06*G0_1_2_3 + 6.42214927929322e-06*G0_1_2_4 + 8.56286570572429e-06*G0_1_2_5 + 8.5628657057243e-06*G0_1_3_0 - 1.07035821321554e-05*G0_1_3_1 - 2.67589553303883e-06*G0_1_3_2 - 9.41915227629673e-05*G0_1_3_3 - 1.28442985585864e-05*G0_1_3_4 - 3.42514628228972e-05*G0_1_3_5 - 8.56286570572428e-06*G0_1_4_0 - 2.14071642643107e-06*G0_1_4_1 + 6.42214927929322e-06*G0_1_4_2 - 1.28442985585864e-05*G0_1_4_3 + 2.9970029970035e-05*G0_1_4_4 - 1.28442985585864e-05*G0_1_4_5 - 1.17739403453709e-05*G0_1_5_1 + 8.56286570572429e-06*G0_1_5_2 - 3.42514628228972e-05*G0_1_5_3 - 1.28442985585864e-05*G0_1_5_4 - 4.70957613814836e-05*G0_1_5_5 - 5.48558584272962e-06*G0_2_0_0 + 5.61938061938157e-06*G0_2_0_2 - 6.42214927929322e-06*G0_2_0_3 + 2.67589553303883e-06*G0_2_0_4 - 8.5628657057243e-06*G0_2_0_5 + 5.48558584272963e-06*G0_2_1_1 - 5.61938061938158e-06*G0_2_1_2 - 2.67589553303883e-06*G0_2_1_3 + 6.42214927929321e-06*G0_2_1_4 + 8.56286570572429e-06*G0_2_1_5 + 5.61938061938157e-06*G0_2_2_0 - 5.61938061938157e-06*G0_2_2_1 + 1.87312687312719e-05*G0_2_2_3 - 1.87312687312719e-05*G0_2_2_4 - 6.42214927929322e-06*G0_2_3_0 - 2.67589553303883e-06*G0_2_3_1 + 1.87312687312719e-05*G0_2_3_2 + 7.49250749250876e-05*G0_2_3_3 + 1.28442985585864e-05*G0_2_3_5 + 2.67589553303883e-06*G0_2_4_0 + 6.42214927929322e-06*G0_2_4_1 - 1.87312687312719e-05*G0_2_4_2 - 7.49250749250874e-05*G0_2_4_4 - 1.28442985585864e-05*G0_2_4_5 - 8.5628657057243e-06*G0_2_5_0 + 8.56286570572429e-06*G0_2_5_1 + 1.28442985585864e-05*G0_2_5_3 - 1.28442985585864e-05*G0_2_5_4 + 2.14071642643107e-06*G0_3_0_0 + 8.5628657057243e-06*G0_3_0_1 - 6.42214927929322e-06*G0_3_0_2 - 2.9970029970035e-05*G0_3_0_3 + 1.28442985585864e-05*G0_3_0_4 + 1.28442985585865e-05*G0_3_0_5 + 8.5628657057243e-06*G0_3_1_0 - 1.07035821321554e-05*G0_3_1_1 - 2.67589553303883e-06*G0_3_1_2 - 9.41915227629673e-05*G0_3_1_3 - 1.28442985585864e-05*G0_3_1_4 - 3.42514628228972e-05*G0_3_1_5 - 6.42214927929322e-06*G0_3_2_0 - 2.67589553303883e-06*G0_3_2_1 + 1.87312687312719e-05*G0_3_2_2 + 7.49250749250876e-05*G0_3_2_3 + 1.28442985585864e-05*G0_3_2_5 - 2.9970029970035e-05*G0_3_3_0 - 9.41915227629673e-05*G0_3_3_1 + 7.49250749250875e-05*G0_3_3_2 + 0.000513771942343458*G0_3_3_3 + 8.5628657057243e-05*G0_3_3_4 + 3.42514628228972e-05*G0_3_3_5 + 1.28442985585864e-05*G0_3_4_0 - 1.28442985585864e-05*G0_3_4_1 + 8.5628657057243e-05*G0_3_4_3 - 8.56286570572429e-05*G0_3_4_4 + 1.28442985585865e-05*G0_3_5_0 - 3.42514628228972e-05*G0_3_5_1 + 1.28442985585864e-05*G0_3_5_2 + 3.42514628228972e-05*G0_3_5_3 - 2.56885971171729e-05*G0_3_5_5 + 1.07035821321553e-05*G0_4_0_0 - 8.56286570572429e-06*G0_4_0_1 + 2.67589553303883e-06*G0_4_0_2 + 1.28442985585864e-05*G0_4_0_3 + 9.41915227629672e-05*G0_4_0_4 + 3.42514628228972e-05*G0_4_0_5 - 8.56286570572429e-06*G0_4_1_0 - 2.14071642643107e-06*G0_4_1_1 + 6.42214927929322e-06*G0_4_1_2 - 1.28442985585864e-05*G0_4_1_3 + 2.9970029970035e-05*G0_4_1_4 - 1.28442985585864e-05*G0_4_1_5 + 2.67589553303883e-06*G0_4_2_0 + 6.42214927929322e-06*G0_4_2_1 - 1.87312687312719e-05*G0_4_2_2 - 7.49250749250874e-05*G0_4_2_4 - 1.28442985585864e-05*G0_4_2_5 + 1.28442985585864e-05*G0_4_3_0 - 1.28442985585864e-05*G0_4_3_1 + 8.5628657057243e-05*G0_4_3_3 - 8.56286570572429e-05*G0_4_3_4 + 9.41915227629672e-05*G0_4_4_0 + 2.9970029970035e-05*G0_4_4_1 - 7.49250749250874e-05*G0_4_4_2 - 8.56286570572429e-05*G0_4_4_3 - 0.000513771942343457*G0_4_4_4 - 3.42514628228972e-05*G0_4_4_5 + 3.42514628228972e-05*G0_4_5_0 - 1.28442985585864e-05*G0_4_5_1 - 1.28442985585864e-05*G0_4_5_2 - 3.42514628228972e-05*G0_4_5_4 + 2.56885971171728e-05*G0_4_5_5 + 1.17739403453709e-05*G0_5_0_0 - 8.5628657057243e-06*G0_5_0_2 + 1.28442985585865e-05*G0_5_0_3 + 3.42514628228972e-05*G0_5_0_4 + 4.70957613814836e-05*G0_5_0_5 - 1.1773940345371e-05*G0_5_1_1 + 8.56286570572429e-06*G0_5_1_2 - 3.42514628228972e-05*G0_5_1_3 - 1.28442985585864e-05*G0_5_1_4 - 4.70957613814836e-05*G0_5_1_5 - 8.5628657057243e-06*G0_5_2_0 + 8.56286570572429e-06*G0_5_2_1 + 1.28442985585864e-05*G0_5_2_3 - 1.28442985585864e-05*G0_5_2_4 + 1.28442985585865e-05*G0_5_3_0 - 3.42514628228972e-05*G0_5_3_1 + 1.28442985585864e-05*G0_5_3_2 + 3.42514628228972e-05*G0_5_3_3 - 2.56885971171729e-05*G0_5_3_5 + 3.42514628228972e-05*G0_5_4_0 - 1.28442985585864e-05*G0_5_4_1 - 1.28442985585864e-05*G0_5_4_2 - 3.42514628228972e-05*G0_5_4_4 + 2.56885971171728e-05*G0_5_4_5 + 4.70957613814836e-05*G0_5_5_0 - 4.70957613814836e-05*G0_5_5_1 - 2.56885971171729e-05*G0_5_5_3 + 2.56885971171728e-05*G0_5_5_4; + A[4] = A[40]; + A[51] = A[25] - 4.43306693306769e-05*G0_0_0_0 + 7.43304314733006e-07*G0_0_0_1 + 1.16698777413083e-05*G0_0_0_2 - 1.48660862946604e-06*G0_0_0_3 - 3.28837828837886e-05*G0_0_0_4 + 7.43304314733009e-07*G0_0_1_0 + 2.33397554826171e-06*G0_0_1_1 + 1.59067123352864e-06*G0_0_1_2 - 3.80571809143302e-06*G0_0_1_3 - 2.08125208125244e-06*G0_0_1_4 - 1.48660862946599e-06*G0_0_1_5 + 1.16698777413083e-05*G0_0_2_0 + 1.59067123352864e-06*G0_0_2_1 - 3.94694591123229e-05*G0_0_2_2 - 4.04357547214758e-06*G0_0_2_3 - 1.58769801626971e-05*G0_0_2_4 + 1.48660862946603e-06*G0_0_2_5 - 1.48660862946604e-06*G0_0_3_0 - 3.80571809143302e-06*G0_0_3_1 - 4.04357547214758e-06*G0_0_3_2 + 7.61143618286606e-06*G0_0_3_3 + 7.13572142143693e-06*G0_0_3_4 - 3.28837828837886e-05*G0_0_4_0 - 2.08125208125244e-06*G0_0_4_1 - 1.58769801626971e-05*G0_0_4_2 + 7.13572142143693e-06*G0_0_4_3 - 2.78293135436041e-05*G0_0_4_4 + 1.1892869035728e-06*G0_0_4_5 - 1.486608629466e-06*G0_0_5_1 + 1.48660862946602e-06*G0_0_5_2 + 1.1892869035728e-06*G0_0_5_4 - 1.18928690357279e-06*G0_0_5_5 + 7.43304314733009e-07*G0_1_0_0 + 2.33397554826171e-06*G0_1_0_1 + 1.59067123352864e-06*G0_1_0_2 - 3.80571809143302e-06*G0_1_0_3 - 2.08125208125244e-06*G0_1_0_4 - 1.486608629466e-06*G0_1_0_5 + 2.33397554826171e-06*G0_1_1_0 - 1.84636791779689e-05*G0_1_1_1 + 2.76509205080683e-06*G0_1_1_2 - 9.33590219304675e-06*G0_1_1_3 + 2.14071642643105e-06*G0_1_1_4 - 7.84929356358082e-06*G0_1_1_5 + 1.59067123352864e-06*G0_1_2_0 + 2.76509205080683e-06*G0_1_2_1 - 2.23883259597583e-05*G0_1_2_2 - 5.53018410161359e-06*G0_1_2_3 - 2.14071642643108e-06*G0_1_2_4 - 3.80571809143302e-06*G0_1_3_0 - 9.33590219304675e-06*G0_1_3_1 - 5.53018410161358e-06*G0_1_3_2 + 1.8552875695736e-05*G0_1_3_3 + 3.33000333000393e-06*G0_1_3_4 + 7.61143618286602e-06*G0_1_3_5 - 2.08125208125244e-06*G0_1_4_0 + 2.14071642643105e-06*G0_1_4_1 - 2.14071642643108e-06*G0_1_4_2 + 3.33000333000393e-06*G0_1_4_3 - 4.56686170971961e-05*G0_1_4_4 - 4.28143285286212e-06*G0_1_4_5 - 1.48660862946599e-06*G0_1_5_0 - 7.84929356358082e-06*G0_1_5_1 + 7.61143618286602e-06*G0_1_5_3 - 4.28143285286211e-06*G0_1_5_4 + 1.1417154274299e-05*G0_1_5_5 + 1.16698777413083e-05*G0_2_0_0 + 1.59067123352864e-06*G0_2_0_1 - 3.94694591123229e-05*G0_2_0_2 - 4.04357547214758e-06*G0_2_0_3 - 1.58769801626971e-05*G0_2_0_4 + 1.48660862946603e-06*G0_2_0_5 + 1.59067123352864e-06*G0_2_1_0 + 2.76509205080683e-06*G0_2_1_1 - 2.23883259597583e-05*G0_2_1_2 - 5.53018410161359e-06*G0_2_1_3 - 2.14071642643108e-06*G0_2_1_4 - 3.94694591123229e-05*G0_2_2_0 - 2.23883259597583e-05*G0_2_2_1 + 0.000417707292707363*G0_2_2_2 + 9.10399124684993e-05*G0_2_2_3 + 0.000171614100185558*G0_2_2_4 + 7.84929356358066e-06*G0_2_2_5 - 4.04357547214758e-06*G0_2_3_0 - 5.53018410161359e-06*G0_2_3_1 + 9.10399124684993e-05*G0_2_3_2 + 1.11792968935845e-05*G0_2_3_3 + 1.23685837971573e-05*G0_2_3_4 - 7.61143618286603e-06*G0_2_3_5 - 1.58769801626971e-05*G0_2_4_0 - 2.14071642643108e-06*G0_2_4_1 + 0.000171614100185558*G0_2_4_2 + 1.23685837971573e-05*G0_2_4_3 + 4.56686170971962e-05*G0_2_4_4 - 1.1417154274299e-05*G0_2_4_5 + 1.48660862946602e-06*G0_2_5_0 + 7.84929356358066e-06*G0_2_5_2 - 7.61143618286603e-06*G0_2_5_3 - 1.1417154274299e-05*G0_2_5_4 + 4.28143285286214e-06*G0_2_5_5 - 1.48660862946604e-06*G0_3_0_0 - 3.80571809143302e-06*G0_3_0_1 - 4.04357547214758e-06*G0_3_0_2 + 7.61143618286606e-06*G0_3_0_3 + 7.13572142143693e-06*G0_3_0_4 - 3.80571809143302e-06*G0_3_1_0 - 9.33590219304675e-06*G0_3_1_1 - 5.53018410161358e-06*G0_3_1_2 + 1.8552875695736e-05*G0_3_1_3 + 3.33000333000392e-06*G0_3_1_4 + 7.61143618286602e-06*G0_3_1_5 - 4.04357547214758e-06*G0_3_2_0 - 5.53018410161359e-06*G0_3_2_1 + 9.10399124684993e-05*G0_3_2_2 + 1.11792968935845e-05*G0_3_2_3 + 1.23685837971573e-05*G0_3_2_4 - 7.61143618286603e-06*G0_3_2_5 + 7.61143618286607e-06*G0_3_3_0 + 1.8552875695736e-05*G0_3_3_1 + 1.11792968935845e-05*G0_3_3_2 - 3.71057513914721e-05*G0_3_3_3 - 2.188287902574e-05*G0_3_3_4 + 7.13572142143693e-06*G0_3_4_0 + 3.33000333000392e-06*G0_3_4_1 + 1.23685837971573e-05*G0_3_4_2 - 2.188287902574e-05*G0_3_4_3 + 7.70657913515185e-05*G0_3_4_4 + 8.56286570572423e-06*G0_3_4_5 + 7.61143618286602e-06*G0_3_5_1 - 7.61143618286603e-06*G0_3_5_2 + 8.56286570572423e-06*G0_3_5_4 - 8.56286570572429e-06*G0_3_5_5 - 3.28837828837886e-05*G0_4_0_0 - 2.08125208125244e-06*G0_4_0_1 - 1.58769801626971e-05*G0_4_0_2 + 7.13572142143693e-06*G0_4_0_3 - 2.78293135436041e-05*G0_4_0_4 + 1.1892869035728e-06*G0_4_0_5 - 2.08125208125244e-06*G0_4_1_0 + 2.14071642643105e-06*G0_4_1_1 - 2.14071642643108e-06*G0_4_1_2 + 3.33000333000393e-06*G0_4_1_3 - 4.56686170971961e-05*G0_4_1_4 - 4.28143285286211e-06*G0_4_1_5 - 1.58769801626971e-05*G0_4_2_0 - 2.14071642643108e-06*G0_4_2_1 + 0.000171614100185558*G0_4_2_2 + 1.23685837971573e-05*G0_4_2_3 + 4.56686170971962e-05*G0_4_2_4 - 1.1417154274299e-05*G0_4_2_5 + 7.13572142143693e-06*G0_4_3_0 + 3.33000333000393e-06*G0_4_3_1 + 1.23685837971573e-05*G0_4_3_2 - 2.188287902574e-05*G0_4_3_3 + 7.70657913515185e-05*G0_4_3_4 + 8.56286570572423e-06*G0_4_3_5 - 2.78293135436041e-05*G0_4_4_0 - 4.56686170971961e-05*G0_4_4_1 + 4.56686170971963e-05*G0_4_4_2 + 7.70657913515185e-05*G0_4_4_3 + 0.000810617953475232*G0_4_4_4 + 0.00011417154274299*G0_4_4_5 + 1.1892869035728e-06*G0_4_5_0 - 4.28143285286211e-06*G0_4_5_1 - 1.1417154274299e-05*G0_4_5_2 + 8.56286570572423e-06*G0_4_5_3 + 0.00011417154274299*G0_4_5_4 - 1.486608629466e-06*G0_5_0_1 + 1.48660862946602e-06*G0_5_0_2 + 1.18928690357281e-06*G0_5_0_4 - 1.1892869035728e-06*G0_5_0_5 - 1.486608629466e-06*G0_5_1_0 - 7.84929356358082e-06*G0_5_1_1 + 7.61143618286602e-06*G0_5_1_3 - 4.28143285286211e-06*G0_5_1_4 + 1.1417154274299e-05*G0_5_1_5 + 1.48660862946602e-06*G0_5_2_0 + 7.84929356358066e-06*G0_5_2_2 - 7.61143618286603e-06*G0_5_2_3 - 1.1417154274299e-05*G0_5_2_4 + 4.28143285286213e-06*G0_5_2_5 + 7.61143618286602e-06*G0_5_3_1 - 7.61143618286603e-06*G0_5_3_2 + 8.56286570572423e-06*G0_5_3_4 - 8.56286570572429e-06*G0_5_3_5 + 1.18928690357281e-06*G0_5_4_0 - 4.28143285286212e-06*G0_5_4_1 - 1.1417154274299e-05*G0_5_4_2 + 8.56286570572423e-06*G0_5_4_3 + 0.00011417154274299*G0_5_4_4 - 1.18928690357279e-06*G0_5_5_0 + 1.1417154274299e-05*G0_5_5_1 + 4.28143285286213e-06*G0_5_5_2 - 8.56286570572429e-06*G0_5_5_3 - 0.00011417154274299*G0_5_5_5; + A[15] = A[51]; + A[86] = A[25] + 5.74425574425668e-05*G0_0_0_0 - 1.64567575281888e-05*G0_0_0_1 + 8.91965177680538e-08*G0_0_0_2 - 1.51634080205534e-05*G0_0_0_3 - 1.37362637362663e-05*G0_0_0_4 + 3.78787878787942e-05*G0_0_0_5 - 1.64567575281888e-05*G0_0_1_0 + 1.94299747871209e-05*G0_0_1_1 - 2.82455639598543e-07*G0_0_1_2 - 2.61643118786019e-06*G0_0_1_3 - 2.40830597973495e-05*G0_0_1_4 + 1.01089386803689e-06*G0_0_1_5 + 8.91965177680606e-08*G0_0_2_0 - 2.82455639598541e-07*G0_0_2_1 - 2.78590457161934e-05*G0_0_2_2 - 1.14171542742991e-05*G0_0_2_3 - 1.07035821321555e-05*G0_0_2_4 - 2.69373483659244e-05*G0_0_2_5 - 1.51634080205534e-05*G0_0_3_0 - 2.61643118786019e-06*G0_0_3_1 - 1.14171542742991e-05*G0_0_3_2 + 7.75415061129478e-05*G0_0_3_3 + 7.8492935635806e-05*G0_0_3_4 + 8.42015127729555e-05*G0_0_3_5 - 1.37362637362663e-05*G0_0_4_0 - 2.40830597973495e-05*G0_0_4_1 - 1.07035821321555e-05*G0_0_4_2 + 7.8492935635806e-05*G0_0_4_3 + 0.00012772941344372*G0_0_4_4 + 0.000102040816326548*G0_0_4_5 + 3.78787878787942e-05*G0_0_5_0 + 1.01089386803689e-06*G0_0_5_1 - 2.69373483659244e-05*G0_0_5_2 + 8.42015127729555e-05*G0_0_5_3 + 0.000102040816326548*G0_0_5_4 + 0.000229294515008839*G0_0_5_5 - 1.64567575281888e-05*G0_1_0_0 + 1.94299747871209e-05*G0_1_0_1 - 2.82455639598543e-07*G0_1_0_2 - 2.61643118786019e-06*G0_1_0_3 - 2.40830597973495e-05*G0_1_0_4 + 1.01089386803689e-06*G0_1_0_5 + 1.94299747871209e-05*G0_1_1_0 - 4.40630797773728e-05*G0_1_1_1 + 7.68576661433934e-06*G0_1_1_2 - 3.88896817468311e-05*G0_1_1_3 - 1.83150183150214e-05*G0_1_1_4 - 6.11293468436427e-05*G0_1_1_5 - 2.82455639598543e-07*G0_1_2_0 + 7.68576661433934e-06*G0_1_2_1 - 2.25518529089996e-05*G0_1_2_2 + 5.53018410161359e-06*G0_1_2_3 + 6.89786404072232e-06*G0_1_2_4 + 1.76014461728777e-05*G0_1_2_5 - 2.61643118786019e-06*G0_1_3_0 - 3.88896817468311e-05*G0_1_3_1 + 5.5301841016136e-06*G0_1_3_2 + 7.84929356358055e-06*G0_1_3_3 + 4.18628990057631e-05*G0_1_3_4 - 2.9970029970035e-05*G0_1_3_5 - 2.40830597973495e-05*G0_1_4_0 - 1.83150183150214e-05*G0_1_4_1 + 6.89786404072232e-06*G0_1_4_2 + 4.18628990057632e-05*G0_1_4_3 + 8.42015127729554e-05*G0_1_4_4 + 1.42714428428737e-06*G0_1_4_5 + 1.01089386803689e-06*G0_1_5_0 - 6.11293468436427e-05*G0_1_5_1 + 1.76014461728777e-05*G0_1_5_2 - 2.9970029970035e-05*G0_1_5_3 + 1.42714428428737e-06*G0_1_5_4 - 0.000129156557728008*G0_1_5_5 + 8.91965177680538e-08*G0_2_0_0 - 2.82455639598542e-07*G0_2_0_1 - 2.78590457161934e-05*G0_2_0_2 - 1.14171542742991e-05*G0_2_0_3 - 1.07035821321555e-05*G0_2_0_4 - 2.69373483659243e-05*G0_2_0_5 - 2.82455639598542e-07*G0_2_1_0 + 7.68576661433934e-06*G0_2_1_1 - 2.25518529089996e-05*G0_2_1_2 + 5.53018410161359e-06*G0_2_1_3 + 6.89786404072232e-06*G0_2_1_4 + 1.76014461728777e-05*G0_2_1_5 - 2.78590457161934e-05*G0_2_2_0 - 2.25518529089996e-05*G0_2_2_1 + 0.000414585414585484*G0_2_2_2 + 7.32600732600858e-05*G0_2_2_3 + 0.000129037629037651*G0_2_2_4 - 1.04657247514407e-05*G0_2_2_5 - 1.14171542742991e-05*G0_2_3_0 + 5.53018410161359e-06*G0_2_3_1 + 7.32600732600858e-05*G0_2_3_2 + 4.75714761429129e-05*G0_2_3_3 + 9.03858046715359e-06*G0_2_3_4 + 4.37657580514798e-05*G0_2_3_5 - 1.07035821321554e-05*G0_2_4_0 + 6.89786404072231e-06*G0_2_4_1 + 0.000129037629037651*G0_2_4_2 + 9.03858046715359e-06*G0_2_4_3 - 7.13572142143102e-07*G0_2_4_4 + 7.13572142143702e-06*G0_2_4_5 - 2.69373483659244e-05*G0_2_5_0 + 1.76014461728777e-05*G0_2_5_1 - 1.04657247514407e-05*G0_2_5_2 + 4.37657580514798e-05*G0_2_5_3 + 7.13572142143702e-06*G0_2_5_4 + 0.000104181532752979*G0_2_5_5 - 1.51634080205534e-05*G0_3_0_0 - 2.61643118786019e-06*G0_3_0_1 - 1.14171542742991e-05*G0_3_0_2 + 7.75415061129478e-05*G0_3_0_3 + 7.8492935635806e-05*G0_3_0_4 + 8.42015127729556e-05*G0_3_0_5 - 2.61643118786019e-06*G0_3_1_0 - 3.88896817468311e-05*G0_3_1_1 + 5.5301841016136e-06*G0_3_1_2 + 7.84929356358054e-06*G0_3_1_3 + 4.18628990057631e-05*G0_3_1_4 - 2.9970029970035e-05*G0_3_1_5 - 1.14171542742991e-05*G0_3_2_0 + 5.53018410161359e-06*G0_3_2_1 + 7.32600732600858e-05*G0_3_2_2 + 4.75714761429129e-05*G0_3_2_3 + 9.03858046715359e-06*G0_3_2_4 + 4.37657580514798e-05*G0_3_2_5 + 7.75415061129477e-05*G0_3_3_0 + 7.84929356358055e-06*G0_3_3_1 + 4.75714761429129e-05*G0_3_3_2 - 0.000322534608248948*G0_3_3_3 - 0.000238808810237422*G0_3_3_4 - 0.000242614528328855*G0_3_3_5 + 7.8492935635806e-05*G0_3_4_0 + 4.18628990057632e-05*G0_3_4_1 + 9.03858046715358e-06*G0_3_4_2 - 0.000238808810237422*G0_3_4_3 - 0.000325388896817523*G0_3_4_4 - 0.000171257314114486*G0_3_4_5 + 8.42015127729555e-05*G0_3_5_0 - 2.9970029970035e-05*G0_3_5_1 + 4.37657580514798e-05*G0_3_5_2 - 0.000242614528328855*G0_3_5_3 - 0.000171257314114486*G0_3_5_4 - 0.000376766091051869*G0_3_5_5 - 1.37362637362663e-05*G0_4_0_0 - 2.40830597973495e-05*G0_4_0_1 - 1.07035821321555e-05*G0_4_0_2 + 7.8492935635806e-05*G0_4_0_3 + 0.00012772941344372*G0_4_0_4 + 0.000102040816326548*G0_4_0_5 - 2.40830597973495e-05*G0_4_1_0 - 1.83150183150214e-05*G0_4_1_1 + 6.89786404072232e-06*G0_4_1_2 + 4.18628990057632e-05*G0_4_1_3 + 8.42015127729554e-05*G0_4_1_4 + 1.42714428428736e-06*G0_4_1_5 - 1.07035821321554e-05*G0_4_2_0 + 6.89786404072232e-06*G0_4_2_1 + 0.000129037629037651*G0_4_2_2 + 9.03858046715358e-06*G0_4_2_3 - 7.13572142143102e-07*G0_4_2_4 + 7.13572142143701e-06*G0_4_2_5 + 7.8492935635806e-05*G0_4_3_0 + 4.18628990057631e-05*G0_4_3_1 + 9.03858046715358e-06*G0_4_3_2 - 0.000238808810237422*G0_4_3_3 - 0.000325388896817523*G0_4_3_4 - 0.000171257314114486*G0_4_3_5 + 0.00012772941344372*G0_4_4_0 + 8.42015127729554e-05*G0_4_4_1 - 7.13572142143075e-07*G0_4_4_2 - 0.000325388896817523*G0_4_4_3 - 0.000742115027829437*G0_4_4_4 - 0.000182674468388785*G0_4_4_5 + 0.000102040816326548*G0_4_5_0 + 1.42714428428736e-06*G0_4_5_1 + 7.13572142143701e-06*G0_4_5_2 - 0.000171257314114486*G0_4_5_3 - 0.000182674468388785*G0_4_5_4 - 0.000211217354074533*G0_4_5_5 + 3.78787878787942e-05*G0_5_0_0 + 1.01089386803688e-06*G0_5_0_1 - 2.69373483659244e-05*G0_5_0_2 + 8.42015127729555e-05*G0_5_0_3 + 0.000102040816326548*G0_5_0_4 + 0.000229294515008839*G0_5_0_5 + 1.01089386803689e-06*G0_5_1_0 - 6.11293468436427e-05*G0_5_1_1 + 1.76014461728777e-05*G0_5_1_2 - 2.9970029970035e-05*G0_5_1_3 + 1.42714428428737e-06*G0_5_1_4 - 0.000129156557728008*G0_5_1_5 - 2.69373483659244e-05*G0_5_2_0 + 1.76014461728777e-05*G0_5_2_1 - 1.04657247514407e-05*G0_5_2_2 + 4.37657580514798e-05*G0_5_2_3 + 7.135721421437e-06*G0_5_2_4 + 0.000104181532752979*G0_5_2_5 + 8.42015127729555e-05*G0_5_3_0 - 2.9970029970035e-05*G0_5_3_1 + 4.37657580514798e-05*G0_5_3_2 - 0.000242614528328855*G0_5_3_3 - 0.000171257314114486*G0_5_3_4 - 0.000376766091051869*G0_5_3_5 + 0.000102040816326548*G0_5_4_0 + 1.42714428428737e-06*G0_5_4_1 + 7.135721421437e-06*G0_5_4_2 - 0.000171257314114486*G0_5_4_3 - 0.000182674468388785*G0_5_4_4 - 0.000211217354074533*G0_5_4_5 + 0.000229294515008839*G0_5_5_0 - 0.000129156557728008*G0_5_5_1 + 0.000104181532752979*G0_5_5_2 - 0.000376766091051869*G0_5_5_3 - 0.000211217354074533*G0_5_5_4 - 0.00115313258170421*G0_5_5_5; + A[41] = A[40] + 1.84636791779679e-05*G0_0_0_0 - 2.76509205080679e-06*G0_0_0_1 - 2.33397554826166e-06*G0_0_0_2 - 2.14071642643107e-06*G0_0_0_3 + 7.84929356358061e-06*G0_0_0_4 + 9.3359021930466e-06*G0_0_0_5 - 2.76509205080679e-06*G0_0_1_0 + 2.23883259597583e-05*G0_0_1_1 - 1.59067123352865e-06*G0_0_1_2 + 2.14071642643108e-06*G0_0_1_3 + 5.53018410161361e-06*G0_0_1_5 - 2.33397554826166e-06*G0_0_2_0 - 1.59067123352865e-06*G0_0_2_1 - 7.43304314733009e-07*G0_0_2_2 + 2.08125208125243e-06*G0_0_2_3 + 1.48660862946602e-06*G0_0_2_4 + 3.80571809143303e-06*G0_0_2_5 - 2.14071642643107e-06*G0_0_3_0 + 2.14071642643108e-06*G0_0_3_1 + 2.08125208125243e-06*G0_0_3_2 + 4.56686170971962e-05*G0_0_3_3 + 4.28143285286216e-06*G0_0_3_4 - 3.3300033300039e-06*G0_0_3_5 + 7.84929356358061e-06*G0_0_4_0 + 1.48660862946602e-06*G0_0_4_2 + 4.28143285286216e-06*G0_0_4_3 - 1.1417154274299e-05*G0_0_4_4 - 7.61143618286606e-06*G0_0_4_5 + 9.33590219304659e-06*G0_0_5_0 + 5.53018410161361e-06*G0_0_5_1 + 3.80571809143303e-06*G0_0_5_2 - 3.3300033300039e-06*G0_0_5_3 - 7.61143618286606e-06*G0_0_5_4 - 1.8552875695736e-05*G0_0_5_5 - 2.76509205080679e-06*G0_1_0_0 + 2.23883259597583e-05*G0_1_0_1 - 1.59067123352865e-06*G0_1_0_2 + 2.14071642643108e-06*G0_1_0_3 + 5.53018410161361e-06*G0_1_0_5 + 2.23883259597583e-05*G0_1_1_0 - 0.000417707292707363*G0_1_1_1 + 3.9469459112323e-05*G0_1_1_2 - 0.000171614100185558*G0_1_1_3 - 7.84929356358056e-06*G0_1_1_4 - 9.10399124684994e-05*G0_1_1_5 - 1.59067123352865e-06*G0_1_2_0 + 3.9469459112323e-05*G0_1_2_1 - 1.16698777413083e-05*G0_1_2_2 + 1.58769801626971e-05*G0_1_2_3 - 1.48660862946602e-06*G0_1_2_4 + 4.0435754721476e-06*G0_1_2_5 + 2.14071642643108e-06*G0_1_3_0 - 0.000171614100185558*G0_1_3_1 + 1.58769801626971e-05*G0_1_3_2 - 4.56686170971964e-05*G0_1_3_3 + 1.14171542742991e-05*G0_1_3_4 - 1.23685837971574e-05*G0_1_3_5 - 7.84929356358056e-06*G0_1_4_1 - 1.48660862946602e-06*G0_1_4_2 + 1.14171542742991e-05*G0_1_4_3 - 4.28143285286215e-06*G0_1_4_4 + 7.61143618286605e-06*G0_1_4_5 + 5.53018410161361e-06*G0_1_5_0 - 9.10399124684994e-05*G0_1_5_1 + 4.0435754721476e-06*G0_1_5_2 - 1.23685837971574e-05*G0_1_5_3 + 7.61143618286604e-06*G0_1_5_4 - 1.11792968935845e-05*G0_1_5_5 - 2.33397554826166e-06*G0_2_0_0 - 1.59067123352865e-06*G0_2_0_1 - 7.43304314733009e-07*G0_2_0_2 + 2.08125208125243e-06*G0_2_0_3 + 1.48660862946602e-06*G0_2_0_4 + 3.80571809143303e-06*G0_2_0_5 - 1.59067123352865e-06*G0_2_1_0 + 3.9469459112323e-05*G0_2_1_1 - 1.16698777413083e-05*G0_2_1_2 + 1.58769801626971e-05*G0_2_1_3 - 1.48660862946602e-06*G0_2_1_4 + 4.0435754721476e-06*G0_2_1_5 - 7.43304314733009e-07*G0_2_2_0 - 1.16698777413083e-05*G0_2_2_1 + 4.43306693306769e-05*G0_2_2_2 + 3.28837828837885e-05*G0_2_2_3 + 1.48660862946603e-06*G0_2_2_5 + 2.08125208125243e-06*G0_2_3_0 + 1.58769801626971e-05*G0_2_3_1 + 3.28837828837885e-05*G0_2_3_2 + 2.78293135436041e-05*G0_2_3_3 - 1.18928690357282e-06*G0_2_3_4 - 7.1357214214369e-06*G0_2_3_5 + 1.48660862946602e-06*G0_2_4_0 - 1.48660862946602e-06*G0_2_4_1 - 1.18928690357282e-06*G0_2_4_3 + 1.1892869035728e-06*G0_2_4_4 + 3.80571809143303e-06*G0_2_5_0 + 4.0435754721476e-06*G0_2_5_1 + 1.48660862946603e-06*G0_2_5_2 - 7.1357214214369e-06*G0_2_5_3 - 7.61143618286607e-06*G0_2_5_5 - 2.14071642643107e-06*G0_3_0_0 + 2.14071642643108e-06*G0_3_0_1 + 2.08125208125243e-06*G0_3_0_2 + 4.56686170971962e-05*G0_3_0_3 + 4.28143285286216e-06*G0_3_0_4 - 3.3300033300039e-06*G0_3_0_5 + 2.14071642643108e-06*G0_3_1_0 - 0.000171614100185558*G0_3_1_1 + 1.58769801626972e-05*G0_3_1_2 - 4.56686170971965e-05*G0_3_1_3 + 1.14171542742991e-05*G0_3_1_4 - 1.23685837971574e-05*G0_3_1_5 + 2.08125208125243e-06*G0_3_2_0 + 1.58769801626972e-05*G0_3_2_1 + 3.28837828837885e-05*G0_3_2_2 + 2.78293135436041e-05*G0_3_2_3 - 1.18928690357282e-06*G0_3_2_4 - 7.1357214214369e-06*G0_3_2_5 + 4.56686170971962e-05*G0_3_3_0 - 4.56686170971965e-05*G0_3_3_1 + 2.78293135436041e-05*G0_3_3_2 - 0.000810617953475233*G0_3_3_3 - 0.000114171542742991*G0_3_3_4 - 7.70657913515187e-05*G0_3_3_5 + 4.28143285286216e-06*G0_3_4_0 + 1.14171542742991e-05*G0_3_4_1 - 1.18928690357282e-06*G0_3_4_2 - 0.000114171542742991*G0_3_4_3 - 8.56286570572429e-06*G0_3_4_5 - 3.3300033300039e-06*G0_3_5_0 - 1.23685837971574e-05*G0_3_5_1 - 7.1357214214369e-06*G0_3_5_2 - 7.70657913515187e-05*G0_3_5_3 - 8.5628657057243e-06*G0_3_5_4 + 2.18828790257399e-05*G0_3_5_5 + 7.84929356358061e-06*G0_4_0_0 + 1.48660862946602e-06*G0_4_0_2 + 4.28143285286216e-06*G0_4_0_3 - 1.1417154274299e-05*G0_4_0_4 - 7.61143618286605e-06*G0_4_0_5 - 7.84929356358056e-06*G0_4_1_1 - 1.48660862946602e-06*G0_4_1_2 + 1.14171542742991e-05*G0_4_1_3 - 4.28143285286215e-06*G0_4_1_4 + 7.61143618286605e-06*G0_4_1_5 + 1.48660862946602e-06*G0_4_2_0 - 1.48660862946602e-06*G0_4_2_1 - 1.18928690357282e-06*G0_4_2_3 + 1.18928690357279e-06*G0_4_2_4 + 4.28143285286216e-06*G0_4_3_0 + 1.14171542742991e-05*G0_4_3_1 - 1.18928690357282e-06*G0_4_3_2 - 0.000114171542742991*G0_4_3_3 - 8.56286570572431e-06*G0_4_3_5 - 1.1417154274299e-05*G0_4_4_0 - 4.28143285286215e-06*G0_4_4_1 + 1.1892869035728e-06*G0_4_4_2 + 0.000114171542742991*G0_4_4_4 + 8.56286570572431e-06*G0_4_4_5 - 7.61143618286605e-06*G0_4_5_0 + 7.61143618286604e-06*G0_4_5_1 - 8.56286570572431e-06*G0_4_5_3 + 8.56286570572431e-06*G0_4_5_4 + 9.33590219304659e-06*G0_5_0_0 + 5.53018410161361e-06*G0_5_0_1 + 3.80571809143303e-06*G0_5_0_2 - 3.3300033300039e-06*G0_5_0_3 - 7.61143618286605e-06*G0_5_0_4 - 1.8552875695736e-05*G0_5_0_5 + 5.53018410161361e-06*G0_5_1_0 - 9.10399124684994e-05*G0_5_1_1 + 4.0435754721476e-06*G0_5_1_2 - 1.23685837971574e-05*G0_5_1_3 + 7.61143618286604e-06*G0_5_1_4 - 1.11792968935845e-05*G0_5_1_5 + 3.80571809143303e-06*G0_5_2_0 + 4.0435754721476e-06*G0_5_2_1 + 1.48660862946603e-06*G0_5_2_2 - 7.1357214214369e-06*G0_5_2_3 - 7.61143618286607e-06*G0_5_2_5 - 3.3300033300039e-06*G0_5_3_0 - 1.23685837971574e-05*G0_5_3_1 - 7.1357214214369e-06*G0_5_3_2 - 7.70657913515187e-05*G0_5_3_3 - 8.56286570572431e-06*G0_5_3_4 + 2.18828790257399e-05*G0_5_3_5 - 7.61143618286605e-06*G0_5_4_0 + 7.61143618286605e-06*G0_5_4_1 - 8.56286570572429e-06*G0_5_4_3 + 8.56286570572432e-06*G0_5_4_4 - 1.8552875695736e-05*G0_5_5_0 - 1.11792968935845e-05*G0_5_5_1 - 7.61143618286607e-06*G0_5_5_2 + 2.18828790257399e-05*G0_5_5_3 + 3.71057513914722e-05*G0_5_5_5; + A[32] = -A[41] - 1.30226915941224e-05*G0_0_0_0 + 3.12187812187862e-07*G0_0_0_1 + 3.12187812187867e-07*G0_0_0_2 + 9.87108129965439e-06*G0_0_0_3 + 2.6164311878602e-06*G0_0_0_4 + 2.61643118786021e-06*G0_0_0_5 + 3.12187812187862e-07*G0_0_1_0 + 1.21158603301481e-05*G0_0_1_1 + 2.97321725893203e-07*G0_0_1_2 + 4.3408971980408e-06*G0_0_1_3 + 9.63322391893983e-06*G0_0_1_4 + 5.76804148232818e-06*G0_0_1_5 + 3.12187812187866e-07*G0_0_2_0 + 2.97321725893203e-07*G0_0_2_1 + 1.21158603301481e-05*G0_0_2_2 + 4.34089719804079e-06*G0_0_2_3 + 5.76804148232818e-06*G0_0_2_4 + 9.63322391893984e-06*G0_0_2_5 + 9.87108129965439e-06*G0_0_3_0 + 4.3408971980408e-06*G0_0_3_1 + 4.34089719804079e-06*G0_0_3_2 - 2.71157414014603e-05*G0_0_3_3 - 3.90086104371884e-05*G0_0_3_4 - 3.90086104371885e-05*G0_0_3_5 + 2.61643118786019e-06*G0_0_4_0 + 9.63322391893983e-06*G0_0_4_1 + 5.76804148232818e-06*G0_0_4_2 - 3.90086104371884e-05*G0_0_4_3 - 6.49350649350759e-05*G0_0_4_4 - 3.85328956757593e-05*G0_0_4_5 + 2.6164311878602e-06*G0_0_5_0 + 5.76804148232819e-06*G0_0_5_1 + 9.63322391893984e-06*G0_0_5_2 - 3.90086104371885e-05*G0_0_5_3 - 3.85328956757594e-05*G0_0_5_4 - 6.49350649350759e-05*G0_0_5_5 + 3.12187812187862e-07*G0_1_0_0 + 1.21158603301481e-05*G0_1_0_1 + 2.97321725893203e-07*G0_1_0_2 + 4.3408971980408e-06*G0_1_0_3 + 9.63322391893983e-06*G0_1_0_4 + 5.76804148232818e-06*G0_1_0_5 + 1.21158603301481e-05*G0_1_1_0 - 0.000325924075924131*G0_1_1_1 + 2.05449312592205e-05*G0_1_1_2 - 7.7838827838841e-05*G0_1_1_3 + 6.36268493411462e-06*G0_1_1_4 - 5.86913086913187e-05*G0_1_1_5 + 2.97321725893203e-07*G0_1_2_0 + 2.05449312592205e-05*G0_1_2_1 + 2.05449312592204e-05*G0_1_2_2 - 4.45982588839807e-06*G0_1_2_4 - 4.45982588839805e-06*G0_1_2_5 + 4.3408971980408e-06*G0_1_3_0 - 7.7838827838841e-05*G0_1_3_1 - 1.35578707007302e-05*G0_1_3_3 - 2.14071642643107e-05*G0_1_3_4 + 2.37857380714498e-07*G0_1_3_5 + 9.63322391893983e-06*G0_1_4_0 + 6.36268493411462e-06*G0_1_4_1 - 4.45982588839807e-06*G0_1_4_2 - 2.14071642643107e-05*G0_1_4_3 - 4.04357547214758e-05*G0_1_4_4 - 3.80571809143301e-06*G0_1_4_5 + 5.76804148232819e-06*G0_1_5_0 - 5.86913086913187e-05*G0_1_5_1 - 4.45982588839805e-06*G0_1_5_2 + 2.37857380714492e-07*G0_1_5_3 - 3.80571809143301e-06*G0_1_5_4 + 1.42714428428734e-06*G0_1_5_5 + 3.12187812187866e-07*G0_2_0_0 + 2.97321725893203e-07*G0_2_0_1 + 1.21158603301481e-05*G0_2_0_2 + 4.34089719804079e-06*G0_2_0_3 + 5.76804148232818e-06*G0_2_0_4 + 9.63322391893984e-06*G0_2_0_5 + 2.97321725893203e-07*G0_2_1_0 + 2.05449312592205e-05*G0_2_1_1 + 2.05449312592204e-05*G0_2_1_2 - 4.45982588839807e-06*G0_2_1_4 - 4.45982588839805e-06*G0_2_1_5 + 1.21158603301481e-05*G0_2_2_0 + 2.05449312592204e-05*G0_2_2_1 - 0.00032592407592413*G0_2_2_2 - 7.78388278388409e-05*G0_2_2_3 - 5.86913086913185e-05*G0_2_2_4 + 6.36268493411453e-06*G0_2_2_5 + 4.34089719804079e-06*G0_2_3_0 - 7.78388278388409e-05*G0_2_3_2 - 1.35578707007301e-05*G0_2_3_3 + 2.37857380714546e-07*G0_2_3_4 - 2.14071642643108e-05*G0_2_3_5 + 5.76804148232818e-06*G0_2_4_0 - 4.45982588839807e-06*G0_2_4_1 - 5.86913086913185e-05*G0_2_4_2 + 2.37857380714553e-07*G0_2_4_3 + 1.42714428428737e-06*G0_2_4_4 - 3.80571809143304e-06*G0_2_4_5 + 9.63322391893984e-06*G0_2_5_0 - 4.45982588839805e-06*G0_2_5_1 + 6.36268493411453e-06*G0_2_5_2 - 2.14071642643108e-05*G0_2_5_3 - 3.80571809143304e-06*G0_2_5_4 - 4.04357547214759e-05*G0_2_5_5 + 9.87108129965439e-06*G0_3_0_0 + 4.3408971980408e-06*G0_3_0_1 + 4.3408971980408e-06*G0_3_0_2 - 2.71157414014603e-05*G0_3_0_3 - 3.90086104371884e-05*G0_3_0_4 - 3.90086104371885e-05*G0_3_0_5 + 4.3408971980408e-06*G0_3_1_0 - 7.7838827838841e-05*G0_3_1_1 - 1.35578707007302e-05*G0_3_1_3 - 2.14071642643107e-05*G0_3_1_4 + 2.37857380714492e-07*G0_3_1_5 + 4.34089719804079e-06*G0_3_2_0 - 7.78388278388408e-05*G0_3_2_2 - 1.35578707007301e-05*G0_3_2_3 + 2.37857380714553e-07*G0_3_2_4 - 2.14071642643108e-05*G0_3_2_5 - 2.71157414014603e-05*G0_3_3_0 - 1.35578707007302e-05*G0_3_3_1 - 1.35578707007301e-05*G0_3_3_2 - 0.000399600399600467*G0_3_3_3 + 9.70458113315419e-05*G0_3_3_4 + 9.70458113315419e-05*G0_3_3_5 - 3.90086104371884e-05*G0_3_4_0 - 2.14071642643107e-05*G0_3_4_1 + 2.37857380714553e-07*G0_3_4_2 + 9.70458113315419e-05*G0_3_4_3 + 0.000158888730317329*G0_3_4_4 + 8.56286570572429e-05*G0_3_4_5 - 3.90086104371885e-05*G0_3_5_0 + 2.37857380714478e-07*G0_3_5_1 - 2.14071642643108e-05*G0_3_5_2 + 9.70458113315419e-05*G0_3_5_3 + 8.56286570572429e-05*G0_3_5_4 + 0.000158888730317329*G0_3_5_5 + 2.61643118786019e-06*G0_4_0_0 + 9.63322391893983e-06*G0_4_0_1 + 5.76804148232818e-06*G0_4_0_2 - 3.90086104371884e-05*G0_4_0_3 - 6.49350649350759e-05*G0_4_0_4 - 3.85328956757593e-05*G0_4_0_5 + 9.63322391893983e-06*G0_4_1_0 + 6.36268493411462e-06*G0_4_1_1 - 4.45982588839807e-06*G0_4_1_2 - 2.14071642643107e-05*G0_4_1_3 - 4.04357547214758e-05*G0_4_1_4 - 3.80571809143301e-06*G0_4_1_5 + 5.76804148232818e-06*G0_4_2_0 - 4.45982588839807e-06*G0_4_2_1 - 5.86913086913185e-05*G0_4_2_2 + 2.37857380714553e-07*G0_4_2_3 + 1.42714428428737e-06*G0_4_2_4 - 3.80571809143304e-06*G0_4_2_5 - 3.90086104371884e-05*G0_4_3_0 - 2.14071642643107e-05*G0_4_3_1 + 2.37857380714553e-07*G0_4_3_2 + 9.70458113315419e-05*G0_4_3_3 + 0.000158888730317328*G0_4_3_4 + 8.56286570572429e-05*G0_4_3_5 - 6.49350649350759e-05*G0_4_4_0 - 4.04357547214758e-05*G0_4_4_1 + 1.42714428428737e-06*G0_4_4_2 + 0.000158888730317328*G0_4_4_3 + 0.000311117453974649*G0_4_4_4 + 8.84829456258177e-05*G0_4_4_5 - 3.85328956757593e-05*G0_4_5_0 - 3.80571809143301e-06*G0_4_5_1 - 3.80571809143304e-06*G0_4_5_2 + 8.5628657057243e-05*G0_4_5_3 + 8.84829456258177e-05*G0_4_5_4 + 8.84829456258177e-05*G0_4_5_5 + 2.6164311878602e-06*G0_5_0_0 + 5.76804148232818e-06*G0_5_0_1 + 9.63322391893984e-06*G0_5_0_2 - 3.90086104371885e-05*G0_5_0_3 - 3.85328956757593e-05*G0_5_0_4 - 6.49350649350759e-05*G0_5_0_5 + 5.76804148232818e-06*G0_5_1_0 - 5.86913086913187e-05*G0_5_1_1 - 4.45982588839805e-06*G0_5_1_2 + 2.37857380714505e-07*G0_5_1_3 - 3.80571809143301e-06*G0_5_1_4 + 1.42714428428736e-06*G0_5_1_5 + 9.63322391893984e-06*G0_5_2_0 - 4.45982588839805e-06*G0_5_2_1 + 6.36268493411453e-06*G0_5_2_2 - 2.14071642643108e-05*G0_5_2_3 - 3.80571809143304e-06*G0_5_2_4 - 4.04357547214759e-05*G0_5_2_5 - 3.90086104371885e-05*G0_5_3_0 + 2.37857380714492e-07*G0_5_3_1 - 2.14071642643108e-05*G0_5_3_2 + 9.7045811331542e-05*G0_5_3_3 + 8.56286570572429e-05*G0_5_3_4 + 0.000158888730317329*G0_5_3_5 - 3.85328956757593e-05*G0_5_4_0 - 3.80571809143301e-06*G0_5_4_1 - 3.80571809143304e-06*G0_5_4_2 + 8.5628657057243e-05*G0_5_4_3 + 8.84829456258177e-05*G0_5_4_4 + 8.84829456258178e-05*G0_5_4_5 - 6.49350649350759e-05*G0_5_5_0 + 1.42714428428734e-06*G0_5_5_1 - 4.04357547214759e-05*G0_5_5_2 + 0.000158888730317329*G0_5_5_3 + 8.84829456258178e-05*G0_5_5_4 + 0.00031111745397465*G0_5_5_5; + A[35] = A[60] + 0.000414585414585485*G0_0_0_0 - 2.25518529089995e-05*G0_0_0_1 - 2.78590457161933e-05*G0_0_0_2 - 1.04657247514408e-05*G0_0_0_3 + 0.000129037629037651*G0_0_0_4 + 7.32600732600855e-05*G0_0_0_5 - 2.25518529089995e-05*G0_0_1_0 + 7.68576661433935e-06*G0_0_1_1 - 2.8245563959855e-07*G0_0_1_2 + 1.76014461728777e-05*G0_0_1_3 + 6.89786404072237e-06*G0_0_1_4 + 5.53018410161365e-06*G0_0_1_5 - 2.78590457161933e-05*G0_0_2_0 - 2.8245563959855e-07*G0_0_2_1 + 8.91965177679793e-08*G0_0_2_2 - 2.69373483659243e-05*G0_0_2_3 - 1.07035821321554e-05*G0_0_2_4 - 1.14171542742991e-05*G0_0_2_5 - 1.04657247514408e-05*G0_0_3_0 + 1.76014461728777e-05*G0_0_3_1 - 2.69373483659243e-05*G0_0_3_2 + 0.000104181532752979*G0_0_3_3 + 7.13572142143686e-06*G0_0_3_4 + 4.37657580514797e-05*G0_0_3_5 + 0.000129037629037651*G0_0_4_0 + 6.89786404072236e-06*G0_0_4_1 - 1.07035821321554e-05*G0_0_4_2 + 7.13572142143686e-06*G0_0_4_3 - 7.13572142143482e-07*G0_0_4_4 + 9.03858046715333e-06*G0_0_4_5 + 7.32600732600854e-05*G0_0_5_0 + 5.53018410161365e-06*G0_0_5_1 - 1.14171542742991e-05*G0_0_5_2 + 4.37657580514797e-05*G0_0_5_3 + 9.03858046715334e-06*G0_0_5_4 + 4.75714761429127e-05*G0_0_5_5 - 2.25518529089995e-05*G0_1_0_0 + 7.68576661433935e-06*G0_1_0_1 - 2.8245563959855e-07*G0_1_0_2 + 1.76014461728777e-05*G0_1_0_3 + 6.89786404072237e-06*G0_1_0_4 + 5.53018410161364e-06*G0_1_0_5 + 7.68576661433935e-06*G0_1_1_0 - 4.40630797773732e-05*G0_1_1_1 + 1.94299747871209e-05*G0_1_1_2 - 6.1129346843643e-05*G0_1_1_3 - 1.83150183150214e-05*G0_1_1_4 - 3.88896817468313e-05*G0_1_1_5 - 2.8245563959855e-07*G0_1_2_0 + 1.94299747871209e-05*G0_1_2_1 - 1.64567575281889e-05*G0_1_2_2 + 1.0108938680369e-06*G0_1_2_3 - 2.40830597973496e-05*G0_1_2_4 - 2.61643118786021e-06*G0_1_2_5 + 1.76014461728777e-05*G0_1_3_0 - 6.1129346843643e-05*G0_1_3_1 + 1.0108938680369e-06*G0_1_3_2 - 0.000129156557728008*G0_1_3_3 + 1.42714428428735e-06*G0_1_3_4 - 2.99700299700351e-05*G0_1_3_5 + 6.89786404072237e-06*G0_1_4_0 - 1.83150183150214e-05*G0_1_4_1 - 2.40830597973496e-05*G0_1_4_2 + 1.42714428428735e-06*G0_1_4_3 + 8.42015127729555e-05*G0_1_4_4 + 4.18628990057632e-05*G0_1_4_5 + 5.53018410161364e-06*G0_1_5_0 - 3.88896817468313e-05*G0_1_5_1 - 2.61643118786021e-06*G0_1_5_2 - 2.99700299700351e-05*G0_1_5_3 + 4.18628990057632e-05*G0_1_5_4 + 7.84929356358056e-06*G0_1_5_5 - 2.78590457161933e-05*G0_2_0_0 - 2.82455639598549e-07*G0_2_0_1 + 8.91965177679793e-08*G0_2_0_2 - 2.69373483659243e-05*G0_2_0_3 - 1.07035821321554e-05*G0_2_0_4 - 1.14171542742991e-05*G0_2_0_5 - 2.8245563959855e-07*G0_2_1_0 + 1.94299747871209e-05*G0_2_1_1 - 1.64567575281889e-05*G0_2_1_2 + 1.0108938680369e-06*G0_2_1_3 - 2.40830597973496e-05*G0_2_1_4 - 2.61643118786021e-06*G0_2_1_5 + 8.91965177679725e-08*G0_2_2_0 - 1.64567575281889e-05*G0_2_2_1 + 5.7442557442567e-05*G0_2_2_2 + 3.78787878787943e-05*G0_2_2_3 - 1.37362637362661e-05*G0_2_2_4 - 1.51634080205534e-05*G0_2_2_5 - 2.69373483659243e-05*G0_2_3_0 + 1.0108938680369e-06*G0_2_3_1 + 3.78787878787943e-05*G0_2_3_2 + 0.00022929451500884*G0_2_3_3 + 0.000102040816326548*G0_2_3_4 + 8.42015127729555e-05*G0_2_3_5 - 1.07035821321554e-05*G0_2_4_0 - 2.40830597973496e-05*G0_2_4_1 - 1.37362637362661e-05*G0_2_4_2 + 0.000102040816326548*G0_2_4_3 + 0.000127729413443721*G0_2_4_4 + 7.8492935635806e-05*G0_2_4_5 - 1.14171542742991e-05*G0_2_5_0 - 2.61643118786021e-06*G0_2_5_1 - 1.51634080205534e-05*G0_2_5_2 + 8.42015127729555e-05*G0_2_5_3 + 7.84929356358061e-05*G0_2_5_4 + 7.75415061129479e-05*G0_2_5_5 - 1.04657247514408e-05*G0_3_0_0 + 1.76014461728777e-05*G0_3_0_1 - 2.69373483659243e-05*G0_3_0_2 + 0.000104181532752979*G0_3_0_3 + 7.13572142143686e-06*G0_3_0_4 + 4.37657580514797e-05*G0_3_0_5 + 1.76014461728777e-05*G0_3_1_0 - 6.1129346843643e-05*G0_3_1_1 + 1.01089386803691e-06*G0_3_1_2 - 0.000129156557728008*G0_3_1_3 + 1.42714428428735e-06*G0_3_1_4 - 2.99700299700351e-05*G0_3_1_5 - 2.69373483659243e-05*G0_3_2_0 + 1.0108938680369e-06*G0_3_2_1 + 3.78787878787943e-05*G0_3_2_2 + 0.00022929451500884*G0_3_2_3 + 0.000102040816326548*G0_3_2_4 + 8.42015127729555e-05*G0_3_2_5 + 0.000104181532752979*G0_3_3_0 - 0.000129156557728008*G0_3_3_1 + 0.00022929451500884*G0_3_3_2 - 0.0011531325817042*G0_3_3_3 - 0.000211217354074532*G0_3_3_4 - 0.000376766091051869*G0_3_3_5 + 7.13572142143686e-06*G0_3_4_0 + 1.42714428428734e-06*G0_3_4_1 + 0.000102040816326548*G0_3_4_2 - 0.000211217354074532*G0_3_4_3 - 0.000182674468388785*G0_3_4_4 - 0.000171257314114486*G0_3_4_5 + 4.37657580514797e-05*G0_3_5_0 - 2.99700299700351e-05*G0_3_5_1 + 8.42015127729555e-05*G0_3_5_2 - 0.000376766091051869*G0_3_5_3 - 0.000171257314114486*G0_3_5_4 - 0.000242614528328855*G0_3_5_5 + 0.000129037629037651*G0_4_0_0 + 6.89786404072237e-06*G0_4_0_1 - 1.07035821321554e-05*G0_4_0_2 + 7.13572142143686e-06*G0_4_0_3 - 7.13572142143509e-07*G0_4_0_4 + 9.03858046715334e-06*G0_4_0_5 + 6.89786404072238e-06*G0_4_1_0 - 1.83150183150214e-05*G0_4_1_1 - 2.40830597973496e-05*G0_4_1_2 + 1.42714428428734e-06*G0_4_1_3 + 8.42015127729555e-05*G0_4_1_4 + 4.18628990057632e-05*G0_4_1_5 - 1.07035821321554e-05*G0_4_2_0 - 2.40830597973496e-05*G0_4_2_1 - 1.37362637362661e-05*G0_4_2_2 + 0.000102040816326548*G0_4_2_3 + 0.000127729413443721*G0_4_2_4 + 7.8492935635806e-05*G0_4_2_5 + 7.13572142143686e-06*G0_4_3_0 + 1.42714428428734e-06*G0_4_3_1 + 0.000102040816326548*G0_4_3_2 - 0.000211217354074532*G0_4_3_3 - 0.000182674468388785*G0_4_3_4 - 0.000171257314114486*G0_4_3_5 - 7.13572142143482e-07*G0_4_4_0 + 8.42015127729555e-05*G0_4_4_1 + 0.000127729413443721*G0_4_4_2 - 0.000182674468388785*G0_4_4_3 - 0.000742115027829438*G0_4_4_4 - 0.000325388896817523*G0_4_4_5 + 9.03858046715334e-06*G0_4_5_0 + 4.18628990057632e-05*G0_4_5_1 + 7.8492935635806e-05*G0_4_5_2 - 0.000171257314114486*G0_4_5_3 - 0.000325388896817523*G0_4_5_4 - 0.000238808810237422*G0_4_5_5 + 7.32600732600854e-05*G0_5_0_0 + 5.53018410161364e-06*G0_5_0_1 - 1.14171542742991e-05*G0_5_0_2 + 4.37657580514797e-05*G0_5_0_3 + 9.03858046715335e-06*G0_5_0_4 + 4.75714761429127e-05*G0_5_0_5 + 5.53018410161364e-06*G0_5_1_0 - 3.88896817468313e-05*G0_5_1_1 - 2.61643118786021e-06*G0_5_1_2 - 2.99700299700351e-05*G0_5_1_3 + 4.18628990057632e-05*G0_5_1_4 + 7.84929356358056e-06*G0_5_1_5 - 1.14171542742991e-05*G0_5_2_0 - 2.61643118786021e-06*G0_5_2_1 - 1.51634080205534e-05*G0_5_2_2 + 8.42015127729555e-05*G0_5_2_3 + 7.84929356358061e-05*G0_5_2_4 + 7.75415061129479e-05*G0_5_2_5 + 4.37657580514797e-05*G0_5_3_0 - 2.99700299700351e-05*G0_5_3_1 + 8.42015127729555e-05*G0_5_3_2 - 0.000376766091051869*G0_5_3_3 - 0.000171257314114486*G0_5_3_4 - 0.000242614528328855*G0_5_3_5 + 9.03858046715334e-06*G0_5_4_0 + 4.18628990057632e-05*G0_5_4_1 + 7.8492935635806e-05*G0_5_4_2 - 0.000171257314114486*G0_5_4_3 - 0.000325388896817523*G0_5_4_4 - 0.000238808810237422*G0_5_4_5 + 4.75714761429127e-05*G0_5_5_0 + 7.84929356358056e-06*G0_5_5_1 + 7.75415061129478e-05*G0_5_5_2 - 0.000242614528328855*G0_5_5_3 - 0.000238808810237422*G0_5_5_4 - 0.000322534608248949*G0_5_5_5; + A[61] = A[16]; + A[74] = A[32] - 4.40630797773727e-05*G0_0_0_0 + 1.94299747871209e-05*G0_0_0_1 + 7.68576661433933e-06*G0_0_0_2 - 1.83150183150214e-05*G0_0_0_3 - 3.88896817468312e-05*G0_0_0_4 - 6.11293468436427e-05*G0_0_0_5 + 1.94299747871209e-05*G0_0_1_0 - 1.64567575281889e-05*G0_0_1_1 - 2.82455639598553e-07*G0_0_1_2 - 2.40830597973496e-05*G0_0_1_3 - 2.61643118786022e-06*G0_0_1_4 + 1.01089386803685e-06*G0_0_1_5 + 7.68576661433933e-06*G0_0_2_0 - 2.82455639598553e-07*G0_0_2_1 - 2.25518529089995e-05*G0_0_2_2 + 6.89786404072237e-06*G0_0_2_3 + 5.53018410161365e-06*G0_0_2_4 + 1.76014461728777e-05*G0_0_2_5 - 1.83150183150214e-05*G0_0_3_0 - 2.40830597973496e-05*G0_0_3_1 + 6.89786404072237e-06*G0_0_3_2 + 8.42015127729556e-05*G0_0_3_3 + 4.18628990057633e-05*G0_0_3_4 + 1.42714428428742e-06*G0_0_3_5 - 3.88896817468312e-05*G0_0_4_0 - 2.61643118786022e-06*G0_0_4_1 + 5.53018410161365e-06*G0_0_4_2 + 4.18628990057633e-05*G0_0_4_3 + 7.84929356358068e-06*G0_0_4_4 - 2.9970029970035e-05*G0_0_4_5 - 6.11293468436427e-05*G0_0_5_0 + 1.01089386803685e-06*G0_0_5_1 + 1.76014461728777e-05*G0_0_5_2 + 1.42714428428742e-06*G0_0_5_3 - 2.9970029970035e-05*G0_0_5_4 - 0.000129156557728008*G0_0_5_5 + 1.94299747871209e-05*G0_1_0_0 - 1.64567575281889e-05*G0_1_0_1 - 2.82455639598553e-07*G0_1_0_2 - 2.40830597973496e-05*G0_1_0_3 - 2.61643118786022e-06*G0_1_0_4 + 1.01089386803685e-06*G0_1_0_5 - 1.64567575281889e-05*G0_1_1_0 + 5.74425574425672e-05*G0_1_1_1 + 8.91965177679521e-08*G0_1_1_2 - 1.37362637362661e-05*G0_1_1_3 - 1.51634080205535e-05*G0_1_1_4 + 3.78787878787942e-05*G0_1_1_5 - 2.82455639598554e-07*G0_1_2_0 + 8.91965177679589e-08*G0_1_2_1 - 2.78590457161932e-05*G0_1_2_2 - 1.07035821321553e-05*G0_1_2_3 - 1.1417154274299e-05*G0_1_2_4 - 2.69373483659243e-05*G0_1_2_5 - 2.40830597973496e-05*G0_1_3_0 - 1.37362637362661e-05*G0_1_3_1 - 1.07035821321553e-05*G0_1_3_2 + 0.000127729413443721*G0_1_3_3 + 7.84929356358061e-05*G0_1_3_4 + 0.000102040816326548*G0_1_3_5 - 2.61643118786022e-06*G0_1_4_0 - 1.51634080205535e-05*G0_1_4_1 - 1.1417154274299e-05*G0_1_4_2 + 7.84929356358061e-05*G0_1_4_3 + 7.75415061129479e-05*G0_1_4_4 + 8.42015127729556e-05*G0_1_4_5 + 1.01089386803685e-06*G0_1_5_0 + 3.78787878787942e-05*G0_1_5_1 - 2.69373483659243e-05*G0_1_5_2 + 0.000102040816326548*G0_1_5_3 + 8.42015127729555e-05*G0_1_5_4 + 0.000229294515008839*G0_1_5_5 + 7.68576661433933e-06*G0_2_0_0 - 2.82455639598553e-07*G0_2_0_1 - 2.25518529089995e-05*G0_2_0_2 + 6.89786404072238e-06*G0_2_0_3 + 5.53018410161365e-06*G0_2_0_4 + 1.76014461728777e-05*G0_2_0_5 - 2.82455639598553e-07*G0_2_1_0 + 8.91965177679589e-08*G0_2_1_1 - 2.78590457161932e-05*G0_2_1_2 - 1.07035821321553e-05*G0_2_1_3 - 1.1417154274299e-05*G0_2_1_4 - 2.69373483659243e-05*G0_2_1_5 - 2.25518529089995e-05*G0_2_2_0 - 2.78590457161932e-05*G0_2_2_1 + 0.000414585414585484*G0_2_2_2 + 0.000129037629037651*G0_2_2_3 + 7.32600732600853e-05*G0_2_2_4 - 1.04657247514408e-05*G0_2_2_5 + 6.89786404072238e-06*G0_2_3_0 - 1.07035821321553e-05*G0_2_3_1 + 0.000129037629037651*G0_2_3_2 - 7.1357214214378e-07*G0_2_3_3 + 9.03858046715331e-06*G0_2_3_4 + 7.13572142143692e-06*G0_2_3_5 + 5.53018410161365e-06*G0_2_4_0 - 1.1417154274299e-05*G0_2_4_1 + 7.32600732600853e-05*G0_2_4_2 + 9.03858046715331e-06*G0_2_4_3 + 4.75714761429126e-05*G0_2_4_4 + 4.37657580514797e-05*G0_2_4_5 + 1.76014461728777e-05*G0_2_5_0 - 2.69373483659243e-05*G0_2_5_1 - 1.04657247514408e-05*G0_2_5_2 + 7.13572142143692e-06*G0_2_5_3 + 4.37657580514797e-05*G0_2_5_4 + 0.000104181532752979*G0_2_5_5 - 1.83150183150214e-05*G0_3_0_0 - 2.40830597973496e-05*G0_3_0_1 + 6.89786404072237e-06*G0_3_0_2 + 8.42015127729556e-05*G0_3_0_3 + 4.18628990057633e-05*G0_3_0_4 + 1.42714428428742e-06*G0_3_0_5 - 2.40830597973496e-05*G0_3_1_0 - 1.37362637362661e-05*G0_3_1_1 - 1.07035821321553e-05*G0_3_1_2 + 0.000127729413443721*G0_3_1_3 + 7.84929356358061e-05*G0_3_1_4 + 0.000102040816326548*G0_3_1_5 + 6.89786404072237e-06*G0_3_2_0 - 1.07035821321553e-05*G0_3_2_1 + 0.000129037629037651*G0_3_2_2 - 7.1357214214378e-07*G0_3_2_3 + 9.03858046715331e-06*G0_3_2_4 + 7.13572142143692e-06*G0_3_2_5 + 8.42015127729556e-05*G0_3_3_0 + 0.000127729413443721*G0_3_3_1 - 7.13572142143753e-07*G0_3_3_2 - 0.00074211502782944*G0_3_3_3 - 0.000325388896817523*G0_3_3_4 - 0.000182674468388785*G0_3_3_5 + 4.18628990057633e-05*G0_3_4_0 + 7.84929356358061e-05*G0_3_4_1 + 9.03858046715331e-06*G0_3_4_2 - 0.000325388896817523*G0_3_4_3 - 0.000238808810237422*G0_3_4_4 - 0.000171257314114486*G0_3_4_5 + 1.42714428428743e-06*G0_3_5_0 + 0.000102040816326548*G0_3_5_1 + 7.13572142143692e-06*G0_3_5_2 - 0.000182674468388785*G0_3_5_3 - 0.000171257314114486*G0_3_5_4 - 0.000211217354074533*G0_3_5_5 - 3.88896817468312e-05*G0_4_0_0 - 2.61643118786022e-06*G0_4_0_1 + 5.53018410161365e-06*G0_4_0_2 + 4.18628990057633e-05*G0_4_0_3 + 7.84929356358067e-06*G0_4_0_4 - 2.9970029970035e-05*G0_4_0_5 - 2.61643118786022e-06*G0_4_1_0 - 1.51634080205535e-05*G0_4_1_1 - 1.1417154274299e-05*G0_4_1_2 + 7.84929356358061e-05*G0_4_1_3 + 7.75415061129479e-05*G0_4_1_4 + 8.42015127729556e-05*G0_4_1_5 + 5.53018410161365e-06*G0_4_2_0 - 1.1417154274299e-05*G0_4_2_1 + 7.32600732600853e-05*G0_4_2_2 + 9.03858046715331e-06*G0_4_2_3 + 4.75714761429126e-05*G0_4_2_4 + 4.37657580514797e-05*G0_4_2_5 + 4.18628990057633e-05*G0_4_3_0 + 7.84929356358061e-05*G0_4_3_1 + 9.03858046715331e-06*G0_4_3_2 - 0.000325388896817523*G0_4_3_3 - 0.000238808810237422*G0_4_3_4 - 0.000171257314114486*G0_4_3_5 + 7.84929356358068e-06*G0_4_4_0 + 7.75415061129479e-05*G0_4_4_1 + 4.75714761429126e-05*G0_4_4_2 - 0.000238808810237422*G0_4_4_3 - 0.000322534608248949*G0_4_4_4 - 0.000242614528328855*G0_4_4_5 - 2.9970029970035e-05*G0_4_5_0 + 8.42015127729556e-05*G0_4_5_1 + 4.37657580514797e-05*G0_4_5_2 - 0.000171257314114486*G0_4_5_3 - 0.000242614528328855*G0_4_5_4 - 0.000376766091051869*G0_4_5_5 - 6.11293468436427e-05*G0_5_0_0 + 1.01089386803685e-06*G0_5_0_1 + 1.76014461728777e-05*G0_5_0_2 + 1.42714428428743e-06*G0_5_0_3 - 2.9970029970035e-05*G0_5_0_4 - 0.000129156557728008*G0_5_0_5 + 1.01089386803685e-06*G0_5_1_0 + 3.78787878787942e-05*G0_5_1_1 - 2.69373483659243e-05*G0_5_1_2 + 0.000102040816326548*G0_5_1_3 + 8.42015127729555e-05*G0_5_1_4 + 0.000229294515008839*G0_5_1_5 + 1.76014461728777e-05*G0_5_2_0 - 2.69373483659243e-05*G0_5_2_1 - 1.04657247514408e-05*G0_5_2_2 + 7.13572142143693e-06*G0_5_2_3 + 4.37657580514797e-05*G0_5_2_4 + 0.000104181532752979*G0_5_2_5 + 1.42714428428743e-06*G0_5_3_0 + 0.000102040816326548*G0_5_3_1 + 7.13572142143692e-06*G0_5_3_2 - 0.000182674468388785*G0_5_3_3 - 0.000171257314114486*G0_5_3_4 - 0.000211217354074533*G0_5_3_5 - 2.9970029970035e-05*G0_5_4_0 + 8.42015127729555e-05*G0_5_4_1 + 4.37657580514797e-05*G0_5_4_2 - 0.000171257314114486*G0_5_4_3 - 0.000242614528328855*G0_5_4_4 - 0.000376766091051869*G0_5_4_5 - 0.000129156557728008*G0_5_5_0 + 0.000229294515008839*G0_5_5_1 + 0.000104181532752979*G0_5_5_2 - 0.000211217354074533*G0_5_5_3 - 0.000376766091051869*G0_5_5_4 - 0.0011531325817042*G0_5_5_5; + A[30] = A[32] - 1.84636791779687e-05*G0_0_0_0 + 2.33397554826169e-06*G0_0_0_1 + 2.76509205080682e-06*G0_0_0_2 + 2.14071642643106e-06*G0_0_0_3 - 9.33590219304672e-06*G0_0_0_4 - 7.84929356358077e-06*G0_0_0_5 + 2.33397554826169e-06*G0_0_1_0 + 7.43304314733001e-07*G0_0_1_1 + 1.59067123352864e-06*G0_0_1_2 - 2.08125208125245e-06*G0_0_1_3 - 3.80571809143302e-06*G0_0_1_4 - 1.48660862946602e-06*G0_0_1_5 + 2.76509205080682e-06*G0_0_2_0 + 1.59067123352864e-06*G0_0_2_1 - 2.23883259597583e-05*G0_0_2_2 - 2.14071642643106e-06*G0_0_2_3 - 5.5301841016136e-06*G0_0_2_4 + 2.14071642643106e-06*G0_0_3_0 - 2.08125208125244e-06*G0_0_3_1 - 2.14071642643106e-06*G0_0_3_2 - 4.56686170971962e-05*G0_0_3_3 + 3.33000333000391e-06*G0_0_3_4 - 4.28143285286213e-06*G0_0_3_5 - 9.33590219304672e-06*G0_0_4_0 - 3.80571809143302e-06*G0_0_4_1 - 5.5301841016136e-06*G0_0_4_2 + 3.33000333000391e-06*G0_0_4_3 + 1.8552875695736e-05*G0_0_4_4 + 7.61143618286603e-06*G0_0_4_5 - 7.84929356358077e-06*G0_0_5_0 - 1.48660862946602e-06*G0_0_5_1 - 4.28143285286214e-06*G0_0_5_3 + 7.61143618286603e-06*G0_0_5_4 + 1.1417154274299e-05*G0_0_5_5 + 2.3339755482617e-06*G0_1_0_0 + 7.43304314733001e-07*G0_1_0_1 + 1.59067123352864e-06*G0_1_0_2 - 2.08125208125245e-06*G0_1_0_3 - 3.80571809143302e-06*G0_1_0_4 - 1.48660862946602e-06*G0_1_0_5 + 7.43304314733002e-07*G0_1_1_0 - 4.43306693306767e-05*G0_1_1_1 + 1.16698777413083e-05*G0_1_1_2 - 3.28837828837885e-05*G0_1_1_3 - 1.48660862946602e-06*G0_1_1_4 + 1.59067123352864e-06*G0_1_2_0 + 1.16698777413083e-05*G0_1_2_1 - 3.94694591123229e-05*G0_1_2_2 - 1.58769801626971e-05*G0_1_2_3 - 4.04357547214757e-06*G0_1_2_4 + 1.48660862946602e-06*G0_1_2_5 - 2.08125208125245e-06*G0_1_3_0 - 3.28837828837885e-05*G0_1_3_1 - 1.58769801626971e-05*G0_1_3_2 - 2.78293135436039e-05*G0_1_3_3 + 7.13572142143693e-06*G0_1_3_4 + 1.18928690357282e-06*G0_1_3_5 - 3.80571809143302e-06*G0_1_4_0 - 1.48660862946603e-06*G0_1_4_1 - 4.04357547214757e-06*G0_1_4_2 + 7.13572142143693e-06*G0_1_4_3 + 7.61143618286605e-06*G0_1_4_4 - 1.48660862946602e-06*G0_1_5_0 + 1.48660862946601e-06*G0_1_5_2 + 1.18928690357283e-06*G0_1_5_3 - 1.18928690357278e-06*G0_1_5_5 + 2.76509205080682e-06*G0_2_0_0 + 1.59067123352864e-06*G0_2_0_1 - 2.23883259597583e-05*G0_2_0_2 - 2.14071642643106e-06*G0_2_0_3 - 5.5301841016136e-06*G0_2_0_4 + 1.59067123352864e-06*G0_2_1_0 + 1.16698777413083e-05*G0_2_1_1 - 3.94694591123229e-05*G0_2_1_2 - 1.58769801626971e-05*G0_2_1_3 - 4.04357547214757e-06*G0_2_1_4 + 1.48660862946602e-06*G0_2_1_5 - 2.23883259597583e-05*G0_2_2_0 - 3.94694591123229e-05*G0_2_2_1 + 0.000417707292707363*G0_2_2_2 + 0.000171614100185558*G0_2_2_3 + 9.10399124684991e-05*G0_2_2_4 + 7.84929356358065e-06*G0_2_2_5 - 2.14071642643106e-06*G0_2_3_0 - 1.58769801626971e-05*G0_2_3_1 + 0.000171614100185558*G0_2_3_2 + 4.56686170971963e-05*G0_2_3_3 + 1.23685837971573e-05*G0_2_3_4 - 1.1417154274299e-05*G0_2_3_5 - 5.5301841016136e-06*G0_2_4_0 - 4.04357547214757e-06*G0_2_4_1 + 9.10399124684991e-05*G0_2_4_2 + 1.23685837971573e-05*G0_2_4_3 + 1.11792968935845e-05*G0_2_4_4 - 7.61143618286605e-06*G0_2_4_5 + 1.48660862946602e-06*G0_2_5_1 + 7.84929356358066e-06*G0_2_5_2 - 1.1417154274299e-05*G0_2_5_3 - 7.61143618286605e-06*G0_2_5_4 + 4.28143285286213e-06*G0_2_5_5 + 2.14071642643106e-06*G0_3_0_0 - 2.08125208125244e-06*G0_3_0_1 - 2.14071642643107e-06*G0_3_0_2 - 4.56686170971962e-05*G0_3_0_3 + 3.33000333000391e-06*G0_3_0_4 - 4.28143285286214e-06*G0_3_0_5 - 2.08125208125244e-06*G0_3_1_0 - 3.28837828837885e-05*G0_3_1_1 - 1.58769801626971e-05*G0_3_1_2 - 2.78293135436039e-05*G0_3_1_3 + 7.13572142143693e-06*G0_3_1_4 + 1.18928690357282e-06*G0_3_1_5 - 2.14071642643106e-06*G0_3_2_0 - 1.58769801626971e-05*G0_3_2_1 + 0.000171614100185558*G0_3_2_2 + 4.56686170971963e-05*G0_3_2_3 + 1.23685837971573e-05*G0_3_2_4 - 1.1417154274299e-05*G0_3_2_5 - 4.56686170971962e-05*G0_3_3_0 - 2.78293135436039e-05*G0_3_3_1 + 4.56686170971963e-05*G0_3_3_2 + 0.000810617953475234*G0_3_3_3 + 7.70657913515186e-05*G0_3_3_4 + 0.000114171542742991*G0_3_3_5 + 3.33000333000391e-06*G0_3_4_0 + 7.13572142143693e-06*G0_3_4_1 + 1.23685837971573e-05*G0_3_4_2 + 7.70657913515186e-05*G0_3_4_3 - 2.18828790257399e-05*G0_3_4_4 + 8.56286570572428e-06*G0_3_4_5 - 4.28143285286213e-06*G0_3_5_0 + 1.18928690357282e-06*G0_3_5_1 - 1.1417154274299e-05*G0_3_5_2 + 0.000114171542742991*G0_3_5_3 + 8.56286570572429e-06*G0_3_5_4 - 9.33590219304672e-06*G0_4_0_0 - 3.80571809143302e-06*G0_4_0_1 - 5.5301841016136e-06*G0_4_0_2 + 3.33000333000391e-06*G0_4_0_3 + 1.8552875695736e-05*G0_4_0_4 + 7.61143618286602e-06*G0_4_0_5 - 3.80571809143302e-06*G0_4_1_0 - 1.48660862946603e-06*G0_4_1_1 - 4.04357547214757e-06*G0_4_1_2 + 7.13572142143693e-06*G0_4_1_3 + 7.61143618286605e-06*G0_4_1_4 - 5.5301841016136e-06*G0_4_2_0 - 4.04357547214757e-06*G0_4_2_1 + 9.10399124684991e-05*G0_4_2_2 + 1.23685837971573e-05*G0_4_2_3 + 1.11792968935845e-05*G0_4_2_4 - 7.61143618286605e-06*G0_4_2_5 + 3.33000333000391e-06*G0_4_3_0 + 7.13572142143693e-06*G0_4_3_1 + 1.23685837971573e-05*G0_4_3_2 + 7.70657913515186e-05*G0_4_3_3 - 2.18828790257399e-05*G0_4_3_4 + 8.56286570572428e-06*G0_4_3_5 + 1.8552875695736e-05*G0_4_4_0 + 7.61143618286605e-06*G0_4_4_1 + 1.11792968935845e-05*G0_4_4_2 - 2.18828790257399e-05*G0_4_4_3 - 3.71057513914719e-05*G0_4_4_4 + 7.61143618286602e-06*G0_4_5_0 - 7.61143618286605e-06*G0_4_5_2 + 8.56286570572427e-06*G0_4_5_3 - 8.56286570572425e-06*G0_4_5_5 - 7.84929356358077e-06*G0_5_0_0 - 1.48660862946602e-06*G0_5_0_1 - 4.28143285286213e-06*G0_5_0_3 + 7.61143618286602e-06*G0_5_0_4 + 1.1417154274299e-05*G0_5_0_5 - 1.48660862946602e-06*G0_5_1_0 + 1.48660862946602e-06*G0_5_1_2 + 1.18928690357282e-06*G0_5_1_3 - 1.18928690357278e-06*G0_5_1_5 + 1.48660862946602e-06*G0_5_2_1 + 7.84929356358065e-06*G0_5_2_2 - 1.1417154274299e-05*G0_5_2_3 - 7.61143618286605e-06*G0_5_2_4 + 4.28143285286213e-06*G0_5_2_5 - 4.28143285286213e-06*G0_5_3_0 + 1.18928690357282e-06*G0_5_3_1 - 1.1417154274299e-05*G0_5_3_2 + 0.000114171542742991*G0_5_3_3 + 8.56286570572429e-06*G0_5_3_4 + 7.61143618286602e-06*G0_5_4_0 - 7.61143618286605e-06*G0_5_4_2 + 8.56286570572428e-06*G0_5_4_3 - 8.56286570572427e-06*G0_5_4_5 + 1.1417154274299e-05*G0_5_5_0 - 1.18928690357279e-06*G0_5_5_1 + 4.28143285286213e-06*G0_5_5_2 - 8.56286570572427e-06*G0_5_5_4 - 0.000114171542742991*G0_5_5_5; + A[82] = A[30] - 2.24775224775254e-05*G0_0_0_0 + 5.48558584272956e-06*G0_0_0_1 + 5.08420151277377e-06*G0_0_0_2 - 2.14071642643106e-06*G0_0_0_3 - 1.17739403453708e-05*G0_0_0_4 - 1.07035821321551e-05*G0_0_0_5 + 5.48558584272956e-06*G0_0_1_0 - 5.61938061938153e-06*G0_0_1_1 + 6.42214927929324e-06*G0_0_1_3 + 8.56286570572428e-06*G0_0_1_4 - 2.67589553303885e-06*G0_0_1_5 + 5.08420151277377e-06*G0_0_2_0 - 5.08420151277382e-06*G0_0_2_2 - 8.56286570572429e-06*G0_0_2_3 + 8.56286570572428e-06*G0_0_2_5 - 2.14071642643106e-06*G0_0_3_0 + 6.42214927929324e-06*G0_0_3_1 - 8.56286570572429e-06*G0_0_3_2 + 2.9970029970035e-05*G0_0_3_3 - 1.28442985585864e-05*G0_0_3_4 - 1.28442985585865e-05*G0_0_3_5 - 1.17739403453708e-05*G0_0_4_0 + 8.56286570572428e-06*G0_0_4_1 - 1.28442985585864e-05*G0_0_4_3 - 4.70957613814836e-05*G0_0_4_4 - 3.42514628228971e-05*G0_0_4_5 - 1.07035821321551e-05*G0_0_5_0 - 2.67589553303885e-06*G0_0_5_1 + 8.56286570572428e-06*G0_0_5_2 - 1.28442985585865e-05*G0_0_5_3 - 3.42514628228971e-05*G0_0_5_4 - 9.41915227629671e-05*G0_0_5_5 + 5.48558584272956e-06*G0_1_0_0 - 5.61938061938154e-06*G0_1_0_1 + 6.42214927929324e-06*G0_1_0_3 + 8.56286570572428e-06*G0_1_0_4 - 2.67589553303884e-06*G0_1_0_5 - 5.61938061938154e-06*G0_1_1_0 + 5.6193806193816e-06*G0_1_1_2 - 1.8731268731272e-05*G0_1_1_3 + 1.87312687312718e-05*G0_1_1_5 + 5.61938061938159e-06*G0_1_2_1 - 5.48558584272965e-06*G0_1_2_2 + 2.67589553303887e-06*G0_1_2_3 - 8.56286570572429e-06*G0_1_2_4 - 6.4221492792932e-06*G0_1_2_5 + 6.42214927929324e-06*G0_1_3_0 - 1.8731268731272e-05*G0_1_3_1 + 2.67589553303887e-06*G0_1_3_2 - 7.49250749250878e-05*G0_1_3_3 - 1.28442985585864e-05*G0_1_3_4 + 8.56286570572428e-06*G0_1_4_0 - 8.56286570572429e-06*G0_1_4_2 - 1.28442985585864e-05*G0_1_4_3 + 1.28442985585864e-05*G0_1_4_5 - 2.67589553303884e-06*G0_1_5_0 + 1.87312687312718e-05*G0_1_5_1 - 6.4221492792932e-06*G0_1_5_2 + 1.28442985585864e-05*G0_1_5_4 + 7.49250749250874e-05*G0_1_5_5 + 5.08420151277377e-06*G0_2_0_0 - 5.08420151277381e-06*G0_2_0_2 - 8.56286570572429e-06*G0_2_0_3 + 8.56286570572428e-06*G0_2_0_5 + 5.6193806193816e-06*G0_2_1_1 - 5.48558584272964e-06*G0_2_1_2 + 2.67589553303887e-06*G0_2_1_3 - 8.56286570572429e-06*G0_2_1_4 - 6.4221492792932e-06*G0_2_1_5 - 5.08420151277382e-06*G0_2_2_0 - 5.48558584272964e-06*G0_2_2_1 + 2.24775224775265e-05*G0_2_2_2 + 1.07035821321554e-05*G0_2_2_3 + 1.1773940345371e-05*G0_2_2_4 + 2.14071642643108e-06*G0_2_2_5 - 8.5628657057243e-06*G0_2_3_0 + 2.67589553303887e-06*G0_2_3_1 + 1.07035821321554e-05*G0_2_3_2 + 9.41915227629673e-05*G0_2_3_3 + 3.42514628228972e-05*G0_2_3_4 + 1.28442985585864e-05*G0_2_3_5 - 8.56286570572429e-06*G0_2_4_1 + 1.1773940345371e-05*G0_2_4_2 + 3.42514628228972e-05*G0_2_4_3 + 4.70957613814836e-05*G0_2_4_4 + 1.28442985585864e-05*G0_2_4_5 + 8.56286570572428e-06*G0_2_5_0 - 6.4221492792932e-06*G0_2_5_1 + 2.14071642643108e-06*G0_2_5_2 + 1.28442985585864e-05*G0_2_5_3 + 1.28442985585864e-05*G0_2_5_4 - 2.9970029970035e-05*G0_2_5_5 - 2.14071642643106e-06*G0_3_0_0 + 6.42214927929324e-06*G0_3_0_1 - 8.56286570572429e-06*G0_3_0_2 + 2.9970029970035e-05*G0_3_0_3 - 1.28442985585864e-05*G0_3_0_4 - 1.28442985585865e-05*G0_3_0_5 + 6.42214927929324e-06*G0_3_1_0 - 1.8731268731272e-05*G0_3_1_1 + 2.67589553303887e-06*G0_3_1_2 - 7.49250749250877e-05*G0_3_1_3 - 1.28442985585864e-05*G0_3_1_4 - 8.56286570572429e-06*G0_3_2_0 + 2.67589553303887e-06*G0_3_2_1 + 1.07035821321554e-05*G0_3_2_2 + 9.41915227629673e-05*G0_3_2_3 + 3.42514628228972e-05*G0_3_2_4 + 1.28442985585864e-05*G0_3_2_5 + 2.9970029970035e-05*G0_3_3_0 - 7.49250749250878e-05*G0_3_3_1 + 9.41915227629673e-05*G0_3_3_2 - 0.000513771942343458*G0_3_3_3 - 3.42514628228972e-05*G0_3_3_4 - 8.56286570572428e-05*G0_3_3_5 - 1.28442985585864e-05*G0_3_4_0 - 1.28442985585864e-05*G0_3_4_1 + 3.42514628228972e-05*G0_3_4_2 - 3.42514628228972e-05*G0_3_4_3 + 2.56885971171729e-05*G0_3_4_4 - 1.28442985585865e-05*G0_3_5_0 + 1.28442985585864e-05*G0_3_5_2 - 8.56286570572428e-05*G0_3_5_3 + 8.56286570572431e-05*G0_3_5_5 - 1.17739403453708e-05*G0_4_0_0 + 8.56286570572429e-06*G0_4_0_1 - 1.28442985585864e-05*G0_4_0_3 - 4.70957613814836e-05*G0_4_0_4 - 3.42514628228971e-05*G0_4_0_5 + 8.56286570572428e-06*G0_4_1_0 - 8.56286570572429e-06*G0_4_1_2 - 1.28442985585864e-05*G0_4_1_3 + 1.28442985585864e-05*G0_4_1_5 - 8.56286570572429e-06*G0_4_2_1 + 1.1773940345371e-05*G0_4_2_2 + 3.42514628228972e-05*G0_4_2_3 + 4.70957613814836e-05*G0_4_2_4 + 1.28442985585864e-05*G0_4_2_5 - 1.28442985585864e-05*G0_4_3_0 - 1.28442985585864e-05*G0_4_3_1 + 3.42514628228972e-05*G0_4_3_2 - 3.42514628228972e-05*G0_4_3_3 + 2.56885971171729e-05*G0_4_3_4 - 4.70957613814836e-05*G0_4_4_0 + 4.70957613814836e-05*G0_4_4_2 + 2.56885971171729e-05*G0_4_4_3 - 2.56885971171729e-05*G0_4_4_5 - 3.42514628228971e-05*G0_4_5_0 + 1.28442985585864e-05*G0_4_5_1 + 1.28442985585864e-05*G0_4_5_2 - 2.56885971171728e-05*G0_4_5_4 + 3.42514628228972e-05*G0_4_5_5 - 1.07035821321551e-05*G0_5_0_0 - 2.67589553303884e-06*G0_5_0_1 + 8.56286570572428e-06*G0_5_0_2 - 1.28442985585865e-05*G0_5_0_3 - 3.42514628228971e-05*G0_5_0_4 - 9.41915227629671e-05*G0_5_0_5 - 2.67589553303884e-06*G0_5_1_0 + 1.87312687312718e-05*G0_5_1_1 - 6.4221492792932e-06*G0_5_1_2 + 1.28442985585864e-05*G0_5_1_4 + 7.49250749250873e-05*G0_5_1_5 + 8.56286570572428e-06*G0_5_2_0 - 6.42214927929321e-06*G0_5_2_1 + 2.14071642643108e-06*G0_5_2_2 + 1.28442985585864e-05*G0_5_2_3 + 1.28442985585864e-05*G0_5_2_4 - 2.9970029970035e-05*G0_5_2_5 - 1.28442985585865e-05*G0_5_3_0 + 1.28442985585864e-05*G0_5_3_2 - 8.56286570572428e-05*G0_5_3_3 + 8.56286570572431e-05*G0_5_3_5 - 3.42514628228971e-05*G0_5_4_0 + 1.28442985585864e-05*G0_5_4_1 + 1.28442985585864e-05*G0_5_4_2 - 2.56885971171729e-05*G0_5_4_4 + 3.42514628228972e-05*G0_5_4_5 - 9.41915227629671e-05*G0_5_5_0 + 7.49250749250874e-05*G0_5_5_1 - 2.9970029970035e-05*G0_5_5_2 + 8.56286570572431e-05*G0_5_5_3 + 3.42514628228972e-05*G0_5_5_4 + 0.000513771942343458*G0_5_5_5; + A[8] = A[82] - 0.000417707292707363*G0_0_0_0 + 3.94694591123229e-05*G0_0_0_1 + 2.23883259597583e-05*G0_0_0_2 - 7.84929356358055e-06*G0_0_0_3 - 9.10399124684992e-05*G0_0_0_4 - 0.000171614100185558*G0_0_0_5 + 3.94694591123229e-05*G0_0_1_0 - 1.16698777413083e-05*G0_0_1_1 - 1.59067123352864e-06*G0_0_1_2 - 1.48660862946604e-06*G0_0_1_3 + 4.04357547214758e-06*G0_0_1_4 + 1.58769801626971e-05*G0_0_1_5 + 2.23883259597583e-05*G0_0_2_0 - 1.59067123352864e-06*G0_0_2_1 - 2.76509205080679e-06*G0_0_2_2 + 5.53018410161361e-06*G0_0_2_4 + 2.14071642643107e-06*G0_0_2_5 - 7.84929356358055e-06*G0_0_3_0 - 1.48660862946604e-06*G0_0_3_1 - 4.28143285286217e-06*G0_0_3_3 + 7.61143618286602e-06*G0_0_3_4 + 1.14171542742991e-05*G0_0_3_5 - 9.10399124684992e-05*G0_0_4_0 + 4.04357547214758e-06*G0_0_4_1 + 5.53018410161361e-06*G0_0_4_2 + 7.61143618286602e-06*G0_0_4_3 - 1.11792968935845e-05*G0_0_4_4 - 1.23685837971573e-05*G0_0_4_5 - 0.000171614100185558*G0_0_5_0 + 1.58769801626971e-05*G0_0_5_1 + 2.14071642643107e-06*G0_0_5_2 + 1.14171542742991e-05*G0_0_5_3 - 1.23685837971573e-05*G0_0_5_4 - 4.56686170971962e-05*G0_0_5_5 + 3.94694591123229e-05*G0_1_0_0 - 1.16698777413083e-05*G0_1_0_1 - 1.59067123352864e-06*G0_1_0_2 - 1.48660862946604e-06*G0_1_0_3 + 4.04357547214758e-06*G0_1_0_4 + 1.58769801626971e-05*G0_1_0_5 - 1.16698777413083e-05*G0_1_1_0 + 4.43306693306771e-05*G0_1_1_1 - 7.43304314733018e-07*G0_1_1_2 + 1.48660862946602e-06*G0_1_1_4 + 3.28837828837886e-05*G0_1_1_5 - 1.59067123352864e-06*G0_1_2_0 - 7.43304314733016e-07*G0_1_2_1 - 2.33397554826164e-06*G0_1_2_2 + 1.48660862946603e-06*G0_1_2_3 + 3.80571809143302e-06*G0_1_2_4 + 2.08125208125242e-06*G0_1_2_5 - 1.48660862946604e-06*G0_1_3_0 + 1.48660862946602e-06*G0_1_3_2 + 1.18928690357282e-06*G0_1_3_3 - 1.18928690357278e-06*G0_1_3_5 + 4.04357547214758e-06*G0_1_4_0 + 1.48660862946602e-06*G0_1_4_1 + 3.80571809143302e-06*G0_1_4_2 - 7.61143618286605e-06*G0_1_4_4 - 7.1357214214369e-06*G0_1_4_5 + 1.58769801626971e-05*G0_1_5_0 + 3.28837828837886e-05*G0_1_5_1 + 2.08125208125242e-06*G0_1_5_2 - 1.1892869035728e-06*G0_1_5_3 - 7.1357214214369e-06*G0_1_5_4 + 2.78293135436042e-05*G0_1_5_5 + 2.23883259597583e-05*G0_2_0_0 - 1.59067123352864e-06*G0_2_0_1 - 2.76509205080679e-06*G0_2_0_2 + 5.53018410161361e-06*G0_2_0_4 + 2.14071642643107e-06*G0_2_0_5 - 1.59067123352864e-06*G0_2_1_0 - 7.43304314733016e-07*G0_2_1_1 - 2.33397554826164e-06*G0_2_1_2 + 1.48660862946603e-06*G0_2_1_3 + 3.80571809143302e-06*G0_2_1_4 + 2.08125208125243e-06*G0_2_1_5 - 2.76509205080678e-06*G0_2_2_0 - 2.33397554826164e-06*G0_2_2_1 + 1.84636791779677e-05*G0_2_2_2 + 7.84929356358055e-06*G0_2_2_3 + 9.33590219304656e-06*G0_2_2_4 - 2.14071642643108e-06*G0_2_2_5 + 1.48660862946603e-06*G0_2_3_1 + 7.84929356358054e-06*G0_2_3_2 - 1.14171542742991e-05*G0_2_3_3 - 7.61143618286605e-06*G0_2_3_4 + 4.28143285286215e-06*G0_2_3_5 + 5.53018410161361e-06*G0_2_4_0 + 3.80571809143302e-06*G0_2_4_1 + 9.33590219304656e-06*G0_2_4_2 - 7.61143618286605e-06*G0_2_4_3 - 1.8552875695736e-05*G0_2_4_4 - 3.33000333000388e-06*G0_2_4_5 + 2.14071642643107e-06*G0_2_5_0 + 2.08125208125242e-06*G0_2_5_1 - 2.14071642643108e-06*G0_2_5_2 + 4.28143285286215e-06*G0_2_5_3 - 3.33000333000388e-06*G0_2_5_4 + 4.56686170971962e-05*G0_2_5_5 - 7.84929356358055e-06*G0_3_0_0 - 1.48660862946604e-06*G0_3_0_1 - 4.28143285286217e-06*G0_3_0_3 + 7.61143618286603e-06*G0_3_0_4 + 1.14171542742991e-05*G0_3_0_5 - 1.48660862946604e-06*G0_3_1_0 + 1.48660862946602e-06*G0_3_1_2 + 1.18928690357282e-06*G0_3_1_3 - 1.1892869035728e-06*G0_3_1_5 + 1.48660862946603e-06*G0_3_2_1 + 7.84929356358054e-06*G0_3_2_2 - 1.14171542742991e-05*G0_3_2_3 - 7.61143618286605e-06*G0_3_2_4 + 4.28143285286215e-06*G0_3_2_5 - 4.28143285286217e-06*G0_3_3_0 + 1.18928690357282e-06*G0_3_3_1 - 1.14171542742991e-05*G0_3_3_2 + 0.000114171542742991*G0_3_3_3 + 8.56286570572438e-06*G0_3_3_4 + 7.61143618286602e-06*G0_3_4_0 - 7.61143618286605e-06*G0_3_4_2 + 8.56286570572438e-06*G0_3_4_3 - 8.56286570572429e-06*G0_3_4_5 + 1.14171542742991e-05*G0_3_5_0 - 1.18928690357278e-06*G0_3_5_1 + 4.28143285286215e-06*G0_3_5_2 - 8.56286570572429e-06*G0_3_5_4 - 0.000114171542742991*G0_3_5_5 - 9.10399124684992e-05*G0_4_0_0 + 4.04357547214758e-06*G0_4_0_1 + 5.53018410161361e-06*G0_4_0_2 + 7.61143618286602e-06*G0_4_0_3 - 1.11792968935845e-05*G0_4_0_4 - 1.23685837971573e-05*G0_4_0_5 + 4.04357547214758e-06*G0_4_1_0 + 1.48660862946602e-06*G0_4_1_1 + 3.80571809143302e-06*G0_4_1_2 - 7.61143618286605e-06*G0_4_1_4 - 7.1357214214369e-06*G0_4_1_5 + 5.53018410161361e-06*G0_4_2_0 + 3.80571809143302e-06*G0_4_2_1 + 9.33590219304656e-06*G0_4_2_2 - 7.61143618286606e-06*G0_4_2_3 - 1.8552875695736e-05*G0_4_2_4 - 3.33000333000389e-06*G0_4_2_5 + 7.61143618286602e-06*G0_4_3_0 - 7.61143618286605e-06*G0_4_3_2 + 8.56286570572438e-06*G0_4_3_3 - 8.56286570572429e-06*G0_4_3_5 - 1.11792968935844e-05*G0_4_4_0 - 7.61143618286605e-06*G0_4_4_1 - 1.8552875695736e-05*G0_4_4_2 + 3.7105751391472e-05*G0_4_4_4 + 2.18828790257399e-05*G0_4_4_5 - 1.23685837971573e-05*G0_4_5_0 - 7.1357214214369e-06*G0_4_5_1 - 3.33000333000388e-06*G0_4_5_2 - 8.56286570572428e-06*G0_4_5_3 + 2.18828790257399e-05*G0_4_5_4 - 7.70657913515187e-05*G0_4_5_5 - 0.000171614100185558*G0_5_0_0 + 1.58769801626971e-05*G0_5_0_1 + 2.14071642643107e-06*G0_5_0_2 + 1.14171542742991e-05*G0_5_0_3 - 1.23685837971573e-05*G0_5_0_4 - 4.56686170971961e-05*G0_5_0_5 + 1.58769801626971e-05*G0_5_1_0 + 3.28837828837886e-05*G0_5_1_1 + 2.08125208125242e-06*G0_5_1_2 - 1.1892869035728e-06*G0_5_1_3 - 7.1357214214369e-06*G0_5_1_4 + 2.78293135436042e-05*G0_5_1_5 + 2.14071642643107e-06*G0_5_2_0 + 2.08125208125243e-06*G0_5_2_1 - 2.14071642643108e-06*G0_5_2_2 + 4.28143285286215e-06*G0_5_2_3 - 3.33000333000389e-06*G0_5_2_4 + 4.56686170971962e-05*G0_5_2_5 + 1.14171542742991e-05*G0_5_3_0 - 1.1892869035728e-06*G0_5_3_1 + 4.28143285286215e-06*G0_5_3_2 - 8.56286570572429e-06*G0_5_3_4 - 0.000114171542742991*G0_5_3_5 - 1.23685837971573e-05*G0_5_4_0 - 7.13572142143691e-06*G0_5_4_1 - 3.33000333000388e-06*G0_5_4_2 - 8.56286570572429e-06*G0_5_4_3 + 2.18828790257399e-05*G0_5_4_4 - 7.70657913515187e-05*G0_5_4_5 - 4.56686170971961e-05*G0_5_5_0 + 2.78293135436042e-05*G0_5_5_1 + 4.56686170971962e-05*G0_5_5_2 - 0.000114171542742991*G0_5_5_3 - 7.70657913515187e-05*G0_5_5_4 - 0.000810617953475234*G0_5_5_5; + A[71] = -A[8] - 0.000325924075924131*G0_0_0_0 + 2.05449312592204e-05*G0_0_0_1 + 1.21158603301481e-05*G0_0_0_2 + 6.36268493411462e-06*G0_0_0_3 - 5.86913086913186e-05*G0_0_0_4 - 7.78388278388409e-05*G0_0_0_5 + 2.05449312592204e-05*G0_0_1_0 + 2.05449312592205e-05*G0_0_1_1 + 2.97321725893203e-07*G0_0_1_2 - 4.45982588839806e-06*G0_0_1_3 - 4.45982588839807e-06*G0_0_1_4 + 1.21158603301481e-05*G0_0_2_0 + 2.97321725893203e-07*G0_0_2_1 + 3.12187812187865e-07*G0_0_2_2 + 9.63322391893983e-06*G0_0_2_3 + 5.76804148232817e-06*G0_0_2_4 + 4.3408971980408e-06*G0_0_2_5 + 6.36268493411462e-06*G0_0_3_0 - 4.45982588839806e-06*G0_0_3_1 + 9.63322391893983e-06*G0_0_3_2 - 4.04357547214758e-05*G0_0_3_3 - 3.80571809143302e-06*G0_0_3_4 - 2.14071642643107e-05*G0_0_3_5 - 5.86913086913186e-05*G0_0_4_0 - 4.45982588839807e-06*G0_0_4_1 + 5.76804148232818e-06*G0_0_4_2 - 3.80571809143302e-06*G0_0_4_3 + 1.4271442842874e-06*G0_0_4_4 + 2.37857380714526e-07*G0_0_4_5 - 7.7838827838841e-05*G0_0_5_0 + 4.3408971980408e-06*G0_0_5_2 - 2.14071642643107e-05*G0_0_5_3 + 2.37857380714526e-07*G0_0_5_4 - 1.35578707007303e-05*G0_0_5_5 + 2.05449312592204e-05*G0_1_0_0 + 2.05449312592205e-05*G0_1_0_1 + 2.97321725893203e-07*G0_1_0_2 - 4.45982588839806e-06*G0_1_0_3 - 4.45982588839807e-06*G0_1_0_4 + 2.05449312592205e-05*G0_1_1_0 - 0.000325924075924132*G0_1_1_1 + 1.21158603301481e-05*G0_1_1_2 - 5.86913086913188e-05*G0_1_1_3 + 6.36268493411462e-06*G0_1_1_4 - 7.78388278388412e-05*G0_1_1_5 + 2.97321725893201e-07*G0_1_2_0 + 1.21158603301482e-05*G0_1_2_1 + 3.12187812187858e-07*G0_1_2_2 + 5.7680414823282e-06*G0_1_2_3 + 9.63322391893983e-06*G0_1_2_4 + 4.3408971980408e-06*G0_1_2_5 - 4.45982588839806e-06*G0_1_3_0 - 5.86913086913188e-05*G0_1_3_1 + 5.7680414823282e-06*G0_1_3_2 + 1.42714428428728e-06*G0_1_3_3 - 3.80571809143301e-06*G0_1_3_4 + 2.37857380714505e-07*G0_1_3_5 - 4.45982588839807e-06*G0_1_4_0 + 6.36268493411462e-06*G0_1_4_1 + 9.63322391893983e-06*G0_1_4_2 - 3.80571809143302e-06*G0_1_4_3 - 4.04357547214758e-05*G0_1_4_4 - 2.14071642643107e-05*G0_1_4_5 - 7.78388278388413e-05*G0_1_5_1 + 4.3408971980408e-06*G0_1_5_2 + 2.37857380714492e-07*G0_1_5_3 - 2.14071642643107e-05*G0_1_5_4 - 1.35578707007301e-05*G0_1_5_5 + 1.21158603301481e-05*G0_2_0_0 + 2.97321725893203e-07*G0_2_0_1 + 3.12187812187865e-07*G0_2_0_2 + 9.63322391893983e-06*G0_2_0_3 + 5.76804148232817e-06*G0_2_0_4 + 4.3408971980408e-06*G0_2_0_5 + 2.97321725893202e-07*G0_2_1_0 + 1.21158603301482e-05*G0_2_1_1 + 3.12187812187858e-07*G0_2_1_2 + 5.7680414823282e-06*G0_2_1_3 + 9.63322391893983e-06*G0_2_1_4 + 4.3408971980408e-06*G0_2_1_5 + 3.12187812187865e-07*G0_2_2_0 + 3.12187812187858e-07*G0_2_2_1 - 1.30226915941224e-05*G0_2_2_2 + 2.61643118786019e-06*G0_2_2_3 + 2.61643118786021e-06*G0_2_2_4 + 9.87108129965439e-06*G0_2_2_5 + 9.63322391893983e-06*G0_2_3_0 + 5.7680414823282e-06*G0_2_3_1 + 2.61643118786019e-06*G0_2_3_2 - 6.49350649350759e-05*G0_2_3_3 - 3.85328956757593e-05*G0_2_3_4 - 3.90086104371885e-05*G0_2_3_5 + 5.76804148232817e-06*G0_2_4_0 + 9.63322391893983e-06*G0_2_4_1 + 2.61643118786021e-06*G0_2_4_2 - 3.85328956757593e-05*G0_2_4_3 - 6.49350649350759e-05*G0_2_4_4 - 3.90086104371885e-05*G0_2_4_5 + 4.3408971980408e-06*G0_2_5_0 + 4.3408971980408e-06*G0_2_5_1 + 9.87108129965439e-06*G0_2_5_2 - 3.90086104371885e-05*G0_2_5_3 - 3.90086104371885e-05*G0_2_5_4 - 2.71157414014602e-05*G0_2_5_5 + 6.36268493411462e-06*G0_3_0_0 - 4.45982588839806e-06*G0_3_0_1 + 9.63322391893983e-06*G0_3_0_2 - 4.04357547214758e-05*G0_3_0_3 - 3.80571809143302e-06*G0_3_0_4 - 2.14071642643107e-05*G0_3_0_5 - 4.45982588839806e-06*G0_3_1_0 - 5.86913086913188e-05*G0_3_1_1 + 5.7680414823282e-06*G0_3_1_2 + 1.42714428428728e-06*G0_3_1_3 - 3.80571809143301e-06*G0_3_1_4 + 2.37857380714492e-07*G0_3_1_5 + 9.63322391893983e-06*G0_3_2_0 + 5.7680414823282e-06*G0_3_2_1 + 2.61643118786019e-06*G0_3_2_2 - 6.49350649350759e-05*G0_3_2_3 - 3.85328956757593e-05*G0_3_2_4 - 3.90086104371885e-05*G0_3_2_5 - 4.04357547214758e-05*G0_3_3_0 + 1.42714428428728e-06*G0_3_3_1 - 6.49350649350759e-05*G0_3_3_2 + 0.000311117453974649*G0_3_3_3 + 8.84829456258177e-05*G0_3_3_4 + 0.000158888730317329*G0_3_3_5 - 3.80571809143302e-06*G0_3_4_0 - 3.80571809143302e-06*G0_3_4_1 - 3.85328956757593e-05*G0_3_4_2 + 8.84829456258177e-05*G0_3_4_3 + 8.84829456258176e-05*G0_3_4_4 + 8.56286570572429e-05*G0_3_4_5 - 2.14071642643107e-05*G0_3_5_0 + 2.37857380714505e-07*G0_3_5_1 - 3.90086104371885e-05*G0_3_5_2 + 0.000158888730317329*G0_3_5_3 + 8.5628657057243e-05*G0_3_5_4 + 9.70458113315419e-05*G0_3_5_5 - 5.86913086913186e-05*G0_4_0_0 - 4.45982588839807e-06*G0_4_0_1 + 5.76804148232817e-06*G0_4_0_2 - 3.80571809143302e-06*G0_4_0_3 + 1.42714428428741e-06*G0_4_0_4 + 2.37857380714546e-07*G0_4_0_5 - 4.45982588839807e-06*G0_4_1_0 + 6.36268493411462e-06*G0_4_1_1 + 9.63322391893983e-06*G0_4_1_2 - 3.80571809143302e-06*G0_4_1_3 - 4.04357547214758e-05*G0_4_1_4 - 2.14071642643107e-05*G0_4_1_5 + 5.76804148232817e-06*G0_4_2_0 + 9.63322391893983e-06*G0_4_2_1 + 2.61643118786021e-06*G0_4_2_2 - 3.85328956757593e-05*G0_4_2_3 - 6.49350649350759e-05*G0_4_2_4 - 3.90086104371885e-05*G0_4_2_5 - 3.80571809143302e-06*G0_4_3_0 - 3.80571809143302e-06*G0_4_3_1 - 3.85328956757593e-05*G0_4_3_2 + 8.84829456258177e-05*G0_4_3_3 + 8.84829456258177e-05*G0_4_3_4 + 8.5628657057243e-05*G0_4_3_5 + 1.42714428428742e-06*G0_4_4_0 - 4.04357547214758e-05*G0_4_4_1 - 6.49350649350759e-05*G0_4_4_2 + 8.84829456258176e-05*G0_4_4_3 + 0.000311117453974649*G0_4_4_4 + 0.000158888730317329*G0_4_4_5 + 2.37857380714539e-07*G0_4_5_0 - 2.14071642643107e-05*G0_4_5_1 - 3.90086104371885e-05*G0_4_5_2 + 8.5628657057243e-05*G0_4_5_3 + 0.000158888730317329*G0_4_5_4 + 9.7045811331542e-05*G0_4_5_5 - 7.78388278388409e-05*G0_5_0_0 + 4.3408971980408e-06*G0_5_0_2 - 2.14071642643107e-05*G0_5_0_3 + 2.37857380714532e-07*G0_5_0_4 - 1.35578707007302e-05*G0_5_0_5 - 7.78388278388412e-05*G0_5_1_1 + 4.3408971980408e-06*G0_5_1_2 + 2.37857380714492e-07*G0_5_1_3 - 2.14071642643107e-05*G0_5_1_4 - 1.355787070073e-05*G0_5_1_5 + 4.3408971980408e-06*G0_5_2_0 + 4.34089719804081e-06*G0_5_2_1 + 9.87108129965439e-06*G0_5_2_2 - 3.90086104371885e-05*G0_5_2_3 - 3.90086104371885e-05*G0_5_2_4 - 2.71157414014603e-05*G0_5_2_5 - 2.14071642643107e-05*G0_5_3_0 + 2.37857380714492e-07*G0_5_3_1 - 3.90086104371885e-05*G0_5_3_2 + 0.000158888730317329*G0_5_3_3 + 8.5628657057243e-05*G0_5_3_4 + 9.70458113315419e-05*G0_5_3_5 + 2.37857380714553e-07*G0_5_4_0 - 2.14071642643107e-05*G0_5_4_1 - 3.90086104371885e-05*G0_5_4_2 + 8.5628657057243e-05*G0_5_4_3 + 0.000158888730317329*G0_5_4_4 + 9.70458113315419e-05*G0_5_4_5 - 1.35578707007302e-05*G0_5_5_0 - 1.355787070073e-05*G0_5_5_1 - 2.71157414014603e-05*G0_5_5_2 + 9.70458113315419e-05*G0_5_5_3 + 9.70458113315419e-05*G0_5_5_4 - 0.000399600399600468*G0_5_5_5; + A[72] = A[71] - 4.43306693306768e-05*G0_0_0_0 + 1.16698777413083e-05*G0_0_0_1 + 7.43304314733001e-07*G0_0_0_2 - 1.48660862946602e-06*G0_0_0_3 - 3.28837828837884e-05*G0_0_0_5 + 1.16698777413083e-05*G0_0_1_0 - 3.9469459112323e-05*G0_0_1_1 + 1.59067123352865e-06*G0_0_1_2 - 4.04357547214759e-06*G0_0_1_3 + 1.48660862946604e-06*G0_0_1_4 - 1.58769801626972e-05*G0_0_1_5 + 7.43304314732996e-07*G0_0_2_0 + 1.59067123352865e-06*G0_0_2_1 + 2.33397554826168e-06*G0_0_2_2 - 3.80571809143301e-06*G0_0_2_3 - 1.48660862946602e-06*G0_0_2_4 - 2.08125208125244e-06*G0_0_2_5 - 1.48660862946602e-06*G0_0_3_0 - 4.04357547214759e-06*G0_0_3_1 - 3.80571809143301e-06*G0_0_3_2 + 7.61143618286602e-06*G0_0_3_3 + 7.1357214214369e-06*G0_0_3_5 + 1.48660862946604e-06*G0_0_4_1 - 1.48660862946602e-06*G0_0_4_2 - 1.18928690357283e-06*G0_0_4_4 + 1.18928690357282e-06*G0_0_4_5 - 3.28837828837884e-05*G0_0_5_0 - 1.58769801626972e-05*G0_0_5_1 - 2.08125208125244e-06*G0_0_5_2 + 7.13572142143691e-06*G0_0_5_3 + 1.18928690357282e-06*G0_0_5_4 - 2.7829313543604e-05*G0_0_5_5 + 1.16698777413083e-05*G0_1_0_0 - 3.9469459112323e-05*G0_1_0_1 + 1.59067123352865e-06*G0_1_0_2 - 4.04357547214759e-06*G0_1_0_3 + 1.48660862946604e-06*G0_1_0_4 - 1.58769801626972e-05*G0_1_0_5 - 3.9469459112323e-05*G0_1_1_0 + 0.000417707292707364*G0_1_1_1 - 2.23883259597584e-05*G0_1_1_2 + 9.10399124684995e-05*G0_1_1_3 + 7.84929356358054e-06*G0_1_1_4 + 0.000171614100185558*G0_1_1_5 + 1.59067123352865e-06*G0_1_2_0 - 2.23883259597584e-05*G0_1_2_1 + 2.76509205080682e-06*G0_1_2_2 - 5.53018410161363e-06*G0_1_2_3 - 2.1407164264311e-06*G0_1_2_5 - 4.04357547214759e-06*G0_1_3_0 + 9.10399124684995e-05*G0_1_3_1 - 5.53018410161363e-06*G0_1_3_2 + 1.11792968935846e-05*G0_1_3_3 - 7.61143618286606e-06*G0_1_3_4 + 1.23685837971574e-05*G0_1_3_5 + 1.48660862946604e-06*G0_1_4_0 + 7.84929356358054e-06*G0_1_4_1 - 7.61143618286606e-06*G0_1_4_3 + 4.2814328528621e-06*G0_1_4_4 - 1.14171542742991e-05*G0_1_4_5 - 1.58769801626972e-05*G0_1_5_0 + 0.000171614100185558*G0_1_5_1 - 2.1407164264311e-06*G0_1_5_2 + 1.23685837971574e-05*G0_1_5_3 - 1.14171542742991e-05*G0_1_5_4 + 4.56686170971964e-05*G0_1_5_5 + 7.43304314732996e-07*G0_2_0_0 + 1.59067123352865e-06*G0_2_0_1 + 2.33397554826168e-06*G0_2_0_2 - 3.80571809143301e-06*G0_2_0_3 - 1.48660862946602e-06*G0_2_0_4 - 2.08125208125244e-06*G0_2_0_5 + 1.59067123352865e-06*G0_2_1_0 - 2.23883259597584e-05*G0_2_1_1 + 2.76509205080682e-06*G0_2_1_2 - 5.53018410161363e-06*G0_2_1_3 - 2.1407164264311e-06*G0_2_1_5 + 2.33397554826168e-06*G0_2_2_0 + 2.76509205080682e-06*G0_2_2_1 - 1.84636791779683e-05*G0_2_2_2 - 9.33590219304668e-06*G0_2_2_3 - 7.84929356358069e-06*G0_2_2_4 + 2.14071642643106e-06*G0_2_2_5 - 3.80571809143301e-06*G0_2_3_0 - 5.53018410161363e-06*G0_2_3_1 - 9.33590219304668e-06*G0_2_3_2 + 1.85528756957359e-05*G0_2_3_3 + 7.61143618286603e-06*G0_2_3_4 + 3.33000333000389e-06*G0_2_3_5 - 1.48660862946602e-06*G0_2_4_0 - 7.84929356358069e-06*G0_2_4_2 + 7.61143618286603e-06*G0_2_4_3 + 1.1417154274299e-05*G0_2_4_4 - 4.28143285286213e-06*G0_2_4_5 - 2.08125208125244e-06*G0_2_5_0 - 2.1407164264311e-06*G0_2_5_1 + 2.14071642643106e-06*G0_2_5_2 + 3.33000333000389e-06*G0_2_5_3 - 4.28143285286213e-06*G0_2_5_4 - 4.56686170971962e-05*G0_2_5_5 - 1.48660862946602e-06*G0_3_0_0 - 4.04357547214759e-06*G0_3_0_1 - 3.80571809143301e-06*G0_3_0_2 + 7.61143618286602e-06*G0_3_0_3 + 7.1357214214369e-06*G0_3_0_5 - 4.04357547214759e-06*G0_3_1_0 + 9.10399124684995e-05*G0_3_1_1 - 5.53018410161363e-06*G0_3_1_2 + 1.11792968935846e-05*G0_3_1_3 - 7.61143618286606e-06*G0_3_1_4 + 1.23685837971574e-05*G0_3_1_5 - 3.80571809143301e-06*G0_3_2_0 - 5.53018410161363e-06*G0_3_2_1 - 9.33590219304668e-06*G0_3_2_2 + 1.85528756957359e-05*G0_3_2_3 + 7.61143618286603e-06*G0_3_2_4 + 3.33000333000389e-06*G0_3_2_5 + 7.61143618286602e-06*G0_3_3_0 + 1.11792968935846e-05*G0_3_3_1 + 1.85528756957359e-05*G0_3_3_2 - 3.71057513914717e-05*G0_3_3_3 - 2.18828790257398e-05*G0_3_3_5 - 7.61143618286606e-06*G0_3_4_1 + 7.61143618286603e-06*G0_3_4_2 - 8.56286570572419e-06*G0_3_4_4 + 8.56286570572432e-06*G0_3_4_5 + 7.13572142143691e-06*G0_3_5_0 + 1.23685837971574e-05*G0_3_5_1 + 3.33000333000389e-06*G0_3_5_2 - 2.18828790257398e-05*G0_3_5_3 + 8.56286570572429e-06*G0_3_5_4 + 7.70657913515186e-05*G0_3_5_5 + 1.48660862946604e-06*G0_4_0_1 - 1.48660862946602e-06*G0_4_0_2 - 1.18928690357283e-06*G0_4_0_4 + 1.1892869035728e-06*G0_4_0_5 + 1.48660862946604e-06*G0_4_1_0 + 7.84929356358054e-06*G0_4_1_1 - 7.61143618286606e-06*G0_4_1_3 + 4.2814328528621e-06*G0_4_1_4 - 1.14171542742991e-05*G0_4_1_5 - 1.48660862946602e-06*G0_4_2_0 - 7.84929356358069e-06*G0_4_2_2 + 7.61143618286603e-06*G0_4_2_3 + 1.1417154274299e-05*G0_4_2_4 - 4.28143285286213e-06*G0_4_2_5 - 7.61143618286606e-06*G0_4_3_1 + 7.61143618286603e-06*G0_4_3_2 - 8.56286570572419e-06*G0_4_3_4 + 8.56286570572431e-06*G0_4_3_5 - 1.18928690357283e-06*G0_4_4_0 + 4.2814328528621e-06*G0_4_4_1 + 1.1417154274299e-05*G0_4_4_2 - 8.56286570572419e-06*G0_4_4_3 - 0.00011417154274299*G0_4_4_4 + 1.1892869035728e-06*G0_4_5_0 - 1.14171542742991e-05*G0_4_5_1 - 4.28143285286213e-06*G0_4_5_2 + 8.56286570572429e-06*G0_4_5_3 + 0.00011417154274299*G0_4_5_5 - 3.28837828837884e-05*G0_5_0_0 - 1.58769801626972e-05*G0_5_0_1 - 2.08125208125244e-06*G0_5_0_2 + 7.13572142143691e-06*G0_5_0_3 + 1.18928690357282e-06*G0_5_0_4 - 2.7829313543604e-05*G0_5_0_5 - 1.58769801626972e-05*G0_5_1_0 + 0.000171614100185558*G0_5_1_1 - 2.1407164264311e-06*G0_5_1_2 + 1.23685837971574e-05*G0_5_1_3 - 1.14171542742991e-05*G0_5_1_4 + 4.56686170971963e-05*G0_5_1_5 - 2.08125208125244e-06*G0_5_2_0 - 2.1407164264311e-06*G0_5_2_1 + 2.14071642643106e-06*G0_5_2_2 + 3.33000333000388e-06*G0_5_2_3 - 4.28143285286214e-06*G0_5_2_4 - 4.56686170971962e-05*G0_5_2_5 + 7.13572142143691e-06*G0_5_3_0 + 1.23685837971574e-05*G0_5_3_1 + 3.33000333000389e-06*G0_5_3_2 - 2.18828790257398e-05*G0_5_3_3 + 8.56286570572431e-06*G0_5_3_4 + 7.70657913515186e-05*G0_5_3_5 + 1.1892869035728e-06*G0_5_4_0 - 1.14171542742991e-05*G0_5_4_1 - 4.28143285286213e-06*G0_5_4_2 + 8.56286570572431e-06*G0_5_4_3 + 0.00011417154274299*G0_5_4_5 - 2.7829313543604e-05*G0_5_5_0 + 4.56686170971963e-05*G0_5_5_1 - 4.56686170971962e-05*G0_5_5_2 + 7.70657913515186e-05*G0_5_5_3 + 0.000114171542742991*G0_5_5_4 + 0.000810617953475233*G0_5_5_5; + A[27] = A[72]; + A[28] = A[82]; + A[80] = A[8]; + A[14] = A[41]; + A[23] = A[32]; + A[53] = A[35]; + A[68] = A[86]; + A[6] = A[60]; + A[17] = A[71]; + A[47] = A[74]; + A[3] = A[30]; + A[79] = A[97]; + A[38] = A[83]; + A[20] = A[2]; + A[18] = A[81]; + A[88] = A[33] + 0.000242436135293319*G0_0_0_0 + 2.43506493506536e-05*G0_0_0_1 - 3.9068074782367e-05*G0_0_0_2 - 3.21107463964655e-06*G0_0_0_3 + 0.000103824746681907*G0_0_0_4 + 0.000377836449265084*G0_0_0_5 + 2.43506493506536e-05*G0_0_1_0 - 0.000168581418581447*G0_0_1_1 + 2.99700299700352e-05*G0_0_1_3 - 5.24475524475612e-05*G0_0_1_4 - 0.000442057942058017*G0_0_1_5 - 3.9068074782367e-05*G0_0_2_0 + 3.90680747823671e-05*G0_0_2_2 - 3.31811046096816e-05*G0_0_2_3 + 3.31811046096817e-05*G0_0_2_5 - 3.21107463964655e-06*G0_0_3_0 + 2.99700299700352e-05*G0_0_3_1 - 3.31811046096816e-05*G0_0_3_2 + 0.000539460539460631*G0_0_3_3 + 0.000111317254174416*G0_0_3_4 - 5.99400599400703e-05*G0_0_3_5 + 0.000103824746681907*G0_0_4_0 - 5.24475524475612e-05*G0_0_4_1 + 0.000111317254174416*G0_0_4_3 + 0.000188383045525934*G0_0_4_4 + 3.85328956757592e-05*G0_0_4_5 + 0.000377836449265084*G0_0_5_0 - 0.000442057942058017*G0_0_5_1 + 3.31811046096817e-05*G0_0_5_2 - 5.99400599400703e-05*G0_0_5_3 + 3.85328956757592e-05*G0_0_5_4 - 0.00101898101898119*G0_0_5_5 + 2.43506493506536e-05*G0_1_0_0 - 0.000168581418581447*G0_1_0_1 + 2.99700299700352e-05*G0_1_0_3 - 5.24475524475612e-05*G0_1_0_4 - 0.000442057942058017*G0_1_0_5 - 0.000168581418581447*G0_1_1_0 + 0.000168581418581448*G0_1_1_2 - 0.00108641358641377*G0_1_1_3 + 0.00108641358641377*G0_1_1_5 + 0.000168581418581448*G0_1_2_1 - 2.43506493506536e-05*G0_1_2_2 + 0.000442057942058017*G0_1_2_3 + 5.24475524475613e-05*G0_1_2_4 - 2.99700299700349e-05*G0_1_2_5 + 2.99700299700352e-05*G0_1_3_0 - 0.00108641358641377*G0_1_3_1 + 0.000442057942058017*G0_1_3_2 - 0.00224775224775263*G0_1_3_3 - 5.99400599400702e-05*G0_1_3_4 - 5.24475524475612e-05*G0_1_4_0 + 5.24475524475613e-05*G0_1_4_2 - 5.99400599400702e-05*G0_1_4_3 + 5.99400599400699e-05*G0_1_4_5 - 0.000442057942058017*G0_1_5_0 + 0.00108641358641377*G0_1_5_1 - 2.99700299700349e-05*G0_1_5_2 + 5.99400599400699e-05*G0_1_5_4 + 0.00224775224775263*G0_1_5_5 - 3.9068074782367e-05*G0_2_0_0 + 3.90680747823671e-05*G0_2_0_2 - 3.31811046096816e-05*G0_2_0_3 + 3.31811046096817e-05*G0_2_0_5 + 0.000168581418581448*G0_2_1_1 - 2.43506493506536e-05*G0_2_1_2 + 0.000442057942058017*G0_2_1_3 + 5.24475524475613e-05*G0_2_1_4 - 2.99700299700349e-05*G0_2_1_5 + 3.90680747823671e-05*G0_2_2_0 - 2.43506493506536e-05*G0_2_2_1 - 0.000242436135293319*G0_2_2_2 - 0.000377836449265085*G0_2_2_3 - 0.000103824746681907*G0_2_2_4 + 3.21107463964666e-06*G0_2_2_5 - 3.31811046096817e-05*G0_2_3_0 + 0.000442057942058017*G0_2_3_1 - 0.000377836449265085*G0_2_3_2 + 0.00101898101898119*G0_2_3_3 - 3.85328956757593e-05*G0_2_3_4 + 5.99400599400699e-05*G0_2_3_5 + 5.24475524475613e-05*G0_2_4_1 - 0.000103824746681907*G0_2_4_2 - 3.85328956757594e-05*G0_2_4_3 - 0.000188383045525934*G0_2_4_4 - 0.000111317254174416*G0_2_4_5 + 3.31811046096817e-05*G0_2_5_0 - 2.99700299700349e-05*G0_2_5_1 + 3.21107463964666e-06*G0_2_5_2 + 5.99400599400699e-05*G0_2_5_3 - 0.000111317254174416*G0_2_5_4 - 0.000539460539460631*G0_2_5_5 - 3.21107463964653e-06*G0_3_0_0 + 2.99700299700352e-05*G0_3_0_1 - 3.31811046096816e-05*G0_3_0_2 + 0.000539460539460631*G0_3_0_3 + 0.000111317254174416*G0_3_0_4 - 5.99400599400704e-05*G0_3_0_5 + 2.99700299700352e-05*G0_3_1_0 - 0.00108641358641377*G0_3_1_1 + 0.000442057942058017*G0_3_1_2 - 0.00224775224775263*G0_3_1_3 - 5.99400599400702e-05*G0_3_1_4 - 3.31811046096816e-05*G0_3_2_0 + 0.000442057942058017*G0_3_2_1 - 0.000377836449265085*G0_3_2_2 + 0.00101898101898119*G0_3_2_3 - 3.85328956757594e-05*G0_3_2_4 + 5.99400599400698e-05*G0_3_2_5 + 0.000539460539460631*G0_3_3_0 - 0.00224775224775263*G0_3_3_1 + 0.00101898101898119*G0_3_3_2 - 0.0107892107892126*G0_3_3_3 - 0.000959040959041121*G0_3_3_4 - 0.0011988011988014*G0_3_3_5 + 0.000111317254174416*G0_3_4_0 - 5.99400599400702e-05*G0_3_4_1 - 3.85328956757594e-05*G0_3_4_2 - 0.000959040959041121*G0_3_4_3 - 0.000222634508348832*G0_3_4_4 - 5.99400599400704e-05*G0_3_5_0 + 5.99400599400698e-05*G0_3_5_2 - 0.0011988011988014*G0_3_5_3 + 0.0011988011988014*G0_3_5_5 + 0.000103824746681907*G0_4_0_0 - 5.24475524475612e-05*G0_4_0_1 + 0.000111317254174416*G0_4_0_3 + 0.000188383045525934*G0_4_0_4 + 3.85328956757592e-05*G0_4_0_5 - 5.24475524475612e-05*G0_4_1_0 + 5.24475524475613e-05*G0_4_1_2 - 5.99400599400702e-05*G0_4_1_3 + 5.99400599400698e-05*G0_4_1_5 + 5.24475524475613e-05*G0_4_2_1 - 0.000103824746681907*G0_4_2_2 - 3.85328956757593e-05*G0_4_2_3 - 0.000188383045525934*G0_4_2_4 - 0.000111317254174416*G0_4_2_5 + 0.000111317254174416*G0_4_3_0 - 5.99400599400702e-05*G0_4_3_1 - 3.85328956757593e-05*G0_4_3_2 - 0.000959040959041121*G0_4_3_3 - 0.000222634508348832*G0_4_3_4 + 0.000188383045525934*G0_4_4_0 - 0.000188383045525934*G0_4_4_2 - 0.000222634508348832*G0_4_4_3 + 0.000222634508348831*G0_4_4_5 + 3.85328956757592e-05*G0_4_5_0 + 5.99400599400699e-05*G0_4_5_1 - 0.000111317254174416*G0_4_5_2 + 0.000222634508348831*G0_4_5_4 + 0.00095904095904112*G0_4_5_5 + 0.000377836449265084*G0_5_0_0 - 0.000442057942058017*G0_5_0_1 + 3.31811046096817e-05*G0_5_0_2 - 5.99400599400703e-05*G0_5_0_3 + 3.85328956757592e-05*G0_5_0_4 - 0.00101898101898119*G0_5_0_5 - 0.000442057942058017*G0_5_1_0 + 0.00108641358641377*G0_5_1_1 - 2.99700299700349e-05*G0_5_1_2 + 5.99400599400699e-05*G0_5_1_4 + 0.00224775224775263*G0_5_1_5 + 3.31811046096817e-05*G0_5_2_0 - 2.99700299700349e-05*G0_5_2_1 + 3.21107463964667e-06*G0_5_2_2 + 5.99400599400699e-05*G0_5_2_3 - 0.000111317254174416*G0_5_2_4 - 0.000539460539460631*G0_5_2_5 - 5.99400599400703e-05*G0_5_3_0 + 5.99400599400698e-05*G0_5_3_2 - 0.0011988011988014*G0_5_3_3 + 0.0011988011988014*G0_5_3_5 + 3.85328956757592e-05*G0_5_4_0 + 5.99400599400699e-05*G0_5_4_1 - 0.000111317254174416*G0_5_4_2 + 0.000222634508348831*G0_5_4_4 + 0.00095904095904112*G0_5_4_5 - 0.00101898101898119*G0_5_5_0 + 0.00224775224775263*G0_5_5_1 - 0.000539460539460631*G0_5_5_2 + 0.0011988011988014*G0_5_5_3 + 0.00095904095904112*G0_5_5_4 + 0.0107892107892126*G0_5_5_5; + A[43] = A[34]; + A[95] = A[59]; + A[52] = A[25]; + } + + /// 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 mass_matrix_f3_p2_q3_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f3_p2_q3_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f3_p2_q3_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1)))), 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 3; + } + + /// 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 mass_matrix_f3_p2_q3_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f3_p2_q3_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f3_p2_q3_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p2_q3_tensor_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p2_q3_tensor_finite_element_0(); + 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 mass_matrix_f3_p2_q3_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f3_p2_q3_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f3_p2_q3_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f3_p2_q3_tensor_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f3_p2_q3_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f3_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/mass_matrix_2d/mass_matrix_f4_p1_q1_excafe.h b/mass_matrix_2d/mass_matrix_f4_p1_q1_excafe.h new file mode 100644 index 0000000..5c1c26f --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f4_p1_q1_excafe.h @@ -0,0 +1,106 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 4.02 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][0]*w[1][2] + w[0][2]*w[1][0]; + const double var_1 = w[0][0]*w[1][0]*w[2][2] + var_0*w[2][0]; + const double var_2 = -1.0000000000000000000000000*x[0][1]; + const double var_3 = var_2 + x[1][1]; + const double var_4 = w[0][0]*w[1][0]*w[2][0]; + const double var_5 = 0.0166666666666666664353702*var_4; + const double var_6 = w[0][1]*w[1][0] + w[0][0]*w[1][1]; + const double var_7 = w[0][0]*w[1][0]*w[2][1] + var_6*w[2][0]; + const double var_8 = var_0*w[2][2] + w[0][2]*w[1][2]*w[2][0]; + const double var_9 = w[0][1]*w[1][2] + w[0][2]*w[1][1]; + const double var_10 = w[0][1]*w[1][1]*w[2][2] + var_9*w[2][1]; + const double var_11 = var_6*w[2][1] + w[0][1]*w[1][1]*w[2][0]; + const double var_12 = 0.0166666666666666664353702*var_11; + const double var_13 = 0.0666666666666666657414808*var_1 + var_12; + const double var_14 = var_0*w[2][1] + var_6*w[2][2] + var_9*w[2][0]; + const double var_15 = 0.0166666666666666664353702*var_14; + const double var_16 = 0.1666666666666666574148081*var_4 + var_15; + const double var_17 = var_9*w[2][2] + w[0][2]*w[1][2]*w[2][1]; + const double var_18 = 0.0166666666666666664353702*var_17; + const double var_19 = w[0][1]*w[1][1]*w[2][1]; + const double var_20 = 0.0166666666666666664353702*var_19; + const double var_21 = w[0][2]*w[1][2]*w[2][2]; + const double var_22 = 0.0666666666666666657414808*var_21; + const double var_23 = var_20 + 0.0111111111111111115351546*var_10 + var_18 + var_13 + var_22 + 0.0500000000000000027755576*var_8 + var_16 + 0.0333333333333333328707404*var_7; + const double var_24 = 0.0166666666666666664353702*var_10; + const double var_25 = var_24 + 0.0666666666666666657414808*var_8; + const double var_26 = 0.1666666666666666574148081*var_21 + var_15; + const double var_27 = 0.0166666666666666664353702*var_7; + const double var_28 = 0.0666666666666666657414808*var_4; + const double var_29 = var_20 + 0.0500000000000000027755576*var_1 + 0.0333333333333333328707404*var_17 + var_25 + var_26 + var_27 + var_28 + 0.0111111111111111115351546*var_11; + const double var_30 = -1.0000000000000000000000000*x[0][0]; + const double var_31 = x[1][0] + var_30; + const double var_32 = x[2][1] + var_2; + const double var_33 = x[2][0] + var_30; + const double var_34 = var_31*var_32 + -1.0000000000000000000000000*var_3*var_33; + const double var_35 = std::abs(var_34); + const double var_36 = 0.0166666666666666664353702*var_8; + const double var_37 = 0.0666666666666666657414808*var_7 + var_36; + const double var_38 = 0.0666666666666666657414808*var_19; + const double var_39 = 0.0166666666666666664353702*var_21; + const double var_40 = 0.0333333333333333328707404*var_1 + 0.0111111111111111115351546*var_17 + var_37 + var_16 + var_24 + var_38 + 0.0500000000000000027755576*var_11 + var_39; + const double var_41 = 0.0666666666666666657414808*var_11 + var_18; + const double var_42 = 0.0333333333333333328707404*var_14; + const double var_43 = 0.0500000000000000027755576*var_19 + var_42; + const double var_44 = var_1 + var_7; + const double var_45 = var_41 + var_25 + 0.0500000000000000027755576*var_21 + 0.1666666666666666574148081*var_44 + var_43 + var_4; + const double var_46 = var_45*w[3][0] + var_40*w[3][1] + var_23*w[3][2]; + A[0] = 0.0178571428571428561515866*var_35*var_46; + const double var_47 = var_17 + var_8; + const double var_48 = 0.0166666666666666664353702*var_1; + const double var_49 = 0.0666666666666666657414808*var_17 + var_48; + const double var_50 = var_11 + var_10; + const double var_51 = var_4 + var_21; + const double var_52 = var_49 + 0.1666666666666666574148081*var_50 + var_37 + 0.0500000000000000027755576*var_51 + var_42 + var_19; + const double var_53 = var_44 + var_47 + var_50; + const double var_54 = var_19 + 0.3333333333333333148296163*var_14 + var_51 + 0.5000000000000000000000000*var_53; + const double var_55 = 0.1666666666666666574148081*var_19 + var_15; + const double var_56 = var_48 + 0.0333333333333333328707404*var_10 + var_55 + var_41 + 0.0111111111111111115351546*var_8 + 0.0500000000000000027755576*var_7 + var_28 + var_39; + const double var_57 = var_56*w[3][1] + var_40*w[3][0] + 0.0333333333333333328707404*var_54*w[3][2]; + A[1] = 0.0178571428571428561515866*var_35*var_57; + const double var_58 = 0.0666666666666666657414808*var_10 + var_27; + const double var_59 = var_58 + 0.0111111111111111115351546*var_1 + var_55 + var_5 + 0.0500000000000000027755576*var_17 + var_22 + var_36 + 0.0333333333333333328707404*var_11; + const double var_60 = var_12 + var_49 + 0.0500000000000000027755576*var_10 + var_5 + 0.0333333333333333328707404*var_8 + 0.0111111111111111115351546*var_7 + var_26 + var_38; + const double var_61 = var_60*w[3][2] + var_59*w[3][1] + 0.0333333333333333328707404*var_54*w[3][0]; + A[5] = 0.0178571428571428561515866*var_35*var_61; + const double var_62 = var_52*w[3][1] + var_59*w[3][2] + var_56*w[3][0]; + A[3] = A[1]; + const double var_63 = 0.0333333333333333328707404*var_54*w[3][1] + var_29*w[3][2] + var_23*w[3][0]; + A[2] = 0.0178571428571428561515866*var_35*var_63; + const double var_64 = var_58 + 0.1666666666666666574148081*var_47 + var_13 + var_21 + var_43 + 0.0500000000000000027755576*var_4; + A[4] = 0.0178571428571428561515866*var_35*var_62; + A[7] = A[5]; + const double var_65 = var_29*w[3][0] + var_64*w[3][2] + var_60*w[3][1]; + A[8] = 0.0178571428571428561515866*var_35*var_65; + A[6] = 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/mass_matrix_2d/mass_matrix_f4_p1_q1_quadrature.h b/mass_matrix_2d/mass_matrix_f4_p1_q1_quadrature.h new file mode 100644 index 0000000..3561392 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f4_p1_q1_quadrature.h @@ -0,0 +1,1481 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F4_P1_Q1_QUADRATURE_H +#define __MASS_MATRIX_F4_P1_Q1_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f4_p1_q1_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f4_p1_q1_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_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 mass_matrix_f4_p1_q1_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f4_p1_q1_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f4_p1_q1_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f4_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 mass_matrix_f4_p1_q1_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class mass_matrix_f4_p1_q1_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f4_p1_q1_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // 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[12][3] = \ + {{0.063089014491502, 0.873821971016996, 0.063089014491502}, + {0.063089014491502, 0.0630890144915021, 0.873821971016996}, + {0.873821971016996, 0.0630890144915021, 0.063089014491502}, + {0.249286745170911, 0.501426509658179, 0.24928674517091}, + {0.249286745170911, 0.24928674517091, 0.501426509658179}, + {0.50142650965818, 0.24928674517091, 0.24928674517091}, + {0.0531450498448159, 0.636502499121399, 0.310352451033785}, + {0.310352451033785, 0.636502499121399, 0.053145049844816}, + {0.053145049844816, 0.310352451033785, 0.636502499121399}, + {0.636502499121399, 0.310352451033785, 0.053145049844816}, + {0.310352451033785, 0.0531450498448161, 0.636502499121399}, + {0.636502499121399, 0.053145049844816, 0.310352451033785}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 9; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 672 + 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 = 24 + for (unsigned int r = 0; r < 3; r++) + { + F0 += FE0[ip][r]*w[3][r]; + F1 += FE0[ip][r]*w[2][r]; + F2 += FE0[ip][r]*w[0][r]; + F3 += FE0[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 5 + double I[1]; + // Number of operations: 5 + I[0] = F0*F1*F2*F3*W12[ip]*det; + + + // Number of operations for primary indices: 27 + for (unsigned int j = 0; j < 3; j++) + { + for (unsigned int k = 0; k < 3; k++) + { + // Number of operations to compute entry: 3 + A[j*3 + k] += FE0[ip][j]*FE0[ip][k]*I[0]; + }// 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 mass_matrix_f4_p1_q1_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f4_p1_q1_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_p1_q1_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 3), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1))))), 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 4; + } + + /// 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 mass_matrix_f4_p1_q1_quadrature_finite_element_0(); + break; + } + case 1: + { + return new mass_matrix_f4_p1_q1_quadrature_finite_element_0(); + break; + } + case 2: + { + return new mass_matrix_f4_p1_q1_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f4_p1_q1_quadrature_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f4_p1_q1_quadrature_finite_element_0(); + break; + } + case 5: + { + return new mass_matrix_f4_p1_q1_quadrature_finite_element_0(); + 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 mass_matrix_f4_p1_q1_quadrature_dofmap_0(); + break; + } + case 1: + { + return new mass_matrix_f4_p1_q1_quadrature_dofmap_0(); + break; + } + case 2: + { + return new mass_matrix_f4_p1_q1_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f4_p1_q1_quadrature_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f4_p1_q1_quadrature_dofmap_0(); + break; + } + case 5: + { + return new mass_matrix_f4_p1_q1_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f4_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/mass_matrix_2d/mass_matrix_f4_p1_q1_tensor.h b/mass_matrix_2d/mass_matrix_f4_p1_q1_tensor.h new file mode 100644 index 0000000..a4f6cc7 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f4_p1_q1_tensor.h @@ -0,0 +1,1510 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F4_P1_Q1_TENSOR_H +#define __MASS_MATRIX_F4_P1_Q1_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f4_p1_q1_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f4_p1_q1_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_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 mass_matrix_f4_p1_q1_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f4_p1_q1_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f4_p1_q1_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f4_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 mass_matrix_f4_p1_q1_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for the tabulation of the cell +/// tensor corresponding to the local contribution to a form from +/// the integral over a cell. + +class mass_matrix_f4_p1_q1_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f4_p1_q1_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 202 + // Number of operations (multiply-add pairs) for tensor contraction: 375 + // Total number of operations (multiply-add pairs): 586 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0_0 = det*w[3][0]*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_0_0_0_1 = det*w[3][0]*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_0_0_0_2 = det*w[3][0]*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_0_0_1_0 = det*w[3][0]*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_0_0_1_1 = det*w[3][0]*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_0_0_1_2 = det*w[3][0]*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_0_0_2_0 = det*w[3][0]*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_0_0_2_1 = det*w[3][0]*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_0_0_2_2 = det*w[3][0]*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_0_1_0_0 = det*w[3][0]*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_0_1_0_1 = det*w[3][0]*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_0_1_0_2 = det*w[3][0]*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_0_1_1_0 = det*w[3][0]*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_0_1_1_1 = det*w[3][0]*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_0_1_1_2 = det*w[3][0]*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_0_1_2_0 = det*w[3][0]*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_0_1_2_1 = det*w[3][0]*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_0_1_2_2 = det*w[3][0]*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_0_2_0_0 = det*w[3][0]*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_0_2_0_1 = det*w[3][0]*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_0_2_0_2 = det*w[3][0]*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_0_2_1_0 = det*w[3][0]*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_0_2_1_1 = det*w[3][0]*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_0_2_1_2 = det*w[3][0]*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_0_2_2_0 = det*w[3][0]*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_0_2_2_1 = det*w[3][0]*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_0_2_2_2 = det*w[3][0]*w[2][2]*w[0][2]*w[1][2]*(1.0); + const double G0_1_0_0_0 = det*w[3][1]*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_1_0_0_1 = det*w[3][1]*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_1_0_0_2 = det*w[3][1]*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_1_0_1_0 = det*w[3][1]*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_1_0_1_1 = det*w[3][1]*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_1_0_1_2 = det*w[3][1]*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_1_0_2_0 = det*w[3][1]*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_1_0_2_1 = det*w[3][1]*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_1_0_2_2 = det*w[3][1]*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_1_1_0_0 = det*w[3][1]*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_1_1_0_1 = det*w[3][1]*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_1_1_0_2 = det*w[3][1]*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_1_1_1_0 = det*w[3][1]*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_1_1_1_1 = det*w[3][1]*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_1_1_1_2 = det*w[3][1]*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_1_1_2_0 = det*w[3][1]*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_1_1_2_1 = det*w[3][1]*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_1_1_2_2 = det*w[3][1]*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_1_2_0_0 = det*w[3][1]*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_1_2_0_1 = det*w[3][1]*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_1_2_0_2 = det*w[3][1]*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_1_2_1_0 = det*w[3][1]*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_1_2_1_1 = det*w[3][1]*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_1_2_1_2 = det*w[3][1]*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_1_2_2_0 = det*w[3][1]*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_1_2_2_1 = det*w[3][1]*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_1_2_2_2 = det*w[3][1]*w[2][2]*w[0][2]*w[1][2]*(1.0); + const double G0_2_0_0_0 = det*w[3][2]*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_2_0_0_1 = det*w[3][2]*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_2_0_0_2 = det*w[3][2]*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_2_0_1_0 = det*w[3][2]*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_2_0_1_1 = det*w[3][2]*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_2_0_1_2 = det*w[3][2]*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_2_0_2_0 = det*w[3][2]*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_2_0_2_1 = det*w[3][2]*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_2_0_2_2 = det*w[3][2]*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_2_1_0_0 = det*w[3][2]*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_2_1_0_1 = det*w[3][2]*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_2_1_0_2 = det*w[3][2]*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_2_1_1_0 = det*w[3][2]*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_2_1_1_1 = det*w[3][2]*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_2_1_1_2 = det*w[3][2]*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_2_1_2_0 = det*w[3][2]*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_2_1_2_1 = det*w[3][2]*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_2_1_2_2 = det*w[3][2]*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_2_2_0_0 = det*w[3][2]*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_2_2_0_1 = det*w[3][2]*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_2_2_0_2 = det*w[3][2]*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_2_2_1_0 = det*w[3][2]*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_2_2_1_1 = det*w[3][2]*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_2_2_1_2 = det*w[3][2]*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_2_2_2_0 = det*w[3][2]*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_2_2_2_1 = det*w[3][2]*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_2_2_2_2 = det*w[3][2]*w[2][2]*w[0][2]*w[1][2]*(1.0); + + // Compute element tensor + A[1] = 0.00297619047619049*G0_0_0_0_0 + 0.0011904761904762*G0_0_0_0_1 + 0.000595238095238093*G0_0_0_0_2 + 0.0011904761904762*G0_0_0_1_0 + 0.00089285714285715*G0_0_0_1_1 + 0.000297619047619046*G0_0_0_1_2 + 0.000595238095238093*G0_0_0_2_0 + 0.000297619047619046*G0_0_0_2_1 + 0.000297619047619046*G0_0_0_2_2 + 0.0011904761904762*G0_0_1_0_0 + 0.000892857142857151*G0_0_1_0_1 + 0.000297619047619046*G0_0_1_0_2 + 0.00089285714285715*G0_0_1_1_0 + 0.0011904761904762*G0_0_1_1_1 + 0.000297619047619046*G0_0_1_1_2 + 0.000297619047619046*G0_0_1_2_0 + 0.000297619047619046*G0_0_1_2_1 + 0.000198412698412697*G0_0_1_2_2 + 0.000595238095238093*G0_0_2_0_0 + 0.000297619047619046*G0_0_2_0_1 + 0.000297619047619046*G0_0_2_0_2 + 0.000297619047619046*G0_0_2_1_0 + 0.000297619047619046*G0_0_2_1_1 + 0.000198412698412697*G0_0_2_1_2 + 0.000297619047619046*G0_0_2_2_0 + 0.000198412698412697*G0_0_2_2_1 + 0.000297619047619046*G0_0_2_2_2 + 0.0011904761904762*G0_1_0_0_0 + 0.000892857142857151*G0_1_0_0_1 + 0.000297619047619046*G0_1_0_0_2 + 0.000892857142857151*G0_1_0_1_0 + 0.0011904761904762*G0_1_0_1_1 + 0.000297619047619046*G0_1_0_1_2 + 0.000297619047619046*G0_1_0_2_0 + 0.000297619047619046*G0_1_0_2_1 + 0.000198412698412697*G0_1_0_2_2 + 0.000892857142857151*G0_1_1_0_0 + 0.0011904761904762*G0_1_1_0_1 + 0.000297619047619046*G0_1_1_0_2 + 0.0011904761904762*G0_1_1_1_0 + 0.00297619047619049*G0_1_1_1_1 + 0.000595238095238092*G0_1_1_1_2 + 0.000297619047619046*G0_1_1_2_0 + 0.000595238095238092*G0_1_1_2_1 + 0.000297619047619045*G0_1_1_2_2 + 0.000297619047619046*G0_1_2_0_0 + 0.000297619047619046*G0_1_2_0_1 + 0.000198412698412697*G0_1_2_0_2 + 0.000297619047619046*G0_1_2_1_0 + 0.000595238095238092*G0_1_2_1_1 + 0.000297619047619045*G0_1_2_1_2 + 0.000198412698412697*G0_1_2_2_0 + 0.000297619047619045*G0_1_2_2_1 + 0.000297619047619045*G0_1_2_2_2 + 0.000595238095238093*G0_2_0_0_0 + 0.000297619047619046*G0_2_0_0_1 + 0.000297619047619046*G0_2_0_0_2 + 0.000297619047619046*G0_2_0_1_0 + 0.000297619047619046*G0_2_0_1_1 + 0.000198412698412697*G0_2_0_1_2 + 0.000297619047619046*G0_2_0_2_0 + 0.000198412698412697*G0_2_0_2_1 + 0.000297619047619046*G0_2_0_2_2 + 0.000297619047619046*G0_2_1_0_0 + 0.000297619047619046*G0_2_1_0_1 + 0.000198412698412697*G0_2_1_0_2 + 0.000297619047619046*G0_2_1_1_0 + 0.000595238095238092*G0_2_1_1_1 + 0.000297619047619045*G0_2_1_1_2 + 0.000198412698412697*G0_2_1_2_0 + 0.000297619047619045*G0_2_1_2_1 + 0.000297619047619045*G0_2_1_2_2 + 0.000297619047619046*G0_2_2_0_0 + 0.000198412698412697*G0_2_2_0_1 + 0.000297619047619046*G0_2_2_0_2 + 0.000198412698412697*G0_2_2_1_0 + 0.000297619047619045*G0_2_2_1_1 + 0.000297619047619045*G0_2_2_1_2 + 0.000297619047619046*G0_2_2_2_0 + 0.000297619047619045*G0_2_2_2_1 + 0.000595238095238092*G0_2_2_2_2; + A[5] = A[1] - 0.0023809523809524*G0_0_0_0_0 - 0.000892857142857153*G0_0_0_0_1 - 0.000297619047619047*G0_0_0_0_2 - 0.000892857142857153*G0_0_0_1_0 - 0.000595238095238104*G0_0_0_1_1 - 9.92063492063494e-05*G0_0_0_1_2 - 0.000297619047619047*G0_0_0_2_0 - 9.92063492063494e-05*G0_0_0_2_1 - 0.000892857142857153*G0_0_1_0_0 - 0.000595238095238105*G0_0_1_0_1 - 9.92063492063493e-05*G0_0_1_0_2 - 0.000595238095238104*G0_0_1_1_0 - 0.000595238095238107*G0_0_1_1_1 - 9.92063492063493e-05*G0_0_1_2_0 + 9.92063492063485e-05*G0_0_1_2_2 - 0.000297619047619047*G0_0_2_0_0 - 9.92063492063493e-05*G0_0_2_0_1 - 9.92063492063494e-05*G0_0_2_1_0 + 9.92063492063485e-05*G0_0_2_1_2 + 9.92063492063484e-05*G0_0_2_2_1 + 0.000297619047619046*G0_0_2_2_2 - 0.000892857142857154*G0_1_0_0_0 - 0.000595238095238105*G0_1_0_0_1 - 9.92063492063494e-05*G0_1_0_0_2 - 0.000595238095238105*G0_1_0_1_0 - 0.000595238095238107*G0_1_0_1_1 - 9.92063492063493e-05*G0_1_0_2_0 + 9.92063492063484e-05*G0_1_0_2_2 - 0.000595238095238105*G0_1_1_0_0 - 0.000595238095238107*G0_1_1_0_1 - 0.000595238095238107*G0_1_1_1_0 + 0.000595238095238106*G0_1_1_1_2 + 0.000595238095238106*G0_1_1_2_1 + 0.000595238095238103*G0_1_1_2_2 - 9.92063492063494e-05*G0_1_2_0_0 + 9.92063492063484e-05*G0_1_2_0_2 + 0.000595238095238106*G0_1_2_1_1 + 0.000595238095238103*G0_1_2_1_2 + 9.92063492063484e-05*G0_1_2_2_0 + 0.000595238095238103*G0_1_2_2_1 + 0.000892857142857152*G0_1_2_2_2 - 0.000297619047619047*G0_2_0_0_0 - 9.92063492063494e-05*G0_2_0_0_1 - 9.92063492063494e-05*G0_2_0_1_0 + 9.92063492063484e-05*G0_2_0_1_2 + 9.92063492063484e-05*G0_2_0_2_1 + 0.000297619047619046*G0_2_0_2_2 - 9.92063492063493e-05*G0_2_1_0_0 + 9.92063492063484e-05*G0_2_1_0_2 + 0.000595238095238106*G0_2_1_1_1 + 0.000595238095238103*G0_2_1_1_2 + 9.92063492063484e-05*G0_2_1_2_0 + 0.000595238095238103*G0_2_1_2_1 + 0.000892857142857152*G0_2_1_2_2 + 9.92063492063484e-05*G0_2_2_0_1 + 0.000297619047619046*G0_2_2_0_2 + 9.92063492063484e-05*G0_2_2_1_0 + 0.000595238095238104*G0_2_2_1_1 + 0.000892857142857152*G0_2_2_1_2 + 0.000297619047619046*G0_2_2_2_0 + 0.000892857142857152*G0_2_2_2_1 + 0.0023809523809524*G0_2_2_2_2; + A[0] = A[5] + 0.0172619047619049*G0_0_0_0_0 + 0.00267857142857145*G0_0_0_0_1 + 0.00267857142857145*G0_0_0_0_2 + 0.00267857142857145*G0_0_0_1_0 + 0.000892857142857154*G0_0_0_1_1 + 0.000396825396825396*G0_0_0_1_2 + 0.00267857142857145*G0_0_0_2_0 + 0.000396825396825396*G0_0_0_2_1 + 0.000892857142857153*G0_0_0_2_2 + 0.00267857142857145*G0_0_1_0_0 + 0.000892857142857154*G0_0_1_0_1 + 0.000396825396825396*G0_0_1_0_2 + 0.000892857142857154*G0_0_1_1_0 + 0.000297619047619059*G0_0_1_1_1 + 0.000396825396825396*G0_0_1_2_0 + 0.00267857142857145*G0_0_2_0_0 + 0.000396825396825396*G0_0_2_0_1 + 0.000892857142857154*G0_0_2_0_2 + 0.000396825396825396*G0_0_2_1_0 + 0.000892857142857154*G0_0_2_2_0 + 0.000297619047619059*G0_0_2_2_2 + 0.00267857142857145*G0_1_0_0_0 + 0.000892857142857154*G0_1_0_0_1 + 0.000396825396825396*G0_1_0_0_2 + 0.000892857142857154*G0_1_0_1_0 + 0.000297619047619059*G0_1_0_1_1 + 0.000396825396825396*G0_1_0_2_0 + 0.000892857142857154*G0_1_1_0_0 + 0.000297619047619059*G0_1_1_0_1 + 0.000297619047619059*G0_1_1_1_0 - 0.00178571428571429*G0_1_1_1_1 - 0.000892857142857151*G0_1_1_1_2 - 0.000892857142857152*G0_1_1_2_1 - 0.000694444444444452*G0_1_1_2_2 + 0.000396825396825396*G0_1_2_0_0 - 0.000892857142857152*G0_1_2_1_1 - 0.000694444444444452*G0_1_2_1_2 - 0.000694444444444452*G0_1_2_2_1 - 0.000892857142857151*G0_1_2_2_2 + 0.00267857142857145*G0_2_0_0_0 + 0.000396825396825396*G0_2_0_0_1 + 0.000892857142857154*G0_2_0_0_2 + 0.000396825396825396*G0_2_0_1_0 + 0.000892857142857154*G0_2_0_2_0 + 0.000297619047619059*G0_2_0_2_2 + 0.000396825396825396*G0_2_1_0_0 - 0.000892857142857151*G0_2_1_1_1 - 0.000694444444444452*G0_2_1_1_2 - 0.000694444444444452*G0_2_1_2_1 - 0.000892857142857151*G0_2_1_2_2 + 0.000892857142857154*G0_2_2_0_0 + 0.000297619047619059*G0_2_2_0_2 - 0.000694444444444452*G0_2_2_1_1 - 0.000892857142857151*G0_2_2_1_2 + 0.000297619047619059*G0_2_2_2_0 - 0.000892857142857151*G0_2_2_2_1 - 0.00178571428571429*G0_2_2_2_2; + A[7] = A[5]; + A[8] = A[1] - 0.00178571428571429*G0_0_0_0_0 - 0.000892857142857153*G0_0_0_0_1 + 0.000297619047619057*G0_0_0_0_2 - 0.000892857142857153*G0_0_0_1_0 - 0.000694444444444453*G0_0_0_1_1 + 0.000297619047619057*G0_0_0_2_0 + 0.000892857142857153*G0_0_0_2_2 - 0.000892857142857153*G0_0_1_0_0 - 0.000694444444444453*G0_0_1_0_1 - 0.000694444444444453*G0_0_1_1_0 - 0.000892857142857154*G0_0_1_1_1 + 0.000396825396825395*G0_0_1_2_2 + 0.000297619047619057*G0_0_2_0_0 + 0.000892857142857153*G0_0_2_0_2 + 0.000396825396825395*G0_0_2_1_2 + 0.000892857142857152*G0_0_2_2_0 + 0.000396825396825395*G0_0_2_2_1 + 0.00267857142857144*G0_0_2_2_2 - 0.000892857142857154*G0_1_0_0_0 - 0.000694444444444453*G0_1_0_0_1 - 0.000694444444444453*G0_1_0_1_0 - 0.000892857142857153*G0_1_0_1_1 + 0.000396825396825395*G0_1_0_2_2 - 0.000694444444444453*G0_1_1_0_0 - 0.000892857142857154*G0_1_1_0_1 - 0.000892857142857154*G0_1_1_1_0 - 0.00178571428571429*G0_1_1_1_1 + 0.000297619047619057*G0_1_1_1_2 + 0.000297619047619057*G0_1_1_2_1 + 0.000892857142857152*G0_1_1_2_2 + 0.000396825396825395*G0_1_2_0_2 + 0.000297619047619057*G0_1_2_1_1 + 0.000892857142857152*G0_1_2_1_2 + 0.000396825396825395*G0_1_2_2_0 + 0.000892857142857152*G0_1_2_2_1 + 0.00267857142857144*G0_1_2_2_2 + 0.000297619047619057*G0_2_0_0_0 + 0.000892857142857153*G0_2_0_0_2 + 0.000396825396825395*G0_2_0_1_2 + 0.000892857142857152*G0_2_0_2_0 + 0.000396825396825395*G0_2_0_2_1 + 0.00267857142857144*G0_2_0_2_2 + 0.000396825396825395*G0_2_1_0_2 + 0.000297619047619057*G0_2_1_1_1 + 0.000892857142857152*G0_2_1_1_2 + 0.000396825396825395*G0_2_1_2_0 + 0.000892857142857152*G0_2_1_2_1 + 0.00267857142857144*G0_2_1_2_2 + 0.000892857142857152*G0_2_2_0_0 + 0.000396825396825395*G0_2_2_0_1 + 0.00267857142857144*G0_2_2_0_2 + 0.000396825396825395*G0_2_2_1_0 + 0.000892857142857152*G0_2_2_1_1 + 0.00267857142857144*G0_2_2_1_2 + 0.00267857142857144*G0_2_2_2_0 + 0.00267857142857144*G0_2_2_2_1 + 0.0172619047619049*G0_2_2_2_2; + A[3] = A[1]; + A[4] = A[8] + 0.000595238095238104*G0_0_0_0_1 - 0.000595238095238104*G0_0_0_0_2 + 0.000595238095238104*G0_0_0_1_0 + 0.000992063492063502*G0_0_0_1_1 - 0.000595238095238104*G0_0_0_2_0 - 0.000992063492063502*G0_0_0_2_2 + 0.000595238095238104*G0_0_1_0_0 + 0.000992063492063502*G0_0_1_0_1 + 0.000992063492063502*G0_0_1_1_0 + 0.00267857142857144*G0_0_1_1_1 + 0.000297619047619046*G0_0_1_1_2 + 0.000297619047619046*G0_0_1_2_1 - 0.000297619047619046*G0_0_1_2_2 - 0.000595238095238104*G0_0_2_0_0 - 0.000992063492063502*G0_0_2_0_2 + 0.000297619047619046*G0_0_2_1_1 - 0.000297619047619047*G0_0_2_1_2 - 0.000992063492063502*G0_0_2_2_0 - 0.000297619047619047*G0_0_2_2_1 - 0.00267857142857144*G0_0_2_2_2 + 0.000595238095238104*G0_1_0_0_0 + 0.000992063492063502*G0_1_0_0_1 + 0.000992063492063502*G0_1_0_1_0 + 0.00267857142857144*G0_1_0_1_1 + 0.000297619047619046*G0_1_0_1_2 + 0.000297619047619046*G0_1_0_2_1 - 0.000297619047619047*G0_1_0_2_2 + 0.000992063492063502*G0_1_1_0_0 + 0.00267857142857144*G0_1_1_0_1 + 0.000297619047619046*G0_1_1_0_2 + 0.00267857142857144*G0_1_1_1_0 + 0.0166666666666668*G0_1_1_1_1 + 0.00208333333333334*G0_1_1_1_2 + 0.000297619047619046*G0_1_1_2_0 + 0.00208333333333334*G0_1_1_2_1 + 0.000297619047619046*G0_1_2_0_1 - 0.000297619047619047*G0_1_2_0_2 + 0.000297619047619046*G0_1_2_1_0 + 0.00208333333333334*G0_1_2_1_1 - 0.000297619047619047*G0_1_2_2_0 - 0.00208333333333334*G0_1_2_2_2 - 0.000595238095238104*G0_2_0_0_0 - 0.000992063492063502*G0_2_0_0_2 + 0.000297619047619046*G0_2_0_1_1 - 0.000297619047619047*G0_2_0_1_2 - 0.000992063492063502*G0_2_0_2_0 - 0.000297619047619047*G0_2_0_2_1 - 0.00267857142857144*G0_2_0_2_2 + 0.000297619047619046*G0_2_1_0_1 - 0.000297619047619047*G0_2_1_0_2 + 0.000297619047619046*G0_2_1_1_0 + 0.00208333333333334*G0_2_1_1_1 - 0.000297619047619047*G0_2_1_2_0 - 0.00208333333333334*G0_2_1_2_2 - 0.000992063492063502*G0_2_2_0_0 - 0.000297619047619047*G0_2_2_0_1 - 0.00267857142857144*G0_2_2_0_2 - 0.000297619047619047*G0_2_2_1_0 - 0.00208333333333334*G0_2_2_1_2 - 0.00267857142857144*G0_2_2_2_0 - 0.00208333333333334*G0_2_2_2_1 - 0.0166666666666668*G0_2_2_2_2; + A[6] = A[4] + 0.00178571428571429*G0_0_0_0_0 - 0.000297619047619057*G0_0_0_0_1 + 0.000892857142857153*G0_0_0_0_2 - 0.000297619047619057*G0_0_0_1_0 - 0.000892857142857152*G0_0_0_1_1 + 0.000892857142857154*G0_0_0_2_0 + 0.000694444444444454*G0_0_0_2_2 - 0.000297619047619057*G0_0_1_0_0 - 0.000892857142857152*G0_0_1_0_1 - 0.000892857142857152*G0_0_1_1_0 - 0.00267857142857144*G0_0_1_1_1 - 0.000396825396825395*G0_0_1_1_2 - 0.000396825396825395*G0_0_1_2_1 + 0.000892857142857153*G0_0_2_0_0 + 0.000694444444444453*G0_0_2_0_2 - 0.000396825396825395*G0_0_2_1_1 + 0.000694444444444454*G0_0_2_2_0 + 0.000892857142857154*G0_0_2_2_2 - 0.000297619047619057*G0_1_0_0_0 - 0.000892857142857152*G0_1_0_0_1 - 0.000892857142857152*G0_1_0_1_0 - 0.00267857142857144*G0_1_0_1_1 - 0.000396825396825395*G0_1_0_1_2 - 0.000396825396825395*G0_1_0_2_1 - 0.000892857142857152*G0_1_1_0_0 - 0.00267857142857144*G0_1_1_0_1 - 0.000396825396825395*G0_1_1_0_2 - 0.00267857142857144*G0_1_1_1_0 - 0.0172619047619049*G0_1_1_1_1 - 0.00267857142857144*G0_1_1_1_2 - 0.000396825396825395*G0_1_1_2_0 - 0.00267857142857144*G0_1_1_2_1 - 0.000892857142857152*G0_1_1_2_2 - 0.000396825396825395*G0_1_2_0_1 - 0.000396825396825395*G0_1_2_1_0 - 0.00267857142857144*G0_1_2_1_1 - 0.000892857142857152*G0_1_2_1_2 - 0.000892857142857152*G0_1_2_2_1 - 0.000297619047619057*G0_1_2_2_2 + 0.000892857142857154*G0_2_0_0_0 + 0.000694444444444454*G0_2_0_0_2 - 0.000396825396825395*G0_2_0_1_1 + 0.000694444444444454*G0_2_0_2_0 + 0.000892857142857154*G0_2_0_2_2 - 0.000396825396825395*G0_2_1_0_1 - 0.000396825396825395*G0_2_1_1_0 - 0.00267857142857144*G0_2_1_1_1 - 0.000892857142857152*G0_2_1_1_2 - 0.000892857142857152*G0_2_1_2_1 - 0.000297619047619057*G0_2_1_2_2 + 0.000694444444444454*G0_2_2_0_0 + 0.000892857142857154*G0_2_2_0_2 - 0.000892857142857152*G0_2_2_1_1 - 0.000297619047619057*G0_2_2_1_2 + 0.000892857142857154*G0_2_2_2_0 - 0.000297619047619057*G0_2_2_2_1 + 0.00178571428571429*G0_2_2_2_2; + A[2] = A[6]; + } + + /// 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 mass_matrix_f4_p1_q1_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f4_p1_q1_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_p1_q1_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 3), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1))))), 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 4; + } + + /// 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 mass_matrix_f4_p1_q1_tensor_finite_element_0(); + break; + } + case 1: + { + return new mass_matrix_f4_p1_q1_tensor_finite_element_0(); + break; + } + case 2: + { + return new mass_matrix_f4_p1_q1_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f4_p1_q1_tensor_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f4_p1_q1_tensor_finite_element_0(); + break; + } + case 5: + { + return new mass_matrix_f4_p1_q1_tensor_finite_element_0(); + 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 mass_matrix_f4_p1_q1_tensor_dofmap_0(); + break; + } + case 1: + { + return new mass_matrix_f4_p1_q1_tensor_dofmap_0(); + break; + } + case 2: + { + return new mass_matrix_f4_p1_q1_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f4_p1_q1_tensor_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f4_p1_q1_tensor_dofmap_0(); + break; + } + case 5: + { + return new mass_matrix_f4_p1_q1_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f4_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/mass_matrix_2d/mass_matrix_f4_p1_q2_excafe.h b/mass_matrix_2d/mass_matrix_f4_p1_q2_excafe.h new file mode 100644 index 0000000..70fe95c --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f4_p1_q2_excafe.h @@ -0,0 +1,175 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 0 minutes and 12.99 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 = -1.0000000000000000000000000*x[0][1]; + const double var_1 = -1.0000000000000000000000000*x[0][0]; + const double var_2 = x[1][0] + var_1; + const double var_3 = var_0 + x[2][1]; + const double var_4 = x[2][0] + var_1; + const double var_5 = var_0 + x[1][1]; + const double var_6 = var_2*var_3 + -1.0000000000000000000000000*var_4*var_5; + const double var_7 = std::abs(var_6); + const double var_8 = w[1][1]*w[2][2] + w[1][2]*w[2][1]; + const double var_9 = w[0][1]*w[3][2] + w[0][2]*w[3][1]; + const double var_10 = var_8*w[0][2]*w[3][2] + var_9*w[1][2]*w[2][2]; + const double var_11 = w[1][1]*w[2][0] + w[1][0]*w[2][1]; + const double var_12 = w[0][1]*w[3][0] + w[0][0]*w[3][1]; + const double var_13 = var_12*w[1][0]*w[2][0] + var_11*w[0][0]*w[3][0]; + const double var_14 = w[1][2]*w[2][0] + w[1][0]*w[2][2]; + const double var_15 = var_11*w[0][2] + var_14*w[0][1] + var_8*w[0][0]; + const double var_16 = var_14*w[3][1]; + const double var_17 = var_11*w[3][2]; + const double var_18 = var_17 + var_16; + const double var_19 = var_18*w[0][0] + var_9*w[1][0]*w[2][0] + var_15*w[3][0]; + const double var_20 = w[0][0]*w[1][0]*w[2][0]*w[3][0]; + const double var_21 = -0.0250000000000000013877788*var_19 + -0.3333333333333333148296163*var_20; + const double var_22 = var_8*w[3][0]; + const double var_23 = var_16 + var_22; + const double var_24 = var_23*w[0][2] + var_15*w[3][2] + var_12*w[1][2]*w[2][2]; + const double var_25 = w[0][2]*w[1][2]*w[2][2]*w[3][2]; + const double var_26 = -0.0666666666666666657414808*var_25 + -0.0166666666666666664353702*var_24; + const double var_27 = w[0][2]*w[3][0] + w[0][0]*w[3][2]; + const double var_28 = var_14*w[0][2]*w[3][2] + var_27*w[1][2]*w[2][2]; + const double var_29 = var_8*w[0][1]*w[3][1] + var_9*w[1][1]*w[2][1]; + const double var_30 = -0.0666666666666666657414808*var_28 + 0.1666666666666666574148081*var_29; + const double var_31 = var_14*w[0][0]*w[3][0] + var_27*w[1][0]*w[2][0]; + const double var_32 = var_11*w[0][1]*w[3][1] + var_12*w[1][1]*w[2][1]; + const double var_33 = -0.0666666666666666657414808*var_31 + 0.1666666666666666574148081*var_32; + const double var_34 = var_14*var_27 + w[0][2]*w[1][0]*w[2][0]*w[3][2] + w[0][0]*w[1][2]*w[2][2]*w[3][0]; + const double var_35 = w[0][1]*w[1][1]*w[2][1]*w[3][1]; + const double var_36 = -0.0333333333333333328707404*var_34 + var_35; + const double var_37 = -0.1000000000000000055511151*var_13 + var_21 + var_33 + 0.5000000000000000000000000*var_30 + -0.0250000000000000013877788*var_10 + var_26 + var_36; + A[11] = 0.0031746031746031746004211*var_37*var_7; + A[31] = A[11]; + const double var_38 = var_24 + var_19; + const double var_39 = var_32 + var_29; + const double var_40 = var_25 + var_20; + const double var_41 = 0.1000000000000000055511151*var_34 + 0.3333333333333333148296163*var_40; + const double var_42 = var_17 + var_22; + const double var_43 = var_27*w[1][1]*w[2][1] + var_42*w[0][1] + var_15*w[3][1]; + const double var_44 = var_31 + var_28; + const double var_45 = var_44 + var_43; + const double var_46 = var_8*var_9 + w[0][2]*w[1][1]*w[2][1]*w[3][2] + w[0][1]*w[1][2]*w[2][2]*w[3][1]; + const double var_47 = w[0][1]*w[1][0]*w[2][0]*w[3][1] + var_11*var_12 + w[0][0]*w[1][1]*w[2][1]*w[3][0]; + const double var_48 = var_46 + var_47; + const double var_49 = var_10 + var_13; + const double var_50 = var_48 + var_49; + const double var_51 = var_35 + var_41 + 0.1333333333333333314829616*var_45 + 0.3333333333333333148296163*var_39 + 0.1000000000000000055511151*var_38 + 0.2000000000000000111022302*var_50; + A[23] = 0.0031746031746031746004211*var_51*var_7; + A[33] = A[23]; + const double var_52 = var_20 + var_35; + const double var_53 = var_31 + var_29; + const double var_54 = var_32 + var_13; + const double var_55 = var_10 + var_28; + const double var_56 = var_46 + var_34; + const double var_57 = var_43 + var_19; + const double var_58 = var_56 + -1.0000000000000000000000000*var_57; + const double var_59 = -0.0873015873015872967410900*var_52 + -0.0079365079365079360673718*var_53 + -0.0158730158730158721347436*var_54 + -0.0071428571428571426341070*var_47 + 0.0015873015873015873002105*var_24 + 0.0055555555555555557675773*var_55 + 0.0206349206349206344690561*w[0][2]*w[1][2]*w[2][2]*w[3][2] + 0.0007936507936507936501053*var_58; + A[1] = 0.0083333333333333332176851*var_59*var_7; + A[6] = A[1]; + const double var_60 = -0.0166666666666666664353702*var_19 + -0.0666666666666666657414808*var_20; + const double var_61 = 0.5000000000000000000000000*var_24 + var_57; + const double var_62 = 0.3333333333333333148296163*var_52 + 0.1000000000000000055511151*var_47; + const double var_63 = -0.0083333333333333332176851*var_56 + -0.0222222222222222230703093*var_53 + -0.0333333333333333328707404*var_54 + -0.0111111111111111115351546*var_61 + -0.2500000000000000000000000*var_62 + 0.0277777777777777762358014*var_25; + A[17] = 0.0095238095238095246686250*var_63*var_7; + const double var_64 = 5.6666666666666660745477202*w[0][1]*w[1][1]*w[2][1]*w[3][1] + 0.0555555555555555524716027*var_43 + 0.1111111111111111049432054*var_48 + 0.0500000000000000027755576*var_44 + 0.2000000000000000111022302*var_40 + 0.5000000000000000000000000*var_39 + 0.0333333333333333328707404*var_34 + 0.0277777777777777762358014*var_38 + 0.0833333333333333287074041*var_49; + const double var_65 = -0.0250000000000000013877788*var_43 + -0.3333333333333333148296163*var_35; + const double var_66 = -0.0666666666666666657414808*var_10 + 0.1666666666666666574148081*var_31; + const double var_67 = 0.1666666666666666574148081*var_13 + -0.0666666666666666657414808*var_29; + const double var_68 = -0.0333333333333333328707404*var_46 + var_20; + const double var_69 = var_65 + -0.1000000000000000055511151*var_32 + 0.5000000000000000000000000*var_66 + -0.0250000000000000013877788*var_28 + var_68 + var_26 + var_67; + A[5] = 0.0031746031746031746004211*var_69*var_7; + const double var_70 = var_34 + var_47; + const double var_71 = var_28 + var_32; + const double var_72 = var_10 + var_29; + const double var_73 = var_24 + var_43; + const double var_74 = 0.5000000000000000000000000*var_19 + var_73; + const double var_75 = var_25 + var_35; + const double var_76 = 0.1000000000000000055511151*var_46 + 0.3333333333333333148296163*var_75; + const double var_77 = -0.0083333333333333332176851*var_70 + 0.0277777777777777762358014*var_20 + -0.0333333333333333328707404*var_72 + -0.0222222222222222230703093*var_71 + -0.2500000000000000000000000*var_76 + -0.0111111111111111115351546*var_74; + A[3] = 0.0095238095238095246686250*var_7*var_77; + const double var_78 = -0.3333333333333333148296163*var_25 + -0.0250000000000000013877788*var_24; + const double var_79 = -0.0250000000000000013877788*var_13 + 0.5000000000000000000000000*var_33 + var_30 + var_78 + -0.1000000000000000055511151*var_10 + var_60 + var_36; + const double var_80 = var_38 + 0.5000000000000000000000000*var_43; + const double var_81 = 0.0277777777777777762358014*var_35 + -0.0083333333333333332176851*var_48 + -0.2500000000000000000000000*var_41 + -0.0333333333333333328707404*var_44 + -0.0111111111111111115351546*var_80 + -0.0222222222222222230703093*var_49; + A[10] = 0.0095238095238095246686250*var_7*var_81; + const double var_82 = var_48 + var_35; + const double var_83 = 0.1333333333333333314829616*var_82 + var_44 + 2.0000000000000000000000000*var_40 + 0.2000000000000000111022302*var_80 + 0.1000000000000000055511151*var_39 + 0.8000000000000000444089210*var_34 + 0.3333333333333333148296163*var_49; + A[28] = 0.0031746031746031746004211*var_7*var_83; + const double var_84 = 0.1666666666666666574148081*var_10 + -0.0666666666666666657414808*var_32; + const double var_85 = 0.1666666666666666574148081*var_28 + -0.0666666666666666657414808*var_13; + const double var_86 = var_25 + -0.0333333333333333328707404*var_47; + const double var_87 = 0.5000000000000000000000000*var_85 + var_65 + var_84 + var_86 + -0.0250000000000000013877788*var_31 + -0.1000000000000000055511151*var_29 + var_60; + A[15] = 0.0031746031746031746004211*var_7*var_87; + const double var_88 = -0.0166666666666666664353702*var_43 + -0.0666666666666666657414808*var_35; + const double var_89 = -0.0250000000000000013877788*var_32 + var_66 + var_68 + -0.1000000000000000055511151*var_28 + var_78 + var_88 + 0.5000000000000000000000000*var_67; + A[4] = 0.0031746031746031746004211*var_7*var_89; + const double var_90 = var_31 + var_13; + const double var_91 = var_71 + var_70; + const double var_92 = var_72 + var_19; + const double var_93 = 0.1000000000000000055511151*var_73 + var_20 + 0.3333333333333333148296163*var_90 + var_76 + 0.2000000000000000111022302*var_91 + 0.1333333333333333314829616*var_92; + A[29] = 0.0031746031746031746004211*var_7*var_93; + A[34] = A[29]; + const double var_94 = -1.0000000000000000000000000*var_38 + var_48; + A[7] = 0.0011904761904761905835781*var_64*var_7; + const double var_95 = 0.1111111111111111049432054*var_70 + 0.0277777777777777762358014*var_73 + 0.5000000000000000000000000*var_90 + 0.0500000000000000027755576*var_72 + 0.0555555555555555524716027*var_19 + 0.0833333333333333287074041*var_71 + 5.6666666666666660745477202*w[0][0]*w[1][0]*w[2][0]*w[3][0] + 0.0333333333333333328707404*var_46 + 0.2000000000000000111022302*var_75; + A[0] = 0.0011904761904761905835781*var_7*var_95; + const double var_96 = 0.0206349206349206344690561*w[0][1]*w[1][1]*w[2][1]*w[3][1] + 0.0015873015873015873002105*var_43 + 0.0007936507936507936501053*var_94 + -0.0158730158730158721347436*var_44 + -0.0873015873015872967410900*var_40 + 0.0055555555555555557675773*var_39 + -0.0071428571428571426341070*var_34 + -0.0079365079365079360673718*var_49; + A[2] = 0.0083333333333333332176851*var_7*var_96; + A[12] = A[2]; + const double var_97 = var_56 + var_53; + A[20] = A[15]; + const double var_98 = var_70 + -1.0000000000000000000000000*var_73; + const double var_99 = 0.0007936507936507936501053*var_98 + -0.0158730158730158721347436*var_72 + 0.0015873015873015873002105*var_19 + 0.0055555555555555557675773*var_90 + 0.0206349206349206344690561*w[0][0]*w[1][0]*w[2][0]*w[3][0] + -0.0079365079365079360673718*var_71 + -0.0071428571428571426341070*var_46 + -0.0873015873015872967410900*var_75; + A[8] = 0.0083333333333333332176851*var_7*var_99; + A[13] = A[8]; + const double var_100 = var_56 + var_25; + const double var_101 = 0.2000000000000000111022302*var_61 + 0.3333333333333333148296163*var_53 + 2.0000000000000000000000000*var_52 + var_54 + 0.8000000000000000444089210*var_47 + 0.1000000000000000055511151*var_55 + 0.1333333333333333314829616*var_100; + A[35] = 0.0031746031746031746004211*var_101*var_7; + const double var_102 = var_70 + var_20; + const double var_103 = var_72 + 0.1000000000000000055511151*var_90 + 0.3333333333333333148296163*var_71 + 0.1333333333333333314829616*var_102 + 0.8000000000000000444089210*var_46 + 2.0000000000000000000000000*var_75 + 0.2000000000000000111022302*var_74; + A[21] = 0.0031746031746031746004211*var_103*var_7; + A[9] = 0.0031746031746031746004211*var_7*var_79; + A[19] = A[9]; + const double var_104 = var_54 + var_24; + const double var_105 = 0.1000000000000000055511151*var_57 + var_62 + 0.1333333333333333314829616*var_104 + 0.3333333333333333148296163*var_55 + 0.2000000000000000111022302*var_97 + var_25; + A[22] = 0.0031746031746031746004211*var_105*var_7; + A[18] = A[3]; + A[32] = A[17]; + const double var_106 = var_21 + var_85 + 0.5000000000000000000000000*var_84 + var_86 + -0.1000000000000000055511151*var_31 + -0.0250000000000000013877788*var_29 + var_88; + A[16] = 0.0031746031746031746004211*var_106*var_7; + A[26] = A[16]; + A[25] = A[10]; + A[30] = A[5]; + A[24] = A[4]; + const double var_107 = 0.0277777777777777762358014*var_57 + 0.1111111111111111049432054*var_56 + 0.0500000000000000027755576*var_54 + 0.0833333333333333287074041*var_53 + 0.2000000000000000111022302*var_52 + 0.0333333333333333328707404*var_47 + 0.0555555555555555524716027*var_24 + 5.6666666666666660745477202*w[0][2]*w[1][2]*w[2][2]*w[3][2] + 0.5000000000000000000000000*var_55; + A[14] = 0.0011904761904761905835781*var_107*var_7; + A[27] = A[22]; + } + + 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/mass_matrix_2d/mass_matrix_f4_p1_q2_quadrature.h b/mass_matrix_2d/mass_matrix_f4_p1_q2_quadrature.h new file mode 100644 index 0000000..481851d --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f4_p1_q2_quadrature.h @@ -0,0 +1,3429 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F4_P1_Q2_QUADRATURE_H +#define __MASS_MATRIX_F4_P1_Q2_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f4_p1_q2_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f4_p1_q2_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_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 mass_matrix_f4_p1_q2_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f4_p1_q2_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f4_p1_q2_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_p1_q2_quadrature_finite_element_1() + { + // 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f4_p1_q2_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f4_p1_q2_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f4_p1_q2_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f4_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 mass_matrix_f4_p1_q2_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f4_p1_q2_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f4_p1_q2_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f4_p1_q2_quadrature_dofmap_1() + { + // 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 mass_matrix_f4_p1_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 mass_matrix_f4_p1_q2_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f4_p1_q2_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // 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[25][3] = \ + {{0.915147549378728, 0.0450425935698037, 0.0398098570514687}, + {0.764365329781281, 0.0376212523451112, 0.198013417873608}, + {0.535660544808143, 0.026364644944471, 0.437974810247386}, + {0.290249932250793, 0.0142857943955714, 0.695464273353636}, + {0.09391279733378, 0.00462228846504648, 0.901464914201173}, + {0.738611533396152, 0.221578609552379, 0.0398098570514687}, + {0.616915871859002, 0.185070710267389, 0.198013417873608}, + {0.43232925297036, 0.129695936782254, 0.437974810247386}, + {0.234259434638082, 0.0702762920082818, 0.695464273353636}, + {0.0757966027350624, 0.0227384830637641, 0.901464914201173}, + {0.480095071474266, 0.480095071474266, 0.0398098570514687}, + {0.400993291063196, 0.400993291063196, 0.198013417873608}, + {0.281012594876307, 0.281012594876307, 0.437974810247386}, + {0.152267863323182, 0.152267863323182, 0.695464273353636}, + {0.0492675428994132, 0.0492675428994133, 0.901464914201173}, + {0.221578609552379, 0.738611533396152, 0.0398098570514687}, + {0.185070710267389, 0.616915871859002, 0.198013417873608}, + {0.129695936782254, 0.43232925297036, 0.437974810247386}, + {0.0702762920082818, 0.234259434638082, 0.695464273353636}, + {0.022738483063764, 0.0757966027350624, 0.901464914201173}, + {0.0450425935698037, 0.915147549378728, 0.0398098570514687}, + {0.0376212523451112, 0.764365329781281, 0.198013417873608}, + {0.0263646449444709, 0.535660544808143, 0.437974810247386}, + {0.0142857943955715, 0.290249932250793, 0.695464273353636}, + {0.00462228846504642, 0.0939127973337801, 0.901464914201173}}; + + static const double FE1[25][6] = \ + {{0.759842524889053, -0.0409849230988147, -0.036640207614552, 0.00717255684496526, 0.145727572487076, 0.164882476492272}, + {0.404143384962011, -0.0347905350890822, -0.119594790557632, 0.0297980510461641, 0.605418365816316, 0.115025523822223}, + {0.03820389372017, -0.0249744559383749, -0.0543309414249184, 0.0461882014671776, 0.938423301877432, 0.0564900002985143}, + {-0.121759885907613, -0.0138776265525463, 0.271876837668966, 0.0397410384743821, 0.807433832894958, 0.0165858034218534}, + {-0.0762735703276687, -0.00457955736373819, 0.723813068870285, 0.0166673234982246, 0.338636367163553, 0.00173636815934475}, + {0.352482461135478, -0.123384449130048, -0.036640207614552, 0.0352840510877738, 0.117616078244268, 0.65464206627708}, + {0.144254514044104, -0.116568374669637, -0.119594790557632, 0.146585935553368, 0.488630481309112, 0.456692234320686}, + {-0.0585120870225412, -0.0960538647466012, -0.0543309414249184, 0.227214213208259, 0.75739729013635, 0.224285389849452}, + {-0.124504469204174, -0.0603987775714151, 0.271876837668966, 0.19549860142211, 0.65167626994723, 0.0658515377372835}, + {-0.0643063527627087, -0.0217044058396818, 0.723813068870285, 0.0819917787365635, 0.273311911925214, 0.00689399907032831}, + {-0.0191125161665053, -0.0191125161665052, -0.036640207614552, 0.0764500646660208, 0.0764500646660208, 0.921965110615521}, + {-0.0794020521078101, -0.07940205210781, -0.119594790557632, 0.31760820843124, 0.31760820843124, 0.643182477910772}, + {-0.123076437918076, -0.123076437918076, -0.0543309414249183, 0.492305751672305, 0.492305751672305, 0.315872313916462}, + {-0.105896858921168, -0.105896858921168, 0.271876837668966, 0.42358743568467, 0.42358743568467, 0.092742008804029}, + {-0.0444129613327222, -0.0444129613327222, 0.723813068870285, 0.177651845330889, 0.177651845330889, 0.00970916313338213}, + {-0.123384449130048, 0.352482461135478, -0.036640207614552, 0.117616078244268, 0.0352840510877737, 0.65464206627708}, + {-0.116568374669637, 0.144254514044104, -0.119594790557632, 0.488630481309112, 0.146585935553368, 0.456692234320686}, + {-0.0960538647466012, -0.0585120870225412, -0.0543309414249183, 0.75739729013635, 0.227214213208259, 0.224285389849452}, + {-0.0603987775714152, -0.124504469204174, 0.271876837668966, 0.65167626994723, 0.195498601422111, 0.0658515377372835}, + {-0.0217044058396819, -0.0643063527627086, 0.723813068870285, 0.273311911925214, 0.0819917787365634, 0.00689399907032831}, + {-0.0409849230988147, 0.759842524889054, -0.036640207614552, 0.145727572487076, 0.00717255684496518, 0.164882476492272}, + {-0.0347905350890822, 0.404143384962011, -0.119594790557632, 0.605418365816316, 0.0297980510461639, 0.115025523822223}, + {-0.024974455938375, 0.03820389372017, -0.0543309414249183, 0.938423301877431, 0.0461882014671776, 0.0564900002985144}, + {-0.0138776265525464, -0.121759885907613, 0.271876837668966, 0.807433832894958, 0.0397410384743823, 0.0165858034218536}, + {-0.00457955736373822, -0.0762735703276687, 0.723813068870285, 0.338636367163553, 0.0166673234982245, 0.00173636815934475}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 36; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 3425 + 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 = 24 + for (unsigned int r = 0; r < 3; r++) + { + F0 += FE0[ip][r]*w[3][r]; + F1 += FE0[ip][r]*w[2][r]; + F2 += FE0[ip][r]*w[0][r]; + F3 += FE0[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 5 + double I[1]; + // Number of operations: 5 + I[0] = F0*F1*F2*F3*W25[ip]*det; + + + // Number of operations for primary indices: 108 + for (unsigned int j = 0; j < 6; j++) + { + for (unsigned int k = 0; k < 6; k++) + { + // Number of operations to compute entry: 3 + A[j*6 + k] += FE1[ip][j]*FE1[ip][k]*I[0]; + }// 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 mass_matrix_f4_p1_q2_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f4_p1_q2_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_p1_q2_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 3), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1))))), 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 4; + } + + /// 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 mass_matrix_f4_p1_q2_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f4_p1_q2_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f4_p1_q2_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f4_p1_q2_quadrature_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f4_p1_q2_quadrature_finite_element_0(); + break; + } + case 5: + { + return new mass_matrix_f4_p1_q2_quadrature_finite_element_0(); + 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 mass_matrix_f4_p1_q2_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f4_p1_q2_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f4_p1_q2_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f4_p1_q2_quadrature_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f4_p1_q2_quadrature_dofmap_0(); + break; + } + case 5: + { + return new mass_matrix_f4_p1_q2_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f4_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/mass_matrix_2d/mass_matrix_f4_p1_q2_tensor.h b/mass_matrix_2d/mass_matrix_f4_p1_q2_tensor.h new file mode 100644 index 0000000..2269412 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f4_p1_q2_tensor.h @@ -0,0 +1,3445 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F4_P1_Q2_TENSOR_H +#define __MASS_MATRIX_F4_P1_Q2_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f4_p1_q2_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f4_p1_q2_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_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 mass_matrix_f4_p1_q2_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f4_p1_q2_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f4_p1_q2_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_p1_q2_tensor_finite_element_1() + { + // 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f4_p1_q2_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f4_p1_q2_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f4_p1_q2_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f4_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 mass_matrix_f4_p1_q2_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f4_p1_q2_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f4_p1_q2_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f4_p1_q2_tensor_dofmap_1() + { + // 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 mass_matrix_f4_p1_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 mass_matrix_f4_p1_q2_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f4_p1_q2_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 202 + // Number of operations (multiply-add pairs) for tensor contraction: 1339 + // Total number of operations (multiply-add pairs): 1550 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0_0 = det*w[3][0]*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_0_0_0_1 = det*w[3][0]*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_0_0_0_2 = det*w[3][0]*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_0_0_1_0 = det*w[3][0]*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_0_0_1_1 = det*w[3][0]*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_0_0_1_2 = det*w[3][0]*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_0_0_2_0 = det*w[3][0]*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_0_0_2_1 = det*w[3][0]*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_0_0_2_2 = det*w[3][0]*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_0_1_0_0 = det*w[3][0]*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_0_1_0_1 = det*w[3][0]*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_0_1_0_2 = det*w[3][0]*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_0_1_1_0 = det*w[3][0]*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_0_1_1_1 = det*w[3][0]*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_0_1_1_2 = det*w[3][0]*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_0_1_2_0 = det*w[3][0]*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_0_1_2_1 = det*w[3][0]*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_0_1_2_2 = det*w[3][0]*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_0_2_0_0 = det*w[3][0]*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_0_2_0_1 = det*w[3][0]*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_0_2_0_2 = det*w[3][0]*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_0_2_1_0 = det*w[3][0]*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_0_2_1_1 = det*w[3][0]*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_0_2_1_2 = det*w[3][0]*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_0_2_2_0 = det*w[3][0]*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_0_2_2_1 = det*w[3][0]*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_0_2_2_2 = det*w[3][0]*w[2][2]*w[0][2]*w[1][2]*(1.0); + const double G0_1_0_0_0 = det*w[3][1]*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_1_0_0_1 = det*w[3][1]*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_1_0_0_2 = det*w[3][1]*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_1_0_1_0 = det*w[3][1]*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_1_0_1_1 = det*w[3][1]*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_1_0_1_2 = det*w[3][1]*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_1_0_2_0 = det*w[3][1]*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_1_0_2_1 = det*w[3][1]*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_1_0_2_2 = det*w[3][1]*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_1_1_0_0 = det*w[3][1]*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_1_1_0_1 = det*w[3][1]*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_1_1_0_2 = det*w[3][1]*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_1_1_1_0 = det*w[3][1]*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_1_1_1_1 = det*w[3][1]*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_1_1_1_2 = det*w[3][1]*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_1_1_2_0 = det*w[3][1]*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_1_1_2_1 = det*w[3][1]*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_1_1_2_2 = det*w[3][1]*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_1_2_0_0 = det*w[3][1]*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_1_2_0_1 = det*w[3][1]*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_1_2_0_2 = det*w[3][1]*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_1_2_1_0 = det*w[3][1]*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_1_2_1_1 = det*w[3][1]*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_1_2_1_2 = det*w[3][1]*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_1_2_2_0 = det*w[3][1]*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_1_2_2_1 = det*w[3][1]*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_1_2_2_2 = det*w[3][1]*w[2][2]*w[0][2]*w[1][2]*(1.0); + const double G0_2_0_0_0 = det*w[3][2]*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_2_0_0_1 = det*w[3][2]*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_2_0_0_2 = det*w[3][2]*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_2_0_1_0 = det*w[3][2]*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_2_0_1_1 = det*w[3][2]*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_2_0_1_2 = det*w[3][2]*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_2_0_2_0 = det*w[3][2]*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_2_0_2_1 = det*w[3][2]*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_2_0_2_2 = det*w[3][2]*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_2_1_0_0 = det*w[3][2]*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_2_1_0_1 = det*w[3][2]*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_2_1_0_2 = det*w[3][2]*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_2_1_1_0 = det*w[3][2]*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_2_1_1_1 = det*w[3][2]*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_2_1_1_2 = det*w[3][2]*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_2_1_2_0 = det*w[3][2]*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_2_1_2_1 = det*w[3][2]*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_2_1_2_2 = det*w[3][2]*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_2_2_0_0 = det*w[3][2]*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_2_2_0_1 = det*w[3][2]*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_2_2_0_2 = det*w[3][2]*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_2_2_1_0 = det*w[3][2]*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_2_2_1_1 = det*w[3][2]*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_2_2_1_2 = det*w[3][2]*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_2_2_2_0 = det*w[3][2]*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_2_2_2_1 = det*w[3][2]*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_2_2_2_2 = det*w[3][2]*w[2][2]*w[0][2]*w[1][2]*(1.0); + + // Compute element tensor + A[9] = -0.000211640211640211*G0_0_0_0_0 - 7.93650793650791e-05*G0_0_0_0_1 - 0.000105820105820105*G0_0_0_0_2 - 7.93650793650791e-05*G0_0_0_1_0 - 5.29100529100528e-05*G0_0_0_1_2 - 0.000105820105820105*G0_0_0_2_0 - 5.29100529100527e-05*G0_0_0_2_1 - 0.000105820105820105*G0_0_0_2_2 - 7.93650793650791e-05*G0_0_1_0_0 - 5.29100529100528e-05*G0_0_1_0_2 + 0.000264550264550263*G0_0_1_1_1 - 5.29100529100527e-05*G0_0_1_2_0 - 7.93650793650791e-05*G0_0_1_2_2 - 0.000105820105820105*G0_0_2_0_0 - 5.29100529100527e-05*G0_0_2_0_1 - 0.000105820105820105*G0_0_2_0_2 - 5.29100529100527e-05*G0_0_2_1_0 - 7.93650793650791e-05*G0_0_2_1_2 - 0.000105820105820105*G0_0_2_2_0 - 7.93650793650791e-05*G0_0_2_2_1 - 0.000211640211640211*G0_0_2_2_2 - 7.93650793650791e-05*G0_1_0_0_0 - 5.29100529100527e-05*G0_1_0_0_2 + 0.000264550264550263*G0_1_0_1_1 - 5.29100529100527e-05*G0_1_0_2_0 - 7.93650793650791e-05*G0_1_0_2_2 + 0.000264550264550263*G0_1_1_0_1 + 0.000264550264550263*G0_1_1_1_0 + 0.00317460317460316*G0_1_1_1_1 + 0.000529100529100527*G0_1_1_1_2 + 0.000529100529100527*G0_1_1_2_1 - 5.29100529100527e-05*G0_1_2_0_0 - 7.93650793650791e-05*G0_1_2_0_2 + 0.000529100529100527*G0_1_2_1_1 - 7.93650793650791e-05*G0_1_2_2_0 - 0.000317460317460316*G0_1_2_2_2 - 0.000105820105820105*G0_2_0_0_0 - 5.29100529100527e-05*G0_2_0_0_1 - 0.000105820105820105*G0_2_0_0_2 - 5.29100529100527e-05*G0_2_0_1_0 - 7.93650793650791e-05*G0_2_0_1_2 - 0.000105820105820105*G0_2_0_2_0 - 7.93650793650791e-05*G0_2_0_2_1 - 0.000211640211640211*G0_2_0_2_2 - 5.29100529100527e-05*G0_2_1_0_0 - 7.93650793650791e-05*G0_2_1_0_2 + 0.000529100529100527*G0_2_1_1_1 - 7.93650793650791e-05*G0_2_1_2_0 - 0.000317460317460316*G0_2_1_2_2 - 0.000105820105820105*G0_2_2_0_0 - 7.93650793650791e-05*G0_2_2_0_1 - 0.000211640211640211*G0_2_2_0_2 - 7.93650793650791e-05*G0_2_2_1_0 - 0.000317460317460316*G0_2_2_1_2 - 0.000211640211640211*G0_2_2_2_0 - 0.000317460317460316*G0_2_2_2_1 - 0.00105820105820105*G0_2_2_2_2; + A[18] = A[9] + 0.000476190476190476*G0_0_0_0_0 + 7.93650793650792e-05*G0_0_0_0_1 + 0.000105820105820106*G0_0_0_0_2 + 7.93650793650791e-05*G0_0_0_1_0 - 7.9365079365079e-05*G0_0_0_1_1 + 0.000105820105820106*G0_0_0_2_0 + 2.64550264550264e-05*G0_0_0_2_2 + 7.93650793650792e-05*G0_0_1_0_0 - 7.9365079365079e-05*G0_0_1_0_1 - 7.9365079365079e-05*G0_0_1_1_0 - 0.000476190476190474*G0_0_1_1_1 - 0.000105820105820105*G0_0_1_1_2 - 0.000105820105820105*G0_0_1_2_1 - 2.64550264550263e-05*G0_0_1_2_2 + 0.000105820105820106*G0_0_2_0_0 + 2.64550264550264e-05*G0_0_2_0_2 - 0.000105820105820105*G0_0_2_1_1 - 2.64550264550264e-05*G0_0_2_1_2 + 2.64550264550264e-05*G0_0_2_2_0 - 2.64550264550264e-05*G0_0_2_2_1 + 7.93650793650791e-05*G0_1_0_0_0 - 7.9365079365079e-05*G0_1_0_0_1 - 7.93650793650789e-05*G0_1_0_1_0 - 0.000476190476190474*G0_1_0_1_1 - 0.000105820105820105*G0_1_0_1_2 - 0.000105820105820105*G0_1_0_2_1 - 2.64550264550263e-05*G0_1_0_2_2 - 7.9365079365079e-05*G0_1_1_0_0 - 0.000476190476190474*G0_1_1_0_1 - 0.000105820105820105*G0_1_1_0_2 - 0.000476190476190474*G0_1_1_1_0 - 0.00396825396825395*G0_1_1_1_1 - 0.000846560846560843*G0_1_1_1_2 - 0.000105820105820105*G0_1_1_2_0 - 0.000846560846560843*G0_1_1_2_1 - 0.000238095238095237*G0_1_1_2_2 - 0.000105820105820105*G0_1_2_0_1 - 2.64550264550264e-05*G0_1_2_0_2 - 0.000105820105820105*G0_1_2_1_0 - 0.000846560846560843*G0_1_2_1_1 - 0.000238095238095237*G0_1_2_1_2 - 2.64550264550264e-05*G0_1_2_2_0 - 0.000238095238095237*G0_1_2_2_1 + 0.000105820105820106*G0_2_0_0_0 + 2.64550264550264e-05*G0_2_0_0_2 - 0.000105820105820105*G0_2_0_1_1 - 2.64550264550263e-05*G0_2_0_1_2 + 2.64550264550264e-05*G0_2_0_2_0 - 2.64550264550264e-05*G0_2_0_2_1 - 0.000105820105820105*G0_2_1_0_1 - 2.64550264550263e-05*G0_2_1_0_2 - 0.000105820105820105*G0_2_1_1_0 - 0.000846560846560843*G0_2_1_1_1 - 0.000238095238095237*G0_2_1_1_2 - 2.64550264550263e-05*G0_2_1_2_0 - 0.000238095238095237*G0_2_1_2_1 + 2.64550264550264e-05*G0_2_2_0_0 - 2.64550264550264e-05*G0_2_2_0_1 - 2.64550264550264e-05*G0_2_2_1_0 - 0.000238095238095237*G0_2_2_1_1 + 0.000264550264550263*G0_2_2_2_2; + A[20] = -0.000211640211640211*G0_0_0_0_0 - 0.000105820105820105*G0_0_0_0_1 - 7.93650793650792e-05*G0_0_0_0_2 - 0.000105820105820105*G0_0_0_1_0 - 0.000105820105820105*G0_0_0_1_1 - 5.29100529100527e-05*G0_0_0_1_2 - 7.93650793650792e-05*G0_0_0_2_0 - 5.29100529100527e-05*G0_0_0_2_1 - 0.000105820105820105*G0_0_1_0_0 - 0.000105820105820105*G0_0_1_0_1 - 5.29100529100527e-05*G0_0_1_0_2 - 0.000105820105820105*G0_0_1_1_0 - 0.000211640211640211*G0_0_1_1_1 - 7.93650793650791e-05*G0_0_1_1_2 - 5.29100529100527e-05*G0_0_1_2_0 - 7.93650793650791e-05*G0_0_1_2_1 - 7.93650793650792e-05*G0_0_2_0_0 - 5.29100529100527e-05*G0_0_2_0_1 - 5.29100529100527e-05*G0_0_2_1_0 - 7.93650793650791e-05*G0_0_2_1_1 + 0.000264550264550263*G0_0_2_2_2 - 0.000105820105820105*G0_1_0_0_0 - 0.000105820105820105*G0_1_0_0_1 - 5.29100529100527e-05*G0_1_0_0_2 - 0.000105820105820105*G0_1_0_1_0 - 0.000211640211640211*G0_1_0_1_1 - 7.93650793650791e-05*G0_1_0_1_2 - 5.29100529100527e-05*G0_1_0_2_0 - 7.93650793650791e-05*G0_1_0_2_1 - 0.000105820105820105*G0_1_1_0_0 - 0.000211640211640211*G0_1_1_0_1 - 7.93650793650791e-05*G0_1_1_0_2 - 0.000211640211640211*G0_1_1_1_0 - 0.00105820105820105*G0_1_1_1_1 - 0.000317460317460316*G0_1_1_1_2 - 7.93650793650791e-05*G0_1_1_2_0 - 0.000317460317460316*G0_1_1_2_1 - 5.29100529100527e-05*G0_1_2_0_0 - 7.93650793650791e-05*G0_1_2_0_1 - 7.93650793650791e-05*G0_1_2_1_0 - 0.000317460317460316*G0_1_2_1_1 + 0.000529100529100526*G0_1_2_2_2 - 7.93650793650792e-05*G0_2_0_0_0 - 5.29100529100527e-05*G0_2_0_0_1 - 5.29100529100527e-05*G0_2_0_1_0 - 7.93650793650791e-05*G0_2_0_1_1 + 0.000264550264550263*G0_2_0_2_2 - 5.29100529100527e-05*G0_2_1_0_0 - 7.93650793650791e-05*G0_2_1_0_1 - 7.93650793650791e-05*G0_2_1_1_0 - 0.000317460317460316*G0_2_1_1_1 + 0.000529100529100526*G0_2_1_2_2 + 0.000264550264550263*G0_2_2_0_2 + 0.000529100529100526*G0_2_2_1_2 + 0.000264550264550263*G0_2_2_2_0 + 0.000529100529100526*G0_2_2_2_1 + 0.00317460317460316*G0_2_2_2_2; + A[13] = 0.000171957671957671*G0_0_0_0_0 + 4.62962962962961e-05*G0_0_0_0_1 + 4.62962962962962e-05*G0_0_0_0_2 + 4.62962962962961e-05*G0_0_0_1_0 + 6.61375661375662e-06*G0_0_0_1_1 + 1.32275132275132e-05*G0_0_0_1_2 + 4.62962962962962e-05*G0_0_0_2_0 + 1.32275132275132e-05*G0_0_0_2_1 + 6.61375661375663e-06*G0_0_0_2_2 + 4.62962962962961e-05*G0_0_1_0_0 + 6.61375661375662e-06*G0_0_1_0_1 + 1.32275132275132e-05*G0_0_1_0_2 + 6.61375661375662e-06*G0_0_1_1_0 - 6.61375661375658e-05*G0_0_1_1_1 - 6.61375661375657e-06*G0_0_1_1_2 + 1.32275132275132e-05*G0_0_1_2_0 - 6.61375661375657e-06*G0_0_1_2_1 - 6.61375661375658e-06*G0_0_1_2_2 + 4.62962962962962e-05*G0_0_2_0_0 + 1.32275132275132e-05*G0_0_2_0_1 + 6.61375661375663e-06*G0_0_2_0_2 + 1.32275132275132e-05*G0_0_2_1_0 - 6.61375661375657e-06*G0_0_2_1_1 - 6.61375661375658e-06*G0_0_2_1_2 + 6.61375661375663e-06*G0_0_2_2_0 - 6.61375661375658e-06*G0_0_2_2_1 - 6.61375661375657e-05*G0_0_2_2_2 + 4.62962962962961e-05*G0_1_0_0_0 + 6.61375661375662e-06*G0_1_0_0_1 + 1.32275132275132e-05*G0_1_0_0_2 + 6.61375661375662e-06*G0_1_0_1_0 - 6.61375661375658e-05*G0_1_0_1_1 - 6.61375661375657e-06*G0_1_0_1_2 + 1.32275132275132e-05*G0_1_0_2_0 - 6.61375661375657e-06*G0_1_0_2_1 - 6.61375661375658e-06*G0_1_0_2_2 + 6.61375661375662e-06*G0_1_1_0_0 - 6.61375661375658e-05*G0_1_1_0_1 - 6.61375661375657e-06*G0_1_1_0_2 - 6.61375661375658e-05*G0_1_1_1_0 - 0.000727513227513224*G0_1_1_1_1 - 0.000132275132275132*G0_1_1_1_2 - 6.61375661375657e-06*G0_1_1_2_0 - 0.000132275132275132*G0_1_1_2_1 - 5.95238095238093e-05*G0_1_1_2_2 + 1.32275132275132e-05*G0_1_2_0_0 - 6.61375661375657e-06*G0_1_2_0_1 - 6.61375661375658e-06*G0_1_2_0_2 - 6.61375661375657e-06*G0_1_2_1_0 - 0.000132275132275132*G0_1_2_1_1 - 5.95238095238093e-05*G0_1_2_1_2 - 6.61375661375658e-06*G0_1_2_2_0 - 5.95238095238093e-05*G0_1_2_2_1 - 0.000132275132275132*G0_1_2_2_2 + 4.62962962962962e-05*G0_2_0_0_0 + 1.32275132275132e-05*G0_2_0_0_1 + 6.61375661375663e-06*G0_2_0_0_2 + 1.32275132275132e-05*G0_2_0_1_0 - 6.61375661375657e-06*G0_2_0_1_1 - 6.61375661375658e-06*G0_2_0_1_2 + 6.61375661375663e-06*G0_2_0_2_0 - 6.61375661375658e-06*G0_2_0_2_1 - 6.61375661375657e-05*G0_2_0_2_2 + 1.32275132275132e-05*G0_2_1_0_0 - 6.61375661375657e-06*G0_2_1_0_1 - 6.61375661375658e-06*G0_2_1_0_2 - 6.61375661375657e-06*G0_2_1_1_0 - 0.000132275132275132*G0_2_1_1_1 - 5.95238095238093e-05*G0_2_1_1_2 - 6.61375661375658e-06*G0_2_1_2_0 - 5.95238095238093e-05*G0_2_1_2_1 - 0.000132275132275132*G0_2_1_2_2 + 6.61375661375663e-06*G0_2_2_0_0 - 6.61375661375658e-06*G0_2_2_0_1 - 6.61375661375657e-05*G0_2_2_0_2 - 6.61375661375658e-06*G0_2_2_1_0 - 5.95238095238093e-05*G0_2_2_1_1 - 0.000132275132275132*G0_2_2_1_2 - 6.61375661375657e-05*G0_2_2_2_0 - 0.000132275132275132*G0_2_2_2_1 - 0.000727513227513223*G0_2_2_2_2; + A[31] = A[9] - 0.000846560846560842*G0_0_0_0_0 - 0.000238095238095237*G0_0_0_0_1 - 0.000105820105820105*G0_0_0_0_2 - 0.000238095238095237*G0_0_0_1_0 - 2.64550264550263e-05*G0_0_0_1_2 - 0.000105820105820105*G0_0_0_2_0 - 2.64550264550263e-05*G0_0_0_2_1 - 0.000238095238095237*G0_0_1_0_0 - 2.64550264550263e-05*G0_0_1_0_2 + 0.000264550264550263*G0_0_1_1_1 - 2.64550264550263e-05*G0_0_1_2_0 + 2.64550264550264e-05*G0_0_1_2_2 - 0.000105820105820105*G0_0_2_0_0 - 2.64550264550263e-05*G0_0_2_0_1 - 2.64550264550263e-05*G0_0_2_1_0 + 2.64550264550263e-05*G0_0_2_1_2 + 2.64550264550264e-05*G0_0_2_2_1 + 0.000105820105820105*G0_0_2_2_2 - 0.000238095238095237*G0_1_0_0_0 - 2.64550264550263e-05*G0_1_0_0_2 + 0.000264550264550263*G0_1_0_1_1 - 2.64550264550263e-05*G0_1_0_2_0 + 2.64550264550264e-05*G0_1_0_2_2 + 0.000264550264550263*G0_1_1_0_1 + 0.000264550264550263*G0_1_1_1_0 - 0.000264550264550263*G0_1_1_1_2 - 0.000264550264550263*G0_1_1_2_1 - 2.64550264550263e-05*G0_1_2_0_0 + 2.64550264550263e-05*G0_1_2_0_2 - 0.000264550264550264*G0_1_2_1_1 + 2.64550264550263e-05*G0_1_2_2_0 + 0.000238095238095237*G0_1_2_2_2 - 0.000105820105820105*G0_2_0_0_0 - 2.64550264550263e-05*G0_2_0_0_1 - 2.64550264550263e-05*G0_2_0_1_0 + 2.64550264550264e-05*G0_2_0_1_2 + 2.64550264550264e-05*G0_2_0_2_1 + 0.000105820105820105*G0_2_0_2_2 - 2.64550264550263e-05*G0_2_1_0_0 + 2.64550264550264e-05*G0_2_1_0_2 - 0.000264550264550264*G0_2_1_1_1 + 2.64550264550264e-05*G0_2_1_2_0 + 0.000238095238095237*G0_2_1_2_2 + 2.64550264550264e-05*G0_2_2_0_1 + 0.000105820105820105*G0_2_2_0_2 + 2.64550264550263e-05*G0_2_2_1_0 + 0.000238095238095237*G0_2_2_1_2 + 0.000105820105820105*G0_2_2_2_0 + 0.000238095238095237*G0_2_2_2_1 + 0.000846560846560842*G0_2_2_2_2; + A[3] = A[18]; + A[17] = A[31] + 0.000264550264550263*G0_0_0_0_0 - 0.000238095238095237*G0_0_0_1_1 - 2.64550264550264e-05*G0_0_0_1_2 - 2.64550264550264e-05*G0_0_0_2_1 + 2.64550264550263e-05*G0_0_0_2_2 - 0.000238095238095237*G0_0_1_0_1 - 2.64550264550264e-05*G0_0_1_0_2 - 0.000238095238095237*G0_0_1_1_0 - 0.000846560846560842*G0_0_1_1_1 - 0.000105820105820105*G0_0_1_1_2 - 2.64550264550264e-05*G0_0_1_2_0 - 0.000105820105820105*G0_0_1_2_1 - 2.64550264550264e-05*G0_0_2_0_1 + 2.64550264550263e-05*G0_0_2_0_2 - 2.64550264550264e-05*G0_0_2_1_0 - 0.000105820105820105*G0_0_2_1_1 + 2.64550264550263e-05*G0_0_2_2_0 + 0.000105820105820105*G0_0_2_2_2 - 0.000238095238095237*G0_1_0_0_1 - 2.64550264550264e-05*G0_1_0_0_2 - 0.000238095238095237*G0_1_0_1_0 - 0.000846560846560842*G0_1_0_1_1 - 0.000105820105820105*G0_1_0_1_2 - 2.64550264550264e-05*G0_1_0_2_0 - 0.000105820105820105*G0_1_0_2_1 - 0.000238095238095237*G0_1_1_0_0 - 0.000846560846560842*G0_1_1_0_1 - 0.000105820105820105*G0_1_1_0_2 - 0.000846560846560842*G0_1_1_1_0 - 0.00396825396825395*G0_1_1_1_1 - 0.000476190476190474*G0_1_1_1_2 - 0.000105820105820105*G0_1_1_2_0 - 0.000476190476190474*G0_1_1_2_1 - 7.9365079365079e-05*G0_1_1_2_2 - 2.64550264550264e-05*G0_1_2_0_0 - 0.000105820105820105*G0_1_2_0_1 - 0.000105820105820105*G0_1_2_1_0 - 0.000476190476190474*G0_1_2_1_1 - 7.9365079365079e-05*G0_1_2_1_2 - 7.9365079365079e-05*G0_1_2_2_1 + 7.93650793650792e-05*G0_1_2_2_2 - 2.64550264550264e-05*G0_2_0_0_1 + 2.64550264550264e-05*G0_2_0_0_2 - 2.64550264550264e-05*G0_2_0_1_0 - 0.000105820105820105*G0_2_0_1_1 + 2.64550264550264e-05*G0_2_0_2_0 + 0.000105820105820105*G0_2_0_2_2 - 2.64550264550264e-05*G0_2_1_0_0 - 0.000105820105820105*G0_2_1_0_1 - 0.000105820105820105*G0_2_1_1_0 - 0.000476190476190474*G0_2_1_1_1 - 7.9365079365079e-05*G0_2_1_1_2 - 7.9365079365079e-05*G0_2_1_2_1 + 7.93650793650792e-05*G0_2_1_2_2 + 2.64550264550264e-05*G0_2_2_0_0 + 0.000105820105820105*G0_2_2_0_2 - 7.9365079365079e-05*G0_2_2_1_1 + 7.93650793650792e-05*G0_2_2_1_2 + 0.000105820105820105*G0_2_2_2_0 + 7.93650793650792e-05*G0_2_2_2_1 + 0.000476190476190475*G0_2_2_2_2; + A[8] = A[13]; + A[21] = -A[31] - 0.000634920634920631*G0_0_0_0_0 + 0.000105820105820106*G0_0_0_0_2 + 0.000423280423280422*G0_0_0_1_1 + 0.000238095238095237*G0_0_0_1_2 + 0.000105820105820106*G0_0_0_2_0 + 0.000238095238095237*G0_0_0_2_1 + 0.000317460317460316*G0_0_0_2_2 + 0.000423280423280422*G0_0_1_0_1 + 0.000238095238095237*G0_0_1_0_2 + 0.000423280423280422*G0_0_1_1_0 + 0.00158730158730158*G0_0_1_1_1 + 0.000634920634920633*G0_0_1_1_2 + 0.000238095238095237*G0_0_1_2_0 + 0.000634920634920633*G0_0_1_2_1 + 0.00058201058201058*G0_0_1_2_2 + 0.000105820105820105*G0_0_2_0_0 + 0.000238095238095237*G0_0_2_0_1 + 0.000317460317460316*G0_0_2_0_2 + 0.000238095238095237*G0_0_2_1_0 + 0.000634920634920633*G0_0_2_1_1 + 0.00058201058201058*G0_0_2_1_2 + 0.000317460317460316*G0_0_2_2_0 + 0.00058201058201058*G0_0_2_2_1 + 0.000952380952380948*G0_0_2_2_2 + 0.000423280423280422*G0_1_0_0_1 + 0.000238095238095237*G0_1_0_0_2 + 0.000423280423280422*G0_1_0_1_0 + 0.00158730158730158*G0_1_0_1_1 + 0.000634920634920633*G0_1_0_1_2 + 0.000238095238095237*G0_1_0_2_0 + 0.000634920634920633*G0_1_0_2_1 + 0.00058201058201058*G0_1_0_2_2 + 0.000423280423280422*G0_1_1_0_0 + 0.00158730158730158*G0_1_1_0_1 + 0.000634920634920633*G0_1_1_0_2 + 0.00158730158730158*G0_1_1_1_0 + 0.00952380952380948*G0_1_1_1_1 + 0.00343915343915343*G0_1_1_1_2 + 0.000634920634920633*G0_1_1_2_0 + 0.00343915343915343*G0_1_1_2_1 + 0.00253968253968253*G0_1_1_2_2 + 0.000238095238095237*G0_1_2_0_0 + 0.000634920634920633*G0_1_2_0_1 + 0.00058201058201058*G0_1_2_0_2 + 0.000634920634920633*G0_1_2_1_0 + 0.00343915343915343*G0_1_2_1_1 + 0.00253968253968253*G0_1_2_1_2 + 0.00058201058201058*G0_1_2_2_0 + 0.00253968253968253*G0_1_2_2_1 + 0.00309523809523808*G0_1_2_2_2 + 0.000105820105820106*G0_2_0_0_0 + 0.000238095238095237*G0_2_0_0_1 + 0.000317460317460316*G0_2_0_0_2 + 0.000238095238095237*G0_2_0_1_0 + 0.000634920634920633*G0_2_0_1_1 + 0.00058201058201058*G0_2_0_1_2 + 0.000317460317460316*G0_2_0_2_0 + 0.00058201058201058*G0_2_0_2_1 + 0.000952380952380948*G0_2_0_2_2 + 0.000238095238095237*G0_2_1_0_0 + 0.000634920634920633*G0_2_1_0_1 + 0.00058201058201058*G0_2_1_0_2 + 0.000634920634920633*G0_2_1_1_0 + 0.00343915343915343*G0_2_1_1_1 + 0.00253968253968253*G0_2_1_1_2 + 0.00058201058201058*G0_2_1_2_0 + 0.00253968253968253*G0_2_1_2_1 + 0.00309523809523808*G0_2_1_2_2 + 0.000317460317460316*G0_2_2_0_0 + 0.00058201058201058*G0_2_2_0_1 + 0.000952380952380948*G0_2_2_0_2 + 0.00058201058201058*G0_2_2_1_0 + 0.00253968253968253*G0_2_2_1_1 + 0.00309523809523808*G0_2_2_1_2 + 0.000952380952380948*G0_2_2_2_0 + 0.00309523809523808*G0_2_2_2_1 + 0.00613756613756611*G0_2_2_2_2; + A[28] = A[21] + 0.0059259259259259*G0_0_0_0_0 + 0.000740740740740739*G0_0_0_0_1 + 0.00285714285714285*G0_0_0_0_2 + 0.000740740740740739*G0_0_0_1_0 + 0.000317460317460317*G0_0_0_1_2 + 0.00285714285714285*G0_0_0_2_0 + 0.000317460317460317*G0_0_0_2_1 + 0.00211640211640211*G0_0_0_2_2 + 0.000740740740740739*G0_0_1_0_0 + 0.000317460317460317*G0_0_1_0_2 - 0.000740740740740738*G0_0_1_1_1 - 0.000317460317460316*G0_0_1_1_2 + 0.000317460317460317*G0_0_1_2_0 - 0.000317460317460316*G0_0_1_2_1 + 0.00285714285714285*G0_0_2_0_0 + 0.000317460317460317*G0_0_2_0_1 + 0.00211640211640211*G0_0_2_0_2 + 0.000317460317460317*G0_0_2_1_0 - 0.000317460317460316*G0_0_2_1_1 + 0.00211640211640211*G0_0_2_2_0 + 0.00211640211640211*G0_0_2_2_2 + 0.000740740740740739*G0_1_0_0_0 + 0.000317460317460317*G0_1_0_0_2 - 0.000740740740740738*G0_1_0_1_1 - 0.000317460317460316*G0_1_0_1_2 + 0.000317460317460317*G0_1_0_2_0 - 0.000317460317460316*G0_1_0_2_1 - 0.000740740740740738*G0_1_1_0_1 - 0.000317460317460316*G0_1_1_0_2 - 0.000740740740740738*G0_1_1_1_0 - 0.0059259259259259*G0_1_1_1_1 - 0.00285714285714285*G0_1_1_1_2 - 0.000317460317460316*G0_1_1_2_0 - 0.00285714285714285*G0_1_1_2_1 - 0.00211640211640211*G0_1_1_2_2 + 0.000317460317460317*G0_1_2_0_0 - 0.000317460317460316*G0_1_2_0_1 - 0.000317460317460316*G0_1_2_1_0 - 0.00285714285714285*G0_1_2_1_1 - 0.00211640211640211*G0_1_2_1_2 - 0.00211640211640211*G0_1_2_2_1 - 0.00211640211640211*G0_1_2_2_2 + 0.00285714285714285*G0_2_0_0_0 + 0.000317460317460317*G0_2_0_0_1 + 0.00211640211640211*G0_2_0_0_2 + 0.000317460317460317*G0_2_0_1_0 - 0.000317460317460316*G0_2_0_1_1 + 0.00211640211640211*G0_2_0_2_0 + 0.00211640211640211*G0_2_0_2_2 + 0.000317460317460317*G0_2_1_0_0 - 0.000317460317460316*G0_2_1_0_1 - 0.000317460317460316*G0_2_1_1_0 - 0.00285714285714285*G0_2_1_1_1 - 0.00211640211640211*G0_2_1_1_2 - 0.00211640211640211*G0_2_1_2_1 - 0.00211640211640211*G0_2_1_2_2 + 0.00211640211640211*G0_2_2_0_0 + 0.00211640211640211*G0_2_2_0_2 - 0.00211640211640211*G0_2_2_1_1 - 0.00211640211640211*G0_2_2_1_2 + 0.00211640211640211*G0_2_2_2_0 - 0.00211640211640211*G0_2_2_2_1; + A[11] = A[31]; + A[30] = 0.00317460317460316*G0_0_0_0_0 + 0.000529100529100526*G0_0_0_0_1 + 0.000264550264550263*G0_0_0_0_2 + 0.000529100529100526*G0_0_0_1_0 + 0.000264550264550263*G0_0_0_2_0 + 0.000529100529100526*G0_0_1_0_0 - 0.000317460317460316*G0_0_1_1_1 - 7.93650793650791e-05*G0_0_1_1_2 - 7.93650793650791e-05*G0_0_1_2_1 - 5.29100529100527e-05*G0_0_1_2_2 + 0.000264550264550263*G0_0_2_0_0 - 7.93650793650791e-05*G0_0_2_1_1 - 5.29100529100527e-05*G0_0_2_1_2 - 5.29100529100527e-05*G0_0_2_2_1 - 7.93650793650791e-05*G0_0_2_2_2 + 0.000529100529100526*G0_1_0_0_0 - 0.000317460317460316*G0_1_0_1_1 - 7.93650793650791e-05*G0_1_0_1_2 - 7.93650793650791e-05*G0_1_0_2_1 - 5.29100529100528e-05*G0_1_0_2_2 - 0.000317460317460316*G0_1_1_0_1 - 7.93650793650791e-05*G0_1_1_0_2 - 0.000317460317460316*G0_1_1_1_0 - 0.00105820105820105*G0_1_1_1_1 - 0.000211640211640211*G0_1_1_1_2 - 7.93650793650791e-05*G0_1_1_2_0 - 0.000211640211640211*G0_1_1_2_1 - 0.000105820105820106*G0_1_1_2_2 - 7.93650793650791e-05*G0_1_2_0_1 - 5.29100529100528e-05*G0_1_2_0_2 - 7.93650793650791e-05*G0_1_2_1_0 - 0.000211640211640211*G0_1_2_1_1 - 0.000105820105820106*G0_1_2_1_2 - 5.29100529100528e-05*G0_1_2_2_0 - 0.000105820105820105*G0_1_2_2_1 - 0.000105820105820105*G0_1_2_2_2 + 0.000264550264550263*G0_2_0_0_0 - 7.93650793650791e-05*G0_2_0_1_1 - 5.29100529100528e-05*G0_2_0_1_2 - 5.29100529100528e-05*G0_2_0_2_1 - 7.93650793650791e-05*G0_2_0_2_2 - 7.93650793650791e-05*G0_2_1_0_1 - 5.29100529100527e-05*G0_2_1_0_2 - 7.93650793650791e-05*G0_2_1_1_0 - 0.000211640211640211*G0_2_1_1_1 - 0.000105820105820105*G0_2_1_1_2 - 5.29100529100528e-05*G0_2_1_2_0 - 0.000105820105820105*G0_2_1_2_1 - 0.000105820105820105*G0_2_1_2_2 - 5.29100529100527e-05*G0_2_2_0_1 - 7.93650793650791e-05*G0_2_2_0_2 - 5.29100529100528e-05*G0_2_2_1_0 - 0.000105820105820105*G0_2_2_1_1 - 0.000105820105820105*G0_2_2_1_2 - 7.93650793650791e-05*G0_2_2_2_0 - 0.000105820105820105*G0_2_2_2_1 - 0.000211640211640211*G0_2_2_2_2; + A[24] = A[30] - 0.000264550264550263*G0_0_0_0_1 + 0.000264550264550263*G0_0_0_0_2 - 0.000264550264550263*G0_0_0_1_0 + 0.000264550264550263*G0_0_0_2_0 - 0.000264550264550263*G0_0_1_0_0 + 0.000238095238095237*G0_0_1_1_1 + 2.64550264550264e-05*G0_0_1_1_2 + 2.64550264550264e-05*G0_0_1_2_1 - 2.64550264550264e-05*G0_0_1_2_2 + 0.000264550264550263*G0_0_2_0_0 + 2.64550264550264e-05*G0_0_2_1_1 - 2.64550264550264e-05*G0_0_2_1_2 - 2.64550264550264e-05*G0_0_2_2_1 - 0.000238095238095237*G0_0_2_2_2 - 0.000264550264550263*G0_1_0_0_0 + 0.000238095238095237*G0_1_0_1_1 + 2.64550264550264e-05*G0_1_0_1_2 + 2.64550264550264e-05*G0_1_0_2_1 - 2.64550264550263e-05*G0_1_0_2_2 + 0.000238095238095237*G0_1_1_0_1 + 2.64550264550264e-05*G0_1_1_0_2 + 0.000238095238095237*G0_1_1_1_0 + 0.000846560846560843*G0_1_1_1_1 + 0.000105820105820105*G0_1_1_1_2 + 2.64550264550264e-05*G0_1_1_2_0 + 0.000105820105820105*G0_1_1_2_1 + 2.64550264550264e-05*G0_1_2_0_1 - 2.64550264550264e-05*G0_1_2_0_2 + 2.64550264550264e-05*G0_1_2_1_0 + 0.000105820105820105*G0_1_2_1_1 - 2.64550264550263e-05*G0_1_2_2_0 - 0.000105820105820105*G0_1_2_2_2 + 0.000264550264550263*G0_2_0_0_0 + 2.64550264550264e-05*G0_2_0_1_1 - 2.64550264550263e-05*G0_2_0_1_2 - 2.64550264550263e-05*G0_2_0_2_1 - 0.000238095238095237*G0_2_0_2_2 + 2.64550264550264e-05*G0_2_1_0_1 - 2.64550264550264e-05*G0_2_1_0_2 + 2.64550264550264e-05*G0_2_1_1_0 + 0.000105820105820105*G0_2_1_1_1 - 2.64550264550264e-05*G0_2_1_2_0 - 0.000105820105820105*G0_2_1_2_2 - 2.64550264550264e-05*G0_2_2_0_1 - 0.000238095238095237*G0_2_2_0_2 - 2.64550264550264e-05*G0_2_2_1_0 - 0.000105820105820105*G0_2_2_1_2 - 0.000238095238095237*G0_2_2_2_0 - 0.000105820105820105*G0_2_2_2_1 - 0.000846560846560843*G0_2_2_2_2; + A[4] = A[24]; + A[25] = A[24] - 0.00396825396825395*G0_0_0_0_0 - 0.000476190476190474*G0_0_0_0_1 - 0.000846560846560843*G0_0_0_0_2 - 0.000476190476190474*G0_0_0_1_0 - 7.9365079365079e-05*G0_0_0_1_1 - 0.000105820105820105*G0_0_0_1_2 - 0.000846560846560843*G0_0_0_2_0 - 0.000105820105820105*G0_0_0_2_1 - 0.000238095238095237*G0_0_0_2_2 - 0.000476190476190474*G0_0_1_0_0 - 7.9365079365079e-05*G0_0_1_0_1 - 0.000105820105820105*G0_0_1_0_2 - 7.93650793650789e-05*G0_0_1_1_0 + 7.9365079365079e-05*G0_0_1_1_1 - 0.000105820105820105*G0_0_1_2_0 - 2.64550264550263e-05*G0_0_1_2_2 - 0.000846560846560843*G0_0_2_0_0 - 0.000105820105820105*G0_0_2_0_1 - 0.000238095238095237*G0_0_2_0_2 - 0.000105820105820105*G0_0_2_1_0 - 2.64550264550263e-05*G0_0_2_1_2 - 0.000238095238095237*G0_0_2_2_0 - 2.64550264550263e-05*G0_0_2_2_1 - 0.000476190476190474*G0_1_0_0_0 - 7.9365079365079e-05*G0_1_0_0_1 - 0.000105820105820105*G0_1_0_0_2 - 7.93650793650789e-05*G0_1_0_1_0 + 7.9365079365079e-05*G0_1_0_1_1 - 0.000105820105820105*G0_1_0_2_0 - 2.64550264550263e-05*G0_1_0_2_2 - 7.93650793650789e-05*G0_1_1_0_0 + 7.93650793650791e-05*G0_1_1_0_1 + 7.93650793650791e-05*G0_1_1_1_0 + 0.000476190476190474*G0_1_1_1_1 + 0.000105820105820105*G0_1_1_1_2 + 0.000105820105820105*G0_1_1_2_1 + 2.64550264550264e-05*G0_1_1_2_2 - 0.000105820105820105*G0_1_2_0_0 - 2.64550264550263e-05*G0_1_2_0_2 + 0.000105820105820105*G0_1_2_1_1 + 2.64550264550264e-05*G0_1_2_1_2 - 2.64550264550263e-05*G0_1_2_2_0 + 2.64550264550264e-05*G0_1_2_2_1 - 0.000846560846560843*G0_2_0_0_0 - 0.000105820105820105*G0_2_0_0_1 - 0.000238095238095237*G0_2_0_0_2 - 0.000105820105820105*G0_2_0_1_0 - 2.64550264550263e-05*G0_2_0_1_2 - 0.000238095238095237*G0_2_0_2_0 - 2.64550264550263e-05*G0_2_0_2_1 - 0.000105820105820105*G0_2_1_0_0 - 2.64550264550263e-05*G0_2_1_0_2 + 0.000105820105820105*G0_2_1_1_1 + 2.64550264550264e-05*G0_2_1_1_2 - 2.64550264550263e-05*G0_2_1_2_0 + 2.64550264550264e-05*G0_2_1_2_1 - 0.000238095238095237*G0_2_2_0_0 - 2.64550264550263e-05*G0_2_2_0_1 - 2.64550264550263e-05*G0_2_2_1_0 + 2.64550264550264e-05*G0_2_2_1_1 + 0.000264550264550263*G0_2_2_2_2; + A[34] = A[28] - 0.00317460317460316*G0_0_0_0_0 - 0.00211640211640211*G0_0_0_0_2 + 0.00021164021164021*G0_0_0_1_1 - 0.000211640211640211*G0_0_0_1_2 - 0.00211640211640211*G0_0_0_2_0 - 0.000211640211640211*G0_0_0_2_1 - 0.0019047619047619*G0_0_0_2_2 + 0.00021164021164021*G0_0_1_0_1 - 0.000211640211640211*G0_0_1_0_2 + 0.00021164021164021*G0_0_1_1_0 + 0.000317460317460316*G0_0_1_1_1 - 0.000211640211640211*G0_0_1_2_0 - 0.000317460317460317*G0_0_1_2_2 - 0.00211640211640211*G0_0_2_0_0 - 0.000211640211640211*G0_0_2_0_1 - 0.0019047619047619*G0_0_2_0_2 - 0.000211640211640211*G0_0_2_1_0 - 0.000317460317460317*G0_0_2_1_2 - 0.0019047619047619*G0_0_2_2_0 - 0.000317460317460317*G0_0_2_2_1 - 0.00253968253968253*G0_0_2_2_2 + 0.000211640211640211*G0_1_0_0_1 - 0.000211640211640211*G0_1_0_0_2 + 0.000211640211640211*G0_1_0_1_0 + 0.000317460317460316*G0_1_0_1_1 - 0.000211640211640211*G0_1_0_2_0 - 0.000317460317460317*G0_1_0_2_2 + 0.00021164021164021*G0_1_1_0_0 + 0.000317460317460316*G0_1_1_0_1 + 0.000317460317460316*G0_1_1_1_0 + 0.000634920634920633*G0_1_1_1_1 + 0.000105820105820105*G0_1_1_1_2 + 0.000105820105820106*G0_1_1_2_1 - 0.000105820105820106*G0_1_1_2_2 - 0.000211640211640211*G0_1_2_0_0 - 0.000317460317460317*G0_1_2_0_2 + 0.000105820105820106*G0_1_2_1_1 - 0.000105820105820106*G0_1_2_1_2 - 0.000317460317460317*G0_1_2_2_0 - 0.000105820105820106*G0_1_2_2_1 - 0.000634920634920633*G0_1_2_2_2 - 0.00211640211640211*G0_2_0_0_0 - 0.000211640211640211*G0_2_0_0_1 - 0.0019047619047619*G0_2_0_0_2 - 0.000211640211640211*G0_2_0_1_0 - 0.000317460317460317*G0_2_0_1_2 - 0.0019047619047619*G0_2_0_2_0 - 0.000317460317460317*G0_2_0_2_1 - 0.00253968253968253*G0_2_0_2_2 - 0.000211640211640211*G0_2_1_0_0 - 0.000317460317460317*G0_2_1_0_2 + 0.000105820105820106*G0_2_1_1_1 - 0.000105820105820106*G0_2_1_1_2 - 0.000317460317460317*G0_2_1_2_0 - 0.000105820105820106*G0_2_1_2_1 - 0.000634920634920633*G0_2_1_2_2 - 0.0019047619047619*G0_2_2_0_0 - 0.000317460317460317*G0_2_2_0_1 - 0.00253968253968253*G0_2_2_0_2 - 0.000317460317460317*G0_2_2_1_0 - 0.000105820105820106*G0_2_2_1_1 - 0.000634920634920633*G0_2_2_1_2 - 0.00253968253968253*G0_2_2_2_0 - 0.000634920634920633*G0_2_2_2_1 - 0.00529100529100527*G0_2_2_2_2; + A[29] = A[34]; + A[14] = -A[9] + 2.64550264550263e-05*G0_0_0_0_0 - 1.98412698412698e-05*G0_0_0_0_1 - 6.61375661375665e-06*G0_0_0_0_2 - 1.98412698412698e-05*G0_0_0_1_0 + 3.96825396825394e-05*G0_0_0_1_1 - 1.98412698412698e-05*G0_0_0_1_2 - 6.61375661375665e-06*G0_0_0_2_0 - 1.98412698412698e-05*G0_0_0_2_1 + 2.64550264550262e-05*G0_0_0_2_2 - 1.98412698412698e-05*G0_0_1_0_0 + 3.96825396825394e-05*G0_0_1_0_1 - 1.98412698412698e-05*G0_0_1_0_2 + 3.96825396825394e-05*G0_0_1_1_0 + 0.000324074074074072*G0_0_1_1_1 + 3.30687830687828e-05*G0_0_1_1_2 - 1.98412698412698e-05*G0_0_1_2_0 + 3.30687830687828e-05*G0_0_1_2_1 - 1.32275132275132e-05*G0_0_1_2_2 - 6.61375661375663e-06*G0_0_2_0_0 - 1.98412698412698e-05*G0_0_2_0_1 + 2.64550264550262e-05*G0_0_2_0_2 - 1.98412698412698e-05*G0_0_2_1_0 + 3.30687830687828e-05*G0_0_2_1_1 - 1.32275132275132e-05*G0_0_2_1_2 + 2.64550264550262e-05*G0_0_2_2_0 - 1.32275132275132e-05*G0_0_2_2_1 + 0.000383597883597881*G0_0_2_2_2 - 1.98412698412698e-05*G0_1_0_0_0 + 3.96825396825394e-05*G0_1_0_0_1 - 1.98412698412698e-05*G0_1_0_0_2 + 3.96825396825394e-05*G0_1_0_1_0 + 0.000324074074074072*G0_1_0_1_1 + 3.30687830687828e-05*G0_1_0_1_2 - 1.98412698412698e-05*G0_1_0_2_0 + 3.30687830687828e-05*G0_1_0_2_1 - 1.32275132275133e-05*G0_1_0_2_2 + 3.96825396825394e-05*G0_1_1_0_0 + 0.000324074074074072*G0_1_1_0_1 + 3.30687830687829e-05*G0_1_1_0_2 + 0.000324074074074072*G0_1_1_1_0 + 0.0034126984126984*G0_1_1_1_1 + 0.000628306878306876*G0_1_1_1_2 + 3.30687830687829e-05*G0_1_1_2_0 + 0.000628306878306876*G0_1_1_2_1 + 0.000132275132275132*G0_1_1_2_2 - 1.98412698412698e-05*G0_1_2_0_0 + 3.30687830687828e-05*G0_1_2_0_1 - 1.32275132275132e-05*G0_1_2_0_2 + 3.30687830687829e-05*G0_1_2_1_0 + 0.000628306878306876*G0_1_2_1_1 + 0.000132275132275132*G0_1_2_1_2 - 1.32275132275132e-05*G0_1_2_2_0 + 0.000132275132275132*G0_1_2_2_1 + 0.000277777777777776*G0_1_2_2_2 - 6.61375661375663e-06*G0_2_0_0_0 - 1.98412698412698e-05*G0_2_0_0_1 + 2.64550264550262e-05*G0_2_0_0_2 - 1.98412698412698e-05*G0_2_0_1_0 + 3.30687830687828e-05*G0_2_0_1_1 - 1.32275132275132e-05*G0_2_0_1_2 + 2.64550264550262e-05*G0_2_0_2_0 - 1.32275132275132e-05*G0_2_0_2_1 + 0.000383597883597881*G0_2_0_2_2 - 1.98412698412698e-05*G0_2_1_0_0 + 3.30687830687828e-05*G0_2_1_0_1 - 1.32275132275132e-05*G0_2_1_0_2 + 3.30687830687828e-05*G0_2_1_1_0 + 0.000628306878306876*G0_2_1_1_1 + 0.000132275132275132*G0_2_1_1_2 - 1.32275132275132e-05*G0_2_1_2_0 + 0.000132275132275132*G0_2_1_2_1 + 0.000277777777777776*G0_2_1_2_2 + 2.64550264550262e-05*G0_2_2_0_0 - 1.32275132275132e-05*G0_2_2_0_1 + 0.000383597883597881*G0_2_2_0_2 - 1.32275132275132e-05*G0_2_2_1_0 + 0.000132275132275132*G0_2_2_1_1 + 0.000277777777777776*G0_2_2_1_2 + 0.000383597883597881*G0_2_2_2_0 + 0.000277777777777776*G0_2_2_2_1 + 0.00568783068783065*G0_2_2_2_2; + A[7] = A[14] + 3.96825396825394e-05*G0_0_0_0_1 - 3.96825396825395e-05*G0_0_0_0_2 + 3.96825396825394e-05*G0_0_0_1_0 + 9.2592592592592e-05*G0_0_0_1_1 - 3.96825396825395e-05*G0_0_0_2_0 - 9.25925925925921e-05*G0_0_0_2_2 + 3.96825396825394e-05*G0_0_1_0_0 + 9.2592592592592e-05*G0_0_1_0_1 + 9.2592592592592e-05*G0_0_1_1_0 + 0.000535714285714282*G0_0_1_1_1 + 3.30687830687828e-05*G0_0_1_1_2 + 3.30687830687828e-05*G0_0_1_2_1 - 3.30687830687829e-05*G0_0_1_2_2 - 3.96825396825395e-05*G0_0_2_0_0 - 9.25925925925921e-05*G0_0_2_0_2 + 3.30687830687828e-05*G0_0_2_1_1 - 3.30687830687829e-05*G0_0_2_1_2 - 9.25925925925921e-05*G0_0_2_2_0 - 3.30687830687829e-05*G0_0_2_2_1 - 0.000535714285714282*G0_0_2_2_2 + 3.96825396825394e-05*G0_1_0_0_0 + 9.2592592592592e-05*G0_1_0_0_1 + 9.2592592592592e-05*G0_1_0_1_0 + 0.000535714285714282*G0_1_0_1_1 + 3.30687830687828e-05*G0_1_0_1_2 + 3.30687830687828e-05*G0_1_0_2_1 - 3.30687830687829e-05*G0_1_0_2_2 + 9.2592592592592e-05*G0_1_1_0_0 + 0.000535714285714282*G0_1_1_0_1 + 3.30687830687828e-05*G0_1_1_0_2 + 0.000535714285714282*G0_1_1_1_0 + 0.00650793650793647*G0_1_1_1_1 + 0.000496031746031743*G0_1_1_1_2 + 3.30687830687828e-05*G0_1_1_2_0 + 0.000496031746031743*G0_1_1_2_1 + 3.30687830687828e-05*G0_1_2_0_1 - 3.30687830687829e-05*G0_1_2_0_2 + 3.30687830687828e-05*G0_1_2_1_0 + 0.000496031746031743*G0_1_2_1_1 - 3.30687830687829e-05*G0_1_2_2_0 - 0.000496031746031743*G0_1_2_2_2 - 3.96825396825395e-05*G0_2_0_0_0 - 9.25925925925921e-05*G0_2_0_0_2 + 3.30687830687828e-05*G0_2_0_1_1 - 3.30687830687829e-05*G0_2_0_1_2 - 9.25925925925921e-05*G0_2_0_2_0 - 3.30687830687829e-05*G0_2_0_2_1 - 0.000535714285714282*G0_2_0_2_2 + 3.30687830687828e-05*G0_2_1_0_1 - 3.30687830687829e-05*G0_2_1_0_2 + 3.30687830687828e-05*G0_2_1_1_0 + 0.000496031746031743*G0_2_1_1_1 - 3.30687830687829e-05*G0_2_1_2_0 - 0.000496031746031743*G0_2_1_2_2 - 9.25925925925921e-05*G0_2_2_0_0 - 3.30687830687829e-05*G0_2_2_0_1 - 0.000535714285714282*G0_2_2_0_2 - 3.30687830687829e-05*G0_2_2_1_0 - 0.000496031746031743*G0_2_2_1_2 - 0.000535714285714282*G0_2_2_2_0 - 0.000496031746031744*G0_2_2_2_1 - 0.00650793650793647*G0_2_2_2_2; + A[0] = A[14] + 0.00650793650793647*G0_0_0_0_0 + 0.000535714285714282*G0_0_0_0_1 + 0.000496031746031743*G0_0_0_0_2 + 0.000535714285714282*G0_0_0_1_0 + 9.2592592592592e-05*G0_0_0_1_1 + 3.30687830687829e-05*G0_0_0_1_2 + 0.000496031746031743*G0_0_0_2_0 + 3.30687830687829e-05*G0_0_0_2_1 + 0.000535714285714282*G0_0_1_0_0 + 9.2592592592592e-05*G0_0_1_0_1 + 3.30687830687829e-05*G0_0_1_0_2 + 9.25925925925921e-05*G0_0_1_1_0 + 3.96825396825395e-05*G0_0_1_1_1 + 3.30687830687829e-05*G0_0_1_2_0 - 3.30687830687829e-05*G0_0_1_2_2 + 0.000496031746031743*G0_0_2_0_0 + 3.30687830687829e-05*G0_0_2_0_1 + 3.30687830687829e-05*G0_0_2_1_0 - 3.30687830687829e-05*G0_0_2_1_2 - 3.30687830687829e-05*G0_0_2_2_1 - 0.000496031746031743*G0_0_2_2_2 + 0.000535714285714282*G0_1_0_0_0 + 9.2592592592592e-05*G0_1_0_0_1 + 3.30687830687829e-05*G0_1_0_0_2 + 9.25925925925921e-05*G0_1_0_1_0 + 3.96825396825395e-05*G0_1_0_1_1 + 3.30687830687829e-05*G0_1_0_2_0 - 3.30687830687829e-05*G0_1_0_2_2 + 9.2592592592592e-05*G0_1_1_0_0 + 3.96825396825395e-05*G0_1_1_0_1 + 3.96825396825395e-05*G0_1_1_1_0 - 3.96825396825395e-05*G0_1_1_1_2 - 3.96825396825395e-05*G0_1_1_2_1 - 9.25925925925921e-05*G0_1_1_2_2 + 3.30687830687829e-05*G0_1_2_0_0 - 3.30687830687829e-05*G0_1_2_0_2 - 3.96825396825395e-05*G0_1_2_1_1 - 9.25925925925921e-05*G0_1_2_1_2 - 3.30687830687829e-05*G0_1_2_2_0 - 9.25925925925921e-05*G0_1_2_2_1 - 0.000535714285714283*G0_1_2_2_2 + 0.000496031746031743*G0_2_0_0_0 + 3.30687830687829e-05*G0_2_0_0_1 + 3.30687830687829e-05*G0_2_0_1_0 - 3.30687830687829e-05*G0_2_0_1_2 - 3.30687830687829e-05*G0_2_0_2_1 - 0.000496031746031743*G0_2_0_2_2 + 3.30687830687829e-05*G0_2_1_0_0 - 3.30687830687829e-05*G0_2_1_0_2 - 3.96825396825395e-05*G0_2_1_1_1 - 9.25925925925921e-05*G0_2_1_1_2 - 3.30687830687829e-05*G0_2_1_2_0 - 9.25925925925921e-05*G0_2_1_2_1 - 0.000535714285714283*G0_2_1_2_2 - 3.30687830687829e-05*G0_2_2_0_1 - 0.000496031746031743*G0_2_2_0_2 - 3.30687830687829e-05*G0_2_2_1_0 - 9.25925925925921e-05*G0_2_2_1_1 - 0.000535714285714283*G0_2_2_1_2 - 0.000496031746031743*G0_2_2_2_0 - 0.000535714285714283*G0_2_2_2_1 - 0.00650793650793647*G0_2_2_2_2; + A[10] = A[25]; + A[5] = A[30]; + A[26] = A[20] - 0.000846560846560843*G0_0_0_0_0 - 0.000105820105820105*G0_0_0_0_1 - 0.000238095238095237*G0_0_0_0_2 - 0.000105820105820105*G0_0_0_1_0 - 2.64550264550264e-05*G0_0_0_1_2 - 0.000238095238095237*G0_0_0_2_0 - 2.64550264550264e-05*G0_0_0_2_1 - 0.000105820105820105*G0_0_1_0_0 - 2.64550264550264e-05*G0_0_1_0_2 + 0.000105820105820105*G0_0_1_1_1 + 2.64550264550263e-05*G0_0_1_1_2 - 2.64550264550264e-05*G0_0_1_2_0 + 2.64550264550263e-05*G0_0_1_2_1 - 0.000238095238095237*G0_0_2_0_0 - 2.64550264550264e-05*G0_0_2_0_1 - 2.64550264550264e-05*G0_0_2_1_0 + 2.64550264550263e-05*G0_0_2_1_1 + 0.000264550264550263*G0_0_2_2_2 - 0.000105820105820105*G0_1_0_0_0 - 2.64550264550264e-05*G0_1_0_0_2 + 0.000105820105820105*G0_1_0_1_1 + 2.64550264550263e-05*G0_1_0_1_2 - 2.64550264550264e-05*G0_1_0_2_0 + 2.64550264550263e-05*G0_1_0_2_1 + 0.000105820105820105*G0_1_1_0_1 + 2.64550264550263e-05*G0_1_1_0_2 + 0.000105820105820105*G0_1_1_1_0 + 0.000846560846560843*G0_1_1_1_1 + 0.000238095238095237*G0_1_1_1_2 + 2.64550264550263e-05*G0_1_1_2_0 + 0.000238095238095237*G0_1_1_2_1 - 2.64550264550264e-05*G0_1_2_0_0 + 2.64550264550263e-05*G0_1_2_0_1 + 2.64550264550263e-05*G0_1_2_1_0 + 0.000238095238095237*G0_1_2_1_1 - 0.000264550264550263*G0_1_2_2_2 - 0.000238095238095237*G0_2_0_0_0 - 2.64550264550264e-05*G0_2_0_0_1 - 2.64550264550264e-05*G0_2_0_1_0 + 2.64550264550263e-05*G0_2_0_1_1 + 0.000264550264550263*G0_2_0_2_2 - 2.64550264550264e-05*G0_2_1_0_0 + 2.64550264550263e-05*G0_2_1_0_1 + 2.64550264550263e-05*G0_2_1_1_0 + 0.000238095238095237*G0_2_1_1_1 - 0.000264550264550263*G0_2_1_2_2 + 0.000264550264550263*G0_2_2_0_2 - 0.000264550264550263*G0_2_2_1_2 + 0.000264550264550263*G0_2_2_2_0 - 0.000264550264550263*G0_2_2_2_1; + A[6] = -0.000727513227513224*G0_0_0_0_0 - 0.000132275132275132*G0_0_0_0_1 - 6.61375661375659e-05*G0_0_0_0_2 - 0.000132275132275132*G0_0_0_1_0 - 5.95238095238092e-05*G0_0_0_1_1 - 6.61375661375657e-06*G0_0_0_1_2 - 6.61375661375659e-05*G0_0_0_2_0 - 6.61375661375657e-06*G0_0_0_2_1 + 6.61375661375657e-06*G0_0_0_2_2 - 0.000132275132275132*G0_0_1_0_0 - 5.95238095238092e-05*G0_0_1_0_1 - 6.61375661375657e-06*G0_0_1_0_2 - 5.95238095238092e-05*G0_0_1_1_0 - 0.000132275132275132*G0_0_1_1_1 - 6.61375661375657e-06*G0_0_1_1_2 - 6.61375661375657e-06*G0_0_1_2_0 - 6.61375661375657e-06*G0_0_1_2_1 + 1.32275132275132e-05*G0_0_1_2_2 - 6.61375661375659e-05*G0_0_2_0_0 - 6.61375661375657e-06*G0_0_2_0_1 + 6.61375661375657e-06*G0_0_2_0_2 - 6.61375661375657e-06*G0_0_2_1_0 - 6.61375661375657e-06*G0_0_2_1_1 + 1.32275132275132e-05*G0_0_2_1_2 + 6.61375661375657e-06*G0_0_2_2_0 + 1.32275132275132e-05*G0_0_2_2_1 + 4.62962962962961e-05*G0_0_2_2_2 - 0.000132275132275132*G0_1_0_0_0 - 5.95238095238092e-05*G0_1_0_0_1 - 6.61375661375657e-06*G0_1_0_0_2 - 5.95238095238092e-05*G0_1_0_1_0 - 0.000132275132275132*G0_1_0_1_1 - 6.61375661375657e-06*G0_1_0_1_2 - 6.61375661375657e-06*G0_1_0_2_0 - 6.61375661375657e-06*G0_1_0_2_1 + 1.32275132275132e-05*G0_1_0_2_2 - 5.95238095238092e-05*G0_1_1_0_0 - 0.000132275132275132*G0_1_1_0_1 - 6.61375661375657e-06*G0_1_1_0_2 - 0.000132275132275132*G0_1_1_1_0 - 0.000727513227513224*G0_1_1_1_1 - 6.61375661375659e-05*G0_1_1_1_2 - 6.61375661375657e-06*G0_1_1_2_0 - 6.61375661375659e-05*G0_1_1_2_1 + 6.61375661375658e-06*G0_1_1_2_2 - 6.61375661375657e-06*G0_1_2_0_0 - 6.61375661375657e-06*G0_1_2_0_1 + 1.32275132275132e-05*G0_1_2_0_2 - 6.61375661375657e-06*G0_1_2_1_0 - 6.61375661375659e-05*G0_1_2_1_1 + 6.61375661375658e-06*G0_1_2_1_2 + 1.32275132275132e-05*G0_1_2_2_0 + 6.61375661375658e-06*G0_1_2_2_1 + 4.62962962962961e-05*G0_1_2_2_2 - 6.61375661375659e-05*G0_2_0_0_0 - 6.61375661375657e-06*G0_2_0_0_1 + 6.61375661375657e-06*G0_2_0_0_2 - 6.61375661375657e-06*G0_2_0_1_0 - 6.61375661375657e-06*G0_2_0_1_1 + 1.32275132275132e-05*G0_2_0_1_2 + 6.61375661375658e-06*G0_2_0_2_0 + 1.32275132275132e-05*G0_2_0_2_1 + 4.62962962962961e-05*G0_2_0_2_2 - 6.61375661375657e-06*G0_2_1_0_0 - 6.61375661375657e-06*G0_2_1_0_1 + 1.32275132275132e-05*G0_2_1_0_2 - 6.61375661375657e-06*G0_2_1_1_0 - 6.61375661375659e-05*G0_2_1_1_1 + 6.61375661375658e-06*G0_2_1_1_2 + 1.32275132275132e-05*G0_2_1_2_0 + 6.61375661375658e-06*G0_2_1_2_1 + 4.62962962962961e-05*G0_2_1_2_2 + 6.61375661375658e-06*G0_2_2_0_0 + 1.32275132275132e-05*G0_2_2_0_1 + 4.62962962962961e-05*G0_2_2_0_2 + 1.32275132275132e-05*G0_2_2_1_0 + 6.61375661375658e-06*G0_2_2_1_1 + 4.62962962962961e-05*G0_2_2_1_2 + 4.62962962962961e-05*G0_2_2_2_0 + 4.62962962962961e-05*G0_2_2_2_1 + 0.000171957671957671*G0_2_2_2_2; + A[1] = A[6]; + A[35] = A[21] + 0.00592592592592589*G0_0_0_0_0 + 0.00285714285714284*G0_0_0_0_1 + 0.000740740740740737*G0_0_0_0_2 + 0.00285714285714284*G0_0_0_1_0 + 0.0021164021164021*G0_0_0_1_1 + 0.000317460317460316*G0_0_0_1_2 + 0.000740740740740737*G0_0_0_2_0 + 0.000317460317460316*G0_0_0_2_1 + 0.00285714285714284*G0_0_1_0_0 + 0.0021164021164021*G0_0_1_0_1 + 0.000317460317460316*G0_0_1_0_2 + 0.0021164021164021*G0_0_1_1_0 + 0.00211640211640211*G0_0_1_1_1 + 0.000317460317460316*G0_0_1_2_0 - 0.000317460317460316*G0_0_1_2_2 + 0.000740740740740737*G0_0_2_0_0 + 0.000317460317460316*G0_0_2_0_1 + 0.000317460317460316*G0_0_2_1_0 - 0.000317460317460316*G0_0_2_1_2 - 0.000317460317460316*G0_0_2_2_1 - 0.000740740740740737*G0_0_2_2_2 + 0.00285714285714284*G0_1_0_0_0 + 0.0021164021164021*G0_1_0_0_1 + 0.000317460317460316*G0_1_0_0_2 + 0.0021164021164021*G0_1_0_1_0 + 0.0021164021164021*G0_1_0_1_1 + 0.000317460317460316*G0_1_0_2_0 - 0.000317460317460316*G0_1_0_2_2 + 0.0021164021164021*G0_1_1_0_0 + 0.0021164021164021*G0_1_1_0_1 + 0.0021164021164021*G0_1_1_1_0 - 0.00211640211640211*G0_1_1_1_2 - 0.00211640211640211*G0_1_1_2_1 - 0.00211640211640211*G0_1_1_2_2 + 0.000317460317460316*G0_1_2_0_0 - 0.000317460317460316*G0_1_2_0_2 - 0.00211640211640211*G0_1_2_1_1 - 0.00211640211640211*G0_1_2_1_2 - 0.000317460317460316*G0_1_2_2_0 - 0.00211640211640211*G0_1_2_2_1 - 0.00285714285714284*G0_1_2_2_2 + 0.000740740740740737*G0_2_0_0_0 + 0.000317460317460316*G0_2_0_0_1 + 0.000317460317460316*G0_2_0_1_0 - 0.000317460317460316*G0_2_0_1_2 - 0.000317460317460316*G0_2_0_2_1 - 0.000740740740740737*G0_2_0_2_2 + 0.000317460317460316*G0_2_1_0_0 - 0.000317460317460316*G0_2_1_0_2 - 0.00211640211640211*G0_2_1_1_1 - 0.00211640211640211*G0_2_1_1_2 - 0.000317460317460316*G0_2_1_2_0 - 0.00211640211640211*G0_2_1_2_1 - 0.00285714285714284*G0_2_1_2_2 - 0.000317460317460316*G0_2_2_0_1 - 0.000740740740740737*G0_2_2_0_2 - 0.000317460317460316*G0_2_2_1_0 - 0.00211640211640211*G0_2_2_1_1 - 0.00285714285714284*G0_2_2_1_2 - 0.000740740740740737*G0_2_2_2_0 - 0.00285714285714284*G0_2_2_2_1 - 0.0059259259259259*G0_2_2_2_2; + A[23] = A[34] - 0.00211640211640211*G0_0_0_0_0 - 0.000423280423280421*G0_0_0_0_1 - 0.000634920634920633*G0_0_0_0_2 - 0.000423280423280421*G0_0_0_1_0 - 0.000105820105820105*G0_0_0_1_2 - 0.000634920634920633*G0_0_0_2_0 - 0.000105820105820105*G0_0_0_2_1 - 0.000317460317460316*G0_0_0_2_2 - 0.000423280423280421*G0_0_1_0_0 - 0.000105820105820105*G0_0_1_0_2 + 0.000423280423280422*G0_0_1_1_1 + 0.000105820105820105*G0_0_1_1_2 - 0.000105820105820105*G0_0_1_2_0 + 0.000105820105820105*G0_0_1_2_1 - 0.000634920634920633*G0_0_2_0_0 - 0.000105820105820105*G0_0_2_0_1 - 0.000317460317460316*G0_0_2_0_2 - 0.000105820105820105*G0_0_2_1_0 + 0.000105820105820105*G0_0_2_1_1 - 0.000317460317460316*G0_0_2_2_0 - 0.000211640211640211*G0_0_2_2_2 - 0.000423280423280421*G0_1_0_0_0 - 0.000105820105820105*G0_1_0_0_2 + 0.000423280423280422*G0_1_0_1_1 + 0.000105820105820106*G0_1_0_1_2 - 0.000105820105820105*G0_1_0_2_0 + 0.000105820105820106*G0_1_0_2_1 + 0.000423280423280422*G0_1_1_0_1 + 0.000105820105820106*G0_1_1_0_2 + 0.000423280423280422*G0_1_1_1_0 + 0.00211640211640211*G0_1_1_1_1 + 0.000634920634920633*G0_1_1_1_2 + 0.000105820105820106*G0_1_1_2_0 + 0.000634920634920633*G0_1_1_2_1 + 0.000317460317460317*G0_1_1_2_2 - 0.000105820105820106*G0_1_2_0_0 + 0.000105820105820105*G0_1_2_0_1 + 0.000105820105820105*G0_1_2_1_0 + 0.000634920634920633*G0_1_2_1_1 + 0.000317460317460317*G0_1_2_1_2 + 0.000317460317460317*G0_1_2_2_1 + 0.000211640211640211*G0_1_2_2_2 - 0.000634920634920633*G0_2_0_0_0 - 0.000105820105820105*G0_2_0_0_1 - 0.000317460317460316*G0_2_0_0_2 - 0.000105820105820105*G0_2_0_1_0 + 0.000105820105820105*G0_2_0_1_1 - 0.000317460317460316*G0_2_0_2_0 - 0.000211640211640211*G0_2_0_2_2 - 0.000105820105820105*G0_2_1_0_0 + 0.000105820105820106*G0_2_1_0_1 + 0.000105820105820106*G0_2_1_1_0 + 0.000634920634920633*G0_2_1_1_1 + 0.000317460317460317*G0_2_1_1_2 + 0.000317460317460317*G0_2_1_2_1 + 0.000211640211640211*G0_2_1_2_2 - 0.000317460317460316*G0_2_2_0_0 - 0.000211640211640211*G0_2_2_0_2 + 0.000317460317460317*G0_2_2_1_1 + 0.000211640211640211*G0_2_2_1_2 - 0.000211640211640211*G0_2_2_2_0 + 0.000211640211640211*G0_2_2_2_1; + A[33] = A[23]; + A[19] = A[9]; + A[16] = A[26]; + A[27] = A[34] - 0.00211640211640211*G0_0_0_0_0 - 0.000634920634920632*G0_0_0_0_1 - 0.000423280423280422*G0_0_0_0_2 - 0.000634920634920632*G0_0_0_1_0 - 0.000317460317460316*G0_0_0_1_1 - 0.000105820105820105*G0_0_0_1_2 - 0.000423280423280422*G0_0_0_2_0 - 0.000105820105820105*G0_0_0_2_1 - 0.000634920634920632*G0_0_1_0_0 - 0.000317460317460316*G0_0_1_0_1 - 0.000105820105820105*G0_0_1_0_2 - 0.000317460317460316*G0_0_1_1_0 - 0.00021164021164021*G0_0_1_1_1 - 0.000105820105820105*G0_0_1_2_0 + 0.000105820105820105*G0_0_1_2_2 - 0.000423280423280422*G0_0_2_0_0 - 0.000105820105820105*G0_0_2_0_1 - 0.000105820105820105*G0_0_2_1_0 + 0.000105820105820105*G0_0_2_1_2 + 0.000105820105820105*G0_0_2_2_1 + 0.000423280423280422*G0_0_2_2_2 - 0.000634920634920631*G0_1_0_0_0 - 0.000317460317460316*G0_1_0_0_1 - 0.000105820105820105*G0_1_0_0_2 - 0.000317460317460316*G0_1_0_1_0 - 0.00021164021164021*G0_1_0_1_1 - 0.000105820105820105*G0_1_0_2_0 + 0.000105820105820105*G0_1_0_2_2 - 0.000317460317460316*G0_1_1_0_0 - 0.00021164021164021*G0_1_1_0_1 - 0.00021164021164021*G0_1_1_1_0 + 0.000211640211640211*G0_1_1_1_2 + 0.000211640211640211*G0_1_1_2_1 + 0.000317460317460316*G0_1_1_2_2 - 0.000105820105820105*G0_1_2_0_0 + 0.000105820105820105*G0_1_2_0_2 + 0.000211640211640211*G0_1_2_1_1 + 0.000317460317460316*G0_1_2_1_2 + 0.000105820105820105*G0_1_2_2_0 + 0.000317460317460316*G0_1_2_2_1 + 0.000634920634920632*G0_1_2_2_2 - 0.000423280423280422*G0_2_0_0_0 - 0.000105820105820105*G0_2_0_0_1 - 0.000105820105820105*G0_2_0_1_0 + 0.000105820105820105*G0_2_0_1_2 + 0.000105820105820105*G0_2_0_2_1 + 0.000423280423280422*G0_2_0_2_2 - 0.000105820105820105*G0_2_1_0_0 + 0.000105820105820105*G0_2_1_0_2 + 0.000211640211640211*G0_2_1_1_1 + 0.000317460317460316*G0_2_1_1_2 + 0.000105820105820105*G0_2_1_2_0 + 0.000317460317460316*G0_2_1_2_1 + 0.000634920634920633*G0_2_1_2_2 + 0.000105820105820105*G0_2_2_0_1 + 0.000423280423280422*G0_2_2_0_2 + 0.000105820105820105*G0_2_2_1_0 + 0.000317460317460316*G0_2_2_1_1 + 0.000634920634920633*G0_2_2_1_2 + 0.000423280423280422*G0_2_2_2_0 + 0.000634920634920633*G0_2_2_2_1 + 0.00211640211640211*G0_2_2_2_2; + A[22] = A[27]; + A[15] = A[20]; + A[32] = A[17]; + A[2] = -0.000727513227513224*G0_0_0_0_0 - 6.61375661375658e-05*G0_0_0_0_1 - 0.000132275132275132*G0_0_0_0_2 - 6.61375661375658e-05*G0_0_0_1_0 + 6.61375661375661e-06*G0_0_0_1_1 - 6.61375661375658e-06*G0_0_0_1_2 - 0.000132275132275132*G0_0_0_2_0 - 6.61375661375658e-06*G0_0_0_2_1 - 5.95238095238093e-05*G0_0_0_2_2 - 6.61375661375658e-05*G0_0_1_0_0 + 6.61375661375661e-06*G0_0_1_0_1 - 6.61375661375658e-06*G0_0_1_0_2 + 6.61375661375661e-06*G0_0_1_1_0 + 4.62962962962962e-05*G0_0_1_1_1 + 1.32275132275132e-05*G0_0_1_1_2 - 6.61375661375658e-06*G0_0_1_2_0 + 1.32275132275132e-05*G0_0_1_2_1 - 6.61375661375659e-06*G0_0_1_2_2 - 0.000132275132275132*G0_0_2_0_0 - 6.61375661375658e-06*G0_0_2_0_1 - 5.95238095238093e-05*G0_0_2_0_2 - 6.61375661375658e-06*G0_0_2_1_0 + 1.32275132275132e-05*G0_0_2_1_1 - 6.61375661375659e-06*G0_0_2_1_2 - 5.95238095238093e-05*G0_0_2_2_0 - 6.61375661375659e-06*G0_0_2_2_1 - 0.000132275132275132*G0_0_2_2_2 - 6.61375661375658e-05*G0_1_0_0_0 + 6.61375661375661e-06*G0_1_0_0_1 - 6.61375661375658e-06*G0_1_0_0_2 + 6.61375661375661e-06*G0_1_0_1_0 + 4.62962962962961e-05*G0_1_0_1_1 + 1.32275132275132e-05*G0_1_0_1_2 - 6.61375661375658e-06*G0_1_0_2_0 + 1.32275132275132e-05*G0_1_0_2_1 - 6.61375661375659e-06*G0_1_0_2_2 + 6.61375661375661e-06*G0_1_1_0_0 + 4.62962962962961e-05*G0_1_1_0_1 + 1.32275132275132e-05*G0_1_1_0_2 + 4.62962962962961e-05*G0_1_1_1_0 + 0.000171957671957671*G0_1_1_1_1 + 4.62962962962962e-05*G0_1_1_1_2 + 1.32275132275132e-05*G0_1_1_2_0 + 4.62962962962962e-05*G0_1_1_2_1 + 6.6137566137566e-06*G0_1_1_2_2 - 6.61375661375658e-06*G0_1_2_0_0 + 1.32275132275132e-05*G0_1_2_0_1 - 6.61375661375659e-06*G0_1_2_0_2 + 1.32275132275132e-05*G0_1_2_1_0 + 4.62962962962962e-05*G0_1_2_1_1 + 6.61375661375659e-06*G0_1_2_1_2 - 6.61375661375659e-06*G0_1_2_2_0 + 6.61375661375659e-06*G0_1_2_2_1 - 6.61375661375659e-05*G0_1_2_2_2 - 0.000132275132275132*G0_2_0_0_0 - 6.61375661375658e-06*G0_2_0_0_1 - 5.95238095238093e-05*G0_2_0_0_2 - 6.61375661375658e-06*G0_2_0_1_0 + 1.32275132275132e-05*G0_2_0_1_1 - 6.61375661375659e-06*G0_2_0_1_2 - 5.95238095238093e-05*G0_2_0_2_0 - 6.61375661375659e-06*G0_2_0_2_1 - 0.000132275132275132*G0_2_0_2_2 - 6.61375661375658e-06*G0_2_1_0_0 + 1.32275132275132e-05*G0_2_1_0_1 - 6.61375661375659e-06*G0_2_1_0_2 + 1.32275132275132e-05*G0_2_1_1_0 + 4.62962962962962e-05*G0_2_1_1_1 + 6.6137566137566e-06*G0_2_1_1_2 - 6.61375661375659e-06*G0_2_1_2_0 + 6.61375661375659e-06*G0_2_1_2_1 - 6.61375661375659e-05*G0_2_1_2_2 - 5.95238095238093e-05*G0_2_2_0_0 - 6.61375661375659e-06*G0_2_2_0_1 - 0.000132275132275132*G0_2_2_0_2 - 6.61375661375659e-06*G0_2_2_1_0 + 6.6137566137566e-06*G0_2_2_1_1 - 6.61375661375659e-05*G0_2_2_1_2 - 0.000132275132275132*G0_2_2_2_0 - 6.61375661375659e-05*G0_2_2_2_1 - 0.000727513227513224*G0_2_2_2_2; + A[12] = A[2]; + } + + /// 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 mass_matrix_f4_p1_q2_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f4_p1_q2_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_p1_q2_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 3), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1))))), 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 4; + } + + /// 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 mass_matrix_f4_p1_q2_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f4_p1_q2_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f4_p1_q2_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f4_p1_q2_tensor_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f4_p1_q2_tensor_finite_element_0(); + break; + } + case 5: + { + return new mass_matrix_f4_p1_q2_tensor_finite_element_0(); + 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 mass_matrix_f4_p1_q2_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f4_p1_q2_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f4_p1_q2_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f4_p1_q2_tensor_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f4_p1_q2_tensor_dofmap_0(); + break; + } + case 5: + { + return new mass_matrix_f4_p1_q2_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f4_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/mass_matrix_2d/mass_matrix_f4_p1_q3_excafe.h b/mass_matrix_2d/mass_matrix_f4_p1_q3_excafe.h new file mode 100644 index 0000000..a96cde8 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f4_p1_q3_excafe.h @@ -0,0 +1,367 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 1 minute and 34.28 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 = -1.0000000000000000000000000*x[0][0]; + const double var_1 = x[1][0] + var_0; + const double var_2 = -1.0000000000000000000000000*x[0][1]; + const double var_3 = var_2 + x[2][1]; + const double var_4 = x[2][0] + var_0; + const double var_5 = var_2 + x[1][1]; + const double var_6 = var_1*var_3 + -1.0000000000000000000000000*var_4*var_5; + const double var_7 = std::abs(var_6); + const double var_8 = w[1][1]*w[2][2] + w[1][2]*w[2][1]; + const double var_9 = w[0][1]*w[3][2] + w[0][2]*w[3][1]; + const double var_10 = var_9*w[1][1]*w[2][1] + var_8*w[0][1]*w[3][1]; + const double var_11 = var_8*w[0][2]*w[3][2] + var_9*w[1][2]*w[2][2]; + const double var_12 = w[1][1]*w[2][0] + w[1][0]*w[2][1]; + const double var_13 = w[0][1]*w[3][0] + w[0][0]*w[3][1]; + const double var_14 = var_12*w[0][0]*w[3][0] + var_13*w[1][0]*w[2][0]; + const double var_15 = -1.0000000000000000000000000*var_14; + const double var_16 = w[1][2]*w[2][0] + w[1][0]*w[2][2]; + const double var_17 = w[0][2]*w[3][0] + w[0][0]*w[3][2]; + const double var_18 = var_16*w[0][0]*w[3][0] + var_17*w[1][0]*w[2][0]; + const double var_19 = -1.0000000000000000000000000*var_18; + const double var_20 = w[0][2]*w[1][2]*w[2][2]*w[3][2]; + const double var_21 = -1.0000000000000000000000000*var_20; + const double var_22 = var_19 + var_21; + const double var_23 = var_16*var_17 + w[0][2]*w[1][0]*w[2][0]*w[3][2] + w[0][0]*w[1][2]*w[2][2]*w[3][0]; + const double var_24 = w[0][1]*w[1][1]*w[2][1]*w[3][1]; + const double var_25 = -0.0003896103896103896100517*var_23 + 0.0003246753246753246750431*var_24; + const double var_26 = var_12*var_13 + w[0][1]*w[1][0]*w[2][0]*w[3][1] + w[0][0]*w[1][1]*w[2][1]*w[3][0]; + const double var_27 = -0.0009740259740259740251292*var_26; + const double var_28 = var_16*w[0][1] + var_8*w[0][0] + var_12*w[0][2]; + const double var_29 = var_12*w[3][2]; + const double var_30 = var_16*w[3][1]; + const double var_31 = var_29 + var_30; + const double var_32 = var_31*w[0][0] + var_9*w[1][0]*w[2][0] + var_28*w[3][0]; + const double var_33 = var_16*w[0][2]*w[3][2] + var_17*w[1][2]*w[2][2]; + const double var_34 = var_13*w[1][1]*w[2][1] + var_12*w[0][1]*w[3][1]; + const double var_35 = var_33 + var_34; + const double var_36 = var_8*var_9 + w[0][2]*w[1][1]*w[2][1]*w[3][2] + w[0][1]*w[1][2]*w[2][2]*w[3][1]; + const double var_37 = var_8*w[3][0]; + const double var_38 = var_37 + var_30; + const double var_39 = var_28*w[3][2] + var_13*w[1][2]*w[2][2] + var_38*w[0][2]; + const double var_40 = var_29 + var_37; + const double var_41 = var_17*w[1][1]*w[2][1] + var_40*w[0][1] + var_28*w[3][1]; + const double var_42 = var_39 + var_41; + const double var_43 = var_36 + var_42; + const double var_44 = w[0][0]*w[1][0]*w[2][0]*w[3][0]; + const double var_45 = 0.2142857142857142738190390*var_44; + const double var_46 = 0.0090909090909090904675249*var_32 + 0.0038961038961038961005168*var_43 + 0.0077922077922077922010335*var_35 + var_45; + const double var_47 = -0.0500000000000000027755576*var_46; + const double var_48 = var_47 + 0.0016233766233766234836355*var_22 + var_27 + -0.0000649350649350649350086*var_10 + 0.0025974025974025974003445*var_15 + -0.0004545454545454545450603*var_11 + var_25; + A[67] = 0.1875000000000000000000000*var_48*var_7; + const double var_49 = var_20 + var_24; + const double var_50 = var_23 + var_26; + const double var_51 = var_10 + var_11; + const double var_52 = var_14 + var_18; + const double var_53 = var_32 + var_52; + const double var_54 = 0.0857142857142857150787307*var_51 + 0.0085714285714285718548178*var_53 + 0.0171428571428571437096355*var_43 + 0.5571428571428571618895376*var_49 + 0.0028571428571428571403790*var_44 + 0.0714285714285714246063463*var_35 + 0.0200000000000000004163336*var_50; + A[34] = -0.0042613636363636369155938*var_54*var_7; + const double var_55 = var_32 + -1.0000000000000000000000000*var_36; + const double var_56 = 0.0002191558441558441692066*var_55*var_7 + 0.0032873376623376621315231*var_7*w[0][0]*w[1][0]*w[2][0]*w[3][0]; + const double var_57 = 0.0025974025974025974003445*var_23; + const double var_58 = 0.0001731601731601731600230*var_23 + 0.0177489177489177502033968*w[0][1]*w[1][1]*w[2][1]*w[3][1] + 0.0005194805194805194800689*var_41; + const double var_59 = -1.0000000000000000000000000*w[0][2]*w[1][2]*w[2][2]*w[3][2]; + const double var_60 = 0.0006060606060606060600804*var_59 + 0.0002164502164502164500287*var_39 + -0.0002597402597402597400345*var_26; + const double var_61 = -5.0000000000000000000000000*w[0][0]*w[1][0]*w[2][0]*w[3][0]; + const double var_62 = 0.0000432900432900432900057*var_32 + 0.0007359307359307359300976*var_36 + 0.0064935064935064939345422*var_61; + const double var_63 = 0.0025108225108225108203330*var_10; + const double var_64 = 0.0028571428571428571403790*var_34 + var_58 + var_60 + 0.0001298701298701298700172*var_33 + var_62 + 0.0036796536796536798673285*var_15 + 0.0002164502164502164500287*var_11 + 0.0015151515151515151502010*var_19 + var_63; + A[8] = 0.0312500000000000000000000*var_64*var_7; + const double var_65 = -1.0000000000000000000000000*var_33; + const double var_66 = -1.0000000000000000000000000*var_11; + const double var_67 = -1.0000000000000000000000000*w[0][0]*w[1][0]*w[2][0]*w[3][0]; + const double var_68 = 0.0002164502164502164500287*var_32 + -0.0002597402597402597400345*var_36 + 0.0006060606060606060600804*var_67; + const double var_69 = -5.0000000000000000000000000*w[0][2]*w[1][2]*w[2][2]*w[3][2]; + const double var_70 = 0.0064935064935064939345422*var_69 + 0.0000432900432900432900057*var_39 + 0.0007359307359307359300976*var_26; + const double var_71 = 0.0025108225108225108203330*var_34; + const double var_72 = var_68 + var_70 + 0.0036796536796536798673285*var_66 + 0.0015151515151515151502010*var_65 + 0.0002164502164502164500287*var_14 + var_58 + 0.0001298701298701298700172*var_18 + 0.0028571428571428571403790*var_10 + var_71; + A[23] = 0.0312500000000000000000000*var_7*var_72; + const double var_73 = var_14 + var_34; + const double var_74 = var_10 + var_18; + const double var_75 = var_26 + var_41; + const double var_76 = var_32 + var_75; + const double var_77 = 0.2142857142857142738190390*var_20; + const double var_78 = 0.0077922077922077922010335*var_74 + 0.0038961038961038961005168*var_76 + var_77 + 0.0090909090909090904675249*var_39; + const double var_79 = var_33 + var_11; + const double var_80 = var_23 + var_36; + const double var_81 = var_24 + var_44; + const double var_82 = var_78 + 0.0136363636363636357012874*var_80 + 0.0129870129870129878690843*var_81 + 0.0422077922077922079724388*var_79; + A[46] = 0.0187500000000000027755576*var_7*var_82 + 0.0000974025974025974025129*var_7*var_73; + A[64] = A[46]; + const double var_83 = 0.0272727272727272714025748*var_36 + 0.0019480519480519480502584*var_53 + 0.0025974025974025974003445*var_44; + const double var_84 = 0.0045454545454545452337625*var_23 + 0.0389610389610389670766999*var_24 + 0.0038961038961038961005168*var_41; + const double var_85 = 0.0025974025974025974003445*var_26; + const double var_86 = var_85 + 0.0068181818181818178506437*var_39 + var_77; + const double var_87 = var_33 + 3.0000000000000000000000000*var_11; + const double var_88 = 3.0000000000000000000000000*var_10 + var_34; + const double var_89 = var_86 + var_84 + 0.0064935064935064939345422*var_88 + 0.0211038961038961039862194*var_87 + var_83; + const double var_90 = var_23 + var_39; + const double var_91 = 0.3441558441558441594487761*w[0][2]*w[1][2]*w[2][2]*w[3][2] + -0.0047619047619047623343125*var_26; + const double var_92 = -0.0021645021645021645002871*var_32 + -0.0032467532467532469672711*var_36 + -0.0095238095238095246686250*var_44; + const double var_93 = 0.0303030303030303038713811*var_33 + -0.0095238095238095246686250*var_14; + const double var_94 = -0.0095238095238095246686250*var_34 + 0.0303030303030303038713811*var_11; + const double var_95 = -0.0476190476190476164042309*var_24; + const double var_96 = var_18 + var_41; + const double var_97 = -0.0032467532467532469672711*var_96 + 0.5000000000000000000000000*var_93 + var_95 + var_94 + var_92 + -0.0129870129870129878690843*var_10 + -0.0010822510822510822501435*var_90 + var_91; + A[24] = 0.0062500000000000003469447*var_7*var_97; + A[42] = A[24]; + const double var_98 = -0.0010822510822510822501435*var_32 + -0.0047619047619047623343125*var_36 + 0.3441558441558441594487761*w[0][0]*w[1][0]*w[2][0]*w[3][0]; + const double var_99 = -0.0095238095238095246686250*var_24 + -0.0021645021645021645002871*var_41; + const double var_100 = -0.0095238095238095246686250*var_11 + 0.0303030303030303038713811*var_18; + const double var_101 = -0.0095238095238095246686250*var_10 + 0.0303030303030303038713811*var_14; + const double var_102 = -0.0476190476190476164042309*var_20; + const double var_103 = var_90 + var_34; + const double var_104 = -0.0010822510822510822501435*var_26 + -0.0032467532467532469672711*var_103 + var_102 + -0.0129870129870129878690843*var_33 + 0.5000000000000000000000000*var_101 + var_100 + var_98 + var_99; + const double var_105 = -1.0000000000000000000000000*var_10; + const double var_106 = var_105 + var_21; + const double var_107 = 0.3000000000000000444089210*var_23; + const double var_108 = -1.0000000000000000000000000*var_24; + const double var_109 = 1.5000000000000000000000000*var_108; + const double var_110 = 0.6000000000000000888178420*var_26; + const double var_111 = 0.5000000000000000000000000*var_106 + 0.3000000000000000444089210*var_66 + 1.5000000000000000000000000*var_14 + var_18 + var_109 + var_110 + var_107; + const double var_112 = 0.0177489177489177502033968*w[0][2]*w[1][2]*w[2][2]*w[3][2] + 0.0005194805194805194800689*var_39 + 0.0001731601731601731600230*var_26; + const double var_113 = -1.0000000000000000000000000*var_34; + const double var_114 = -5.0000000000000000000000000*w[0][1]*w[1][1]*w[2][1]*w[3][1]; + const double var_115 = 0.0007359307359307359300976*var_23 + 0.0064935064935064939345422*var_114 + 0.0000432900432900432900057*var_41; + const double var_116 = var_68 + 0.0001298701298701298700172*var_14 + 0.0002164502164502164500287*var_18 + 0.0025108225108225108203330*var_33 + var_112 + 0.0015151515151515151502010*var_113 + 0.0036796536796536798673285*var_105 + var_115 + 0.0028571428571428571403790*var_11; + A[14] = 0.0312500000000000000000000*var_116*var_7; + A[41] = A[14]; + const double var_117 = 0.0389610389610389670766999*var_20 + 0.0038961038961038961005168*var_39 + 0.0045454545454545452337625*var_26; + const double var_118 = 0.2142857142857142738190390*var_24; + const double var_119 = var_57 + 0.0068181818181818178506437*var_41 + var_118; + const double var_120 = var_119 + 0.0211038961038961039862194*var_88 + 0.0064935064935064939345422*var_87 + var_117 + var_83; + const double var_121 = 4.5000000000000000000000000*w[0][2]*w[1][2]*w[2][2]*w[3][2] + -0.3000000000000000444089210*var_26; + const double var_122 = var_108 + var_15; + const double var_123 = -1.0000000000000000000000000*var_44; + const double var_124 = 0.3000000000000000444089210*var_36; + const double var_125 = var_124 + 1.5000000000000000000000000*var_123; + const double var_126 = 0.6000000000000000888178420*var_23; + const double var_127 = var_113 + var_39; + const double var_128 = var_125 + var_126 + 1.5000000000000000000000000*var_33 + var_121 + 0.5000000000000000000000000*var_122 + 0.3000000000000000444089210*var_127 + var_11; + A[69] = 0.0007305194805194805459519*var_128*var_7; + A[96] = A[69]; + const double var_129 = var_32 + var_41; + const double var_130 = 0.0002164502164502164500287*var_74 + 0.0036796536796536798673285*var_39 + 0.2500000000000000000000000*var_85 + 0.0010822510822510822501435*var_129 + 0.0833333333333333287074041*var_20; + const double var_131 = 0.0084415584415584409005984*var_36 + 0.0075757575757575759678453*var_67; + const double var_132 = var_57 + var_130 + 0.0008658008658008658001148*var_14 + 0.0125541125541125536679843*var_33 + var_131 + 0.0030303030303030303004019*var_113 + 0.0222943722943722937024358*var_11; + const double var_133 = var_14 + var_11; + const double var_134 = var_32 + var_39; + const double var_135 = 0.0147186147186147194693140*var_41 + var_57 + 0.0008658008658008658001148*var_133 + 0.3333333333333333148296163*var_24 + 0.0043290043290043290005742*var_134; + const double var_136 = 0.0500000000000000027755576*var_135; + const double var_137 = var_10 + var_34; + const double var_138 = var_52 + var_137 + var_79; + const double var_139 = var_32 + var_42; + const double var_140 = 0.3000000000000000444089210*var_139 + 0.5000000000000000000000000*var_138 + var_44 + var_49; + const double var_141 = var_36 + var_50; + A[99] = 0.0043831168831168828420308*var_140*var_7 + 0.0017532467532467533536528*var_141*var_7; + const double var_142 = var_32 + 0.3333333333333333148296163*var_36; + const double var_143 = -0.3000000000000000444089210*var_23 + 4.5000000000000000000000000*w[0][1]*w[1][1]*w[2][1]*w[3][1]; + const double var_144 = 0.6000000000000000888178420*var_36 + 0.5000000000000000000000000*var_123; + const double var_145 = 1.5000000000000000000000000*var_21; + const double var_146 = var_19 + var_75; + const double var_147 = var_34 + 0.3000000000000000444089210*var_146 + var_145 + 0.5000000000000000000000000*var_65 + 1.5000000000000000000000000*var_10 + var_143 + var_144; + A[39] = 0.0007305194805194805459519*var_147*var_7; + const double var_148 = var_32 + var_90; + const double var_149 = 0.0077922077922077922010335*var_133 + 0.0038961038961038961005168*var_148 + var_118 + 0.0090909090909090904675249*var_41; + const double var_150 = 0.0025974025974025974003445*var_36; + const double var_151 = 0.0077922077922077922010335*var_51 + 0.0134199134199134203354609*w[0][0]*w[1][0]*w[2][0]*w[3][0] + var_150 + 0.0012987012987012987001723*var_52 + 0.0714285714285714246063463*var_49 + 0.0030303030303030303004019*var_35 + -0.0001443001443001443000191*var_32 + -0.0004329004329004329000574*var_50; + const double var_152 = var_65 + var_41; + const double var_153 = var_125 + 1.5000000000000000000000000*var_34 + 0.5000000000000000000000000*var_22 + var_110 + var_10 + 0.3000000000000000444089210*var_152 + var_143; + A[89] = 0.0007305194805194805459519*var_153*var_7; + const double var_154 = 0.0005194805194805194800689*var_142 + 0.0177489177489177502033968*w[0][0]*w[1][0]*w[2][0]*w[3][0]; + const double var_155 = 0.0025108225108225108203330*var_18; + const double var_156 = var_155 + var_154 + var_60 + 0.0028571428571428571403790*var_14 + 0.0002164502164502164500287*var_33 + 0.0036796536796536798673285*var_113 + 0.0015151515151515151502010*var_105 + var_115 + 0.0001298701298701298700172*var_11; + A[17] = 0.0312500000000000000000000*var_156*var_7; + const double var_157 = 0.0010822510822510822501435*var_69 + 0.0005194805194805194800689*var_26; + const double var_158 = -1.0000000000000000000000000*w[0][1]*w[1][1]*w[2][1]*w[3][1]; + const double var_159 = 0.0084415584415584409005984*var_23 + 0.0075757575757575759678453*var_158; + const double var_160 = 0.0043290043290043290005742*var_42 + var_150 + 0.3333333333333333148296163*var_44 + 0.0008658008658008658001148*var_35 + 0.0147186147186147194693140*var_32; + const double var_161 = 0.0500000000000000027755576*var_160; + const double var_162 = 0.0025108225108225108203330*var_14; + const double var_163 = var_157 + 0.0006060606060606060600804*var_66 + 0.2000000000000000111022302*var_159 + 0.0044588744588744590874319*var_18 + 0.0001731601731601731600230*var_10 + var_162 + var_161; + A[15] = 0.0312500000000000000000000*var_163*var_7; + A[51] = A[15]; + A[98] = A[89]; + const double var_164 = var_79 + var_39; + const double var_165 = 0.0025974025974025974003445*var_20 + 0.0019480519480519480502584*var_164 + 0.0272727272727272714025748*var_26; + const double var_166 = 0.0038961038961038961005168*var_32 + 0.0045454545454545452337625*var_36 + 0.0389610389610389670766999*var_44; + const double var_167 = var_10 + 3.0000000000000000000000000*var_34; + const double var_168 = 3.0000000000000000000000000*var_14 + var_18; + const double var_169 = var_119 + 0.0064935064935064939345422*var_168 + var_165 + 0.0211038961038961039862194*var_167 + var_166; + const double var_170 = var_66 + var_108; + const double var_171 = 0.1250000000000000000000000*var_74 + 0.0833333333333333287074041*var_39 + 0.0722222222222222293153138*var_26 + 0.1083333333333333370340767*var_73 + 0.1666666666666666574148081*var_80 + 19.0000000000000000000000000*w[0][2]*w[1][2]*w[2][2]*w[3][2] + 1.0833333333333332593184650*var_79 + 0.0416666666666666643537020*var_129 + 0.4333333333333333481363070*var_81; + A[22] = 0.0001623376623376623375215*var_171*var_7; + const double var_172 = -0.0009740259740259740251292*var_36 + 0.0016233766233766234836355*var_123; + const double var_173 = var_33 + var_18; + const double var_174 = var_36 + var_26; + const double var_175 = var_20 + var_44; + const double var_176 = 0.0134199134199134203354609*w[0][1]*w[1][1]*w[2][1]*w[3][1] + -0.0001443001443001443000191*var_41 + var_57 + 0.0030303030303030303004019*var_133 + 0.0714285714285714246063463*var_175 + 0.0012987012987012987001723*var_137 + -0.0004329004329004329000574*var_174 + 0.0077922077922077922010335*var_173; + A[2] = 0.0031250000000000001734723*var_176*var_7; + A[20] = A[2]; + const double var_177 = var_137 + var_41; + const double var_178 = 0.0085714285714285718548178*var_177 + 0.0714285714285714246063463*var_133 + 0.0171428571428571437096355*var_148 + 0.5571428571428571618895376*var_175 + 0.0028571428571428571403790*var_24 + 0.0200000000000000004163336*var_174 + 0.0857142857142857150787307*var_173; + A[56] = -0.0042613636363636369155938*var_178*var_7; + const double var_179 = -0.1500000000000000222044605*var_50 + 1.5000000000000000000000000*var_44; + const double var_180 = var_179 + 0.1250000000000000000000000*var_52 + -0.0750000000000000111022302*var_43 + -1.0000000000000000000000000*var_49 + -0.3750000000000000000000000*var_35 + -0.0250000000000000013877788*var_32; + const double var_181 = 0.0003246753246753246750431*var_20 + -0.0003896103896103896100517*var_26; + const double var_182 = -0.0500000000000000027755576*var_149; + const double var_183 = var_172 + -0.0004545454545454545450603*var_18 + -0.0000649350649350649350086*var_33 + var_181 + 0.0016233766233766234836355*var_113 + 0.0025974025974025974003445*var_105 + var_182; + A[37] = 0.1875000000000000000000000*var_183*var_7; + A[73] = A[37]; + const double var_184 = var_149 + 0.0129870129870129878690843*var_175 + 0.0422077922077922079724388*var_137 + 0.0136363636363636357012874*var_174; + const double var_185 = -0.0003896103896103896100517*var_36 + 0.0003246753246753246750431*var_44; + const double var_186 = 0.0016233766233766234836355*var_106 + var_27 + -0.0000649350649350649350086*var_18 + -0.0004545454545454545450603*var_33 + 0.0025974025974025974003445*var_113 + var_185 + var_182; + A[48] = 0.1875000000000000000000000*var_186*var_7; + A[93] = A[39]; + const double var_187 = var_90 + var_15; + const double var_188 = var_109 + var_33 + var_121 + 0.5000000000000000000000000*var_113 + 0.3000000000000000444089210*var_187 + 1.5000000000000000000000000*var_11 + var_144; + A[49] = 0.0007305194805194805459519*var_188*var_7; + const double var_189 = 1.5000000000000000000000000*var_20 + -0.1500000000000000222044605*var_80; + const double var_190 = -0.3750000000000000000000000*var_74 + -0.0250000000000000013877788*var_39 + var_189 + -0.0750000000000000111022302*var_76 + 0.1250000000000000000000000*var_79 + -1.0000000000000000000000000*var_81; + const double var_191 = -0.0002597402597402597400345*var_23 + 0.0006060606060606060600804*var_158 + 0.0002164502164502164500287*var_41; + const double var_192 = 0.0001298701298701298700172*var_34 + 0.0028571428571428571403790*var_33 + var_112 + 0.0002164502164502164500287*var_10 + 0.0015151515151515151502010*var_15 + var_62 + var_191 + 0.0025108225108225108203330*var_11 + 0.0036796536796536798673285*var_19; + A[6] = 0.0312500000000000000000000*var_192*var_7; + A[60] = A[6]; + const double var_193 = -0.0032467532467532469672711*var_142 + -0.0476190476190476164042309*var_44; + const double var_194 = var_23 + var_10; + const double var_195 = var_93 + -0.0010822510822510822501435*var_39 + 0.5000000000000000000000000*var_94 + var_193 + var_91 + -0.0032467532467532469672711*var_194 + 0.0129870129870129878690843*var_19 + var_99; + A[26] = 0.0062500000000000003469447*var_195*var_7; + const double var_196 = 0.0750000000000000111022302*var_42 + var_124 + 0.5000000000000000000000000*var_179 + -0.1250000000000000000000000*var_52 + var_49 + 0.1500000000000000222044605*var_35 + -0.0500000000000000027755576*var_32; + A[9] = 0.0003246753246753246750431*var_196*var_7 + 0.0001298701298701298700172*var_51*var_7; + const double var_197 = 0.3000000000000000444089210*var_26; + const double var_198 = 0.5000000000000000000000000*var_170 + var_14 + var_145 + 1.5000000000000000000000000*var_18 + var_126 + var_197 + 0.3000000000000000444089210*var_105; + A[59] = var_56 + 0.0007305194805194805459519*var_198*var_7; + A[95] = A[59]; + const double var_199 = -0.0095238095238095246686250*var_20 + -0.0021645021645021645002871*var_39; + const double var_200 = 0.1500000000000000222044605*var_74 + -0.0500000000000000027755576*var_39 + 0.5000000000000000000000000*var_189 + var_197 + -0.1250000000000000000000000*var_79 + 0.0750000000000000111022302*var_129 + var_81; + const double var_201 = 0.0714285714285714246063463*var_74 + 0.0171428571428571437096355*var_76 + 0.0857142857142857150787307*var_73 + 0.0200000000000000004163336*var_80 + 0.5571428571428571618895376*var_81 + 0.0085714285714285718548178*var_164 + 0.0028571428571428571403790*var_20; + A[78] = -0.0042613636363636369155938*var_201*var_7; + A[87] = A[78]; + A[35] = 0.0004870129870129870125646*var_190*var_7 + -0.0000852272727272727339751*var_7*var_73; + A[65] = A[56]; + A[4] = 0.0000338203463203463203170*var_114*var_7 + 0.0062500000000000003469447*var_132*var_7; + A[29] = 0.0001298701298701298700172*var_7*var_73 + 0.0003246753246753246750431*var_200*var_7; + A[33] = 0.0375000000000000055511151*var_120*var_7; + const double var_202 = 0.0068181818181818178506437*var_32 + var_45 + var_150; + const double var_203 = var_84 + 0.0211038961038961039862194*var_168 + var_165 + 0.0064935064935064939345422*var_167 + var_202; + const double var_204 = 0.0303030303030303038713811*var_10 + -0.0095238095238095246686250*var_33; + const double var_205 = 0.0030303030303030303004019*var_74 + -0.0001443001443001443000191*var_39 + var_85 + 0.0077922077922077922010335*var_73 + -0.0004329004329004329000574*var_80 + 0.0134199134199134203354609*w[0][2]*w[1][2]*w[2][2]*w[3][2] + 0.0012987012987012987001723*var_79 + 0.0714285714285714246063463*var_81; + A[1] = 0.0031250000000000001734723*var_205*var_7; + A[10] = A[1]; + A[77] = 0.0375000000000000055511151*var_203*var_7; + const double var_206 = -0.0009740259740259740251292*var_23; + const double var_207 = 1.5000000000000000000000000*var_24 + -0.1500000000000000222044605*var_174; + const double var_208 = var_33 + var_75; + const double var_209 = 0.0015151515151515151502010*var_59 + 0.0016883116883116883102239*var_26; + const double var_210 = var_155 + 0.2000000000000000111022302*var_57 + 0.0044588744588744590874319*var_14 + 0.0006060606060606060600804*var_105 + 0.0010822510822510822501435*var_114 + var_209 + 0.0001731601731601731600230*var_11 + var_161; + A[76] = A[67]; + const double var_211 = var_47 + 0.0016233766233766234836355*var_122 + -0.0004545454545454545450603*var_10 + var_181 + 0.0025974025974025974003445*var_19 + -0.0000649350649350649350086*var_11 + var_206; + A[58] = 0.1875000000000000000000000*var_211*var_7; + const double var_212 = -0.0500000000000000027755576*var_78; + A[53] = A[35]; + const double var_213 = 0.0272727272727272714025748*var_23 + 0.0025974025974025974003445*var_24 + 0.0019480519480519480502584*var_177; + const double var_214 = 3.0000000000000000000000000*var_33 + var_11; + const double var_215 = var_14 + 3.0000000000000000000000000*var_18; + const double var_216 = var_213 + 0.0064935064935064939345422*var_214 + var_117 + 0.0211038961038961039862194*var_215 + var_202; + A[55] = 0.0375000000000000055511151*var_216*var_7; + A[94] = A[49]; + const double var_217 = var_199 + var_95 + -0.0129870129870129878690843*var_34 + var_101 + 0.5000000000000000000000000*var_100 + var_98 + -0.0032467532467532469672711*var_208 + -0.0010822510822510822501435*var_23; + A[7] = 0.0062500000000000003469447*var_217*var_7; + A[70] = A[7]; + const double var_218 = var_11 + var_26; + const double var_219 = 0.0008658008658008658001148*var_34 + var_130 + var_159 + 0.0222943722943722937024358*var_33 + var_150 + 0.0030303030303030303004019*var_15 + 0.0125541125541125536679843*var_11; + A[16] = 0.0062500000000000003469447*var_219*var_7 + 0.0000338203463203463203170*var_61*var_7; + A[61] = A[16]; + const double var_220 = 0.0136363636363636357012874*var_50 + 0.0422077922077922079724388*var_52 + 0.0129870129870129878690843*var_49 + var_46; + A[57] = 0.0187500000000000027755576*var_220*var_7 + 0.0000974025974025974025129*var_51*var_7; + const double var_221 = -0.0250000000000000013877788*var_41 + -0.3750000000000000000000000*var_133 + -0.0750000000000000111022302*var_148 + var_207 + -1.0000000000000000000000000*var_175 + 0.1250000000000000000000000*var_137; + A[47] = 0.0004870129870129870125646*var_221*var_7 + -0.0000852272727272727339751*var_173*var_7; + A[74] = A[47]; + const double var_222 = var_14 + var_39; + const double var_223 = -0.0500000000000000027755576*var_41 + 0.1500000000000000222044605*var_133 + 0.5000000000000000000000000*var_207 + var_175 + -0.1250000000000000000000000*var_137 + var_107 + 0.0750000000000000111022302*var_134; + A[40] = A[4]; + A[38] = 0.0187500000000000027755576*var_184*var_7 + 0.0000974025974025974025129*var_173*var_7; + const double var_224 = var_70 + 0.0015151515151515151502010*var_66 + 0.0002164502164502164500287*var_34 + var_154 + 0.0036796536796536798673285*var_65 + 0.0028571428571428571403790*var_18 + 0.0001298701298701298700172*var_10 + var_191 + var_162; + A[25] = 0.0312500000000000000000000*var_224*var_7; + A[52] = A[25]; + const double var_225 = var_212 + -0.0004545454545454545450603*var_34 + 0.0016233766233766234836355*var_170 + 0.0025974025974025974003445*var_65 + -0.0000649350649350649350086*var_14 + var_185 + var_206; + A[36] = 0.1875000000000000000000000*var_225*var_7; + A[63] = A[36]; + A[88] = 0.0375000000000000055511151*var_169*var_7; + const double var_226 = var_213 + 0.0211038961038961039862194*var_214 + var_86 + 0.0064935064935064939345422*var_215 + var_166; + A[66] = 0.0375000000000000055511151*var_226*var_7; + const double var_227 = var_157 + 0.0006060606060606060600804*var_65 + 0.2000000000000000111022302*var_131 + 0.0001731601731601731600230*var_18 + 0.0044588744588744590874319*var_10 + var_136 + var_71; + A[90] = A[9]; + A[5] = 0.0062500000000000003469447*var_104*var_7; + A[19] = 0.0003246753246753246750431*var_223*var_7 + 0.0001298701298701298700172*var_173*var_7; + A[91] = A[19]; + A[43] = A[34]; + A[79] = 0.0007305194805194805459519*var_111*var_7 + var_56; + A[75] = A[57]; + A[85] = A[58]; + A[68] = 0.0004870129870129870125646*var_180*var_7 + -0.0000852272727272727339751*var_51*var_7; + A[12] = 0.0031250000000000001734723*var_151*var_7; + const double var_228 = -0.0047619047619047623343125*var_23 + 0.3441558441558441594487761*w[0][1]*w[1][1]*w[2][1]*w[3][1]; + const double var_229 = 0.0303030303030303038713811*var_34 + -0.0095238095238095246686250*var_18; + const double var_230 = var_102 + -0.0010822510822510822501435*var_75 + var_92 + 0.5000000000000000000000000*var_229 + var_228 + -0.0032467532467532469672711*var_222 + -0.0129870129870129878690843*var_11 + var_204; + A[13] = 0.0062500000000000003469447*var_230*var_7; + A[31] = A[13]; + A[71] = A[17]; + A[80] = A[8]; + const double var_231 = var_212 + -0.0000649350649350649350086*var_34 + 0.0025974025974025974003445*var_66 + 0.0016233766233766234836355*var_65 + var_172 + -0.0004545454545454545450603*var_14 + var_25; + A[45] = 0.1875000000000000000000000*var_231*var_7; + const double var_232 = 0.0416666666666666643537020*var_42 + 0.0722222222222222293153138*var_36 + 19.0000000000000000000000000*w[0][0]*w[1][0]*w[2][0]*w[3][0] + 0.1083333333333333370340767*var_51 + 1.0833333333333332593184650*var_52 + 0.4333333333333333481363070*var_49 + 0.1250000000000000000000000*var_35 + 0.0833333333333333287074041*var_32 + 0.1666666666666666574148081*var_50; + A[0] = 0.0001623376623376623375215*var_232*var_7; + const double var_233 = -0.0032467532467532469672711*var_218 + var_199 + -0.0010822510822510822501435*var_41 + var_193 + 0.0129870129870129878690843*var_15 + var_228 + var_229 + 0.5000000000000000000000000*var_204; + A[18] = 0.0062500000000000003469447*var_233*var_7; + A[32] = A[23]; + const double var_234 = 19.0000000000000000000000000*w[0][1]*w[1][1]*w[2][1]*w[3][1] + 0.0833333333333333287074041*var_41 + 0.1250000000000000000000000*var_133 + 0.4333333333333333481363070*var_175 + 1.0833333333333332593184650*var_137 + 0.0416666666666666643537020*var_134 + 0.1666666666666666574148081*var_174 + 0.1083333333333333370340767*var_173 + 0.0722222222222222293153138*var_23; + A[11] = 0.0001623376623376623375215*var_234*var_7; + A[54] = A[45]; + A[50] = A[5]; + A[44] = 0.0375000000000000055511151*var_7*var_89; + A[62] = A[26]; + A[92] = A[29]; + A[81] = A[18]; + A[27] = 0.0312500000000000000000000*var_210*var_7; + A[72] = A[27]; + const double var_235 = 0.0010822510822510822501435*var_61 + 0.0044588744588744590874319*var_34 + 0.0001731601731601731600230*var_33 + 0.2000000000000000111022302*var_150 + var_136 + var_209 + 0.0006060606060606060600804*var_19 + var_63; + A[28] = 0.0312500000000000000000000*var_235*var_7; + A[84] = A[48]; + A[3] = 0.0312500000000000000000000*var_227*var_7; + A[86] = A[68]; + A[83] = A[38]; + A[82] = A[28]; + A[21] = A[12]; + A[97] = A[79]; + A[30] = A[3]; + } + + 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/mass_matrix_2d/mass_matrix_f4_p1_q3_quadrature.h b/mass_matrix_2d/mass_matrix_f4_p1_q3_quadrature.h new file mode 100644 index 0000000..3c4e56a --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f4_p1_q3_quadrature.h @@ -0,0 +1,4651 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F4_P1_Q3_QUADRATURE_H +#define __MASS_MATRIX_F4_P1_Q3_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f4_p1_q3_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f4_p1_q3_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_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 mass_matrix_f4_p1_q3_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f4_p1_q3_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f4_p1_q3_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_p1_q3_quadrature_finite_element_1() + { + // 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f4_p1_q3_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f4_p1_q3_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f4_p1_q3_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f4_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 mass_matrix_f4_p1_q3_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f4_p1_q3_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f4_p1_q3_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f4_p1_q3_quadrature_dofmap_1() + { + // 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.0*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 mass_matrix_f4_p1_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 mass_matrix_f4_p1_q3_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f4_p1_q3_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Array of quadrature weights. + static const double W36[36] = {0.00619426535265906, 0.0116108747669979, 0.0120606064042655, 0.0084515357969434, 0.0037652982126918, 0.000748542561236343, 0.0130433943300833, 0.0244492622580587, 0.0253962715890485, 0.0177965759970269, 0.00792866733379675, 0.00157622175402364, 0.0169175056800133, 0.0317111115907051, 0.0329393989007878, 0.023082463651359, 0.0102836172287667, 0.00204438659154493, 0.0169175056800133, 0.0317111115907051, 0.0329393989007878, 0.023082463651359, 0.0102836172287667, 0.00204438659154493, 0.0130433943300833, 0.0244492622580587, 0.0253962715890485, 0.0177965759970269, 0.00792866733379675, 0.00157622175402364, 0.00619426535265908, 0.0116108747669979, 0.0120606064042655, 0.00845153579694342, 0.00376529821269181, 0.000748542561236345}; + // Quadrature points on the UFC reference element: (0.0327753666144599, 0.0293164271597849), (0.0287653330125591, 0.148078599668484), (0.0223868729780306, 0.336984690281154), (0.0149015633666711, 0.55867151877155), (0.00779187470128645, 0.769233862030055), (0.00246669715267023, 0.926945671319741), (0.164429241594827, 0.0293164271597849), (0.144311486950417, 0.148078599668484), (0.112311681780954, 0.336984690281154), (0.0747589734626491, 0.55867151877155), (0.0390907007328242, 0.769233862030055), (0.01237506041744, 0.926945671319741), (0.369529924372377, 0.0293164271597849), (0.324318304588776, 0.148078599668484), (0.252403568076518, 0.336984690281154), (0.168009519121192, 0.55867151877155), (0.0878504549759972, 0.769233862030055), (0.0278110821153606, 0.926945671319741), (0.601153648467838, 0.0293164271597849), (0.52760309574274, 0.148078599668484), (0.410611741642328, 0.336984690281154), (0.273318962107258, 0.55867151877155), (0.142915682993948, 0.769233862030055), (0.0452432465648983, 0.926945671319741), (0.806254331245388, 0.0293164271597849), (0.707609913381099, 0.148078599668484), (0.550703627937892, 0.336984690281154), (0.366569507765801, 0.55867151877155), (0.191675437237121, 0.769233862030055), (0.0606792682628189, 0.926945671319741), (0.937908206225755, 0.0293164271597849), (0.823156067318956, 0.148078599668484), (0.640628436740815, 0.336984690281154), (0.426426917861779, 0.55867151877155), (0.222974263268659, 0.769233862030055), (0.0705876315275886, 0.926945671319741) + + // Value of basis functions at quadrature points. + static const double FE0[36][3] = \ + {{0.937908206225755, 0.03277536661446, 0.0293164271597848}, + {0.823156067318957, 0.0287653330125592, 0.148078599668484}, + {0.640628436740815, 0.0223868729780305, 0.336984690281154}, + {0.426426917861779, 0.0149015633666711, 0.55867151877155}, + {0.222974263268659, 0.00779187470128651, 0.769233862030055}, + {0.0705876315275887, 0.00246669715267028, 0.926945671319741}, + {0.806254331245388, 0.164429241594827, 0.0293164271597848}, + {0.707609913381099, 0.144311486950417, 0.148078599668484}, + {0.550703627937892, 0.112311681780954, 0.336984690281154}, + {0.366569507765801, 0.0747589734626491, 0.55867151877155}, + {0.191675437237121, 0.0390907007328243, 0.769233862030055}, + {0.0606792682628189, 0.0123750604174401, 0.926945671319741}, + {0.601153648467838, 0.369529924372377, 0.0293164271597848}, + {0.52760309574274, 0.324318304588776, 0.148078599668484}, + {0.410611741642328, 0.252403568076518, 0.336984690281154}, + {0.273318962107258, 0.168009519121192, 0.55867151877155}, + {0.142915682993948, 0.0878504549759972, 0.769233862030055}, + {0.0452432465648984, 0.0278110821153607, 0.926945671319741}, + {0.369529924372377, 0.601153648467839, 0.0293164271597848}, + {0.324318304588776, 0.52760309574274, 0.148078599668484}, + {0.252403568076518, 0.410611741642328, 0.336984690281154}, + {0.168009519121192, 0.273318962107258, 0.55867151877155}, + {0.0878504549759972, 0.142915682993948, 0.769233862030055}, + {0.0278110821153607, 0.0452432465648984, 0.926945671319741}, + {0.164429241594827, 0.806254331245388, 0.0293164271597848}, + {0.144311486950417, 0.707609913381099, 0.148078599668484}, + {0.112311681780954, 0.550703627937892, 0.336984690281154}, + {0.0747589734626489, 0.366569507765801, 0.55867151877155}, + {0.0390907007328242, 0.191675437237121, 0.769233862030055}, + {0.0123750604174401, 0.0606792682628189, 0.926945671319741}, + {0.03277536661446, 0.937908206225755, 0.0293164271597848}, + {0.0287653330125592, 0.823156067318957, 0.148078599668484}, + {0.0223868729780305, 0.640628436740815, 0.336984690281154}, + {0.0149015633666711, 0.426426917861779, 0.55867151877155}, + {0.00779187470128645, 0.222974263268659, 0.769233862030055}, + {0.00246669715267034, 0.0705876315275887, 0.926945671319741}}; + + static const double FE1[36][10] = \ + {{0.692116405326339, 0.02809979214053, 0.0255622715011347, -0.00389870712577275, -0.00394357498286782, 0.224416734425978, -0.112850342203846, 0.250894855131633, -0.124729708262302, 0.0243322740491734}, + {0.283934759651154, 0.0251489409971642, 0.0640171956914923, -0.0175137741663261, -0.0106528248707412, 0.806022543976085, -0.304843939147456, 0.156575676330067, -0.0973575486190499, 0.0946689701576109}, + {-0.0230667189458806, 0.0201820871510281, -0.00182545940770507, -0.0316681717528919, 0.000371870446193849, 0.89558289813655, 0.0106415390326746, 0.0594961764142811, -0.0602031247994332, 0.130488903725183}, + {-0.042916247694867, 0.0139171991648146, -0.0611798040376018, -0.0357880903185195, 0.0253254357551023, 0.299401977386427, 0.724719094689676, 0.00798601215243768, -0.0273165975674619, 0.0958510204699925}, + {0.0491311892659461, 0.00752079361748066, 0.154762873078755, -0.026341495488006, 0.0352713041777646, -0.255537670979266, 1.00933258876242, -0.0025884423606554, -0.00763548751524317, 0.0360843474408066}, + {0.0497485688239403, 0.00243938401571425, 0.644479118812606, -0.0102130829170651, 0.0183234311516915, -0.232087782696187, 0.524347954533704, -0.000617609305981537, -0.000777734182289297, 0.00435775176386716}, + {0.239508104110957, 0.0627683640711487, 0.0255622715011347, -0.0109916789233747, -0.0197843414303476, 0.150905638607928, -0.0970095757563665, 0.846395762124882, -0.302290885970787, 0.104936341664825}, + {0.0487956775975465, 0.0641196764159749, 0.0640171956914923, -0.0545304359767136, -0.0534436711248166, 0.529434975607773, -0.26205309289338, 0.515966174346368, -0.260579700000555, 0.40827320033631}, + {-0.0624669400507792, 0.0619241738506681, -0.00182545940770509, -0.112928533782117, 0.00186561987722207, 0.544580480381976, 0.00914778960164644, 0.181500084071326, -0.18454889805122, 0.562751683508982}, + {-0.0164528736892738, 0.0514890982575726, -0.0611798040376018, -0.145793810693828, 0.127054023323504, 0.0918877602754595, 0.622990507121273, 0.0122960172501371, -0.0956618757635125, 0.413370957956269}, + {0.0580370533440932, 0.0324831299939718, 0.154762873078755, -0.119445891298145, 0.176950996894466, -0.281967732783221, 0.867652896045716, -0.0143289535245541, -0.0297631768059827, 0.1556188050549}, + {0.045115774663025, 0.0116944490193934, 0.644479118812606, -0.0497031543433876, 0.0919259858517786, -0.207033374665612, 0.450745399833617, -0.00276397053159101, -0.00325364379944372, 0.0187934151596152}, + {-0.0474645235382767, -0.0178848851455664, 0.0255622715011347, 0.00529373373938191, -0.044462323864076, 0.0637197133595963, -0.0723315933226381, 0.803179075351347, 0.108551677668697, 0.1758368542504}, + {-0.0641414000235847, 0.00450421741088884, 0.0640171956914923, -0.00584473256502761, -0.120106591488146, 0.204898420912783, -0.195390172530051, 0.448763755411812, -0.0208247444397816, 0.684124051619613}, + {-0.0365624407658455, 0.0380796136728451, -0.00182545940770511, -0.0929282395408237, 0.00419269933650997, 0.144355545313924, 0.00682071014235854, 0.108123175205576, -0.11323192829258, 0.94297632433574}, + {0.029034487004146, 0.062328097021337, -0.0611798040376018, -0.209488219289238, 0.285534757531946, -0.123712995627073, 0.464509772912832, -0.037204260833003, -0.102487957137557, 0.692666122454212}, + {0.0641393355313791, 0.0561718105163469, 0.154762873078755, -0.223953257707656, 0.397670681113729, -0.282604617367218, 0.646933211826454, -0.0322748977125214, -0.0416081953276764, 0.260763056048409}, + {0.0364487137089397, 0.024427326771013, 0.644479118812606, -0.106328278377059, 0.206589790661253, -0.163106070537901, 0.336081595024143, -0.00489365931747124, -0.00518977181109788, 0.0314912350655752}, + {-0.0178848851455664, -0.0474645235382767, 0.0255622715011347, 0.0637197133595962, -0.072331593322638, 0.00529373373938194, -0.044462323864076, 0.108551677668697, 0.803179075351347, 0.1758368542504}, + {0.00450421741088887, -0.0641414000235847, 0.0640171956914923, 0.204898420912783, -0.195390172530051, -0.00584473256502761, -0.120106591488146, -0.0208247444397817, 0.448763755411812, 0.684124051619613}, + {0.0380796136728452, -0.0365624407658455, -0.00182545940770511, 0.144355545313924, 0.00682071014235857, -0.0929282395408238, 0.00419269933651001, -0.11323192829258, 0.108123175205576, 0.94297632433574}, + {0.062328097021337, 0.029034487004146, -0.0611798040376018, -0.123712995627073, 0.464509772912832, -0.209488219289239, 0.285534757531946, -0.102487957137557, -0.0372042608330028, 0.692666122454212}, + {0.0561718105163469, 0.0641393355313791, 0.154762873078755, -0.282604617367218, 0.646933211826454, -0.223953257707657, 0.397670681113729, -0.0416081953276766, -0.0322748977125212, 0.260763056048409}, + {0.0244273267710131, 0.0364487137089397, 0.644479118812606, -0.163106070537901, 0.336081595024142, -0.106328278377059, 0.206589790661253, -0.00518977181109807, -0.00489365931747109, 0.0314912350655752}, + {0.0627683640711488, 0.239508104110958, 0.0255622715011347, 0.150905638607928, -0.0970095757563665, -0.0109916789233747, -0.0197843414303476, -0.302290885970787, 0.846395762124882, 0.104936341664825}, + {0.064119676415975, 0.0487956775975466, 0.0640171956914923, 0.529434975607773, -0.26205309289338, -0.0545304359767137, -0.0534436711248165, -0.260579700000555, 0.515966174346368, 0.40827320033631}, + {0.0619241738506681, -0.0624669400507792, -0.00182545940770511, 0.544580480381976, 0.00914778960164649, -0.112928533782117, 0.00186561987722211, -0.18454889805122, 0.181500084071326, 0.562751683508982}, + {0.0514890982575726, -0.0164528736892739, -0.0611798040376018, 0.0918877602754599, 0.622990507121273, -0.145793810693828, 0.127054023323504, -0.0956618757635126, 0.0122960172501373, 0.413370957956269}, + {0.0324831299939719, 0.0580370533440933, 0.154762873078755, -0.28196773278322, 0.867652896045716, -0.119445891298145, 0.176950996894467, -0.0297631768059829, -0.0143289535245539, 0.1556188050549}, + {0.0116944490193935, 0.0451157746630249, 0.644479118812606, -0.207033374665612, 0.450745399833616, -0.0497031543433881, 0.091925985851779, -0.00325364379944393, -0.0027639705315908, 0.0187934151596153}, + {0.02809979214053, 0.692116405326339, 0.0255622715011347, 0.224416734425978, -0.112850342203846, -0.00389870712577277, -0.00394357498286788, -0.124729708262302, 0.250894855131634, 0.0243322740491735}, + {0.0251489409971643, 0.283934759651153, 0.0640171956914923, 0.806022543976084, -0.304843939147455, -0.0175137741663261, -0.0106528248707413, -0.0973575486190503, 0.156575676330067, 0.0946689701576112}, + {0.0201820871510282, -0.0230667189458806, -0.0018254594077051, 0.89558289813655, 0.0106415390326748, -0.0316681717528918, 0.000371870446193856, -0.0602031247994334, 0.0594961764142812, 0.130488903725183}, + {0.0139171991648146, -0.042916247694867, -0.0611798040376018, 0.299401977386428, 0.724719094689675, -0.0357880903185195, 0.0253254357551024, -0.027316597567462, 0.00798601215243784, 0.0958510204699924}, + {0.00752079361748067, 0.0491311892659461, 0.154762873078755, -0.255537670979266, 1.00933258876242, -0.026341495488006, 0.0352713041777647, -0.00763548751524335, -0.00258844236065517, 0.0360843474408064}, + {0.00243938401571438, 0.0497485688239402, 0.644479118812606, -0.232087782696186, 0.524347954533703, -0.0102130829170658, 0.0183234311516924, -0.000777734182289533, -0.00061760930598137, 0.00435775176386732}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 100; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 11844 + for (unsigned int ip = 0; ip < 36; 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 = 24 + for (unsigned int r = 0; r < 3; r++) + { + F0 += FE0[ip][r]*w[3][r]; + F1 += FE0[ip][r]*w[2][r]; + F2 += FE0[ip][r]*w[0][r]; + F3 += FE0[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 5 + double I[1]; + // Number of operations: 5 + I[0] = F0*F1*F2*F3*W36[ip]*det; + + + // Number of operations for primary indices: 300 + for (unsigned int j = 0; j < 10; j++) + { + for (unsigned int k = 0; k < 10; k++) + { + // Number of operations to compute entry: 3 + A[j*10 + k] += FE1[ip][j]*FE1[ip][k]*I[0]; + }// 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 mass_matrix_f4_p1_q3_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f4_p1_q3_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_p1_q3_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 3), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1))))), 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 4; + } + + /// 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 mass_matrix_f4_p1_q3_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f4_p1_q3_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f4_p1_q3_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f4_p1_q3_quadrature_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f4_p1_q3_quadrature_finite_element_0(); + break; + } + case 5: + { + return new mass_matrix_f4_p1_q3_quadrature_finite_element_0(); + 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 mass_matrix_f4_p1_q3_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f4_p1_q3_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f4_p1_q3_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f4_p1_q3_quadrature_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f4_p1_q3_quadrature_dofmap_0(); + break; + } + case 5: + { + return new mass_matrix_f4_p1_q3_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f4_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/mass_matrix_2d/mass_matrix_f4_p1_q3_tensor.h b/mass_matrix_2d/mass_matrix_f4_p1_q3_tensor.h new file mode 100644 index 0000000..fdc0f24 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f4_p1_q3_tensor.h @@ -0,0 +1,4709 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F4_P1_Q3_TENSOR_H +#define __MASS_MATRIX_F4_P1_Q3_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f4_p1_q3_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f4_p1_q3_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_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 mass_matrix_f4_p1_q3_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f4_p1_q3_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f4_p1_q3_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_p1_q3_tensor_finite_element_1() + { + // 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -0.0227284322524247}; + + // 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.0227284322524247}; + + // 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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; + } + 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.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 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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; + } + } + + } + + /// 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.0471404520791032, -0.0288675134594813, -0.0166666666666667, 0.0782460796435952, 0.0606091526731326, 0.0349927106111882, -0.0601337794302955, -0.0508223195384204, -0.0393667994375868, -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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0333333333333333, 0.0, 0.0, 0.104978131833565, 0.0, 0.0, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.234738238930786, 0.0, -0.262445329583912, 0.0, -0.203289278153682, 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, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941915, 13.6626010212795, 0.0, 0.611010092660779, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513775, 0.0, 7.83836717690617, 0.0, 0.0, 8.4, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[10][10] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.0, 6.12372435695795, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.30550504633039, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699941, -1.80739222823013, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845308, 0.0, 9.69948452238571, 4.2, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[10][10] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 10; t++) + { + for (unsigned int u = 0; u < 10; u++) + { + for (unsigned int tu = 0; tu < 10; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 10; s++) + { + for (unsigned int t = 0; t < 10; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f4_p1_q3_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f4_p1_q3_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f4_p1_q3_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f4_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 mass_matrix_f4_p1_q3_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f4_p1_q3_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f4_p1_q3_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f4_p1_q3_tensor_dofmap_1() + { + // 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.0*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 mass_matrix_f4_p1_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 mass_matrix_f4_p1_q3_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f4_p1_q3_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 202 + // Number of operations (multiply-add pairs) for tensor contraction: 2985 + // Total number of operations (multiply-add pairs): 3196 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0_0 = det*w[3][0]*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_0_0_0_1 = det*w[3][0]*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_0_0_0_2 = det*w[3][0]*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_0_0_1_0 = det*w[3][0]*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_0_0_1_1 = det*w[3][0]*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_0_0_1_2 = det*w[3][0]*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_0_0_2_0 = det*w[3][0]*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_0_0_2_1 = det*w[3][0]*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_0_0_2_2 = det*w[3][0]*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_0_1_0_0 = det*w[3][0]*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_0_1_0_1 = det*w[3][0]*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_0_1_0_2 = det*w[3][0]*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_0_1_1_0 = det*w[3][0]*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_0_1_1_1 = det*w[3][0]*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_0_1_1_2 = det*w[3][0]*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_0_1_2_0 = det*w[3][0]*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_0_1_2_1 = det*w[3][0]*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_0_1_2_2 = det*w[3][0]*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_0_2_0_0 = det*w[3][0]*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_0_2_0_1 = det*w[3][0]*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_0_2_0_2 = det*w[3][0]*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_0_2_1_0 = det*w[3][0]*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_0_2_1_1 = det*w[3][0]*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_0_2_1_2 = det*w[3][0]*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_0_2_2_0 = det*w[3][0]*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_0_2_2_1 = det*w[3][0]*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_0_2_2_2 = det*w[3][0]*w[2][2]*w[0][2]*w[1][2]*(1.0); + const double G0_1_0_0_0 = det*w[3][1]*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_1_0_0_1 = det*w[3][1]*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_1_0_0_2 = det*w[3][1]*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_1_0_1_0 = det*w[3][1]*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_1_0_1_1 = det*w[3][1]*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_1_0_1_2 = det*w[3][1]*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_1_0_2_0 = det*w[3][1]*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_1_0_2_1 = det*w[3][1]*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_1_0_2_2 = det*w[3][1]*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_1_1_0_0 = det*w[3][1]*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_1_1_0_1 = det*w[3][1]*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_1_1_0_2 = det*w[3][1]*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_1_1_1_0 = det*w[3][1]*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_1_1_1_1 = det*w[3][1]*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_1_1_1_2 = det*w[3][1]*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_1_1_2_0 = det*w[3][1]*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_1_1_2_1 = det*w[3][1]*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_1_1_2_2 = det*w[3][1]*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_1_2_0_0 = det*w[3][1]*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_1_2_0_1 = det*w[3][1]*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_1_2_0_2 = det*w[3][1]*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_1_2_1_0 = det*w[3][1]*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_1_2_1_1 = det*w[3][1]*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_1_2_1_2 = det*w[3][1]*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_1_2_2_0 = det*w[3][1]*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_1_2_2_1 = det*w[3][1]*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_1_2_2_2 = det*w[3][1]*w[2][2]*w[0][2]*w[1][2]*(1.0); + const double G0_2_0_0_0 = det*w[3][2]*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_2_0_0_1 = det*w[3][2]*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_2_0_0_2 = det*w[3][2]*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_2_0_1_0 = det*w[3][2]*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_2_0_1_1 = det*w[3][2]*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_2_0_1_2 = det*w[3][2]*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_2_0_2_0 = det*w[3][2]*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_2_0_2_1 = det*w[3][2]*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_2_0_2_2 = det*w[3][2]*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_2_1_0_0 = det*w[3][2]*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_2_1_0_1 = det*w[3][2]*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_2_1_0_2 = det*w[3][2]*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_2_1_1_0 = det*w[3][2]*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_2_1_1_1 = det*w[3][2]*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_2_1_1_2 = det*w[3][2]*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_2_1_2_0 = det*w[3][2]*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_2_1_2_1 = det*w[3][2]*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_2_1_2_2 = det*w[3][2]*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_2_2_0_0 = det*w[3][2]*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_2_2_0_1 = det*w[3][2]*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_2_2_0_2 = det*w[3][2]*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_2_2_1_0 = det*w[3][2]*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_2_2_1_1 = det*w[3][2]*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_2_2_1_2 = det*w[3][2]*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_2_2_2_0 = det*w[3][2]*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_2_2_2_1 = det*w[3][2]*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_2_2_2_2 = det*w[3][2]*w[2][2]*w[0][2]*w[1][2]*(1.0); + + // Compute element tensor + A[73] = -0.000304383116883128*G0_0_0_0_0 - 7.30519480519508e-05*G0_0_0_0_1 - 8.52272727272757e-05*G0_0_0_0_2 - 7.30519480519508e-05*G0_0_0_1_0 - 7.30519480519507e-05*G0_0_0_1_1 - 3.65259740259753e-05*G0_0_0_1_2 - 8.52272727272757e-05*G0_0_0_2_0 - 3.65259740259753e-05*G0_0_0_2_1 - 3.65259740259752e-05*G0_0_0_2_2 - 7.30519480519508e-05*G0_0_1_0_0 - 7.30519480519507e-05*G0_0_1_0_1 - 3.65259740259753e-05*G0_0_1_0_2 - 7.30519480519507e-05*G0_0_1_1_0 - 0.000304383116883128*G0_0_1_1_1 - 8.52272727272757e-05*G0_0_1_1_2 - 3.65259740259753e-05*G0_0_1_2_0 - 8.52272727272757e-05*G0_0_1_2_1 - 3.65259740259752e-05*G0_0_1_2_2 - 8.52272727272757e-05*G0_0_2_0_0 - 3.65259740259753e-05*G0_0_2_0_1 - 3.65259740259752e-05*G0_0_2_0_2 - 3.65259740259753e-05*G0_0_2_1_0 - 8.52272727272757e-05*G0_0_2_1_1 - 3.65259740259752e-05*G0_0_2_1_2 - 3.65259740259752e-05*G0_0_2_2_0 - 3.65259740259752e-05*G0_0_2_2_1 - 1.21753246753249e-05*G0_0_2_2_2 - 7.30519480519508e-05*G0_1_0_0_0 - 7.30519480519507e-05*G0_1_0_0_1 - 3.65259740259753e-05*G0_1_0_0_2 - 7.30519480519507e-05*G0_1_0_1_0 - 0.000304383116883128*G0_1_0_1_1 - 8.52272727272757e-05*G0_1_0_1_2 - 3.65259740259753e-05*G0_1_0_2_0 - 8.52272727272757e-05*G0_1_0_2_1 - 3.65259740259752e-05*G0_1_0_2_2 - 7.30519480519507e-05*G0_1_1_0_0 - 0.000304383116883128*G0_1_1_0_1 - 8.52272727272757e-05*G0_1_1_0_2 - 0.000304383116883128*G0_1_1_1_0 - 0.00200892857142865*G0_1_1_1_1 - 0.000487012987013005*G0_1_1_1_2 - 8.52272727272757e-05*G0_1_1_2_0 - 0.000487012987013005*G0_1_1_2_1 - 0.000182629870129876*G0_1_1_2_2 - 3.65259740259753e-05*G0_1_2_0_0 - 8.52272727272757e-05*G0_1_2_0_1 - 3.65259740259752e-05*G0_1_2_0_2 - 8.52272727272757e-05*G0_1_2_1_0 - 0.000487012987013005*G0_1_2_1_1 - 0.000182629870129876*G0_1_2_1_2 - 3.65259740259752e-05*G0_1_2_2_0 - 0.000182629870129876*G0_1_2_2_1 - 7.30519480519504e-05*G0_1_2_2_2 - 8.52272727272757e-05*G0_2_0_0_0 - 3.65259740259753e-05*G0_2_0_0_1 - 3.65259740259752e-05*G0_2_0_0_2 - 3.65259740259753e-05*G0_2_0_1_0 - 8.52272727272757e-05*G0_2_0_1_1 - 3.65259740259752e-05*G0_2_0_1_2 - 3.65259740259752e-05*G0_2_0_2_0 - 3.65259740259752e-05*G0_2_0_2_1 - 1.21753246753249e-05*G0_2_0_2_2 - 3.65259740259753e-05*G0_2_1_0_0 - 8.52272727272757e-05*G0_2_1_0_1 - 3.65259740259752e-05*G0_2_1_0_2 - 8.52272727272757e-05*G0_2_1_1_0 - 0.000487012987013005*G0_2_1_1_1 - 0.000182629870129876*G0_2_1_1_2 - 3.65259740259752e-05*G0_2_1_2_0 - 0.000182629870129876*G0_2_1_2_1 - 7.30519480519505e-05*G0_2_1_2_2 - 3.65259740259752e-05*G0_2_2_0_0 - 3.65259740259752e-05*G0_2_2_0_1 - 1.21753246753249e-05*G0_2_2_0_2 - 3.65259740259752e-05*G0_2_2_1_0 - 0.000182629870129876*G0_2_2_1_1 - 7.30519480519505e-05*G0_2_2_1_2 - 1.21753246753249e-05*G0_2_2_2_0 - 7.30519480519504e-05*G0_2_2_2_1 + 6.08766233766262e-05*G0_2_2_2_2; + A[69] = -0.00109577922077926*G0_0_0_0_0 - 0.000365259740259753*G0_0_0_0_1 - 0.000365259740259753*G0_0_0_1_0 - 0.000219155844155852*G0_0_0_1_1 + 0.000438311688311703*G0_0_0_2_2 - 0.000365259740259753*G0_0_1_0_0 - 0.000219155844155852*G0_0_1_0_1 - 0.000219155844155852*G0_0_1_1_0 - 0.000219155844155852*G0_0_1_1_1 + 0.000219155844155852*G0_0_1_2_2 + 0.000438311688311703*G0_0_2_0_2 + 0.000219155844155852*G0_0_2_1_2 + 0.000438311688311703*G0_0_2_2_0 + 0.000219155844155852*G0_0_2_2_1 + 0.00109577922077926*G0_0_2_2_2 - 0.000365259740259753*G0_1_0_0_0 - 0.000219155844155852*G0_1_0_0_1 - 0.000219155844155852*G0_1_0_1_0 - 0.000219155844155852*G0_1_0_1_1 + 0.000219155844155852*G0_1_0_2_2 - 0.000219155844155852*G0_1_1_0_0 - 0.000219155844155852*G0_1_1_0_1 - 0.000219155844155852*G0_1_1_1_0 - 0.000365259740259753*G0_1_1_1_1 + 0.000219155844155852*G0_1_1_2_2 + 0.000219155844155852*G0_1_2_0_2 + 0.000219155844155852*G0_1_2_1_2 + 0.000219155844155852*G0_1_2_2_0 + 0.000219155844155852*G0_1_2_2_1 + 0.000730519480519505*G0_1_2_2_2 + 0.000438311688311703*G0_2_0_0_2 + 0.000219155844155852*G0_2_0_1_2 + 0.000438311688311703*G0_2_0_2_0 + 0.000219155844155852*G0_2_0_2_1 + 0.00109577922077926*G0_2_0_2_2 + 0.000219155844155852*G0_2_1_0_2 + 0.000219155844155852*G0_2_1_1_2 + 0.000219155844155852*G0_2_1_2_0 + 0.000219155844155852*G0_2_1_2_1 + 0.000730519480519505*G0_2_1_2_2 + 0.000438311688311703*G0_2_2_0_0 + 0.000219155844155852*G0_2_2_0_1 + 0.00109577922077926*G0_2_2_0_2 + 0.000219155844155852*G0_2_2_1_0 + 0.000219155844155852*G0_2_2_1_1 + 0.000730519480519505*G0_2_2_1_2 + 0.00109577922077926*G0_2_2_2_0 + 0.000730519480519505*G0_2_2_2_1 + 0.00328733766233778*G0_2_2_2_2; + A[7] = 0.0021509740259741*G0_0_0_0_0 + 0.000189393939393946*G0_0_0_0_1 + 9.46969696969728e-05*G0_0_0_0_2 + 0.000189393939393946*G0_0_0_1_0 - 2.02922077922084e-05*G0_0_0_1_1 - 6.76406926406951e-06*G0_0_0_1_2 + 9.46969696969728e-05*G0_0_0_2_0 - 6.7640692640695e-06*G0_0_0_2_1 - 6.76406926406951e-06*G0_0_0_2_2 + 0.000189393939393946*G0_0_1_0_0 - 2.02922077922084e-05*G0_0_1_0_1 - 6.7640692640695e-06*G0_0_1_0_2 - 2.02922077922085e-05*G0_0_1_1_0 - 8.1168831168834e-05*G0_0_1_1_1 - 2.02922077922085e-05*G0_0_1_1_2 - 6.76406926406951e-06*G0_0_1_2_0 - 2.02922077922085e-05*G0_0_1_2_1 - 1.3528138528139e-05*G0_0_1_2_2 + 9.46969696969728e-05*G0_0_2_0_0 - 6.7640692640695e-06*G0_0_2_0_1 - 6.76406926406951e-06*G0_0_2_0_2 - 6.7640692640695e-06*G0_0_2_1_0 - 2.02922077922085e-05*G0_0_2_1_1 - 1.3528138528139e-05*G0_0_2_1_2 - 6.7640692640695e-06*G0_0_2_2_0 - 1.3528138528139e-05*G0_0_2_2_1 - 2.02922077922085e-05*G0_0_2_2_2 + 0.000189393939393946*G0_1_0_0_0 - 2.02922077922085e-05*G0_1_0_0_1 - 6.76406926406951e-06*G0_1_0_0_2 - 2.02922077922085e-05*G0_1_0_1_0 - 8.1168831168834e-05*G0_1_0_1_1 - 2.02922077922085e-05*G0_1_0_1_2 - 6.76406926406951e-06*G0_1_0_2_0 - 2.02922077922085e-05*G0_1_0_2_1 - 1.3528138528139e-05*G0_1_0_2_2 - 2.02922077922085e-05*G0_1_1_0_0 - 8.1168831168834e-05*G0_1_1_0_1 - 2.02922077922085e-05*G0_1_1_0_2 - 8.1168831168834e-05*G0_1_1_1_0 - 0.000297619047619059*G0_1_1_1_1 - 5.95238095238117e-05*G0_1_1_1_2 - 2.02922077922085e-05*G0_1_1_2_0 - 5.95238095238117e-05*G0_1_1_2_1 - 2.97619047619058e-05*G0_1_1_2_2 - 6.76406926406951e-06*G0_1_2_0_0 - 2.02922077922085e-05*G0_1_2_0_1 - 1.3528138528139e-05*G0_1_2_0_2 - 2.02922077922085e-05*G0_1_2_1_0 - 5.95238095238117e-05*G0_1_2_1_1 - 2.97619047619058e-05*G0_1_2_1_2 - 1.3528138528139e-05*G0_1_2_2_0 - 2.97619047619058e-05*G0_1_2_2_1 - 2.97619047619058e-05*G0_1_2_2_2 + 9.46969696969728e-05*G0_2_0_0_0 - 6.76406926406951e-06*G0_2_0_0_1 - 6.76406926406951e-06*G0_2_0_0_2 - 6.7640692640695e-06*G0_2_0_1_0 - 2.02922077922085e-05*G0_2_0_1_1 - 1.3528138528139e-05*G0_2_0_1_2 - 6.76406926406951e-06*G0_2_0_2_0 - 1.3528138528139e-05*G0_2_0_2_1 - 2.02922077922085e-05*G0_2_0_2_2 - 6.76406926406951e-06*G0_2_1_0_0 - 2.02922077922085e-05*G0_2_1_0_1 - 1.3528138528139e-05*G0_2_1_0_2 - 2.02922077922085e-05*G0_2_1_1_0 - 5.95238095238117e-05*G0_2_1_1_1 - 2.97619047619058e-05*G0_2_1_1_2 - 1.3528138528139e-05*G0_2_1_2_0 - 2.97619047619058e-05*G0_2_1_2_1 - 2.97619047619058e-05*G0_2_1_2_2 - 6.7640692640695e-06*G0_2_2_0_0 - 1.3528138528139e-05*G0_2_2_0_1 - 2.02922077922085e-05*G0_2_2_0_2 - 1.3528138528139e-05*G0_2_2_1_0 - 2.97619047619058e-05*G0_2_2_1_1 - 2.97619047619058e-05*G0_2_2_1_2 - 2.02922077922085e-05*G0_2_2_2_0 - 2.97619047619058e-05*G0_2_2_2_1 - 5.95238095238117e-05*G0_2_2_2_2; + A[37] = A[73]; + A[25] = 0.000554653679653698*G0_0_0_0_0 + 7.84632034632061e-05*G0_0_0_0_1 + 8.92857142857173e-05*G0_0_0_0_2 + 7.84632034632061e-05*G0_0_0_1_0 + 2.29978354978363e-05*G0_0_0_1_1 + 1.62337662337668e-05*G0_0_0_1_2 + 8.92857142857173e-05*G0_0_0_2_0 + 1.62337662337668e-05*G0_0_0_2_1 - 8.11688311688337e-06*G0_0_0_2_2 + 7.84632034632061e-05*G0_0_1_0_0 + 2.29978354978363e-05*G0_0_1_0_1 + 1.62337662337668e-05*G0_0_1_0_2 + 2.29978354978363e-05*G0_0_1_1_0 + 6.76406926406946e-06*G0_0_1_1_1 + 6.76406926406949e-06*G0_0_1_1_2 + 1.62337662337668e-05*G0_0_1_2_0 + 6.76406926406948e-06*G0_0_1_2_1 + 1.35281385281388e-06*G0_0_1_2_2 + 8.92857142857173e-05*G0_0_2_0_0 + 1.62337662337668e-05*G0_0_2_0_1 - 8.11688311688337e-06*G0_0_2_0_2 + 1.62337662337668e-05*G0_0_2_1_0 + 6.76406926406948e-06*G0_0_2_1_1 + 1.35281385281388e-06*G0_0_2_1_2 - 8.11688311688336e-06*G0_0_2_2_0 + 1.35281385281388e-06*G0_0_2_2_1 - 0.000114989177489181*G0_0_2_2_2 + 7.84632034632061e-05*G0_1_0_0_0 + 2.29978354978363e-05*G0_1_0_0_1 + 1.62337662337668e-05*G0_1_0_0_2 + 2.29978354978363e-05*G0_1_0_1_0 + 6.76406926406947e-06*G0_1_0_1_1 + 6.76406926406948e-06*G0_1_0_1_2 + 1.62337662337668e-05*G0_1_0_2_0 + 6.76406926406949e-06*G0_1_0_2_1 + 1.35281385281388e-06*G0_1_0_2_2 + 2.29978354978363e-05*G0_1_1_0_0 + 6.76406926406947e-06*G0_1_1_0_1 + 6.76406926406949e-06*G0_1_1_0_2 + 6.76406926406947e-06*G0_1_1_1_0 - 1.89393939393947e-05*G0_1_1_1_1 + 4.05844155844168e-06*G0_1_1_1_2 + 6.76406926406949e-06*G0_1_1_2_0 + 4.05844155844168e-06*G0_1_1_2_1 + 5.41125541125558e-06*G0_1_1_2_2 + 1.62337662337668e-05*G0_1_2_0_0 + 6.76406926406948e-06*G0_1_2_0_1 + 1.35281385281388e-06*G0_1_2_0_2 + 6.76406926406948e-06*G0_1_2_1_0 + 4.05844155844168e-06*G0_1_2_1_1 + 5.41125541125557e-06*G0_1_2_1_2 + 1.35281385281388e-06*G0_1_2_2_0 + 5.41125541125557e-06*G0_1_2_2_1 - 4.73484848484866e-05*G0_1_2_2_2 + 8.92857142857173e-05*G0_2_0_0_0 + 1.62337662337668e-05*G0_2_0_0_1 - 8.11688311688337e-06*G0_2_0_0_2 + 1.62337662337668e-05*G0_2_0_1_0 + 6.76406926406948e-06*G0_2_0_1_1 + 1.35281385281388e-06*G0_2_0_1_2 - 8.11688311688337e-06*G0_2_0_2_0 + 1.35281385281388e-06*G0_2_0_2_1 - 0.000114989177489181*G0_2_0_2_2 + 1.62337662337668e-05*G0_2_1_0_0 + 6.76406926406948e-06*G0_2_1_0_1 + 1.35281385281388e-06*G0_2_1_0_2 + 6.76406926406949e-06*G0_2_1_1_0 + 4.05844155844168e-06*G0_2_1_1_1 + 5.41125541125557e-06*G0_2_1_1_2 + 1.35281385281388e-06*G0_2_1_2_0 + 5.41125541125557e-06*G0_2_1_2_1 - 4.73484848484866e-05*G0_2_1_2_2 - 8.11688311688337e-06*G0_2_2_0_0 + 1.35281385281388e-06*G0_2_2_0_1 - 0.000114989177489181*G0_2_2_0_2 + 1.35281385281388e-06*G0_2_2_1_0 + 5.41125541125557e-06*G0_2_2_1_1 - 4.73484848484866e-05*G0_2_2_1_2 - 0.000114989177489181*G0_2_2_2_0 - 4.73484848484866e-05*G0_2_2_2_1 - 0.00101461038961043*G0_2_2_2_2; + A[85] = A[73] - 0.00170454545454551*G0_0_0_0_0 - 0.000231331168831176*G0_0_0_0_1 - 0.000401785714285727*G0_0_0_0_2 - 0.000231331168831176*G0_0_0_1_0 - 4.87012987013003e-05*G0_0_0_1_2 - 0.000401785714285727*G0_0_0_2_0 - 4.87012987013003e-05*G0_0_0_2_1 - 0.000146103896103901*G0_0_0_2_2 - 0.000231331168831176*G0_0_1_0_0 - 4.87012987013003e-05*G0_0_1_0_2 + 0.000231331168831177*G0_0_1_1_1 + 4.87012987013004e-05*G0_0_1_1_2 - 4.87012987013003e-05*G0_0_1_2_0 + 4.87012987013004e-05*G0_0_1_2_1 - 0.000401785714285727*G0_0_2_0_0 - 4.87012987013003e-05*G0_0_2_0_1 - 0.000146103896103901*G0_0_2_0_2 - 4.87012987013003e-05*G0_0_2_1_0 + 4.87012987013004e-05*G0_0_2_1_1 - 0.000146103896103901*G0_0_2_2_0 - 6.08766233766254e-05*G0_0_2_2_2 - 0.000231331168831176*G0_1_0_0_0 - 4.87012987013003e-05*G0_1_0_0_2 + 0.000231331168831177*G0_1_0_1_1 + 4.87012987013004e-05*G0_1_0_1_2 - 4.87012987013003e-05*G0_1_0_2_0 + 4.87012987013004e-05*G0_1_0_2_1 + 0.000231331168831177*G0_1_1_0_1 + 4.87012987013004e-05*G0_1_1_0_2 + 0.000231331168831177*G0_1_1_1_0 + 0.00170454545454552*G0_1_1_1_1 + 0.000401785714285729*G0_1_1_1_2 + 4.87012987013004e-05*G0_1_1_2_0 + 0.000401785714285729*G0_1_1_2_1 + 0.000146103896103901*G0_1_1_2_2 - 4.87012987013003e-05*G0_1_2_0_0 + 4.87012987013004e-05*G0_1_2_0_1 + 4.87012987013004e-05*G0_1_2_1_0 + 0.000401785714285729*G0_1_2_1_1 + 0.000146103896103901*G0_1_2_1_2 + 0.000146103896103901*G0_1_2_2_1 + 6.08766233766253e-05*G0_1_2_2_2 - 0.000401785714285727*G0_2_0_0_0 - 4.87012987013003e-05*G0_2_0_0_1 - 0.000146103896103901*G0_2_0_0_2 - 4.87012987013003e-05*G0_2_0_1_0 + 4.87012987013004e-05*G0_2_0_1_1 - 0.000146103896103901*G0_2_0_2_0 - 6.08766233766254e-05*G0_2_0_2_2 - 4.87012987013003e-05*G0_2_1_0_0 + 4.87012987013004e-05*G0_2_1_0_1 + 4.87012987013004e-05*G0_2_1_1_0 + 0.000401785714285729*G0_2_1_1_1 + 0.000146103896103901*G0_2_1_1_2 + 0.000146103896103901*G0_2_1_2_1 + 6.08766233766253e-05*G0_2_1_2_2 - 0.000146103896103901*G0_2_2_0_0 - 6.08766233766254e-05*G0_2_2_0_2 + 0.000146103896103901*G0_2_2_1_1 + 6.08766233766253e-05*G0_2_2_1_2 - 6.08766233766254e-05*G0_2_2_2_0 + 6.08766233766253e-05*G0_2_2_2_1; + A[58] = A[85]; + A[67] = A[85] - 0.000182629870129877*G0_0_0_0_1 + 0.000182629870129875*G0_0_0_0_2 - 0.000182629870129877*G0_0_0_1_0 - 0.000109577922077926*G0_0_0_1_1 + 0.000182629870129875*G0_0_0_2_0 + 0.000109577922077925*G0_0_0_2_2 - 0.000182629870129877*G0_0_1_0_0 - 0.000109577922077926*G0_0_1_0_1 - 0.000109577922077926*G0_0_1_1_0 + 0.000182629870129875*G0_0_2_0_0 + 0.000109577922077925*G0_0_2_0_2 + 0.000109577922077925*G0_0_2_2_0 - 0.000182629870129877*G0_1_0_0_0 - 0.000109577922077926*G0_1_0_0_1 - 0.000109577922077926*G0_1_0_1_0 - 0.000109577922077926*G0_1_1_0_0 + 0.000365259740259755*G0_1_1_1_1 + 7.30519480519508e-05*G0_1_1_1_2 + 7.30519480519508e-05*G0_1_1_2_1 + 7.30519480519508e-05*G0_1_2_1_1 - 7.30519480519508e-05*G0_1_2_2_2 + 0.000182629870129875*G0_2_0_0_0 + 0.000109577922077925*G0_2_0_0_2 + 0.000109577922077925*G0_2_0_2_0 + 7.30519480519508e-05*G0_2_1_1_1 - 7.30519480519508e-05*G0_2_1_2_2 + 0.000109577922077925*G0_2_2_0_0 - 7.30519480519508e-05*G0_2_2_1_2 - 7.30519480519508e-05*G0_2_2_2_1 - 0.000365259740259755*G0_2_2_2_2; + A[76] = A[67]; + A[11] = -A[7] + 0.00222132034632042*G0_0_0_0_0 + 0.000209686147186155*G0_0_0_0_1 + 0.000112283549783553*G0_0_0_0_2 + 0.000209686147186155*G0_0_0_1_0 + 6.7640692640696e-06*G0_0_0_1_1 + 0.000112283549783553*G0_0_0_2_0 + 4.96031746031761e-06*G0_0_0_2_2 + 0.000209686147186155*G0_0_1_0_0 + 6.7640692640696e-06*G0_0_1_0_1 + 6.7640692640696e-06*G0_0_1_1_0 + 9.46969696969735e-05*G0_0_1_1_1 - 6.76406926406948e-06*G0_0_1_1_2 - 6.76406926406948e-06*G0_0_1_2_1 - 6.7640692640695e-06*G0_0_1_2_2 + 0.000112283549783553*G0_0_2_0_0 + 4.96031746031761e-06*G0_0_2_0_2 - 6.76406926406948e-06*G0_0_2_1_1 - 6.7640692640695e-06*G0_0_2_1_2 + 4.96031746031761e-06*G0_0_2_2_0 - 6.7640692640695e-06*G0_0_2_2_1 - 2.70562770562781e-06*G0_0_2_2_2 + 0.000209686147186155*G0_1_0_0_0 + 6.76406926406958e-06*G0_1_0_0_1 + 6.76406926406958e-06*G0_1_0_1_0 + 9.46969696969735e-05*G0_1_0_1_1 - 6.76406926406948e-06*G0_1_0_1_2 - 6.76406926406948e-06*G0_1_0_2_1 - 6.7640692640695e-06*G0_1_0_2_2 + 6.76406926406958e-06*G0_1_1_0_0 + 9.46969696969735e-05*G0_1_1_0_1 - 6.76406926406948e-06*G0_1_1_0_2 + 9.46969696969735e-05*G0_1_1_1_0 + 0.00278679653679663*G0_1_1_1_1 + 0.000116341991341995*G0_1_1_1_2 - 6.76406926406948e-06*G0_1_1_2_0 + 0.000116341991341995*G0_1_1_2_1 - 2.70562770562784e-06*G0_1_1_2_2 - 6.76406926406949e-06*G0_1_2_0_1 - 6.7640692640695e-06*G0_1_2_0_2 - 6.76406926406949e-06*G0_1_2_1_0 + 0.000116341991341995*G0_1_2_1_1 - 2.70562770562784e-06*G0_1_2_1_2 - 6.7640692640695e-06*G0_1_2_2_0 - 2.70562770562784e-06*G0_1_2_2_1 - 9.46969696969731e-06*G0_1_2_2_2 + 0.000112283549783553*G0_2_0_0_0 + 4.96031746031761e-06*G0_2_0_0_2 - 6.76406926406948e-06*G0_2_0_1_1 - 6.7640692640695e-06*G0_2_0_1_2 + 4.96031746031761e-06*G0_2_0_2_0 - 6.7640692640695e-06*G0_2_0_2_1 - 2.70562770562781e-06*G0_2_0_2_2 - 6.76406926406949e-06*G0_2_1_0_1 - 6.7640692640695e-06*G0_2_1_0_2 - 6.76406926406949e-06*G0_2_1_1_0 + 0.000116341991341995*G0_2_1_1_1 - 2.70562770562783e-06*G0_2_1_1_2 - 6.76406926406949e-06*G0_2_1_2_0 - 2.70562770562784e-06*G0_2_1_2_1 - 9.46969696969731e-06*G0_2_1_2_2 + 4.96031746031761e-06*G0_2_2_0_0 - 6.7640692640695e-06*G0_2_2_0_1 - 2.70562770562781e-06*G0_2_2_0_2 - 6.7640692640695e-06*G0_2_2_1_0 - 2.70562770562784e-06*G0_2_2_1_1 - 9.46969696969731e-06*G0_2_2_1_2 - 2.70562770562781e-06*G0_2_2_2_0 - 9.46969696969731e-06*G0_2_2_2_1 + 1.08225108225111e-05*G0_2_2_2_2; + A[32] = -1.89393939393947e-05*G0_0_0_0_0 + 6.76406926406946e-06*G0_0_0_0_1 + 4.05844155844167e-06*G0_0_0_0_2 + 6.76406926406946e-06*G0_0_0_1_0 + 2.29978354978363e-05*G0_0_0_1_1 + 6.76406926406948e-06*G0_0_0_1_2 + 4.05844155844167e-06*G0_0_0_2_0 + 6.76406926406948e-06*G0_0_0_2_1 + 5.41125541125557e-06*G0_0_0_2_2 + 6.76406926406946e-06*G0_0_1_0_0 + 2.29978354978363e-05*G0_0_1_0_1 + 6.76406926406948e-06*G0_0_1_0_2 + 2.29978354978363e-05*G0_0_1_1_0 + 7.84632034632062e-05*G0_0_1_1_1 + 1.62337662337668e-05*G0_0_1_1_2 + 6.76406926406948e-06*G0_0_1_2_0 + 1.62337662337668e-05*G0_0_1_2_1 + 1.35281385281388e-06*G0_0_1_2_2 + 4.05844155844167e-06*G0_0_2_0_0 + 6.76406926406948e-06*G0_0_2_0_1 + 5.41125541125557e-06*G0_0_2_0_2 + 6.76406926406948e-06*G0_0_2_1_0 + 1.62337662337668e-05*G0_0_2_1_1 + 1.35281385281388e-06*G0_0_2_1_2 + 5.41125541125557e-06*G0_0_2_2_0 + 1.35281385281388e-06*G0_0_2_2_1 - 4.73484848484865e-05*G0_0_2_2_2 + 6.76406926406946e-06*G0_1_0_0_0 + 2.29978354978363e-05*G0_1_0_0_1 + 6.76406926406948e-06*G0_1_0_0_2 + 2.29978354978363e-05*G0_1_0_1_0 + 7.84632034632062e-05*G0_1_0_1_1 + 1.62337662337668e-05*G0_1_0_1_2 + 6.76406926406948e-06*G0_1_0_2_0 + 1.62337662337668e-05*G0_1_0_2_1 + 1.35281385281388e-06*G0_1_0_2_2 + 2.29978354978363e-05*G0_1_1_0_0 + 7.84632034632062e-05*G0_1_1_0_1 + 1.62337662337668e-05*G0_1_1_0_2 + 7.84632034632062e-05*G0_1_1_1_0 + 0.0005546536796537*G0_1_1_1_1 + 8.92857142857174e-05*G0_1_1_1_2 + 1.62337662337668e-05*G0_1_1_2_0 + 8.92857142857174e-05*G0_1_1_2_1 - 8.11688311688343e-06*G0_1_1_2_2 + 6.76406926406948e-06*G0_1_2_0_0 + 1.62337662337668e-05*G0_1_2_0_1 + 1.35281385281388e-06*G0_1_2_0_2 + 1.62337662337668e-05*G0_1_2_1_0 + 8.92857142857174e-05*G0_1_2_1_1 - 8.11688311688342e-06*G0_1_2_1_2 + 1.35281385281388e-06*G0_1_2_2_0 - 8.11688311688342e-06*G0_1_2_2_1 - 0.000114989177489182*G0_1_2_2_2 + 4.05844155844167e-06*G0_2_0_0_0 + 6.76406926406948e-06*G0_2_0_0_1 + 5.41125541125557e-06*G0_2_0_0_2 + 6.76406926406948e-06*G0_2_0_1_0 + 1.62337662337668e-05*G0_2_0_1_1 + 1.35281385281388e-06*G0_2_0_1_2 + 5.41125541125557e-06*G0_2_0_2_0 + 1.35281385281388e-06*G0_2_0_2_1 - 4.73484848484865e-05*G0_2_0_2_2 + 6.76406926406948e-06*G0_2_1_0_0 + 1.62337662337668e-05*G0_2_1_0_1 + 1.35281385281388e-06*G0_2_1_0_2 + 1.62337662337668e-05*G0_2_1_1_0 + 8.92857142857174e-05*G0_2_1_1_1 - 8.11688311688343e-06*G0_2_1_1_2 + 1.35281385281388e-06*G0_2_1_2_0 - 8.11688311688343e-06*G0_2_1_2_1 - 0.000114989177489182*G0_2_1_2_2 + 5.41125541125557e-06*G0_2_2_0_0 + 1.35281385281388e-06*G0_2_2_0_1 - 4.73484848484865e-05*G0_2_2_0_2 + 1.35281385281388e-06*G0_2_2_1_0 - 8.11688311688342e-06*G0_2_2_1_1 - 0.000114989177489182*G0_2_2_1_2 - 4.73484848484865e-05*G0_2_2_2_0 - 0.000114989177489182*G0_2_2_2_1 - 0.00101461038961042*G0_2_2_2_2; + A[45] = A[73] - 1.21753246753248e-05*G0_0_0_0_1 + 1.21753246753251e-05*G0_0_0_0_2 - 1.21753246753248e-05*G0_0_0_1_0 + 3.65259740259755e-05*G0_0_0_1_1 + 1.21753246753251e-05*G0_0_0_2_0 - 3.65259740259754e-05*G0_0_0_2_2 - 1.21753246753248e-05*G0_0_1_0_0 + 3.65259740259755e-05*G0_0_1_0_1 + 3.65259740259755e-05*G0_0_1_1_0 + 0.000292207792207803*G0_0_1_1_1 + 4.87012987013004e-05*G0_0_1_1_2 + 4.87012987013004e-05*G0_0_1_2_1 - 4.87012987013004e-05*G0_0_1_2_2 + 1.21753246753251e-05*G0_0_2_0_0 - 3.65259740259754e-05*G0_0_2_0_2 + 4.87012987013004e-05*G0_0_2_1_1 - 4.87012987013004e-05*G0_0_2_1_2 - 3.65259740259754e-05*G0_0_2_2_0 - 4.87012987013004e-05*G0_0_2_2_1 - 0.000292207792207803*G0_0_2_2_2 - 1.21753246753248e-05*G0_1_0_0_0 + 3.65259740259755e-05*G0_1_0_0_1 + 3.65259740259755e-05*G0_1_0_1_0 + 0.000292207792207803*G0_1_0_1_1 + 4.87012987013004e-05*G0_1_0_1_2 + 4.87012987013004e-05*G0_1_0_2_1 - 4.87012987013004e-05*G0_1_0_2_2 + 3.65259740259755e-05*G0_1_1_0_0 + 0.000292207792207803*G0_1_1_0_1 + 4.87012987013004e-05*G0_1_1_0_2 + 0.000292207792207803*G0_1_1_1_0 + 0.00206980519480527*G0_1_1_1_1 + 0.000413961038961054*G0_1_1_1_2 + 4.87012987013004e-05*G0_1_1_2_0 + 0.000413961038961054*G0_1_1_2_1 + 4.87012987013004e-05*G0_1_2_0_1 - 4.87012987013004e-05*G0_1_2_0_2 + 4.87012987013004e-05*G0_1_2_1_0 + 0.000413961038961054*G0_1_2_1_1 - 4.87012987013004e-05*G0_1_2_2_0 - 0.000413961038961054*G0_1_2_2_2 + 1.21753246753251e-05*G0_2_0_0_0 - 3.65259740259754e-05*G0_2_0_0_2 + 4.87012987013004e-05*G0_2_0_1_1 - 4.87012987013004e-05*G0_2_0_1_2 - 3.65259740259754e-05*G0_2_0_2_0 - 4.87012987013004e-05*G0_2_0_2_1 - 0.000292207792207803*G0_2_0_2_2 + 4.87012987013004e-05*G0_2_1_0_1 - 4.87012987013004e-05*G0_2_1_0_2 + 4.87012987013004e-05*G0_2_1_1_0 + 0.000413961038961054*G0_2_1_1_1 - 4.87012987013004e-05*G0_2_1_2_0 - 0.000413961038961054*G0_2_1_2_2 - 3.65259740259754e-05*G0_2_2_0_0 - 4.87012987013004e-05*G0_2_2_0_1 - 0.000292207792207802*G0_2_2_0_2 - 4.87012987013004e-05*G0_2_2_1_0 - 0.000413961038961054*G0_2_2_1_2 - 0.000292207792207803*G0_2_2_2_0 - 0.000413961038961054*G0_2_2_2_1 - 0.00206980519480527*G0_2_2_2_2; + A[93] = -0.000365259740259753*G0_0_0_0_0 - 0.000219155844155852*G0_0_0_0_2 + 0.000219155844155851*G0_0_0_1_1 - 0.000219155844155852*G0_0_0_2_0 - 0.000219155844155852*G0_0_0_2_2 + 0.000219155844155851*G0_0_1_0_1 + 0.000219155844155851*G0_0_1_1_0 + 0.000730519480519505*G0_0_1_1_1 + 0.000219155844155851*G0_0_1_1_2 + 0.000219155844155851*G0_0_1_2_1 - 0.000219155844155852*G0_0_2_0_0 - 0.000219155844155852*G0_0_2_0_2 + 0.000219155844155851*G0_0_2_1_1 - 0.000219155844155852*G0_0_2_2_0 - 0.000365259740259753*G0_0_2_2_2 + 0.000219155844155851*G0_1_0_0_1 + 0.000219155844155851*G0_1_0_1_0 + 0.000730519480519505*G0_1_0_1_1 + 0.000219155844155851*G0_1_0_1_2 + 0.000219155844155851*G0_1_0_2_1 + 0.000219155844155851*G0_1_1_0_0 + 0.000730519480519505*G0_1_1_0_1 + 0.000219155844155851*G0_1_1_0_2 + 0.000730519480519505*G0_1_1_1_0 + 0.00328733766233778*G0_1_1_1_1 + 0.00109577922077926*G0_1_1_1_2 + 0.000219155844155851*G0_1_1_2_0 + 0.00109577922077926*G0_1_1_2_1 + 0.000438311688311703*G0_1_1_2_2 + 0.000219155844155851*G0_1_2_0_1 + 0.000219155844155851*G0_1_2_1_0 + 0.00109577922077926*G0_1_2_1_1 + 0.000438311688311703*G0_1_2_1_2 + 0.000438311688311703*G0_1_2_2_1 - 0.000219155844155852*G0_2_0_0_0 - 0.000219155844155852*G0_2_0_0_2 + 0.000219155844155851*G0_2_0_1_1 - 0.000219155844155852*G0_2_0_2_0 - 0.000365259740259753*G0_2_0_2_2 + 0.000219155844155851*G0_2_1_0_1 + 0.000219155844155851*G0_2_1_1_0 + 0.00109577922077926*G0_2_1_1_1 + 0.000438311688311703*G0_2_1_1_2 + 0.000438311688311703*G0_2_1_2_1 - 0.000219155844155852*G0_2_2_0_0 - 0.000365259740259753*G0_2_2_0_2 + 0.000438311688311703*G0_2_2_1_1 - 0.000365259740259753*G0_2_2_2_0 - 0.00109577922077926*G0_2_2_2_2; + A[60] = -0.00101461038961042*G0_0_0_0_0 - 4.73484848484865e-05*G0_0_0_0_1 - 0.000114989177489181*G0_0_0_0_2 - 4.73484848484865e-05*G0_0_0_1_0 + 5.41125541125559e-06*G0_0_0_1_1 + 1.3528138528139e-06*G0_0_0_1_2 - 0.000114989177489181*G0_0_0_2_0 + 1.35281385281391e-06*G0_0_0_2_1 - 8.1168831168833e-06*G0_0_0_2_2 - 4.73484848484865e-05*G0_0_1_0_0 + 5.41125541125559e-06*G0_0_1_0_1 + 1.3528138528139e-06*G0_0_1_0_2 + 5.41125541125559e-06*G0_0_1_1_0 + 4.05844155844169e-06*G0_0_1_1_1 + 6.76406926406949e-06*G0_0_1_1_2 + 1.3528138528139e-06*G0_0_1_2_0 + 6.76406926406949e-06*G0_0_1_2_1 + 1.62337662337668e-05*G0_0_1_2_2 - 0.000114989177489181*G0_0_2_0_0 + 1.35281385281391e-06*G0_0_2_0_1 - 8.11688311688331e-06*G0_0_2_0_2 + 1.35281385281391e-06*G0_0_2_1_0 + 6.76406926406949e-06*G0_0_2_1_1 + 1.62337662337668e-05*G0_0_2_1_2 - 8.11688311688331e-06*G0_0_2_2_0 + 1.62337662337668e-05*G0_0_2_2_1 + 8.92857142857175e-05*G0_0_2_2_2 - 4.73484848484865e-05*G0_1_0_0_0 + 5.41125541125559e-06*G0_1_0_0_1 + 1.3528138528139e-06*G0_1_0_0_2 + 5.41125541125559e-06*G0_1_0_1_0 + 4.05844155844169e-06*G0_1_0_1_1 + 6.76406926406949e-06*G0_1_0_1_2 + 1.3528138528139e-06*G0_1_0_2_0 + 6.76406926406949e-06*G0_1_0_2_1 + 1.62337662337668e-05*G0_1_0_2_2 + 5.41125541125559e-06*G0_1_1_0_0 + 4.05844155844169e-06*G0_1_1_0_1 + 6.76406926406949e-06*G0_1_1_0_2 + 4.05844155844169e-06*G0_1_1_1_0 - 1.89393939393947e-05*G0_1_1_1_1 + 6.76406926406949e-06*G0_1_1_1_2 + 6.76406926406949e-06*G0_1_1_2_0 + 6.76406926406949e-06*G0_1_1_2_1 + 2.29978354978363e-05*G0_1_1_2_2 + 1.3528138528139e-06*G0_1_2_0_0 + 6.76406926406949e-06*G0_1_2_0_1 + 1.62337662337668e-05*G0_1_2_0_2 + 6.76406926406949e-06*G0_1_2_1_0 + 6.76406926406949e-06*G0_1_2_1_1 + 2.29978354978363e-05*G0_1_2_1_2 + 1.62337662337668e-05*G0_1_2_2_0 + 2.29978354978363e-05*G0_1_2_2_1 + 7.84632034632062e-05*G0_1_2_2_2 - 0.000114989177489181*G0_2_0_0_0 + 1.35281385281391e-06*G0_2_0_0_1 - 8.11688311688331e-06*G0_2_0_0_2 + 1.35281385281391e-06*G0_2_0_1_0 + 6.76406926406949e-06*G0_2_0_1_1 + 1.62337662337668e-05*G0_2_0_1_2 - 8.11688311688331e-06*G0_2_0_2_0 + 1.62337662337668e-05*G0_2_0_2_1 + 8.92857142857175e-05*G0_2_0_2_2 + 1.3528138528139e-06*G0_2_1_0_0 + 6.76406926406949e-06*G0_2_1_0_1 + 1.62337662337668e-05*G0_2_1_0_2 + 6.76406926406949e-06*G0_2_1_1_0 + 6.76406926406949e-06*G0_2_1_1_1 + 2.29978354978363e-05*G0_2_1_1_2 + 1.62337662337668e-05*G0_2_1_2_0 + 2.29978354978363e-05*G0_2_1_2_1 + 7.84632034632062e-05*G0_2_1_2_2 - 8.11688311688332e-06*G0_2_2_0_0 + 1.62337662337668e-05*G0_2_2_0_1 + 8.92857142857175e-05*G0_2_2_0_2 + 1.62337662337668e-05*G0_2_2_1_0 + 2.29978354978363e-05*G0_2_2_1_1 + 7.84632034632062e-05*G0_2_2_1_2 + 8.92857142857175e-05*G0_2_2_2_0 + 7.84632034632063e-05*G0_2_2_2_1 + 0.000554653679653699*G0_2_2_2_2; + A[16] = A[60] + 0.000845508658008687*G0_0_0_0_0 + 2.84090909090919e-05*G0_0_0_0_1 + 0.000116341991341995*G0_0_0_0_2 + 2.84090909090919e-05*G0_0_0_1_0 + 0.000116341991341995*G0_0_0_2_0 + 6.08766233766254e-05*G0_0_0_2_2 + 2.84090909090919e-05*G0_0_1_0_0 + 6.76406926406948e-06*G0_0_1_2_2 + 0.000116341991341995*G0_0_2_0_0 + 6.08766233766254e-05*G0_0_2_0_2 + 6.76406926406948e-06*G0_0_2_1_2 + 6.08766233766254e-05*G0_0_2_2_0 + 6.76406926406948e-06*G0_0_2_2_1 + 5.00541125541141e-05*G0_0_2_2_2 + 2.8409090909092e-05*G0_1_0_0_0 + 6.76406926406948e-06*G0_1_0_2_2 - 2.84090909090923e-05*G0_1_1_1_1 - 6.76406926406951e-06*G0_1_1_2_2 + 6.76406926406948e-06*G0_1_2_0_2 - 6.76406926406951e-06*G0_1_2_1_2 + 6.76406926406949e-06*G0_1_2_2_0 - 6.76406926406951e-06*G0_1_2_2_1 + 0.000116341991341995*G0_2_0_0_0 + 6.08766233766254e-05*G0_2_0_0_2 + 6.76406926406948e-06*G0_2_0_1_2 + 6.08766233766254e-05*G0_2_0_2_0 + 6.76406926406948e-06*G0_2_0_2_1 + 5.00541125541141e-05*G0_2_0_2_2 + 6.76406926406948e-06*G0_2_1_0_2 - 6.76406926406951e-06*G0_2_1_1_2 + 6.76406926406949e-06*G0_2_1_2_0 - 6.76406926406951e-06*G0_2_1_2_1 + 6.08766233766254e-05*G0_2_2_0_0 + 6.76406926406948e-06*G0_2_2_0_1 + 5.00541125541141e-05*G0_2_2_0_2 + 6.76406926406948e-06*G0_2_2_1_0 - 6.76406926406951e-06*G0_2_2_1_1 + 5.00541125541141e-05*G0_2_2_2_0 - 3.38203463203477e-05*G0_2_2_2_2; + A[40] = A[16] + 0.000121753246753251*G0_0_0_0_0 + 2.43506493506502e-05*G0_0_0_0_1 + 2.43506493506502e-05*G0_0_0_1_0 - 3.65259740259753e-05*G0_0_0_2_2 + 2.43506493506502e-05*G0_0_1_0_0 - 2.43506493506502e-05*G0_0_1_1_1 - 3.65259740259753e-05*G0_0_2_0_2 - 3.65259740259753e-05*G0_0_2_2_0 - 6.08766233766254e-05*G0_0_2_2_2 + 2.43506493506502e-05*G0_1_0_0_0 - 2.43506493506502e-05*G0_1_0_1_1 - 2.43506493506502e-05*G0_1_1_0_1 - 2.43506493506502e-05*G0_1_1_1_0 - 0.000121753246753251*G0_1_1_1_1 + 3.65259740259753e-05*G0_1_1_2_2 + 3.65259740259753e-05*G0_1_2_1_2 + 3.65259740259753e-05*G0_1_2_2_1 + 6.08766233766255e-05*G0_1_2_2_2 - 3.65259740259753e-05*G0_2_0_0_2 - 3.65259740259753e-05*G0_2_0_2_0 - 6.08766233766254e-05*G0_2_0_2_2 + 3.65259740259753e-05*G0_2_1_1_2 + 3.65259740259753e-05*G0_2_1_2_1 + 6.08766233766255e-05*G0_2_1_2_2 - 3.65259740259753e-05*G0_2_2_0_0 - 6.08766233766254e-05*G0_2_2_0_2 + 3.65259740259753e-05*G0_2_2_1_1 + 6.08766233766254e-05*G0_2_2_1_2 - 6.08766233766254e-05*G0_2_2_2_0 + 6.08766233766255e-05*G0_2_2_2_1; + A[4] = A[40]; + A[1] = 0.000223214285714293*G0_0_0_0_0 + 2.43506493506502e-05*G0_0_0_0_1 + 9.46969696969727e-06*G0_0_0_0_2 + 2.43506493506502e-05*G0_0_0_1_0 + 8.11688311688341e-06*G0_0_0_1_1 + 9.46969696969727e-06*G0_0_0_2_0 - 1.3528138528139e-06*G0_0_0_2_2 + 2.43506493506502e-05*G0_0_1_0_0 + 8.11688311688341e-06*G0_0_1_0_1 + 8.11688311688341e-06*G0_0_1_1_0 + 2.43506493506503e-05*G0_0_1_1_1 + 9.46969696969727e-06*G0_0_2_0_0 - 1.3528138528139e-06*G0_0_2_0_2 - 1.3528138528139e-06*G0_0_2_2_0 + 4.05844155844171e-06*G0_0_2_2_2 + 2.43506493506502e-05*G0_1_0_0_0 + 8.11688311688341e-06*G0_1_0_0_1 + 8.11688311688341e-06*G0_1_0_1_0 + 2.43506493506503e-05*G0_1_0_1_1 + 8.11688311688341e-06*G0_1_1_0_0 + 2.43506493506503e-05*G0_1_1_0_1 + 2.43506493506503e-05*G0_1_1_1_0 + 0.000223214285714294*G0_1_1_1_1 + 9.46969696969734e-06*G0_1_1_1_2 + 9.46969696969734e-06*G0_1_1_2_1 - 1.35281385281389e-06*G0_1_1_2_2 + 9.46969696969734e-06*G0_1_2_1_1 - 1.35281385281389e-06*G0_1_2_1_2 - 1.35281385281389e-06*G0_1_2_2_1 + 4.05844155844171e-06*G0_1_2_2_2 + 9.46969696969727e-06*G0_2_0_0_0 - 1.3528138528139e-06*G0_2_0_0_2 - 1.3528138528139e-06*G0_2_0_2_0 + 4.05844155844171e-06*G0_2_0_2_2 + 9.46969696969734e-06*G0_2_1_1_1 - 1.35281385281389e-06*G0_2_1_1_2 - 1.35281385281389e-06*G0_2_1_2_1 + 4.05844155844171e-06*G0_2_1_2_2 - 1.3528138528139e-06*G0_2_2_0_0 + 4.05844155844171e-06*G0_2_2_0_2 - 1.35281385281389e-06*G0_2_2_1_1 + 4.05844155844171e-06*G0_2_2_1_2 + 4.05844155844171e-06*G0_2_2_2_0 + 4.05844155844171e-06*G0_2_2_2_1 + 4.19372294372309e-05*G0_2_2_2_2; + A[99] = 0.00438311688311703*G0_0_0_0_0 + 0.00219155844155852*G0_0_0_0_1 + 0.00219155844155852*G0_0_0_0_2 + 0.00219155844155852*G0_0_0_1_0 + 0.00175324675324681*G0_0_0_1_1 + 0.00131493506493511*G0_0_0_1_2 + 0.00219155844155852*G0_0_0_2_0 + 0.00131493506493511*G0_0_0_2_1 + 0.00175324675324681*G0_0_0_2_2 + 0.00219155844155852*G0_0_1_0_0 + 0.00175324675324681*G0_0_1_0_1 + 0.00131493506493511*G0_0_1_0_2 + 0.00175324675324681*G0_0_1_1_0 + 0.00219155844155852*G0_0_1_1_1 + 0.00131493506493511*G0_0_1_1_2 + 0.00131493506493511*G0_0_1_2_0 + 0.00131493506493511*G0_0_1_2_1 + 0.00131493506493511*G0_0_1_2_2 + 0.00219155844155852*G0_0_2_0_0 + 0.00131493506493511*G0_0_2_0_1 + 0.00175324675324681*G0_0_2_0_2 + 0.00131493506493511*G0_0_2_1_0 + 0.00131493506493511*G0_0_2_1_1 + 0.00131493506493511*G0_0_2_1_2 + 0.00175324675324681*G0_0_2_2_0 + 0.00131493506493511*G0_0_2_2_1 + 0.00219155844155851*G0_0_2_2_2 + 0.00219155844155852*G0_1_0_0_0 + 0.00175324675324681*G0_1_0_0_1 + 0.00131493506493511*G0_1_0_0_2 + 0.00175324675324681*G0_1_0_1_0 + 0.00219155844155852*G0_1_0_1_1 + 0.00131493506493511*G0_1_0_1_2 + 0.00131493506493511*G0_1_0_2_0 + 0.00131493506493511*G0_1_0_2_1 + 0.00131493506493511*G0_1_0_2_2 + 0.00175324675324681*G0_1_1_0_0 + 0.00219155844155852*G0_1_1_0_1 + 0.00131493506493511*G0_1_1_0_2 + 0.00219155844155852*G0_1_1_1_0 + 0.00438311688311703*G0_1_1_1_1 + 0.00219155844155852*G0_1_1_1_2 + 0.00131493506493511*G0_1_1_2_0 + 0.00219155844155852*G0_1_1_2_1 + 0.00175324675324681*G0_1_1_2_2 + 0.00131493506493511*G0_1_2_0_0 + 0.00131493506493511*G0_1_2_0_1 + 0.00131493506493511*G0_1_2_0_2 + 0.00131493506493511*G0_1_2_1_0 + 0.00219155844155852*G0_1_2_1_1 + 0.00175324675324681*G0_1_2_1_2 + 0.00131493506493511*G0_1_2_2_0 + 0.00175324675324681*G0_1_2_2_1 + 0.00219155844155851*G0_1_2_2_2 + 0.00219155844155852*G0_2_0_0_0 + 0.00131493506493511*G0_2_0_0_1 + 0.00175324675324681*G0_2_0_0_2 + 0.00131493506493511*G0_2_0_1_0 + 0.00131493506493511*G0_2_0_1_1 + 0.00131493506493511*G0_2_0_1_2 + 0.00175324675324681*G0_2_0_2_0 + 0.00131493506493511*G0_2_0_2_1 + 0.00219155844155851*G0_2_0_2_2 + 0.00131493506493511*G0_2_1_0_0 + 0.00131493506493511*G0_2_1_0_1 + 0.00131493506493511*G0_2_1_0_2 + 0.00131493506493511*G0_2_1_1_0 + 0.00219155844155852*G0_2_1_1_1 + 0.00175324675324681*G0_2_1_1_2 + 0.00131493506493511*G0_2_1_2_0 + 0.00175324675324681*G0_2_1_2_1 + 0.00219155844155851*G0_2_1_2_2 + 0.00175324675324681*G0_2_2_0_0 + 0.00131493506493511*G0_2_2_0_1 + 0.00219155844155851*G0_2_2_0_2 + 0.00131493506493511*G0_2_2_1_0 + 0.00175324675324681*G0_2_2_1_1 + 0.00219155844155851*G0_2_2_1_2 + 0.00219155844155851*G0_2_2_2_0 + 0.00219155844155851*G0_2_2_2_1 + 0.00438311688311703*G0_2_2_2_2; + A[78] = A[73] - 0.00206980519480526*G0_0_0_0_0 - 0.000292207792207802*G0_0_0_0_1 - 0.000219155844155851*G0_0_0_0_2 - 0.000292207792207802*G0_0_0_1_0 - 3.65259740259752e-05*G0_0_0_1_2 - 0.000219155844155851*G0_0_0_2_0 - 3.65259740259752e-05*G0_0_0_2_1 - 4.87012987013003e-05*G0_0_0_2_2 - 0.000292207792207802*G0_0_1_0_0 - 3.65259740259752e-05*G0_0_1_0_2 - 6.08766233766254e-05*G0_0_1_1_1 + 1.21753246753251e-05*G0_0_1_1_2 - 3.65259740259752e-05*G0_0_1_2_0 + 1.21753246753251e-05*G0_0_1_2_1 - 0.000219155844155851*G0_0_2_0_0 - 3.65259740259752e-05*G0_0_2_0_1 - 4.87012987013003e-05*G0_0_2_0_2 - 3.65259740259752e-05*G0_0_2_1_0 + 1.21753246753251e-05*G0_0_2_1_1 - 4.87012987013003e-05*G0_0_2_2_0 - 2.43506493506503e-05*G0_0_2_2_2 - 0.000292207792207802*G0_1_0_0_0 - 3.65259740259752e-05*G0_1_0_0_2 - 6.08766233766255e-05*G0_1_0_1_1 + 1.21753246753251e-05*G0_1_0_1_2 - 3.65259740259752e-05*G0_1_0_2_0 + 1.21753246753251e-05*G0_1_0_2_1 - 6.08766233766255e-05*G0_1_1_0_1 + 1.21753246753251e-05*G0_1_1_0_2 - 6.08766233766255e-05*G0_1_1_1_0 - 0.000365259740259753*G0_1_1_1_1 + 0.000182629870129877*G0_1_1_1_2 + 1.21753246753251e-05*G0_1_1_2_0 + 0.000182629870129877*G0_1_1_2_1 + 9.74025974026008e-05*G0_1_1_2_2 - 3.65259740259753e-05*G0_1_2_0_0 + 1.21753246753251e-05*G0_1_2_0_1 + 1.21753246753251e-05*G0_1_2_1_0 + 0.000182629870129877*G0_1_2_1_1 + 9.74025974026008e-05*G0_1_2_1_2 + 9.74025974026008e-05*G0_1_2_2_1 + 3.65259740259752e-05*G0_1_2_2_2 - 0.000219155844155851*G0_2_0_0_0 - 3.65259740259752e-05*G0_2_0_0_1 - 4.87012987013003e-05*G0_2_0_0_2 - 3.65259740259753e-05*G0_2_0_1_0 + 1.21753246753251e-05*G0_2_0_1_1 - 4.87012987013003e-05*G0_2_0_2_0 - 2.43506493506503e-05*G0_2_0_2_2 - 3.65259740259753e-05*G0_2_1_0_0 + 1.21753246753251e-05*G0_2_1_0_1 + 1.21753246753251e-05*G0_2_1_1_0 + 0.000182629870129877*G0_2_1_1_1 + 9.74025974026008e-05*G0_2_1_1_2 + 9.74025974026008e-05*G0_2_1_2_1 + 3.65259740259752e-05*G0_2_1_2_2 - 4.87012987013003e-05*G0_2_2_0_0 - 2.43506493506503e-05*G0_2_2_0_2 + 9.74025974026008e-05*G0_2_2_1_1 + 3.65259740259752e-05*G0_2_2_1_2 - 2.43506493506503e-05*G0_2_2_2_0 + 3.65259740259752e-05*G0_2_2_2_1 - 7.30519480519512e-05*G0_2_2_2_2; + A[21] = 4.19372294372309e-05*G0_0_0_0_0 + 4.0584415584417e-06*G0_0_0_0_1 + 4.0584415584417e-06*G0_0_0_0_2 + 4.0584415584417e-06*G0_0_0_1_0 - 1.35281385281389e-06*G0_0_0_1_1 + 4.0584415584417e-06*G0_0_0_2_0 - 1.35281385281389e-06*G0_0_0_2_2 + 4.0584415584417e-06*G0_0_1_0_0 - 1.35281385281389e-06*G0_0_1_0_1 - 1.35281385281389e-06*G0_0_1_1_0 + 9.46969696969734e-06*G0_0_1_1_1 + 4.0584415584417e-06*G0_0_2_0_0 - 1.35281385281389e-06*G0_0_2_0_2 - 1.35281385281389e-06*G0_0_2_2_0 + 9.46969696969732e-06*G0_0_2_2_2 + 4.0584415584417e-06*G0_1_0_0_0 - 1.35281385281389e-06*G0_1_0_0_1 - 1.35281385281389e-06*G0_1_0_1_0 + 9.46969696969735e-06*G0_1_0_1_1 - 1.35281385281389e-06*G0_1_1_0_0 + 9.46969696969734e-06*G0_1_1_0_1 + 9.46969696969734e-06*G0_1_1_1_0 + 0.000223214285714294*G0_1_1_1_1 + 2.43506493506502e-05*G0_1_1_1_2 + 2.43506493506502e-05*G0_1_1_2_1 + 8.11688311688341e-06*G0_1_1_2_2 + 2.43506493506502e-05*G0_1_2_1_1 + 8.11688311688341e-06*G0_1_2_1_2 + 8.11688311688341e-06*G0_1_2_2_1 + 2.43506493506502e-05*G0_1_2_2_2 + 4.0584415584417e-06*G0_2_0_0_0 - 1.35281385281389e-06*G0_2_0_0_2 - 1.35281385281389e-06*G0_2_0_2_0 + 9.46969696969732e-06*G0_2_0_2_2 + 2.43506493506502e-05*G0_2_1_1_1 + 8.11688311688341e-06*G0_2_1_1_2 + 8.11688311688341e-06*G0_2_1_2_1 + 2.43506493506502e-05*G0_2_1_2_2 - 1.35281385281389e-06*G0_2_2_0_0 + 9.46969696969732e-06*G0_2_2_0_2 + 8.11688311688341e-06*G0_2_2_1_1 + 2.43506493506502e-05*G0_2_2_1_2 + 9.46969696969731e-06*G0_2_2_2_0 + 2.43506493506502e-05*G0_2_2_2_1 + 0.000223214285714293*G0_2_2_2_2; + A[89] = A[93] - 0.000730519480519505*G0_0_0_0_0 - 0.000146103896103901*G0_0_0_0_2 + 0.000219155844155852*G0_0_0_1_1 - 0.000146103896103901*G0_0_0_2_0 + 0.000219155844155852*G0_0_1_0_1 + 0.000219155844155852*G0_0_1_1_0 + 0.000365259740259753*G0_0_1_1_1 - 0.000146103896103901*G0_0_2_0_0 + 0.000146103896103901*G0_0_2_2_2 + 0.000219155844155852*G0_1_0_0_1 + 0.000219155844155852*G0_1_0_1_0 + 0.000365259740259753*G0_1_0_1_1 + 0.000219155844155852*G0_1_1_0_0 + 0.000365259740259753*G0_1_1_0_1 + 0.000365259740259753*G0_1_1_1_0 - 0.000365259740259753*G0_1_1_1_2 - 0.000365259740259753*G0_1_1_2_1 - 0.000219155844155851*G0_1_1_2_2 - 0.000365259740259753*G0_1_2_1_1 - 0.000219155844155851*G0_1_2_1_2 - 0.000219155844155851*G0_1_2_2_1 - 0.000146103896103901*G0_2_0_0_0 + 0.000146103896103902*G0_2_0_2_2 - 0.000365259740259753*G0_2_1_1_1 - 0.000219155844155851*G0_2_1_1_2 - 0.000219155844155851*G0_2_1_2_1 + 0.000146103896103902*G0_2_2_0_2 - 0.000219155844155851*G0_2_2_1_1 + 0.000146103896103902*G0_2_2_2_0 + 0.000730519480519507*G0_2_2_2_2; + A[94] = A[69] + 0.000730519480519506*G0_0_0_0_0 + 0.000146103896103901*G0_0_0_0_1 + 0.000146103896103901*G0_0_0_1_0 - 0.000219155844155852*G0_0_0_2_2 + 0.000146103896103901*G0_0_1_0_0 - 0.000146103896103901*G0_0_1_1_1 - 0.000219155844155852*G0_0_2_0_2 - 0.000219155844155852*G0_0_2_2_0 - 0.000365259740259754*G0_0_2_2_2 + 0.000146103896103901*G0_1_0_0_0 - 0.000146103896103901*G0_1_0_1_1 - 0.000146103896103901*G0_1_1_0_1 - 0.000146103896103901*G0_1_1_1_0 - 0.000730519480519507*G0_1_1_1_1 + 0.000219155844155852*G0_1_1_2_2 + 0.000219155844155852*G0_1_2_1_2 + 0.000219155844155852*G0_1_2_2_1 + 0.000365259740259753*G0_1_2_2_2 - 0.000219155844155852*G0_2_0_0_2 - 0.000219155844155852*G0_2_0_2_0 - 0.000365259740259753*G0_2_0_2_2 + 0.000219155844155852*G0_2_1_1_2 + 0.000219155844155852*G0_2_1_2_1 + 0.000365259740259753*G0_2_1_2_2 - 0.000219155844155852*G0_2_2_0_0 - 0.000365259740259753*G0_2_2_0_2 + 0.000219155844155852*G0_2_2_1_1 + 0.000365259740259753*G0_2_2_1_2 - 0.000365259740259754*G0_2_2_2_0 + 0.000365259740259753*G0_2_2_2_1; + A[51] = A[25] - 3.38203463203475e-05*G0_0_0_0_0 + 5.00541125541141e-05*G0_0_0_0_2 - 6.76406926406947e-06*G0_0_0_1_1 + 6.76406926406947e-06*G0_0_0_1_2 + 5.00541125541141e-05*G0_0_0_2_0 + 6.76406926406948e-06*G0_0_0_2_1 + 6.08766233766253e-05*G0_0_0_2_2 - 6.76406926406947e-06*G0_0_1_0_1 + 6.76406926406947e-06*G0_0_1_0_2 - 6.76406926406947e-06*G0_0_1_1_0 + 6.76406926406947e-06*G0_0_1_2_0 + 5.00541125541141e-05*G0_0_2_0_0 + 6.76406926406948e-06*G0_0_2_0_1 + 6.08766233766253e-05*G0_0_2_0_2 + 6.76406926406947e-06*G0_0_2_1_0 + 6.08766233766253e-05*G0_0_2_2_0 + 0.000116341991341995*G0_0_2_2_2 - 6.76406926406948e-06*G0_1_0_0_1 + 6.76406926406947e-06*G0_1_0_0_2 - 6.76406926406947e-06*G0_1_0_1_0 + 6.76406926406948e-06*G0_1_0_2_0 - 6.76406926406948e-06*G0_1_1_0_0 - 2.84090909090925e-05*G0_1_1_1_1 + 6.76406926406948e-06*G0_1_2_0_0 + 2.8409090909092e-05*G0_1_2_2_2 + 5.00541125541142e-05*G0_2_0_0_0 + 6.76406926406948e-06*G0_2_0_0_1 + 6.08766233766253e-05*G0_2_0_0_2 + 6.76406926406947e-06*G0_2_0_1_0 + 6.08766233766253e-05*G0_2_0_2_0 + 0.000116341991341995*G0_2_0_2_2 + 6.76406926406948e-06*G0_2_1_0_0 + 2.8409090909092e-05*G0_2_1_2_2 + 6.08766233766253e-05*G0_2_2_0_0 + 0.000116341991341995*G0_2_2_0_2 + 2.8409090909092e-05*G0_2_2_1_2 + 0.000116341991341995*G0_2_2_2_0 + 2.8409090909092e-05*G0_2_2_2_1 + 0.000845508658008688*G0_2_2_2_2; + A[72] = A[51] + 6.08766233766255e-05*G0_0_0_0_1 - 6.08766233766253e-05*G0_0_0_0_2 + 6.08766233766255e-05*G0_0_0_1_0 + 3.65259740259753e-05*G0_0_0_1_1 - 6.08766233766253e-05*G0_0_0_2_0 - 3.65259740259752e-05*G0_0_0_2_2 + 6.08766233766255e-05*G0_0_1_0_0 + 3.65259740259753e-05*G0_0_1_0_1 + 3.65259740259753e-05*G0_0_1_1_0 - 6.08766233766254e-05*G0_0_2_0_0 - 3.65259740259752e-05*G0_0_2_0_2 - 3.65259740259752e-05*G0_0_2_2_0 + 6.08766233766255e-05*G0_1_0_0_0 + 3.65259740259753e-05*G0_1_0_0_1 + 3.65259740259753e-05*G0_1_0_1_0 + 3.65259740259753e-05*G0_1_1_0_0 - 0.000121753246753251*G0_1_1_1_1 - 2.43506493506502e-05*G0_1_1_1_2 - 2.43506493506502e-05*G0_1_1_2_1 - 2.43506493506502e-05*G0_1_2_1_1 + 2.43506493506502e-05*G0_1_2_2_2 - 6.08766233766253e-05*G0_2_0_0_0 - 3.65259740259752e-05*G0_2_0_0_2 - 3.65259740259752e-05*G0_2_0_2_0 - 2.43506493506502e-05*G0_2_1_1_1 + 2.43506493506502e-05*G0_2_1_2_2 - 3.65259740259752e-05*G0_2_2_0_0 + 2.43506493506502e-05*G0_2_2_1_2 + 2.43506493506502e-05*G0_2_2_2_1 + 0.00012175324675325*G0_2_2_2_2; + A[15] = A[51]; + A[36] = A[45] + 0.000365259740259753*G0_0_0_0_0 + 7.30519480519507e-05*G0_0_0_0_1 + 7.30519480519507e-05*G0_0_0_1_0 - 0.000109577922077926*G0_0_0_2_2 + 7.30519480519507e-05*G0_0_1_0_0 - 7.30519480519507e-05*G0_0_1_1_1 - 0.000109577922077926*G0_0_2_0_2 - 0.000109577922077926*G0_0_2_2_0 - 0.000182629870129876*G0_0_2_2_2 + 7.30519480519507e-05*G0_1_0_0_0 - 7.30519480519507e-05*G0_1_0_1_1 - 7.30519480519507e-05*G0_1_1_0_1 - 7.30519480519507e-05*G0_1_1_1_0 - 0.000365259740259754*G0_1_1_1_1 + 0.000109577922077926*G0_1_1_2_2 + 0.000109577922077926*G0_1_2_1_2 + 0.000109577922077926*G0_1_2_2_1 + 0.000182629870129877*G0_1_2_2_2 - 0.000109577922077926*G0_2_0_0_2 - 0.000109577922077926*G0_2_0_2_0 - 0.000182629870129876*G0_2_0_2_2 + 0.000109577922077926*G0_2_1_1_2 + 0.000109577922077926*G0_2_1_2_1 + 0.000182629870129877*G0_2_1_2_2 - 0.000109577922077926*G0_2_2_0_0 - 0.000182629870129876*G0_2_2_0_2 + 0.000109577922077926*G0_2_2_1_1 + 0.000182629870129877*G0_2_2_1_2 - 0.000182629870129876*G0_2_2_2_0 + 0.000182629870129877*G0_2_2_2_1; + A[86] = A[85] + 0.00273944805194814*G0_0_0_0_0 + 0.000365259740259753*G0_0_0_0_1 + 0.000547889610389628*G0_0_0_0_2 + 0.000365259740259753*G0_0_0_1_0 + 7.30519480519505e-05*G0_0_0_1_2 + 0.000547889610389628*G0_0_0_2_0 + 7.30519480519505e-05*G0_0_0_2_1 + 0.000109577922077926*G0_0_0_2_2 + 0.000365259740259753*G0_0_1_0_0 + 7.30519480519505e-05*G0_0_1_0_2 - 0.000109577922077926*G0_0_1_1_1 + 7.30519480519505e-05*G0_0_1_2_0 + 0.000547889610389628*G0_0_2_0_0 + 7.30519480519505e-05*G0_0_2_0_1 + 0.000109577922077926*G0_0_2_0_2 + 7.30519480519505e-05*G0_0_2_1_0 + 0.000109577922077926*G0_0_2_2_0 - 0.000109577922077926*G0_0_2_2_2 + 0.000365259740259753*G0_1_0_0_0 + 7.30519480519505e-05*G0_1_0_0_2 - 0.000109577922077926*G0_1_0_1_1 + 7.30519480519505e-05*G0_1_0_2_0 - 0.000109577922077926*G0_1_1_0_1 - 0.000109577922077926*G0_1_1_1_0 - 0.000182629870129876*G0_1_1_1_1 + 7.30519480519505e-05*G0_1_2_0_0 - 7.30519480519504e-05*G0_1_2_2_2 + 0.000547889610389628*G0_2_0_0_0 + 7.30519480519505e-05*G0_2_0_0_1 + 0.000109577922077926*G0_2_0_0_2 + 7.30519480519505e-05*G0_2_0_1_0 + 0.000109577922077926*G0_2_0_2_0 - 0.000109577922077926*G0_2_0_2_2 + 7.30519480519505e-05*G0_2_1_0_0 - 7.30519480519504e-05*G0_2_1_2_2 + 0.000109577922077926*G0_2_2_0_0 - 0.000109577922077926*G0_2_2_0_2 - 7.30519480519504e-05*G0_2_2_1_2 - 0.000109577922077926*G0_2_2_2_0 - 7.30519480519504e-05*G0_2_2_2_1 - 0.000547889610389628*G0_2_2_2_2; + A[41] = A[40] + 2.8409090909092e-05*G0_0_0_0_0 + 6.76406926406949e-06*G0_0_0_2_2 - 2.8409090909092e-05*G0_0_1_1_1 - 6.76406926406948e-06*G0_0_1_2_2 + 6.76406926406949e-06*G0_0_2_0_2 - 6.76406926406948e-06*G0_0_2_1_2 + 6.76406926406949e-06*G0_0_2_2_0 - 6.76406926406948e-06*G0_0_2_2_1 - 2.8409090909092e-05*G0_1_0_1_1 - 6.76406926406948e-06*G0_1_0_2_2 - 2.8409090909092e-05*G0_1_1_0_1 - 2.8409090909092e-05*G0_1_1_1_0 - 0.000845508658008687*G0_1_1_1_1 - 0.000116341991341995*G0_1_1_1_2 - 0.000116341991341995*G0_1_1_2_1 - 6.08766233766255e-05*G0_1_1_2_2 - 6.76406926406948e-06*G0_1_2_0_2 - 0.000116341991341995*G0_1_2_1_1 - 6.08766233766255e-05*G0_1_2_1_2 - 6.76406926406948e-06*G0_1_2_2_0 - 6.08766233766255e-05*G0_1_2_2_1 - 5.00541125541142e-05*G0_1_2_2_2 + 6.7640692640695e-06*G0_2_0_0_2 - 6.76406926406948e-06*G0_2_0_1_2 + 6.76406926406949e-06*G0_2_0_2_0 - 6.76406926406948e-06*G0_2_0_2_1 - 6.76406926406948e-06*G0_2_1_0_2 - 0.000116341991341995*G0_2_1_1_1 - 6.08766233766255e-05*G0_2_1_1_2 - 6.76406926406948e-06*G0_2_1_2_0 - 6.08766233766255e-05*G0_2_1_2_1 - 5.00541125541142e-05*G0_2_1_2_2 + 6.76406926406949e-06*G0_2_2_0_0 - 6.76406926406948e-06*G0_2_2_0_1 - 6.76406926406948e-06*G0_2_2_1_0 - 6.08766233766255e-05*G0_2_2_1_1 - 5.00541125541142e-05*G0_2_2_1_2 - 5.00541125541142e-05*G0_2_2_2_1 + 3.38203463203476e-05*G0_2_2_2_2; + A[97] = 0.00328733766233777*G0_0_0_0_0 + 0.00109577922077926*G0_0_0_0_1 + 0.000730519480519505*G0_0_0_0_2 + 0.00109577922077926*G0_0_0_1_0 + 0.000438311688311703*G0_0_0_1_1 + 0.000219155844155852*G0_0_0_1_2 + 0.000730519480519505*G0_0_0_2_0 + 0.000219155844155852*G0_0_0_2_1 + 0.000219155844155851*G0_0_0_2_2 + 0.00109577922077926*G0_0_1_0_0 + 0.000438311688311703*G0_0_1_0_1 + 0.000219155844155852*G0_0_1_0_2 + 0.000438311688311703*G0_0_1_1_0 + 0.000219155844155852*G0_0_1_2_0 + 0.000730519480519505*G0_0_2_0_0 + 0.000219155844155852*G0_0_2_0_1 + 0.000219155844155851*G0_0_2_0_2 + 0.000219155844155852*G0_0_2_1_0 + 0.000219155844155851*G0_0_2_2_0 + 0.00109577922077926*G0_1_0_0_0 + 0.000438311688311703*G0_1_0_0_1 + 0.000219155844155852*G0_1_0_0_2 + 0.000438311688311703*G0_1_0_1_0 + 0.000219155844155852*G0_1_0_2_0 + 0.000438311688311703*G0_1_1_0_0 - 0.00109577922077926*G0_1_1_1_1 - 0.000365259740259753*G0_1_1_1_2 - 0.000365259740259753*G0_1_1_2_1 - 0.000219155844155852*G0_1_1_2_2 + 0.000219155844155852*G0_1_2_0_0 - 0.000365259740259753*G0_1_2_1_1 - 0.000219155844155852*G0_1_2_1_2 - 0.000219155844155852*G0_1_2_2_1 - 0.000219155844155852*G0_1_2_2_2 + 0.000730519480519505*G0_2_0_0_0 + 0.000219155844155852*G0_2_0_0_1 + 0.000219155844155851*G0_2_0_0_2 + 0.000219155844155852*G0_2_0_1_0 + 0.000219155844155851*G0_2_0_2_0 + 0.000219155844155852*G0_2_1_0_0 - 0.000365259740259753*G0_2_1_1_1 - 0.000219155844155852*G0_2_1_1_2 - 0.000219155844155852*G0_2_1_2_1 - 0.000219155844155852*G0_2_1_2_2 + 0.000219155844155851*G0_2_2_0_0 - 0.000219155844155852*G0_2_2_1_1 - 0.000219155844155852*G0_2_2_1_2 - 0.000219155844155852*G0_2_2_2_1 - 0.000365259740259753*G0_2_2_2_2; + A[64] = -A[78] - 0.00213068181818189*G0_0_0_0_0 - 0.000267857142857152*G0_0_0_0_1 - 0.000158279220779226*G0_0_0_0_2 - 0.000267857142857152*G0_0_0_1_0 - 0.000158279220779226*G0_0_0_2_0 + 0.000170454545454551*G0_0_0_2_2 - 0.000267857142857152*G0_0_1_0_0 - 0.000267857142857152*G0_0_1_1_1 + 0.000133928571428576*G0_0_1_2_2 - 0.000158279220779226*G0_0_2_0_0 + 0.000170454545454551*G0_0_2_0_2 + 0.000133928571428576*G0_0_2_1_2 + 0.000170454545454551*G0_0_2_2_0 + 0.000133928571428576*G0_0_2_2_1 + 0.000754870129870156*G0_0_2_2_2 - 0.000267857142857152*G0_1_0_0_0 - 0.000267857142857153*G0_1_0_1_1 + 0.000133928571428576*G0_1_0_2_2 - 0.000267857142857153*G0_1_1_0_1 - 0.000267857142857153*G0_1_1_1_0 - 0.0021306818181819*G0_1_1_1_1 - 0.000158279220779227*G0_1_1_1_2 - 0.000158279220779227*G0_1_1_2_1 + 0.000170454545454551*G0_1_1_2_2 + 0.000133928571428576*G0_1_2_0_2 - 0.000158279220779227*G0_1_2_1_1 + 0.000170454545454551*G0_1_2_1_2 + 0.000133928571428576*G0_1_2_2_0 + 0.000170454545454551*G0_1_2_2_1 + 0.000754870129870156*G0_1_2_2_2 - 0.000158279220779226*G0_2_0_0_0 + 0.000170454545454551*G0_2_0_0_2 + 0.000133928571428576*G0_2_0_1_2 + 0.000170454545454551*G0_2_0_2_0 + 0.000133928571428576*G0_2_0_2_1 + 0.000754870129870156*G0_2_0_2_2 + 0.000133928571428576*G0_2_1_0_2 - 0.000158279220779227*G0_2_1_1_1 + 0.000170454545454551*G0_2_1_1_2 + 0.000133928571428576*G0_2_1_2_0 + 0.000170454545454551*G0_2_1_2_1 + 0.000754870129870157*G0_2_1_2_2 + 0.000170454545454551*G0_2_2_0_0 + 0.000133928571428576*G0_2_2_0_1 + 0.000754870129870156*G0_2_2_0_2 + 0.000133928571428576*G0_2_2_1_0 + 0.000170454545454551*G0_2_2_1_1 + 0.000754870129870156*G0_2_2_1_2 + 0.000754870129870156*G0_2_2_2_0 + 0.000754870129870156*G0_2_2_2_1 + 0.00400568181818196*G0_2_2_2_2; + A[75] = A[64] + 0.00377435064935077*G0_0_0_0_0 + 0.00069399350649353*G0_0_0_0_1 + 0.000645292207792229*G0_0_0_0_2 + 0.00069399350649353*G0_0_0_1_0 + 0.000182629870129876*G0_0_0_1_1 + 9.74025974026005e-05*G0_0_0_1_2 + 0.000645292207792229*G0_0_0_2_0 + 9.74025974026005e-05*G0_0_0_2_1 + 0.00069399350649353*G0_0_1_0_0 + 0.000182629870129876*G0_0_1_0_1 + 9.74025974026005e-05*G0_0_1_0_2 + 0.000182629870129876*G0_0_1_1_0 + 4.87012987013004e-05*G0_0_1_1_1 + 9.74025974026005e-05*G0_0_1_2_0 - 9.74025974026007e-05*G0_0_1_2_2 + 0.000645292207792229*G0_0_2_0_0 + 9.74025974026005e-05*G0_0_2_0_1 + 9.74025974026005e-05*G0_0_2_1_0 - 9.74025974026008e-05*G0_0_2_1_2 - 9.74025974026007e-05*G0_0_2_2_1 - 0.00064529220779223*G0_0_2_2_2 + 0.00069399350649353*G0_1_0_0_0 + 0.000182629870129876*G0_1_0_0_1 + 9.74025974026005e-05*G0_1_0_0_2 + 0.000182629870129876*G0_1_0_1_0 + 4.87012987013004e-05*G0_1_0_1_1 + 9.74025974026005e-05*G0_1_0_2_0 - 9.74025974026008e-05*G0_1_0_2_2 + 0.000182629870129876*G0_1_1_0_0 + 4.87012987013004e-05*G0_1_1_0_1 + 4.87012987013004e-05*G0_1_1_1_0 - 4.87012987013004e-05*G0_1_1_1_2 - 4.87012987013005e-05*G0_1_1_2_1 - 0.000182629870129877*G0_1_1_2_2 + 9.74025974026005e-05*G0_1_2_0_0 - 9.74025974026008e-05*G0_1_2_0_2 - 4.87012987013005e-05*G0_1_2_1_1 - 0.000182629870129877*G0_1_2_1_2 - 9.74025974026008e-05*G0_1_2_2_0 - 0.000182629870129877*G0_1_2_2_1 - 0.000693993506493531*G0_1_2_2_2 + 0.000645292207792229*G0_2_0_0_0 + 9.74025974026005e-05*G0_2_0_0_1 + 9.74025974026005e-05*G0_2_0_1_0 - 9.74025974026008e-05*G0_2_0_1_2 - 9.74025974026007e-05*G0_2_0_2_1 - 0.00064529220779223*G0_2_0_2_2 + 9.74025974026005e-05*G0_2_1_0_0 - 9.74025974026007e-05*G0_2_1_0_2 - 4.87012987013004e-05*G0_2_1_1_1 - 0.000182629870129877*G0_2_1_1_2 - 9.74025974026008e-05*G0_2_1_2_0 - 0.000182629870129877*G0_2_1_2_1 - 0.000693993506493531*G0_2_1_2_2 - 9.74025974026008e-05*G0_2_2_0_1 - 0.00064529220779223*G0_2_2_0_2 - 9.74025974026008e-05*G0_2_2_1_0 - 0.000182629870129877*G0_2_2_1_1 - 0.000693993506493531*G0_2_2_1_2 - 0.00064529220779223*G0_2_2_2_0 - 0.000693993506493531*G0_2_2_2_1 - 0.00377435064935078*G0_2_2_2_2; + A[55] = A[75] + 0.00401785714285728*G0_0_0_0_0 + 0.00158279220779226*G0_0_0_0_2 - 8.52272727272759e-05*G0_0_0_1_1 + 8.52272727272755e-05*G0_0_0_1_2 + 0.00158279220779226*G0_0_0_2_0 + 8.52272727272755e-05*G0_0_0_2_1 + 0.00076704545454548*G0_0_0_2_2 - 8.52272727272758e-05*G0_0_1_0_1 + 8.52272727272755e-05*G0_0_1_0_2 - 8.52272727272758e-05*G0_0_1_1_0 - 7.30519480519506e-05*G0_0_1_1_1 + 8.52272727272755e-05*G0_0_1_2_0 + 7.30519480519504e-05*G0_0_1_2_2 + 0.00158279220779226*G0_0_2_0_0 + 8.52272727272755e-05*G0_0_2_0_1 + 0.00076704545454548*G0_0_2_0_2 + 8.52272727272755e-05*G0_0_2_1_0 + 7.30519480519504e-05*G0_0_2_1_2 + 0.00076704545454548*G0_0_2_2_0 + 7.30519480519504e-05*G0_0_2_2_1 + 0.000584415584415604*G0_0_2_2_2 - 8.52272727272758e-05*G0_1_0_0_1 + 8.52272727272755e-05*G0_1_0_0_2 - 8.52272727272758e-05*G0_1_0_1_0 - 7.30519480519506e-05*G0_1_0_1_1 + 8.52272727272755e-05*G0_1_0_2_0 + 7.30519480519505e-05*G0_1_0_2_2 - 8.52272727272758e-05*G0_1_1_0_0 - 7.30519480519506e-05*G0_1_1_0_1 - 7.30519480519506e-05*G0_1_1_1_0 - 0.000146103896103902*G0_1_1_1_1 - 2.43506493506502e-05*G0_1_1_1_2 - 2.43506493506502e-05*G0_1_1_2_1 + 2.43506493506502e-05*G0_1_1_2_2 + 8.52272727272756e-05*G0_1_2_0_0 + 7.30519480519505e-05*G0_1_2_0_2 - 2.43506493506502e-05*G0_1_2_1_1 + 2.43506493506502e-05*G0_1_2_1_2 + 7.30519480519505e-05*G0_1_2_2_0 + 2.43506493506502e-05*G0_1_2_2_1 + 0.000146103896103901*G0_1_2_2_2 + 0.00158279220779226*G0_2_0_0_0 + 8.52272727272755e-05*G0_2_0_0_1 + 0.00076704545454548*G0_2_0_0_2 + 8.52272727272755e-05*G0_2_0_1_0 + 7.30519480519505e-05*G0_2_0_1_2 + 0.00076704545454548*G0_2_0_2_0 + 7.30519480519505e-05*G0_2_0_2_1 + 0.000584415584415604*G0_2_0_2_2 + 8.52272727272756e-05*G0_2_1_0_0 + 7.30519480519505e-05*G0_2_1_0_2 - 2.43506493506502e-05*G0_2_1_1_1 + 2.43506493506502e-05*G0_2_1_1_2 + 7.30519480519505e-05*G0_2_1_2_0 + 2.43506493506502e-05*G0_2_1_2_1 + 0.000146103896103901*G0_2_1_2_2 + 0.00076704545454548*G0_2_2_0_0 + 7.30519480519505e-05*G0_2_2_0_1 + 0.000584415584415604*G0_2_2_0_2 + 7.30519480519505e-05*G0_2_2_1_0 + 2.43506493506502e-05*G0_2_2_1_1 + 0.000146103896103901*G0_2_2_1_2 + 0.000584415584415604*G0_2_2_2_0 + 0.000146103896103901*G0_2_2_2_1 + 0.00121753246753251*G0_2_2_2_2; + A[54] = A[45]; + A[71] = A[72] + 3.38203463203475e-05*G0_0_0_0_0 - 5.00541125541143e-05*G0_0_0_0_1 - 5.00541125541143e-05*G0_0_0_1_0 - 6.08766233766255e-05*G0_0_0_1_1 - 6.76406926406949e-06*G0_0_0_1_2 - 6.7640692640695e-06*G0_0_0_2_1 + 6.76406926406947e-06*G0_0_0_2_2 - 5.00541125541143e-05*G0_0_1_0_0 - 6.08766233766255e-05*G0_0_1_0_1 - 6.76406926406949e-06*G0_0_1_0_2 - 6.08766233766255e-05*G0_0_1_1_0 - 0.000116341991341996*G0_0_1_1_1 - 6.7640692640695e-06*G0_0_1_2_0 - 6.7640692640695e-06*G0_0_2_0_1 + 6.76406926406946e-06*G0_0_2_0_2 - 6.7640692640695e-06*G0_0_2_1_0 + 6.76406926406946e-06*G0_0_2_2_0 - 5.00541125541143e-05*G0_1_0_0_0 - 6.08766233766255e-05*G0_1_0_0_1 - 6.76406926406949e-06*G0_1_0_0_2 - 6.08766233766255e-05*G0_1_0_1_0 - 0.000116341991341996*G0_1_0_1_1 - 6.7640692640695e-06*G0_1_0_2_0 - 6.08766233766255e-05*G0_1_1_0_0 - 0.000116341991341996*G0_1_1_0_1 - 0.000116341991341996*G0_1_1_1_0 - 0.000845508658008691*G0_1_1_1_1 - 2.84090909090921e-05*G0_1_1_1_2 - 2.84090909090921e-05*G0_1_1_2_1 - 6.7640692640695e-06*G0_1_2_0_0 - 2.8409090909092e-05*G0_1_2_1_1 - 6.7640692640695e-06*G0_2_0_0_1 + 6.76406926406946e-06*G0_2_0_0_2 - 6.7640692640695e-06*G0_2_0_1_0 + 6.76406926406946e-06*G0_2_0_2_0 - 6.7640692640695e-06*G0_2_1_0_0 - 2.8409090909092e-05*G0_2_1_1_1 + 6.76406926406946e-06*G0_2_2_0_0 + 2.84090909090926e-05*G0_2_2_2_2; + A[10] = A[1]; + A[35] = A[45] - 0.000182629870129876*G0_0_0_0_0 - 0.000109577922077926*G0_0_0_0_2 - 0.000109577922077926*G0_0_0_2_0 - 7.30519480519508e-05*G0_0_1_1_1 + 7.30519480519506e-05*G0_0_1_2_2 - 0.000109577922077926*G0_0_2_0_0 + 7.30519480519506e-05*G0_0_2_1_2 + 7.30519480519506e-05*G0_0_2_2_1 + 0.000365259740259753*G0_0_2_2_2 - 7.30519480519508e-05*G0_1_0_1_1 + 7.30519480519506e-05*G0_1_0_2_2 - 7.30519480519508e-05*G0_1_1_0_1 - 7.30519480519508e-05*G0_1_1_1_0 - 0.000547889610389631*G0_1_1_1_1 - 0.000109577922077926*G0_1_1_1_2 - 0.000109577922077926*G0_1_1_2_1 + 0.000109577922077926*G0_1_1_2_2 + 7.30519480519506e-05*G0_1_2_0_2 - 0.000109577922077926*G0_1_2_1_1 + 0.000109577922077926*G0_1_2_1_2 + 7.30519480519506e-05*G0_1_2_2_0 + 0.000109577922077926*G0_1_2_2_1 + 0.00054788961038963*G0_1_2_2_2 - 0.000109577922077926*G0_2_0_0_0 + 7.30519480519506e-05*G0_2_0_1_2 + 7.30519480519506e-05*G0_2_0_2_1 + 0.000365259740259753*G0_2_0_2_2 + 7.30519480519506e-05*G0_2_1_0_2 - 0.000109577922077926*G0_2_1_1_1 + 0.000109577922077926*G0_2_1_1_2 + 7.30519480519506e-05*G0_2_1_2_0 + 0.000109577922077926*G0_2_1_2_1 + 0.00054788961038963*G0_2_1_2_2 + 7.30519480519506e-05*G0_2_2_0_1 + 0.000365259740259753*G0_2_2_0_2 + 7.30519480519506e-05*G0_2_2_1_0 + 0.000109577922077926*G0_2_2_1_1 + 0.00054788961038963*G0_2_2_1_2 + 0.000365259740259753*G0_2_2_2_0 + 0.00054788961038963*G0_2_2_2_1 + 0.00273944805194815*G0_2_2_2_2; + A[27] = A[72]; + A[83] = A[64] + 4.87012987013003e-05*G0_0_0_0_1 - 4.87012987013004e-05*G0_0_0_0_2 + 4.87012987013003e-05*G0_0_0_1_0 + 0.000182629870129876*G0_0_0_1_1 - 4.87012987013004e-05*G0_0_0_2_0 - 0.000182629870129876*G0_0_0_2_2 + 4.87012987013003e-05*G0_0_1_0_0 + 0.000182629870129876*G0_0_1_0_1 + 0.000182629870129876*G0_0_1_1_0 + 0.000693993506493531*G0_0_1_1_1 + 9.74025974026007e-05*G0_0_1_1_2 + 9.74025974026007e-05*G0_0_1_2_1 - 9.74025974026007e-05*G0_0_1_2_2 - 4.87012987013004e-05*G0_0_2_0_0 - 0.000182629870129876*G0_0_2_0_2 + 9.74025974026007e-05*G0_0_2_1_1 - 9.74025974026008e-05*G0_0_2_1_2 - 0.000182629870129876*G0_0_2_2_0 - 9.74025974026007e-05*G0_0_2_2_1 - 0.00069399350649353*G0_0_2_2_2 + 4.87012987013003e-05*G0_1_0_0_0 + 0.000182629870129876*G0_1_0_0_1 + 0.000182629870129876*G0_1_0_1_0 + 0.000693993506493531*G0_1_0_1_1 + 9.74025974026007e-05*G0_1_0_1_2 + 9.74025974026007e-05*G0_1_0_2_1 - 9.74025974026008e-05*G0_1_0_2_2 + 0.000182629870129876*G0_1_1_0_0 + 0.000693993506493531*G0_1_1_0_1 + 9.74025974026007e-05*G0_1_1_0_2 + 0.000693993506493531*G0_1_1_1_0 + 0.00377435064935079*G0_1_1_1_1 + 0.000645292207792231*G0_1_1_1_2 + 9.74025974026007e-05*G0_1_1_2_0 + 0.000645292207792231*G0_1_1_2_1 + 9.74025974026007e-05*G0_1_2_0_1 - 9.74025974026008e-05*G0_1_2_0_2 + 9.74025974026007e-05*G0_1_2_1_0 + 0.000645292207792231*G0_1_2_1_1 - 9.74025974026008e-05*G0_1_2_2_0 - 0.000645292207792231*G0_1_2_2_2 - 4.87012987013004e-05*G0_2_0_0_0 - 0.000182629870129876*G0_2_0_0_2 + 9.74025974026007e-05*G0_2_0_1_1 - 9.74025974026008e-05*G0_2_0_1_2 - 0.000182629870129876*G0_2_0_2_0 - 9.74025974026007e-05*G0_2_0_2_1 - 0.00069399350649353*G0_2_0_2_2 + 9.74025974026007e-05*G0_2_1_0_1 - 9.74025974026007e-05*G0_2_1_0_2 + 9.74025974026007e-05*G0_2_1_1_0 + 0.000645292207792231*G0_2_1_1_1 - 9.74025974026008e-05*G0_2_1_2_0 - 0.000645292207792231*G0_2_1_2_2 - 0.000182629870129876*G0_2_2_0_0 - 9.74025974026008e-05*G0_2_2_0_1 - 0.00069399350649353*G0_2_2_0_2 - 9.74025974026008e-05*G0_2_2_1_0 - 0.00064529220779223*G0_2_2_1_2 - 0.00069399350649353*G0_2_2_2_0 - 0.000645292207792231*G0_2_2_2_1 - 0.00377435064935078*G0_2_2_2_2; + A[46] = A[64]; + A[61] = A[16]; + A[57] = A[75]; + A[74] = A[73] - 0.000182629870129876*G0_0_0_0_0 - 0.000109577922077926*G0_0_0_0_1 - 0.000109577922077926*G0_0_0_1_0 - 0.000109577922077926*G0_0_1_0_0 + 0.000365259740259754*G0_0_1_1_1 + 7.30519480519506e-05*G0_0_1_1_2 + 7.30519480519506e-05*G0_0_1_2_1 + 7.30519480519506e-05*G0_0_2_1_1 - 7.30519480519509e-05*G0_0_2_2_2 - 0.000109577922077925*G0_1_0_0_0 + 0.000365259740259754*G0_1_0_1_1 + 7.30519480519506e-05*G0_1_0_1_2 + 7.30519480519506e-05*G0_1_0_2_1 + 0.000365259740259754*G0_1_1_0_1 + 7.30519480519506e-05*G0_1_1_0_2 + 0.000365259740259754*G0_1_1_1_0 + 0.00273944805194815*G0_1_1_1_1 + 0.00054788961038963*G0_1_1_1_2 + 7.30519480519506e-05*G0_1_1_2_0 + 0.00054788961038963*G0_1_1_2_1 + 0.000109577922077926*G0_1_1_2_2 + 7.30519480519506e-05*G0_1_2_0_1 + 7.30519480519506e-05*G0_1_2_1_0 + 0.00054788961038963*G0_1_2_1_1 + 0.000109577922077926*G0_1_2_1_2 + 0.000109577922077926*G0_1_2_2_1 - 0.000109577922077926*G0_1_2_2_2 + 7.30519480519506e-05*G0_2_0_1_1 - 7.30519480519509e-05*G0_2_0_2_2 + 7.30519480519506e-05*G0_2_1_0_1 + 7.30519480519506e-05*G0_2_1_1_0 + 0.00054788961038963*G0_2_1_1_1 + 0.000109577922077926*G0_2_1_1_2 + 0.000109577922077926*G0_2_1_2_1 - 0.000109577922077926*G0_2_1_2_2 - 7.30519480519509e-05*G0_2_2_0_2 + 0.000109577922077926*G0_2_2_1_1 - 0.000109577922077926*G0_2_2_1_2 - 7.30519480519509e-05*G0_2_2_2_0 - 0.000109577922077926*G0_2_2_2_1 - 0.000547889610389631*G0_2_2_2_2; + A[2] = 0.000223214285714293*G0_0_0_0_0 + 9.46969696969731e-06*G0_0_0_0_1 + 2.43506493506501e-05*G0_0_0_0_2 + 9.46969696969731e-06*G0_0_0_1_0 - 1.3528138528139e-06*G0_0_0_1_1 + 2.43506493506501e-05*G0_0_0_2_0 + 8.11688311688339e-06*G0_0_0_2_2 + 9.46969696969731e-06*G0_0_1_0_0 - 1.3528138528139e-06*G0_0_1_0_1 - 1.3528138528139e-06*G0_0_1_1_0 + 4.05844155844171e-06*G0_0_1_1_1 + 2.43506493506501e-05*G0_0_2_0_0 + 8.11688311688339e-06*G0_0_2_0_2 + 8.11688311688339e-06*G0_0_2_2_0 + 2.43506493506502e-05*G0_0_2_2_2 + 9.46969696969731e-06*G0_1_0_0_0 - 1.3528138528139e-06*G0_1_0_0_1 - 1.3528138528139e-06*G0_1_0_1_0 + 4.05844155844171e-06*G0_1_0_1_1 - 1.35281385281389e-06*G0_1_1_0_0 + 4.05844155844171e-06*G0_1_1_0_1 + 4.05844155844171e-06*G0_1_1_1_0 + 4.1937229437231e-05*G0_1_1_1_1 + 4.05844155844171e-06*G0_1_1_1_2 + 4.05844155844171e-06*G0_1_1_2_1 - 1.35281385281389e-06*G0_1_1_2_2 + 4.05844155844171e-06*G0_1_2_1_1 - 1.35281385281389e-06*G0_1_2_1_2 - 1.35281385281389e-06*G0_1_2_2_1 + 9.46969696969733e-06*G0_1_2_2_2 + 2.43506493506501e-05*G0_2_0_0_0 + 8.11688311688339e-06*G0_2_0_0_2 + 8.11688311688339e-06*G0_2_0_2_0 + 2.43506493506502e-05*G0_2_0_2_2 + 4.05844155844172e-06*G0_2_1_1_1 - 1.35281385281389e-06*G0_2_1_1_2 - 1.35281385281389e-06*G0_2_1_2_1 + 9.46969696969733e-06*G0_2_1_2_2 + 8.11688311688339e-06*G0_2_2_0_0 + 2.43506493506502e-05*G0_2_2_0_2 - 1.35281385281389e-06*G0_2_2_1_1 + 9.46969696969733e-06*G0_2_2_1_2 + 2.43506493506502e-05*G0_2_2_2_0 + 9.46969696969733e-06*G0_2_2_2_1 + 0.000223214285714294*G0_2_2_2_2; + A[48] = A[73] + 0.000365259740259754*G0_0_0_0_0 + 7.30519480519506e-05*G0_0_0_0_2 - 0.000109577922077926*G0_0_0_1_1 + 7.30519480519506e-05*G0_0_0_2_0 - 0.000109577922077926*G0_0_1_0_1 - 0.000109577922077926*G0_0_1_1_0 - 0.000182629870129876*G0_0_1_1_1 + 7.30519480519506e-05*G0_0_2_0_0 - 7.30519480519506e-05*G0_0_2_2_2 - 0.000109577922077926*G0_1_0_0_1 - 0.000109577922077926*G0_1_0_1_0 - 0.000182629870129876*G0_1_0_1_1 - 0.000109577922077926*G0_1_1_0_0 - 0.000182629870129876*G0_1_1_0_1 - 0.000182629870129876*G0_1_1_1_0 + 0.000182629870129877*G0_1_1_1_2 + 0.000182629870129877*G0_1_1_2_1 + 0.000109577922077926*G0_1_1_2_2 + 0.000182629870129877*G0_1_2_1_1 + 0.000109577922077926*G0_1_2_1_2 + 0.000109577922077926*G0_1_2_2_1 + 7.30519480519506e-05*G0_2_0_0_0 - 7.30519480519506e-05*G0_2_0_2_2 + 0.000182629870129877*G0_2_1_1_1 + 0.000109577922077926*G0_2_1_1_2 + 0.000109577922077926*G0_2_1_2_1 - 7.30519480519506e-05*G0_2_2_0_2 + 0.000109577922077926*G0_2_2_1_1 - 7.30519480519505e-05*G0_2_2_2_0 - 0.000365259740259753*G0_2_2_2_2; + A[30] = A[32] - 2.84090909090923e-05*G0_0_0_0_0 - 6.76406926406945e-06*G0_0_0_1_1 - 6.76406926406945e-06*G0_0_1_0_1 - 6.76406926406945e-06*G0_0_1_1_0 + 6.76406926406951e-06*G0_0_1_1_2 + 6.7640692640695e-06*G0_0_1_2_1 + 6.76406926406951e-06*G0_0_2_1_1 + 2.84090909090919e-05*G0_0_2_2_2 - 6.76406926406945e-06*G0_1_0_0_1 - 6.76406926406945e-06*G0_1_0_1_0 + 6.76406926406951e-06*G0_1_0_1_2 + 6.7640692640695e-06*G0_1_0_2_1 - 6.76406926406945e-06*G0_1_1_0_0 + 6.7640692640695e-06*G0_1_1_0_2 - 3.3820346320347e-05*G0_1_1_1_1 + 5.00541125541144e-05*G0_1_1_1_2 + 6.7640692640695e-06*G0_1_1_2_0 + 5.00541125541145e-05*G0_1_1_2_1 + 6.08766233766256e-05*G0_1_1_2_2 + 6.7640692640695e-06*G0_1_2_0_1 + 6.7640692640695e-06*G0_1_2_1_0 + 5.00541125541145e-05*G0_1_2_1_1 + 6.08766233766256e-05*G0_1_2_1_2 + 6.08766233766256e-05*G0_1_2_2_1 + 0.000116341991341995*G0_1_2_2_2 + 6.76406926406951e-06*G0_2_0_1_1 + 2.84090909090919e-05*G0_2_0_2_2 + 6.7640692640695e-06*G0_2_1_0_1 + 6.7640692640695e-06*G0_2_1_1_0 + 5.00541125541145e-05*G0_2_1_1_1 + 6.08766233766256e-05*G0_2_1_1_2 + 6.08766233766256e-05*G0_2_1_2_1 + 0.000116341991341995*G0_2_1_2_2 + 2.84090909090919e-05*G0_2_2_0_2 + 6.08766233766256e-05*G0_2_2_1_1 + 0.000116341991341995*G0_2_2_1_2 + 2.84090909090919e-05*G0_2_2_2_0 + 0.000116341991341995*G0_2_2_2_1 + 0.000845508658008687*G0_2_2_2_2; + A[82] = A[30] - 0.00012175324675325*G0_0_0_0_0 - 2.43506493506502e-05*G0_0_0_0_2 + 3.65259740259753e-05*G0_0_0_1_1 - 2.43506493506502e-05*G0_0_0_2_0 + 3.65259740259753e-05*G0_0_1_0_1 + 3.65259740259753e-05*G0_0_1_1_0 + 6.08766233766254e-05*G0_0_1_1_1 - 2.43506493506502e-05*G0_0_2_0_0 + 2.43506493506502e-05*G0_0_2_2_2 + 3.65259740259753e-05*G0_1_0_0_1 + 3.65259740259753e-05*G0_1_0_1_0 + 6.08766233766254e-05*G0_1_0_1_1 + 3.65259740259753e-05*G0_1_1_0_0 + 6.08766233766254e-05*G0_1_1_0_1 + 6.08766233766254e-05*G0_1_1_1_0 - 6.08766233766257e-05*G0_1_1_1_2 - 6.08766233766257e-05*G0_1_1_2_1 - 3.65259740259753e-05*G0_1_1_2_2 - 6.08766233766257e-05*G0_1_2_1_1 - 3.65259740259753e-05*G0_1_2_1_2 - 3.65259740259753e-05*G0_1_2_2_1 - 2.43506493506502e-05*G0_2_0_0_0 + 2.43506493506502e-05*G0_2_0_2_2 - 6.08766233766257e-05*G0_2_1_1_1 - 3.65259740259753e-05*G0_2_1_1_2 - 3.65259740259753e-05*G0_2_1_2_1 + 2.43506493506502e-05*G0_2_2_0_2 - 3.65259740259753e-05*G0_2_2_1_1 + 2.43506493506502e-05*G0_2_2_2_0 + 0.000121753246753251*G0_2_2_2_2; + A[8] = A[82] - 0.000845508658008686*G0_0_0_0_0 - 0.000116341991341995*G0_0_0_0_1 - 2.84090909090918e-05*G0_0_0_0_2 - 0.000116341991341995*G0_0_0_1_0 - 6.08766233766255e-05*G0_0_0_1_1 - 2.84090909090918e-05*G0_0_0_2_0 - 0.000116341991341995*G0_0_1_0_0 - 6.08766233766255e-05*G0_0_1_0_1 - 6.08766233766255e-05*G0_0_1_1_0 - 5.00541125541142e-05*G0_0_1_1_1 - 6.76406926406947e-06*G0_0_1_1_2 - 6.76406926406947e-06*G0_0_1_2_1 - 2.84090909090918e-05*G0_0_2_0_0 - 6.76406926406947e-06*G0_0_2_1_1 - 0.000116341991341995*G0_1_0_0_0 - 6.08766233766255e-05*G0_1_0_0_1 - 6.08766233766255e-05*G0_1_0_1_0 - 5.00541125541142e-05*G0_1_0_1_1 - 6.76406926406947e-06*G0_1_0_1_2 - 6.76406926406947e-06*G0_1_0_2_1 - 6.08766233766255e-05*G0_1_1_0_0 - 5.00541125541142e-05*G0_1_1_0_1 - 6.76406926406947e-06*G0_1_1_0_2 - 5.00541125541142e-05*G0_1_1_1_0 + 3.3820346320348e-05*G0_1_1_1_1 - 6.76406926406947e-06*G0_1_1_2_0 + 6.76406926406952e-06*G0_1_1_2_2 - 6.76406926406947e-06*G0_1_2_0_1 - 6.76406926406947e-06*G0_1_2_1_0 + 6.76406926406952e-06*G0_1_2_1_2 + 6.76406926406953e-06*G0_1_2_2_1 - 2.84090909090918e-05*G0_2_0_0_0 - 6.76406926406947e-06*G0_2_0_1_1 - 6.76406926406947e-06*G0_2_1_0_1 - 6.76406926406947e-06*G0_2_1_1_0 + 6.76406926406953e-06*G0_2_1_1_2 + 6.76406926406953e-06*G0_2_1_2_1 + 6.76406926406953e-06*G0_2_2_1_1 + 2.84090909090917e-05*G0_2_2_2_2; + A[28] = A[82]; + A[98] = A[89]; + A[80] = A[8]; + A[14] = A[41]; + A[39] = A[93]; + A[23] = A[32]; + A[87] = A[78]; + A[42] = -A[11] + 1.08225108225112e-05*G0_0_0_0_0 - 9.46969696969728e-06*G0_0_0_0_1 - 2.7056277056278e-06*G0_0_0_0_2 - 9.46969696969727e-06*G0_0_0_1_0 - 2.70562770562771e-06*G0_0_0_1_1 - 6.76406926406949e-06*G0_0_0_1_2 - 2.7056277056278e-06*G0_0_0_2_0 - 6.76406926406948e-06*G0_0_0_2_1 + 4.96031746031765e-06*G0_0_0_2_2 - 9.46969696969727e-06*G0_0_1_0_0 - 2.70562770562771e-06*G0_0_1_0_1 - 6.76406926406948e-06*G0_0_1_0_2 - 2.70562770562771e-06*G0_0_1_1_0 + 0.000116341991341996*G0_0_1_1_1 - 6.76406926406946e-06*G0_0_1_1_2 - 6.76406926406948e-06*G0_0_1_2_0 - 6.76406926406946e-06*G0_0_1_2_1 - 2.7056277056278e-06*G0_0_2_0_0 - 6.76406926406948e-06*G0_0_2_0_1 + 4.96031746031765e-06*G0_0_2_0_2 - 6.76406926406948e-06*G0_0_2_1_0 - 6.76406926406946e-06*G0_0_2_1_1 + 4.96031746031766e-06*G0_0_2_2_0 + 0.000112283549783554*G0_0_2_2_2 - 9.46969696969727e-06*G0_1_0_0_0 - 2.70562770562772e-06*G0_1_0_0_1 - 6.76406926406948e-06*G0_1_0_0_2 - 2.70562770562772e-06*G0_1_0_1_0 + 0.000116341991341996*G0_1_0_1_1 - 6.76406926406946e-06*G0_1_0_1_2 - 6.76406926406948e-06*G0_1_0_2_0 - 6.76406926406946e-06*G0_1_0_2_1 - 2.70562770562772e-06*G0_1_1_0_0 + 0.000116341991341996*G0_1_1_0_1 - 6.76406926406946e-06*G0_1_1_0_2 + 0.000116341991341996*G0_1_1_1_0 + 0.00278679653679664*G0_1_1_1_1 + 9.46969696969727e-05*G0_1_1_1_2 - 6.76406926406946e-06*G0_1_1_2_0 + 9.46969696969728e-05*G0_1_1_2_1 + 6.76406926406952e-06*G0_1_1_2_2 - 6.76406926406948e-06*G0_1_2_0_0 - 6.76406926406947e-06*G0_1_2_0_1 - 6.76406926406946e-06*G0_1_2_1_0 + 9.46969696969727e-05*G0_1_2_1_1 + 6.76406926406952e-06*G0_1_2_1_2 + 6.76406926406952e-06*G0_1_2_2_1 + 0.000209686147186155*G0_1_2_2_2 - 2.7056277056278e-06*G0_2_0_0_0 - 6.76406926406948e-06*G0_2_0_0_1 + 4.96031746031765e-06*G0_2_0_0_2 - 6.76406926406948e-06*G0_2_0_1_0 - 6.76406926406946e-06*G0_2_0_1_1 + 4.96031746031766e-06*G0_2_0_2_0 + 0.000112283549783554*G0_2_0_2_2 - 6.76406926406949e-06*G0_2_1_0_0 - 6.76406926406947e-06*G0_2_1_0_1 - 6.76406926406946e-06*G0_2_1_1_0 + 9.46969696969728e-05*G0_2_1_1_1 + 6.76406926406952e-06*G0_2_1_1_2 + 6.76406926406952e-06*G0_2_1_2_1 + 0.000209686147186155*G0_2_1_2_2 + 4.96031746031766e-06*G0_2_2_0_0 + 0.000112283549783554*G0_2_2_0_2 + 6.76406926406952e-06*G0_2_2_1_1 + 0.000209686147186155*G0_2_2_1_2 + 0.000112283549783554*G0_2_2_2_0 + 0.000209686147186155*G0_2_2_2_1 + 0.00222132034632042*G0_2_2_2_2; + A[26] = A[42] - 0.000238095238095246*G0_0_0_0_0 - 2.97619047619058e-05*G0_0_0_0_1 - 6.08766233766254e-05*G0_0_0_0_2 - 2.97619047619058e-05*G0_0_0_1_0 - 6.76406926406949e-06*G0_0_0_1_2 - 6.08766233766254e-05*G0_0_0_2_0 - 6.7640692640695e-06*G0_0_0_2_1 - 1.35281385281389e-05*G0_0_0_2_2 - 2.97619047619058e-05*G0_0_1_0_0 - 6.7640692640695e-06*G0_0_1_0_2 + 2.97619047619058e-05*G0_0_1_1_1 + 6.76406926406948e-06*G0_0_1_1_2 - 6.76406926406949e-06*G0_0_1_2_0 + 6.76406926406949e-06*G0_0_1_2_1 - 6.08766233766254e-05*G0_0_2_0_0 - 6.7640692640695e-06*G0_0_2_0_1 - 1.35281385281389e-05*G0_0_2_0_2 - 6.76406926406949e-06*G0_0_2_1_0 + 6.76406926406949e-06*G0_0_2_1_1 - 1.35281385281389e-05*G0_0_2_2_0 + 9.4696969696973e-05*G0_0_2_2_2 - 2.97619047619058e-05*G0_1_0_0_0 - 6.7640692640695e-06*G0_1_0_0_2 + 2.97619047619058e-05*G0_1_0_1_1 + 6.76406926406948e-06*G0_1_0_1_2 - 6.76406926406949e-06*G0_1_0_2_0 + 6.76406926406949e-06*G0_1_0_2_1 + 2.97619047619058e-05*G0_1_1_0_1 + 6.76406926406949e-06*G0_1_1_0_2 + 2.97619047619058e-05*G0_1_1_1_0 + 0.000238095238095247*G0_1_1_1_1 + 6.08766233766255e-05*G0_1_1_1_2 + 6.76406926406948e-06*G0_1_1_2_0 + 6.08766233766255e-05*G0_1_1_2_1 + 1.3528138528139e-05*G0_1_1_2_2 - 6.76406926406949e-06*G0_1_2_0_0 + 6.76406926406949e-06*G0_1_2_0_1 + 6.76406926406948e-06*G0_1_2_1_0 + 6.08766233766255e-05*G0_1_2_1_1 + 1.3528138528139e-05*G0_1_2_1_2 + 1.3528138528139e-05*G0_1_2_2_1 - 9.46969696969729e-05*G0_1_2_2_2 - 6.08766233766254e-05*G0_2_0_0_0 - 6.76406926406949e-06*G0_2_0_0_1 - 1.35281385281389e-05*G0_2_0_0_2 - 6.76406926406949e-06*G0_2_0_1_0 + 6.76406926406949e-06*G0_2_0_1_1 - 1.35281385281389e-05*G0_2_0_2_0 + 9.46969696969731e-05*G0_2_0_2_2 - 6.76406926406949e-06*G0_2_1_0_0 + 6.76406926406949e-06*G0_2_1_0_1 + 6.76406926406948e-06*G0_2_1_1_0 + 6.08766233766255e-05*G0_2_1_1_1 + 1.3528138528139e-05*G0_2_1_1_2 + 1.3528138528139e-05*G0_2_1_2_1 - 9.46969696969729e-05*G0_2_1_2_2 - 1.35281385281389e-05*G0_2_2_0_0 + 9.46969696969731e-05*G0_2_2_0_2 + 1.3528138528139e-05*G0_2_2_1_1 - 9.46969696969729e-05*G0_2_2_1_2 + 9.46969696969731e-05*G0_2_2_2_0 - 9.46969696969729e-05*G0_2_2_2_1; + A[90] = A[26] + 0.00054112554112556*G0_0_0_0_0 + 1.89393939393946e-05*G0_0_0_0_1 + 4.05844155844169e-05*G0_0_0_0_2 + 1.89393939393946e-05*G0_0_0_1_0 + 5.41125541125559e-06*G0_0_0_1_1 + 4.05844155844167e-06*G0_0_0_1_2 + 4.05844155844169e-05*G0_0_0_2_0 + 4.05844155844167e-06*G0_0_0_2_1 - 4.05844155844176e-06*G0_0_0_2_2 + 1.89393939393946e-05*G0_0_1_0_0 + 5.41125541125561e-06*G0_0_1_0_1 + 4.05844155844167e-06*G0_0_1_0_2 + 5.4112554112556e-06*G0_0_1_1_0 + 7.84632034632062e-05*G0_0_1_1_1 + 3.78787878787892e-05*G0_0_1_1_2 + 4.05844155844166e-06*G0_0_1_2_0 + 3.78787878787892e-05*G0_0_1_2_1 + 3.11147186147196e-05*G0_0_1_2_2 + 4.05844155844169e-05*G0_0_2_0_0 + 4.05844155844167e-06*G0_0_2_0_1 - 4.05844155844174e-06*G0_0_2_0_2 + 4.05844155844167e-06*G0_0_2_1_0 + 3.78787878787892e-05*G0_0_2_1_1 + 3.11147186147196e-05*G0_0_2_1_2 - 4.05844155844175e-06*G0_0_2_2_0 + 3.11147186147196e-05*G0_0_2_2_1 - 0.000140692640692646*G0_0_2_2_2 + 1.89393939393946e-05*G0_1_0_0_0 + 5.4112554112556e-06*G0_1_0_0_1 + 4.05844155844168e-06*G0_1_0_0_2 + 5.41125541125561e-06*G0_1_0_1_0 + 7.84632034632062e-05*G0_1_0_1_1 + 3.78787878787892e-05*G0_1_0_1_2 + 4.05844155844167e-06*G0_1_0_2_0 + 3.78787878787892e-05*G0_1_0_2_1 + 3.11147186147196e-05*G0_1_0_2_2 + 5.4112554112556e-06*G0_1_1_0_0 + 7.84632034632062e-05*G0_1_1_0_1 + 3.78787878787892e-05*G0_1_1_0_2 + 7.84632034632062e-05*G0_1_1_1_0 + 0.000384199134199148*G0_1_1_1_1 + 0.000150162337662343*G0_1_1_1_2 + 3.78787878787892e-05*G0_1_1_2_0 + 0.000150162337662343*G0_1_1_2_1 + 0.00010416666666667*G0_1_1_2_2 + 4.05844155844167e-06*G0_1_2_0_0 + 3.78787878787892e-05*G0_1_2_0_1 + 3.11147186147196e-05*G0_1_2_0_2 + 3.78787878787892e-05*G0_1_2_1_0 + 0.000150162337662343*G0_1_2_1_1 + 0.00010416666666667*G0_1_2_1_2 + 3.11147186147196e-05*G0_1_2_2_0 + 0.00010416666666667*G0_1_2_2_1 + 3.5173160173161e-05*G0_1_2_2_2 + 4.05844155844169e-05*G0_2_0_0_0 + 4.05844155844167e-06*G0_2_0_0_1 - 4.05844155844175e-06*G0_2_0_0_2 + 4.05844155844167e-06*G0_2_0_1_0 + 3.78787878787892e-05*G0_2_0_1_1 + 3.11147186147196e-05*G0_2_0_1_2 - 4.05844155844175e-06*G0_2_0_2_0 + 3.11147186147196e-05*G0_2_0_2_1 - 0.000140692640692646*G0_2_0_2_2 + 4.05844155844167e-06*G0_2_1_0_0 + 3.78787878787892e-05*G0_2_1_0_1 + 3.11147186147196e-05*G0_2_1_0_2 + 3.78787878787892e-05*G0_2_1_1_0 + 0.000150162337662343*G0_2_1_1_1 + 0.00010416666666667*G0_2_1_1_2 + 3.11147186147196e-05*G0_2_1_2_0 + 0.00010416666666667*G0_2_1_2_1 + 3.51731601731611e-05*G0_2_1_2_2 - 4.05844155844176e-06*G0_2_2_0_0 + 3.11147186147196e-05*G0_2_2_0_1 - 0.000140692640692646*G0_2_2_0_2 + 3.11147186147196e-05*G0_2_2_1_0 + 0.00010416666666667*G0_2_2_1_1 + 3.51731601731611e-05*G0_2_2_1_2 - 0.000140692640692646*G0_2_2_2_0 + 3.51731601731611e-05*G0_2_2_2_1 - 0.00182629870129877*G0_2_2_2_2; + A[92] = -A[90] + 0.000568181818181837*G0_0_0_0_0 + 8.92857142857174e-05*G0_0_0_0_1 + 8.11688311688342e-06*G0_0_0_0_2 + 8.92857142857174e-05*G0_0_0_1_0 + 7.30519480519505e-05*G0_0_0_1_1 + 8.11688311688338e-06*G0_0_0_1_2 + 8.11688311688343e-06*G0_0_0_2_0 + 8.11688311688338e-06*G0_0_0_2_1 - 4.87012987013003e-05*G0_0_0_2_2 + 8.92857142857174e-05*G0_0_1_0_0 + 7.30519480519505e-05*G0_0_1_0_1 + 8.11688311688338e-06*G0_0_1_0_2 + 7.30519480519505e-05*G0_0_1_1_0 + 0.000178571428571435*G0_0_1_1_1 + 4.87012987013004e-05*G0_0_1_1_2 + 8.11688311688338e-06*G0_0_1_2_0 + 4.87012987013004e-05*G0_0_1_2_1 + 8.11688311688343e-06*G0_0_1_2_2 + 8.11688311688341e-06*G0_0_2_0_0 + 8.11688311688337e-06*G0_0_2_0_1 - 4.87012987013003e-05*G0_0_2_0_2 + 8.11688311688337e-06*G0_0_2_1_0 + 4.87012987013004e-05*G0_0_2_1_1 + 8.11688311688344e-06*G0_0_2_1_2 - 4.87012987013003e-05*G0_0_2_2_0 + 8.11688311688343e-06*G0_0_2_2_1 + 8.11688311688367e-06*G0_0_2_2_2 + 8.92857142857174e-05*G0_1_0_0_0 + 7.30519480519505e-05*G0_1_0_0_1 + 8.11688311688339e-06*G0_1_0_0_2 + 7.30519480519505e-05*G0_1_0_1_0 + 0.000178571428571435*G0_1_0_1_1 + 4.87012987013004e-05*G0_1_0_1_2 + 8.11688311688339e-06*G0_1_0_2_0 + 4.87012987013004e-05*G0_1_0_2_1 + 8.11688311688344e-06*G0_1_0_2_2 + 7.30519480519505e-05*G0_1_1_0_0 + 0.000178571428571435*G0_1_1_0_1 + 4.87012987013004e-05*G0_1_1_0_2 + 0.000178571428571435*G0_1_1_1_0 + 0.000649350649350672*G0_1_1_1_1 + 0.000178571428571435*G0_1_1_1_2 + 4.87012987013004e-05*G0_1_1_2_0 + 0.000178571428571435*G0_1_1_2_1 + 7.30519480519506e-05*G0_1_1_2_2 + 8.11688311688338e-06*G0_1_2_0_0 + 4.87012987013004e-05*G0_1_2_0_1 + 8.11688311688343e-06*G0_1_2_0_2 + 4.87012987013004e-05*G0_1_2_1_0 + 0.000178571428571435*G0_1_2_1_1 + 7.30519480519506e-05*G0_1_2_1_2 + 8.11688311688343e-06*G0_1_2_2_0 + 7.30519480519506e-05*G0_1_2_2_1 + 8.92857142857175e-05*G0_1_2_2_2 + 8.11688311688342e-06*G0_2_0_0_0 + 8.11688311688339e-06*G0_2_0_0_1 - 4.87012987013002e-05*G0_2_0_0_2 + 8.11688311688338e-06*G0_2_0_1_0 + 4.87012987013004e-05*G0_2_0_1_1 + 8.11688311688344e-06*G0_2_0_1_2 - 4.87012987013002e-05*G0_2_0_2_0 + 8.11688311688343e-06*G0_2_0_2_1 + 8.11688311688365e-06*G0_2_0_2_2 + 8.11688311688337e-06*G0_2_1_0_0 + 4.87012987013004e-05*G0_2_1_0_1 + 8.11688311688343e-06*G0_2_1_0_2 + 4.87012987013004e-05*G0_2_1_1_0 + 0.000178571428571435*G0_2_1_1_1 + 7.30519480519506e-05*G0_2_1_1_2 + 8.11688311688343e-06*G0_2_1_2_0 + 7.30519480519506e-05*G0_2_1_2_1 + 8.92857142857176e-05*G0_2_1_2_2 - 4.87012987013003e-05*G0_2_2_0_0 + 8.11688311688343e-06*G0_2_2_0_1 + 8.11688311688365e-06*G0_2_2_0_2 + 8.11688311688343e-06*G0_2_2_1_0 + 7.30519480519506e-05*G0_2_2_1_1 + 8.92857142857176e-05*G0_2_2_1_2 + 8.11688311688365e-06*G0_2_2_2_0 + 8.92857142857176e-05*G0_2_2_2_1 + 0.000568181818181839*G0_2_2_2_2; + A[62] = A[26]; + A[19] = -A[90] + 0.000568181818181838*G0_0_0_0_0 + 8.11688311688344e-06*G0_0_0_0_1 + 8.92857142857173e-05*G0_0_0_0_2 + 8.11688311688343e-06*G0_0_0_1_0 - 4.87012987013003e-05*G0_0_0_1_1 + 8.11688311688339e-06*G0_0_0_1_2 + 8.92857142857173e-05*G0_0_0_2_0 + 8.1168831168834e-06*G0_0_0_2_1 + 7.30519480519505e-05*G0_0_0_2_2 + 8.11688311688343e-06*G0_0_1_0_0 - 4.87012987013003e-05*G0_0_1_0_1 + 8.11688311688339e-06*G0_0_1_0_2 - 4.87012987013003e-05*G0_0_1_1_0 + 8.11688311688363e-06*G0_0_1_1_1 + 8.11688311688345e-06*G0_0_1_1_2 + 8.1168831168834e-06*G0_0_1_2_0 + 8.11688311688344e-06*G0_0_1_2_1 + 4.87012987013004e-05*G0_0_1_2_2 + 8.92857142857173e-05*G0_0_2_0_0 + 8.11688311688339e-06*G0_0_2_0_1 + 7.30519480519505e-05*G0_0_2_0_2 + 8.11688311688339e-06*G0_0_2_1_0 + 8.11688311688344e-06*G0_0_2_1_1 + 4.87012987013004e-05*G0_0_2_1_2 + 7.30519480519505e-05*G0_0_2_2_0 + 4.87012987013004e-05*G0_0_2_2_1 + 0.000178571428571435*G0_0_2_2_2 + 8.11688311688346e-06*G0_1_0_0_0 - 4.87012987013003e-05*G0_1_0_0_1 + 8.1168831168834e-06*G0_1_0_0_2 - 4.87012987013003e-05*G0_1_0_1_0 + 8.11688311688363e-06*G0_1_0_1_1 + 8.11688311688344e-06*G0_1_0_1_2 + 8.1168831168834e-06*G0_1_0_2_0 + 8.11688311688344e-06*G0_1_0_2_1 + 4.87012987013004e-05*G0_1_0_2_2 - 4.87012987013003e-05*G0_1_1_0_0 + 8.11688311688365e-06*G0_1_1_0_1 + 8.11688311688345e-06*G0_1_1_0_2 + 8.11688311688365e-06*G0_1_1_1_0 + 0.00056818181818184*G0_1_1_1_1 + 8.92857142857176e-05*G0_1_1_1_2 + 8.11688311688345e-06*G0_1_1_2_0 + 8.92857142857177e-05*G0_1_1_2_1 + 7.30519480519506e-05*G0_1_1_2_2 + 8.1168831168834e-06*G0_1_2_0_0 + 8.11688311688344e-06*G0_1_2_0_1 + 4.87012987013004e-05*G0_1_2_0_2 + 8.11688311688345e-06*G0_1_2_1_0 + 8.92857142857177e-05*G0_1_2_1_1 + 7.30519480519506e-05*G0_1_2_1_2 + 4.87012987013004e-05*G0_1_2_2_0 + 7.30519480519506e-05*G0_1_2_2_1 + 0.000178571428571435*G0_1_2_2_2 + 8.92857142857173e-05*G0_2_0_0_0 + 8.1168831168834e-06*G0_2_0_0_1 + 7.30519480519505e-05*G0_2_0_0_2 + 8.11688311688339e-06*G0_2_0_1_0 + 8.11688311688344e-06*G0_2_0_1_1 + 4.87012987013004e-05*G0_2_0_1_2 + 7.30519480519505e-05*G0_2_0_2_0 + 4.87012987013004e-05*G0_2_0_2_1 + 0.000178571428571435*G0_2_0_2_2 + 8.11688311688339e-06*G0_2_1_0_0 + 8.11688311688344e-06*G0_2_1_0_1 + 4.87012987013004e-05*G0_2_1_0_2 + 8.11688311688345e-06*G0_2_1_1_0 + 8.92857142857177e-05*G0_2_1_1_1 + 7.30519480519506e-05*G0_2_1_1_2 + 4.87012987013004e-05*G0_2_1_2_0 + 7.30519480519506e-05*G0_2_1_2_1 + 0.000178571428571435*G0_2_1_2_2 + 7.30519480519505e-05*G0_2_2_0_0 + 4.87012987013004e-05*G0_2_2_0_1 + 0.000178571428571435*G0_2_2_0_2 + 4.87012987013004e-05*G0_2_2_1_0 + 7.30519480519506e-05*G0_2_2_1_1 + 0.000178571428571435*G0_2_2_1_2 + 0.000178571428571435*G0_2_2_2_0 + 0.000178571428571435*G0_2_2_2_1 + 0.000649350649350672*G0_2_2_2_2; + A[96] = A[69]; + A[65] = -A[83] - 0.00213068181818189*G0_0_0_0_0 - 0.000158279220779226*G0_0_0_0_1 - 0.000267857142857152*G0_0_0_0_2 - 0.000158279220779226*G0_0_0_1_0 + 0.000170454545454551*G0_0_0_1_1 - 0.000267857142857152*G0_0_0_2_0 - 0.000158279220779226*G0_0_1_0_0 + 0.000170454545454551*G0_0_1_0_1 + 0.000170454545454551*G0_0_1_1_0 + 0.000754870129870156*G0_0_1_1_1 + 0.000133928571428576*G0_0_1_1_2 + 0.000133928571428576*G0_0_1_2_1 - 0.000267857142857152*G0_0_2_0_0 + 0.000133928571428576*G0_0_2_1_1 - 0.000267857142857153*G0_0_2_2_2 - 0.000158279220779226*G0_1_0_0_0 + 0.000170454545454551*G0_1_0_0_1 + 0.000170454545454551*G0_1_0_1_0 + 0.000754870129870156*G0_1_0_1_1 + 0.000133928571428576*G0_1_0_1_2 + 0.000133928571428576*G0_1_0_2_1 + 0.000170454545454551*G0_1_1_0_0 + 0.000754870129870156*G0_1_1_0_1 + 0.000133928571428576*G0_1_1_0_2 + 0.000754870129870156*G0_1_1_1_0 + 0.00400568181818196*G0_1_1_1_1 + 0.000754870129870157*G0_1_1_1_2 + 0.000133928571428576*G0_1_1_2_0 + 0.000754870129870157*G0_1_1_2_1 + 0.000170454545454551*G0_1_1_2_2 + 0.000133928571428576*G0_1_2_0_1 + 0.000133928571428576*G0_1_2_1_0 + 0.000754870129870157*G0_1_2_1_1 + 0.000170454545454551*G0_1_2_1_2 + 0.000170454545454551*G0_1_2_2_1 - 0.000158279220779227*G0_1_2_2_2 - 0.000267857142857152*G0_2_0_0_0 + 0.000133928571428576*G0_2_0_1_1 - 0.000267857142857153*G0_2_0_2_2 + 0.000133928571428576*G0_2_1_0_1 + 0.000133928571428576*G0_2_1_1_0 + 0.000754870129870157*G0_2_1_1_1 + 0.000170454545454551*G0_2_1_1_2 + 0.000170454545454551*G0_2_1_2_1 - 0.000158279220779227*G0_2_1_2_2 - 0.000267857142857153*G0_2_2_0_2 + 0.000170454545454551*G0_2_2_1_1 - 0.000158279220779227*G0_2_2_1_2 - 0.000267857142857153*G0_2_2_2_0 - 0.000158279220779227*G0_2_2_2_1 - 0.0021306818181819*G0_2_2_2_2; + A[53] = A[35]; + A[70] = A[7]; + A[68] = A[86]; + A[6] = A[60]; + A[17] = A[71]; + A[9] = A[90]; + A[34] = -A[75] + 0.00400568181818195*G0_0_0_0_0 + 0.000754870129870155*G0_0_0_0_1 + 0.000754870129870155*G0_0_0_0_2 + 0.000754870129870155*G0_0_0_1_0 + 0.000170454545454551*G0_0_0_1_1 + 0.000133928571428576*G0_0_0_1_2 + 0.000754870129870155*G0_0_0_2_0 + 0.000133928571428576*G0_0_0_2_1 + 0.000170454545454551*G0_0_0_2_2 + 0.000754870129870155*G0_0_1_0_0 + 0.000170454545454551*G0_0_1_0_1 + 0.000133928571428576*G0_0_1_0_2 + 0.000170454545454551*G0_0_1_1_0 - 0.000158279220779226*G0_0_1_1_1 + 0.000133928571428576*G0_0_1_2_0 + 0.000754870129870155*G0_0_2_0_0 + 0.000133928571428576*G0_0_2_0_1 + 0.000170454545454551*G0_0_2_0_2 + 0.000133928571428576*G0_0_2_1_0 + 0.000170454545454551*G0_0_2_2_0 - 0.000158279220779226*G0_0_2_2_2 + 0.000754870129870155*G0_1_0_0_0 + 0.000170454545454551*G0_1_0_0_1 + 0.000133928571428576*G0_1_0_0_2 + 0.000170454545454551*G0_1_0_1_0 - 0.000158279220779226*G0_1_0_1_1 + 0.000133928571428576*G0_1_0_2_0 + 0.000170454545454551*G0_1_1_0_0 - 0.000158279220779226*G0_1_1_0_1 - 0.000158279220779226*G0_1_1_1_0 - 0.00213068181818189*G0_1_1_1_1 - 0.000267857142857152*G0_1_1_1_2 - 0.000267857142857152*G0_1_1_2_1 + 0.000133928571428576*G0_1_2_0_0 - 0.000267857142857152*G0_1_2_1_1 - 0.000267857142857152*G0_1_2_2_2 + 0.000754870129870155*G0_2_0_0_0 + 0.000133928571428576*G0_2_0_0_1 + 0.000170454545454551*G0_2_0_0_2 + 0.000133928571428576*G0_2_0_1_0 + 0.000170454545454551*G0_2_0_2_0 - 0.000158279220779226*G0_2_0_2_2 + 0.000133928571428576*G0_2_1_0_0 - 0.000267857142857152*G0_2_1_1_1 - 0.000267857142857152*G0_2_1_2_2 + 0.000170454545454551*G0_2_2_0_0 - 0.000158279220779226*G0_2_2_0_2 - 0.000267857142857152*G0_2_2_1_2 - 0.000158279220779226*G0_2_2_2_0 - 0.000267857142857152*G0_2_2_2_1 - 0.00213068181818189*G0_2_2_2_2; + A[24] = A[42]; + A[84] = A[48]; + A[59] = A[97] - 0.000365259740259754*G0_0_0_0_1 + 0.000365259740259752*G0_0_0_0_2 - 0.000365259740259754*G0_0_0_1_0 - 0.000219155844155852*G0_0_0_1_1 + 0.000365259740259752*G0_0_0_2_0 + 0.000219155844155851*G0_0_0_2_2 - 0.000365259740259754*G0_0_1_0_0 - 0.000219155844155852*G0_0_1_0_1 - 0.000219155844155852*G0_0_1_1_0 + 0.000365259740259752*G0_0_2_0_0 + 0.000219155844155851*G0_0_2_0_2 + 0.000219155844155851*G0_0_2_2_0 - 0.000365259740259754*G0_1_0_0_0 - 0.000219155844155852*G0_1_0_0_1 - 0.000219155844155852*G0_1_0_1_0 - 0.000219155844155852*G0_1_1_0_0 + 0.000730519480519507*G0_1_1_1_1 + 0.000146103896103901*G0_1_1_1_2 + 0.000146103896103901*G0_1_1_2_1 + 0.000146103896103901*G0_1_2_1_1 - 0.000146103896103901*G0_1_2_2_2 + 0.000365259740259752*G0_2_0_0_0 + 0.000219155844155851*G0_2_0_0_2 + 0.000219155844155851*G0_2_0_2_0 + 0.000146103896103901*G0_2_1_1_1 - 0.000146103896103901*G0_2_1_2_2 + 0.000219155844155851*G0_2_2_0_0 - 0.000146103896103901*G0_2_2_1_2 - 0.000146103896103901*G0_2_2_2_1 - 0.000730519480519506*G0_2_2_2_2; + A[47] = A[74]; + A[91] = A[19]; + A[66] = A[55] - 0.00657467532467554*G0_0_0_0_0 - 0.000547889610389628*G0_0_0_0_1 - 0.00164366883116889*G0_0_0_0_2 - 0.000547889610389628*G0_0_0_1_0 - 7.30519480519504e-05*G0_0_0_1_1 - 0.000109577922077925*G0_0_0_1_2 - 0.00164366883116889*G0_0_0_2_0 - 0.000109577922077925*G0_0_0_2_1 - 0.000547889610389628*G0_0_1_0_0 - 7.30519480519504e-05*G0_0_1_0_1 - 0.000109577922077926*G0_0_1_0_2 - 7.30519480519504e-05*G0_0_1_1_0 - 0.000109577922077925*G0_0_1_2_0 + 0.000109577922077926*G0_0_1_2_2 - 0.00164366883116889*G0_0_2_0_0 - 0.000109577922077925*G0_0_2_0_1 - 0.000109577922077925*G0_0_2_1_0 + 0.000109577922077926*G0_0_2_1_2 + 0.000109577922077926*G0_0_2_2_1 + 0.00164366883116889*G0_0_2_2_2 - 0.000547889610389628*G0_1_0_0_0 - 7.30519480519504e-05*G0_1_0_0_1 - 0.000109577922077926*G0_1_0_0_2 - 7.30519480519504e-05*G0_1_0_1_0 - 0.000109577922077926*G0_1_0_2_0 + 0.000109577922077926*G0_1_0_2_2 - 7.30519480519504e-05*G0_1_1_0_0 + 7.30519480519506e-05*G0_1_1_2_2 - 0.000109577922077926*G0_1_2_0_0 + 0.000109577922077926*G0_1_2_0_2 + 7.30519480519506e-05*G0_1_2_1_2 + 0.000109577922077926*G0_1_2_2_0 + 7.30519480519506e-05*G0_1_2_2_1 + 0.00054788961038963*G0_1_2_2_2 - 0.00164366883116889*G0_2_0_0_0 - 0.000109577922077925*G0_2_0_0_1 - 0.000109577922077925*G0_2_0_1_0 + 0.000109577922077926*G0_2_0_1_2 + 0.000109577922077926*G0_2_0_2_1 + 0.00164366883116889*G0_2_0_2_2 - 0.000109577922077926*G0_2_1_0_0 + 0.000109577922077926*G0_2_1_0_2 + 7.30519480519506e-05*G0_2_1_1_2 + 0.000109577922077926*G0_2_1_2_0 + 7.30519480519506e-05*G0_2_1_2_1 + 0.00054788961038963*G0_2_1_2_2 + 0.000109577922077926*G0_2_2_0_1 + 0.00164366883116889*G0_2_2_0_2 + 0.000109577922077926*G0_2_2_1_0 + 7.30519480519506e-05*G0_2_2_1_1 + 0.00054788961038963*G0_2_2_1_2 + 0.00164366883116889*G0_2_2_2_0 + 0.00054788961038963*G0_2_2_2_1 + 0.00657467532467555*G0_2_2_2_2; + A[56] = A[65]; + A[77] = A[55] + 0.00158279220779226*G0_0_0_0_1 - 0.00158279220779226*G0_0_0_0_2 + 0.00158279220779226*G0_0_0_1_0 + 0.000852272727272758*G0_0_0_1_1 - 0.00158279220779226*G0_0_0_2_0 - 0.000852272727272755*G0_0_0_2_2 + 0.00158279220779226*G0_0_1_0_0 + 0.000852272727272758*G0_0_1_0_1 + 0.000852272727272758*G0_0_1_1_0 + 0.000657467532467556*G0_0_1_1_1 + 7.30519480519506e-05*G0_0_1_1_2 + 7.30519480519506e-05*G0_0_1_2_1 - 7.30519480519504e-05*G0_0_1_2_2 - 0.00158279220779226*G0_0_2_0_0 - 0.000852272727272755*G0_0_2_0_2 + 7.30519480519506e-05*G0_0_2_1_1 - 7.30519480519504e-05*G0_0_2_1_2 - 0.000852272727272755*G0_0_2_2_0 - 7.30519480519504e-05*G0_0_2_2_1 - 0.000657467532467554*G0_0_2_2_2 + 0.00158279220779226*G0_1_0_0_0 + 0.000852272727272758*G0_1_0_0_1 + 0.000852272727272758*G0_1_0_1_0 + 0.000657467532467556*G0_1_0_1_1 + 7.30519480519506e-05*G0_1_0_1_2 + 7.30519480519506e-05*G0_1_0_2_1 - 7.30519480519504e-05*G0_1_0_2_2 + 0.000852272727272758*G0_1_1_0_0 + 0.000657467532467556*G0_1_1_0_1 + 7.30519480519506e-05*G0_1_1_0_2 + 0.000657467532467556*G0_1_1_1_0 + 0.00136363636363641*G0_1_1_1_1 + 0.000170454545454551*G0_1_1_1_2 + 7.30519480519506e-05*G0_1_1_2_0 + 0.000170454545454552*G0_1_1_2_1 + 7.30519480519506e-05*G0_1_2_0_1 - 7.30519480519504e-05*G0_1_2_0_2 + 7.30519480519506e-05*G0_1_2_1_0 + 0.000170454545454551*G0_1_2_1_1 - 7.30519480519504e-05*G0_1_2_2_0 - 0.000170454545454551*G0_1_2_2_2 - 0.00158279220779226*G0_2_0_0_0 - 0.000852272727272755*G0_2_0_0_2 + 7.30519480519506e-05*G0_2_0_1_1 - 7.30519480519504e-05*G0_2_0_1_2 - 0.000852272727272755*G0_2_0_2_0 - 7.30519480519504e-05*G0_2_0_2_1 - 0.000657467532467554*G0_2_0_2_2 + 7.30519480519506e-05*G0_2_1_0_1 - 7.30519480519504e-05*G0_2_1_0_2 + 7.30519480519506e-05*G0_2_1_1_0 + 0.000170454545454552*G0_2_1_1_1 - 7.30519480519504e-05*G0_2_1_2_0 - 0.000170454545454551*G0_2_1_2_2 - 0.000852272727272755*G0_2_2_0_0 - 7.30519480519504e-05*G0_2_2_0_1 - 0.000657467532467554*G0_2_2_0_2 - 7.30519480519504e-05*G0_2_2_1_0 - 0.000170454545454551*G0_2_2_1_2 - 0.000657467532467554*G0_2_2_2_0 - 0.000170454545454551*G0_2_2_2_1 - 0.00136363636363641*G0_2_2_2_2; + A[3] = A[30]; + A[12] = A[21]; + A[49] = A[94]; + A[33] = A[55] - 0.00793831168831195*G0_0_0_0_0 - 0.00071834415584418*G0_0_0_0_1 - 0.00230113636363644*G0_0_0_0_2 - 0.00071834415584418*G0_0_0_1_0 - 0.000182629870129876*G0_0_0_1_2 - 0.00230113636363644*G0_0_0_2_0 - 0.000182629870129876*G0_0_0_2_1 - 0.000925324675324705*G0_0_0_2_2 - 0.00071834415584418*G0_0_1_0_0 - 0.000182629870129876*G0_0_1_0_2 + 0.000718344155844181*G0_0_1_1_1 + 0.000182629870129876*G0_0_1_1_2 - 0.000182629870129876*G0_0_1_2_0 + 0.000182629870129876*G0_0_1_2_1 - 0.00230113636363644*G0_0_2_0_0 - 0.000182629870129876*G0_0_2_0_1 - 0.000925324675324705*G0_0_2_0_2 - 0.000182629870129876*G0_0_2_1_0 + 0.000182629870129876*G0_0_2_1_1 - 0.000925324675324705*G0_0_2_2_0 - 0.000487012987013003*G0_0_2_2_2 - 0.00071834415584418*G0_1_0_0_0 - 0.000182629870129876*G0_1_0_0_2 + 0.000718344155844181*G0_1_0_1_1 + 0.000182629870129876*G0_1_0_1_2 - 0.000182629870129876*G0_1_0_2_0 + 0.000182629870129876*G0_1_0_2_1 + 0.000718344155844181*G0_1_1_0_1 + 0.000182629870129876*G0_1_1_0_2 + 0.000718344155844181*G0_1_1_1_0 + 0.00793831168831197*G0_1_1_1_1 + 0.00230113636363644*G0_1_1_1_2 + 0.000182629870129876*G0_1_1_2_0 + 0.00230113636363644*G0_1_1_2_1 + 0.000925324675324708*G0_1_1_2_2 - 0.000182629870129876*G0_1_2_0_0 + 0.000182629870129876*G0_1_2_0_1 + 0.000182629870129876*G0_1_2_1_0 + 0.00230113636363644*G0_1_2_1_1 + 0.000925324675324708*G0_1_2_1_2 + 0.000925324675324708*G0_1_2_2_1 + 0.000487012987013004*G0_1_2_2_2 - 0.00230113636363644*G0_2_0_0_0 - 0.000182629870129876*G0_2_0_0_1 - 0.000925324675324706*G0_2_0_0_2 - 0.000182629870129876*G0_2_0_1_0 + 0.000182629870129876*G0_2_0_1_1 - 0.000925324675324705*G0_2_0_2_0 - 0.000487012987013003*G0_2_0_2_2 - 0.000182629870129876*G0_2_1_0_0 + 0.000182629870129876*G0_2_1_0_1 + 0.000182629870129876*G0_2_1_1_0 + 0.00230113636363644*G0_2_1_1_1 + 0.000925324675324708*G0_2_1_1_2 + 0.000925324675324708*G0_2_1_2_1 + 0.000487012987013004*G0_2_1_2_2 - 0.000925324675324706*G0_2_2_0_0 - 0.000487012987013003*G0_2_2_0_2 + 0.000925324675324708*G0_2_2_1_1 + 0.000487012987013004*G0_2_2_1_2 - 0.000487012987013003*G0_2_2_2_0 + 0.000487012987013004*G0_2_2_2_1; + A[29] = A[92]; + A[44] = A[33] - 7.30519480519505e-05*G0_0_0_1_1 + 7.30519480519505e-05*G0_0_0_2_2 - 7.30519480519505e-05*G0_0_1_0_1 - 7.30519480519505e-05*G0_0_1_1_0 - 0.000547889610389629*G0_0_1_1_1 - 0.000109577922077926*G0_0_1_1_2 - 0.000109577922077926*G0_0_1_2_1 + 0.000109577922077926*G0_0_1_2_2 + 7.30519480519505e-05*G0_0_2_0_2 - 0.000109577922077926*G0_0_2_1_1 + 0.000109577922077926*G0_0_2_1_2 + 7.30519480519505e-05*G0_0_2_2_0 + 0.000109577922077926*G0_0_2_2_1 + 0.000547889610389629*G0_0_2_2_2 - 7.30519480519505e-05*G0_1_0_0_1 - 7.30519480519505e-05*G0_1_0_1_0 - 0.000547889610389629*G0_1_0_1_1 - 0.000109577922077926*G0_1_0_1_2 - 0.000109577922077926*G0_1_0_2_1 + 0.000109577922077926*G0_1_0_2_2 - 7.30519480519505e-05*G0_1_1_0_0 - 0.00054788961038963*G0_1_1_0_1 - 0.000109577922077926*G0_1_1_0_2 - 0.000547889610389629*G0_1_1_1_0 - 0.00657467532467556*G0_1_1_1_1 - 0.00164366883116889*G0_1_1_1_2 - 0.000109577922077926*G0_1_1_2_0 - 0.00164366883116889*G0_1_1_2_1 - 0.000109577922077926*G0_1_2_0_1 + 0.000109577922077926*G0_1_2_0_2 - 0.000109577922077926*G0_1_2_1_0 - 0.00164366883116889*G0_1_2_1_1 + 0.000109577922077926*G0_1_2_2_0 + 0.00164366883116889*G0_1_2_2_2 + 7.30519480519505e-05*G0_2_0_0_2 - 0.000109577922077926*G0_2_0_1_1 + 0.000109577922077926*G0_2_0_1_2 + 7.30519480519505e-05*G0_2_0_2_0 + 0.000109577922077926*G0_2_0_2_1 + 0.000547889610389629*G0_2_0_2_2 - 0.000109577922077926*G0_2_1_0_1 + 0.000109577922077926*G0_2_1_0_2 - 0.000109577922077926*G0_2_1_1_0 - 0.00164366883116889*G0_2_1_1_1 + 0.000109577922077926*G0_2_1_2_0 + 0.00164366883116889*G0_2_1_2_2 + 7.30519480519505e-05*G0_2_2_0_0 + 0.000109577922077926*G0_2_2_0_1 + 0.000547889610389629*G0_2_2_0_2 + 0.000109577922077926*G0_2_2_1_0 + 0.00164366883116889*G0_2_2_1_2 + 0.000547889610389629*G0_2_2_2_0 + 0.00164366883116889*G0_2_2_2_1 + 0.00657467532467555*G0_2_2_2_2; + A[63] = A[36]; + A[0] = -A[26] + 0.00278679653679663*G0_0_0_0_0 + 0.000116341991341996*G0_0_0_0_1 + 9.46969696969726e-05*G0_0_0_0_2 + 0.000116341991341996*G0_0_0_1_0 - 2.70562770562775e-06*G0_0_0_1_1 - 6.76406926406949e-06*G0_0_0_1_2 + 9.46969696969726e-05*G0_0_0_2_0 - 6.76406926406949e-06*G0_0_0_2_1 + 6.76406926406955e-06*G0_0_0_2_2 + 0.000116341991341996*G0_0_1_0_0 - 2.70562770562776e-06*G0_0_1_0_1 - 6.76406926406949e-06*G0_0_1_0_2 - 2.70562770562776e-06*G0_0_1_1_0 - 9.46969696969727e-06*G0_0_1_1_1 - 6.76406926406949e-06*G0_0_1_1_2 - 6.76406926406948e-06*G0_0_1_2_0 - 6.76406926406948e-06*G0_0_1_2_1 + 9.46969696969726e-05*G0_0_2_0_0 - 6.76406926406949e-06*G0_0_2_0_1 + 6.76406926406954e-06*G0_0_2_0_2 - 6.76406926406948e-06*G0_0_2_1_0 - 6.76406926406948e-06*G0_0_2_1_1 + 6.76406926406955e-06*G0_0_2_2_0 + 0.000209686147186155*G0_0_2_2_2 + 0.000116341991341996*G0_1_0_0_0 - 2.70562770562776e-06*G0_1_0_0_1 - 6.76406926406949e-06*G0_1_0_0_2 - 2.70562770562775e-06*G0_1_0_1_0 - 9.46969696969727e-06*G0_1_0_1_1 - 6.76406926406949e-06*G0_1_0_1_2 - 6.76406926406948e-06*G0_1_0_2_0 - 6.76406926406948e-06*G0_1_0_2_1 - 2.70562770562776e-06*G0_1_1_0_0 - 9.46969696969727e-06*G0_1_1_0_1 - 6.76406926406948e-06*G0_1_1_0_2 - 9.46969696969727e-06*G0_1_1_1_0 + 1.08225108225113e-05*G0_1_1_1_1 - 2.70562770562778e-06*G0_1_1_1_2 - 6.76406926406948e-06*G0_1_1_2_0 - 2.70562770562779e-06*G0_1_1_2_1 + 4.96031746031768e-06*G0_1_1_2_2 - 6.76406926406948e-06*G0_1_2_0_0 - 6.76406926406948e-06*G0_1_2_0_1 - 6.76406926406948e-06*G0_1_2_1_0 - 2.70562770562778e-06*G0_1_2_1_1 + 4.96031746031768e-06*G0_1_2_1_2 + 4.96031746031768e-06*G0_1_2_2_1 + 0.000112283549783554*G0_1_2_2_2 + 9.46969696969726e-05*G0_2_0_0_0 - 6.76406926406948e-06*G0_2_0_0_1 + 6.76406926406955e-06*G0_2_0_0_2 - 6.76406926406948e-06*G0_2_0_1_0 - 6.76406926406948e-06*G0_2_0_1_1 + 6.76406926406955e-06*G0_2_0_2_0 + 0.000209686147186155*G0_2_0_2_2 - 6.76406926406949e-06*G0_2_1_0_0 - 6.76406926406948e-06*G0_2_1_0_1 - 6.76406926406948e-06*G0_2_1_1_0 - 2.70562770562778e-06*G0_2_1_1_1 + 4.96031746031768e-06*G0_2_1_1_2 + 4.96031746031768e-06*G0_2_1_2_1 + 0.000112283549783554*G0_2_1_2_2 + 6.76406926406954e-06*G0_2_2_0_0 + 0.000209686147186155*G0_2_2_0_2 + 4.96031746031768e-06*G0_2_2_1_1 + 0.000112283549783554*G0_2_2_1_2 + 0.000209686147186155*G0_2_2_2_0 + 0.000112283549783554*G0_2_2_2_1 + 0.00222132034632042*G0_2_2_2_2; + A[81] = -A[0] + 0.00278679653679663*G0_0_0_0_0 + 9.46969696969732e-05*G0_0_0_0_1 + 0.000116341991341995*G0_0_0_0_2 + 9.46969696969732e-05*G0_0_0_1_0 + 6.76406926406958e-06*G0_0_0_1_1 - 6.76406926406948e-06*G0_0_0_1_2 + 0.000116341991341995*G0_0_0_2_0 - 6.76406926406948e-06*G0_0_0_2_1 - 2.7056277056278e-06*G0_0_0_2_2 + 9.46969696969732e-05*G0_0_1_0_0 + 6.7640692640696e-06*G0_0_1_0_1 - 6.76406926406948e-06*G0_0_1_0_2 + 6.76406926406959e-06*G0_0_1_1_0 + 0.000209686147186155*G0_0_1_1_1 - 6.76406926406948e-06*G0_0_1_2_0 - 6.76406926406948e-06*G0_0_1_2_2 + 0.000116341991341995*G0_0_2_0_0 - 6.76406926406948e-06*G0_0_2_0_1 - 2.7056277056278e-06*G0_0_2_0_2 - 6.76406926406948e-06*G0_0_2_1_0 - 6.76406926406948e-06*G0_0_2_1_2 - 2.70562770562781e-06*G0_0_2_2_0 - 6.76406926406948e-06*G0_0_2_2_1 - 9.46969696969726e-06*G0_0_2_2_2 + 9.46969696969732e-05*G0_1_0_0_0 + 6.76406926406958e-06*G0_1_0_0_1 - 6.76406926406948e-06*G0_1_0_0_2 + 6.76406926406958e-06*G0_1_0_1_0 + 0.000209686147186155*G0_1_0_1_1 - 6.76406926406948e-06*G0_1_0_2_0 - 6.76406926406948e-06*G0_1_0_2_2 + 6.76406926406958e-06*G0_1_1_0_0 + 0.000209686147186155*G0_1_1_0_1 + 0.000209686147186155*G0_1_1_1_0 + 0.00222132034632043*G0_1_1_1_1 + 0.000112283549783554*G0_1_1_1_2 + 0.000112283549783554*G0_1_1_2_1 + 4.9603174603177e-06*G0_1_1_2_2 - 6.76406926406948e-06*G0_1_2_0_0 - 6.76406926406948e-06*G0_1_2_0_2 + 0.000112283549783554*G0_1_2_1_1 + 4.9603174603177e-06*G0_1_2_1_2 - 6.76406926406948e-06*G0_1_2_2_0 + 4.9603174603177e-06*G0_1_2_2_1 - 2.70562770562776e-06*G0_1_2_2_2 + 0.000116341991341995*G0_2_0_0_0 - 6.76406926406948e-06*G0_2_0_0_1 - 2.7056277056278e-06*G0_2_0_0_2 - 6.76406926406948e-06*G0_2_0_1_0 - 6.76406926406948e-06*G0_2_0_1_2 - 2.70562770562781e-06*G0_2_0_2_0 - 6.76406926406948e-06*G0_2_0_2_1 - 9.46969696969726e-06*G0_2_0_2_2 - 6.76406926406948e-06*G0_2_1_0_0 - 6.76406926406948e-06*G0_2_1_0_2 + 0.000112283549783554*G0_2_1_1_1 + 4.9603174603177e-06*G0_2_1_1_2 - 6.76406926406948e-06*G0_2_1_2_0 + 4.9603174603177e-06*G0_2_1_2_1 - 2.70562770562776e-06*G0_2_1_2_2 - 2.70562770562781e-06*G0_2_2_0_0 - 6.76406926406948e-06*G0_2_2_0_1 - 9.46969696969726e-06*G0_2_2_0_2 - 6.76406926406948e-06*G0_2_2_1_0 + 4.9603174603177e-06*G0_2_2_1_1 - 2.70562770562776e-06*G0_2_2_1_2 - 9.46969696969727e-06*G0_2_2_2_0 - 2.70562770562777e-06*G0_2_2_2_1 + 1.08225108225113e-05*G0_2_2_2_2; + A[31] = A[81] + 0.000238095238095246*G0_0_0_0_0 + 6.08766233766254e-05*G0_0_0_0_1 + 2.97619047619057e-05*G0_0_0_0_2 + 6.08766233766254e-05*G0_0_0_1_0 + 1.3528138528139e-05*G0_0_0_1_1 + 6.7640692640695e-06*G0_0_0_1_2 + 2.97619047619057e-05*G0_0_0_2_0 + 6.7640692640695e-06*G0_0_0_2_1 + 6.08766233766254e-05*G0_0_1_0_0 + 1.3528138528139e-05*G0_0_1_0_1 + 6.7640692640695e-06*G0_0_1_0_2 + 1.3528138528139e-05*G0_0_1_1_0 - 9.46969696969732e-05*G0_0_1_1_1 + 6.7640692640695e-06*G0_0_1_2_0 - 6.7640692640695e-06*G0_0_1_2_2 + 2.97619047619057e-05*G0_0_2_0_0 + 6.7640692640695e-06*G0_0_2_0_1 + 6.7640692640695e-06*G0_0_2_1_0 - 6.7640692640695e-06*G0_0_2_1_2 - 6.76406926406949e-06*G0_0_2_2_1 - 2.97619047619058e-05*G0_0_2_2_2 + 6.08766233766254e-05*G0_1_0_0_0 + 1.3528138528139e-05*G0_1_0_0_1 + 6.7640692640695e-06*G0_1_0_0_2 + 1.3528138528139e-05*G0_1_0_1_0 - 9.46969696969732e-05*G0_1_0_1_1 + 6.7640692640695e-06*G0_1_0_2_0 - 6.7640692640695e-06*G0_1_0_2_2 + 1.3528138528139e-05*G0_1_1_0_0 - 9.46969696969732e-05*G0_1_1_0_1 - 9.46969696969733e-05*G0_1_1_1_0 + 9.46969696969727e-05*G0_1_1_1_2 + 9.46969696969727e-05*G0_1_1_2_1 - 1.3528138528139e-05*G0_1_1_2_2 + 6.7640692640695e-06*G0_1_2_0_0 - 6.7640692640695e-06*G0_1_2_0_2 + 9.46969696969727e-05*G0_1_2_1_1 - 1.3528138528139e-05*G0_1_2_1_2 - 6.76406926406949e-06*G0_1_2_2_0 - 1.3528138528139e-05*G0_1_2_2_1 - 6.08766233766255e-05*G0_1_2_2_2 + 2.97619047619057e-05*G0_2_0_0_0 + 6.7640692640695e-06*G0_2_0_0_1 + 6.7640692640695e-06*G0_2_0_1_0 - 6.7640692640695e-06*G0_2_0_1_2 - 6.76406926406949e-06*G0_2_0_2_1 - 2.97619047619058e-05*G0_2_0_2_2 + 6.7640692640695e-06*G0_2_1_0_0 - 6.7640692640695e-06*G0_2_1_0_2 + 9.46969696969727e-05*G0_2_1_1_1 - 1.3528138528139e-05*G0_2_1_1_2 - 6.7640692640695e-06*G0_2_1_2_0 - 1.3528138528139e-05*G0_2_1_2_1 - 6.08766233766255e-05*G0_2_1_2_2 - 6.76406926406949e-06*G0_2_2_0_1 - 2.97619047619058e-05*G0_2_2_0_2 - 6.76406926406949e-06*G0_2_2_1_0 - 1.3528138528139e-05*G0_2_2_1_1 - 6.08766233766255e-05*G0_2_2_1_2 - 2.97619047619058e-05*G0_2_2_2_0 - 6.08766233766255e-05*G0_2_2_2_1 - 0.000238095238095246*G0_2_2_2_2; + A[22] = -A[31] + 1.08225108225112e-05*G0_0_0_0_0 - 2.7056277056278e-06*G0_0_0_0_1 - 9.46969696969729e-06*G0_0_0_0_2 - 2.7056277056278e-06*G0_0_0_1_0 + 4.96031746031768e-06*G0_0_0_1_1 - 6.76406926406948e-06*G0_0_0_1_2 - 9.46969696969729e-06*G0_0_0_2_0 - 6.76406926406948e-06*G0_0_0_2_1 - 2.70562770562778e-06*G0_0_0_2_2 - 2.7056277056278e-06*G0_0_1_0_0 + 4.96031746031768e-06*G0_0_1_0_1 - 6.76406926406948e-06*G0_0_1_0_2 + 4.96031746031769e-06*G0_0_1_1_0 + 0.000112283549783554*G0_0_1_1_1 - 6.76406926406948e-06*G0_0_1_2_0 - 6.76406926406947e-06*G0_0_1_2_2 - 9.4696969696973e-06*G0_0_2_0_0 - 6.76406926406948e-06*G0_0_2_0_1 - 2.70562770562779e-06*G0_0_2_0_2 - 6.76406926406948e-06*G0_0_2_1_0 - 6.76406926406947e-06*G0_0_2_1_2 - 2.70562770562779e-06*G0_0_2_2_0 - 6.76406926406946e-06*G0_0_2_2_1 + 0.000116341991341995*G0_0_2_2_2 - 2.7056277056278e-06*G0_1_0_0_0 + 4.96031746031768e-06*G0_1_0_0_1 - 6.76406926406948e-06*G0_1_0_0_2 + 4.96031746031769e-06*G0_1_0_1_0 + 0.000112283549783554*G0_1_0_1_1 - 6.76406926406948e-06*G0_1_0_2_0 - 6.76406926406947e-06*G0_1_0_2_2 + 4.96031746031769e-06*G0_1_1_0_0 + 0.000112283549783554*G0_1_1_0_1 + 0.000112283549783554*G0_1_1_1_0 + 0.00222132034632042*G0_1_1_1_1 + 0.000209686147186155*G0_1_1_1_2 + 0.000209686147186155*G0_1_1_2_1 + 6.76406926406953e-06*G0_1_1_2_2 - 6.76406926406948e-06*G0_1_2_0_0 - 6.76406926406947e-06*G0_1_2_0_2 + 0.000209686147186155*G0_1_2_1_1 + 6.76406926406954e-06*G0_1_2_1_2 - 6.76406926406947e-06*G0_1_2_2_0 + 6.76406926406952e-06*G0_1_2_2_1 + 9.46969696969731e-05*G0_1_2_2_2 - 9.46969696969729e-06*G0_2_0_0_0 - 6.76406926406948e-06*G0_2_0_0_1 - 2.70562770562778e-06*G0_2_0_0_2 - 6.76406926406948e-06*G0_2_0_1_0 - 6.76406926406947e-06*G0_2_0_1_2 - 2.70562770562779e-06*G0_2_0_2_0 - 6.76406926406947e-06*G0_2_0_2_1 + 0.000116341991341995*G0_2_0_2_2 - 6.76406926406948e-06*G0_2_1_0_0 - 6.76406926406947e-06*G0_2_1_0_2 + 0.000209686147186155*G0_2_1_1_1 + 6.76406926406954e-06*G0_2_1_1_2 - 6.76406926406947e-06*G0_2_1_2_0 + 6.76406926406953e-06*G0_2_1_2_1 + 9.4696969696973e-05*G0_2_1_2_2 - 2.70562770562778e-06*G0_2_2_0_0 - 6.76406926406947e-06*G0_2_2_0_1 + 0.000116341991341995*G0_2_2_0_2 - 6.76406926406946e-06*G0_2_2_1_0 + 6.76406926406952e-06*G0_2_2_1_1 + 9.46969696969731e-05*G0_2_2_1_2 + 0.000116341991341995*G0_2_2_2_0 + 9.4696969696973e-05*G0_2_2_2_1 + 0.00278679653679663*G0_2_2_2_2; + A[5] = -A[22] + 0.00222132034632042*G0_0_0_0_0 + 0.000112283549783554*G0_0_0_0_1 + 0.000209686147186154*G0_0_0_0_2 + 0.000112283549783554*G0_0_0_1_0 + 4.96031746031763e-06*G0_0_0_1_1 + 0.000209686147186154*G0_0_0_2_0 + 6.76406926406949e-06*G0_0_0_2_2 + 0.000112283549783554*G0_0_1_0_0 + 4.96031746031763e-06*G0_0_1_0_1 + 4.96031746031763e-06*G0_0_1_1_0 - 2.70562770562781e-06*G0_0_1_1_1 - 6.7640692640695e-06*G0_0_1_1_2 - 6.7640692640695e-06*G0_0_1_2_1 - 6.76406926406948e-06*G0_0_1_2_2 + 0.000209686147186154*G0_0_2_0_0 + 6.7640692640695e-06*G0_0_2_0_2 - 6.7640692640695e-06*G0_0_2_1_1 - 6.76406926406948e-06*G0_0_2_1_2 + 6.76406926406949e-06*G0_0_2_2_0 - 6.76406926406948e-06*G0_0_2_2_1 + 9.4696969696973e-05*G0_0_2_2_2 + 0.000112283549783554*G0_1_0_0_0 + 4.96031746031763e-06*G0_1_0_0_1 + 4.96031746031763e-06*G0_1_0_1_0 - 2.70562770562781e-06*G0_1_0_1_1 - 6.7640692640695e-06*G0_1_0_1_2 - 6.7640692640695e-06*G0_1_0_2_1 - 6.76406926406948e-06*G0_1_0_2_2 + 4.96031746031763e-06*G0_1_1_0_0 - 2.70562770562781e-06*G0_1_1_0_1 - 6.7640692640695e-06*G0_1_1_0_2 - 2.70562770562781e-06*G0_1_1_1_0 + 1.08225108225111e-05*G0_1_1_1_1 - 9.46969696969732e-06*G0_1_1_1_2 - 6.7640692640695e-06*G0_1_1_2_0 - 9.46969696969732e-06*G0_1_1_2_1 - 2.7056277056278e-06*G0_1_1_2_2 - 6.7640692640695e-06*G0_1_2_0_1 - 6.76406926406948e-06*G0_1_2_0_2 - 6.7640692640695e-06*G0_1_2_1_0 - 9.46969696969732e-06*G0_1_2_1_1 - 2.7056277056278e-06*G0_1_2_1_2 - 6.76406926406948e-06*G0_1_2_2_0 - 2.7056277056278e-06*G0_1_2_2_1 + 0.000116341991341995*G0_1_2_2_2 + 0.000209686147186154*G0_2_0_0_0 + 6.7640692640695e-06*G0_2_0_0_2 - 6.7640692640695e-06*G0_2_0_1_1 - 6.76406926406948e-06*G0_2_0_1_2 + 6.76406926406948e-06*G0_2_0_2_0 - 6.76406926406948e-06*G0_2_0_2_1 + 9.4696969696973e-05*G0_2_0_2_2 - 6.7640692640695e-06*G0_2_1_0_1 - 6.76406926406948e-06*G0_2_1_0_2 - 6.7640692640695e-06*G0_2_1_1_0 - 9.46969696969732e-06*G0_2_1_1_1 - 2.7056277056278e-06*G0_2_1_1_2 - 6.76406926406948e-06*G0_2_1_2_0 - 2.7056277056278e-06*G0_2_1_2_1 + 0.000116341991341995*G0_2_1_2_2 + 6.76406926406949e-06*G0_2_2_0_0 - 6.76406926406948e-06*G0_2_2_0_1 + 9.4696969696973e-05*G0_2_2_0_2 - 6.76406926406948e-06*G0_2_2_1_0 - 2.7056277056278e-06*G0_2_2_1_1 + 0.000116341991341995*G0_2_2_1_2 + 9.4696969696973e-05*G0_2_2_2_0 + 0.000116341991341995*G0_2_2_2_1 + 0.00278679653679663*G0_2_2_2_2; + A[13] = A[31]; + A[50] = A[5]; + A[79] = A[97]; + A[38] = A[83]; + A[20] = A[2]; + A[18] = A[81]; + A[88] = A[77] - 0.00657467532467556*G0_0_0_0_0 - 0.00164366883116889*G0_0_0_0_1 - 0.000547889610389629*G0_0_0_0_2 - 0.00164366883116889*G0_0_0_1_0 - 0.000109577922077926*G0_0_0_1_2 - 0.000547889610389629*G0_0_0_2_0 - 0.000109577922077926*G0_0_0_2_1 - 7.30519480519505e-05*G0_0_0_2_2 - 0.00164366883116889*G0_0_1_0_0 - 0.000109577922077926*G0_0_1_0_2 + 0.00164366883116889*G0_0_1_1_1 + 0.000109577922077926*G0_0_1_1_2 - 0.000109577922077926*G0_0_1_2_0 + 0.000109577922077926*G0_0_1_2_1 - 0.000547889610389629*G0_0_2_0_0 - 0.000109577922077926*G0_0_2_0_1 - 7.30519480519505e-05*G0_0_2_0_2 - 0.000109577922077926*G0_0_2_1_0 + 0.000109577922077926*G0_0_2_1_1 - 7.30519480519504e-05*G0_0_2_2_0 - 0.00164366883116889*G0_1_0_0_0 - 0.000109577922077926*G0_1_0_0_2 + 0.00164366883116889*G0_1_0_1_1 + 0.000109577922077926*G0_1_0_1_2 - 0.000109577922077926*G0_1_0_2_0 + 0.000109577922077926*G0_1_0_2_1 + 0.00164366883116889*G0_1_1_0_1 + 0.000109577922077926*G0_1_1_0_2 + 0.00164366883116889*G0_1_1_1_0 + 0.00657467532467556*G0_1_1_1_1 + 0.000547889610389629*G0_1_1_1_2 + 0.000109577922077926*G0_1_1_2_0 + 0.000547889610389629*G0_1_1_2_1 + 7.30519480519506e-05*G0_1_1_2_2 - 0.000109577922077926*G0_1_2_0_0 + 0.000109577922077926*G0_1_2_0_1 + 0.000109577922077926*G0_1_2_1_0 + 0.000547889610389629*G0_1_2_1_1 + 7.30519480519506e-05*G0_1_2_1_2 + 7.30519480519505e-05*G0_1_2_2_1 - 0.000547889610389629*G0_2_0_0_0 - 0.000109577922077926*G0_2_0_0_1 - 7.30519480519505e-05*G0_2_0_0_2 - 0.000109577922077926*G0_2_0_1_0 + 0.000109577922077926*G0_2_0_1_1 - 7.30519480519504e-05*G0_2_0_2_0 - 0.000109577922077926*G0_2_1_0_0 + 0.000109577922077926*G0_2_1_0_1 + 0.000109577922077926*G0_2_1_1_0 + 0.000547889610389629*G0_2_1_1_1 + 7.30519480519506e-05*G0_2_1_1_2 + 7.30519480519506e-05*G0_2_1_2_1 - 7.30519480519504e-05*G0_2_2_0_0 + 7.30519480519506e-05*G0_2_2_1_1; + A[43] = A[34]; + A[95] = A[59]; + A[52] = A[25]; + } + + /// 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 mass_matrix_f4_p1_q3_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f4_p1_q3_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_p1_q3_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 3, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 3), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1))))), 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 4; + } + + /// 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 mass_matrix_f4_p1_q3_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f4_p1_q3_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f4_p1_q3_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f4_p1_q3_tensor_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f4_p1_q3_tensor_finite_element_0(); + break; + } + case 5: + { + return new mass_matrix_f4_p1_q3_tensor_finite_element_0(); + 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 mass_matrix_f4_p1_q3_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f4_p1_q3_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f4_p1_q3_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f4_p1_q3_tensor_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f4_p1_q3_tensor_dofmap_0(); + break; + } + case 5: + { + return new mass_matrix_f4_p1_q3_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f4_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/mass_matrix_2d/mass_matrix_f4_p1_q4_excafe.h b/mass_matrix_2d/mass_matrix_f4_p1_q4_excafe.h new file mode 100644 index 0000000..cb6ee65 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f4_p1_q4_excafe.h @@ -0,0 +1,639 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 11 minutes and 16.67 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[1][2]*w[3][1] + w[1][1]*w[3][2]; + const double var_1 = w[1][0]*w[3][1] + w[1][1]*w[3][0]; + const double var_2 = w[1][0]*w[3][2] + w[1][2]*w[3][0]; + const double var_3 = var_0*w[0][0] + var_2*w[0][1] + var_1*w[0][2]; + const double var_4 = w[0][2]*w[2][0] + w[0][0]*w[2][2]; + const double var_5 = var_1*w[2][2]; + const double var_6 = var_0*w[2][0]; + const double var_7 = var_5 + var_6; + const double var_8 = var_3*w[2][1] + var_7*w[0][1] + var_4*w[1][1]*w[3][1]; + const double var_9 = w[0][0]*w[1][2]*w[2][0]*w[3][2] + w[0][2]*w[1][0]*w[2][2]*w[3][0] + var_2*var_4; + const double var_10 = w[0][1]*w[1][1]*w[2][1]*w[3][1]; + const double var_11 = 0.0088888888888888888811790*var_9 + -0.0010884353741496598320243*var_8 + -0.0408163265306122416409274*var_10; + const double var_12 = -1.0000000000000000000000000*x[0][0]; + const double var_13 = x[1][0] + var_12; + const double var_14 = -1.0000000000000000000000000*x[0][1]; + const double var_15 = var_14 + x[2][1]; + const double var_16 = x[2][0] + var_12; + const double var_17 = var_14 + x[1][1]; + const double var_18 = -1.0000000000000000000000000*var_16*var_17 + var_13*var_15; + const double var_19 = std::abs(var_18); + const double var_20 = w[0][1]*w[2][2] + w[0][2]*w[2][1]; + const double var_21 = w[0][1]*w[1][2]*w[2][1]*w[3][2] + var_0*var_20 + w[0][2]*w[1][1]*w[2][2]*w[3][1]; + const double var_22 = w[0][0]*w[2][1] + w[0][1]*w[2][0]; + const double var_23 = var_1*var_22 + w[0][1]*w[1][0]*w[2][1]*w[3][0] + w[0][0]*w[1][1]*w[2][0]*w[3][1]; + const double var_24 = var_21 + var_23; + const double var_25 = var_22*w[1][1]*w[3][1] + var_1*w[0][1]*w[2][1]; + const double var_26 = var_0*w[0][1]*w[2][1] + var_20*w[1][1]*w[3][1]; + const double var_27 = var_26 + var_25; + const double var_28 = var_0*w[0][2]*w[2][2] + var_20*w[1][2]*w[3][2]; + const double var_29 = var_1*w[0][0]*w[2][0] + var_22*w[1][0]*w[3][0]; + const double var_30 = var_28 + var_29; + const double var_31 = var_2*w[0][2]*w[2][2] + var_4*w[1][2]*w[3][2]; + const double var_32 = var_4*w[1][0]*w[3][0] + var_2*w[0][0]*w[2][0]; + const double var_33 = var_31 + var_32; + const double var_34 = w[0][0]*w[1][0]*w[2][0]*w[3][0]; + const double var_35 = w[0][2]*w[1][2]*w[2][2]*w[3][2]; + const double var_36 = var_34 + var_35; + const double var_37 = var_2*w[2][1]; + const double var_38 = var_5 + var_37; + const double var_39 = var_20*w[1][0]*w[3][0] + var_3*w[2][0] + var_38*w[0][0]; + const double var_40 = var_37 + var_6; + const double var_41 = var_40*w[0][2] + var_3*w[2][2] + var_22*w[1][2]*w[3][2]; + const double var_42 = var_41 + var_39; + const double var_43 = 5399.0000000000000000000000000*w[0][1]*w[1][1]*w[2][1]*w[3][1] + 5.9166666666666660745477202*var_42 + 17.7500000000000000000000000*var_30 + 218.5000000000000000000000000*var_27 + 14.5666666666666664298190881*var_9 + 11.8333333333333321490954404*var_8 + 23.6666666666666642981908808*var_24 + 87.4000000000000056843418861*var_36 + 21.8500000000000014210854715*var_33; + A[16] = 0.0000003083336416669750059*var_19*var_43; + const double var_44 = -1.0000000000000000000000000*var_31; + const double var_45 = 0.0004884004884004884000648*var_34 + -0.0056980056980056982898764*var_21 + -0.0018396418396418394956837*var_39; + const double var_46 = -1.0000000000000000000000000*var_10; + const double var_47 = 0.0190476190476190493372499*var_46 + -0.0120797720797720786051199*var_9 + -0.0020350020350020348557096*var_8; + const double var_48 = 4.8034188034188041172001249*w[0][2]*w[1][2]*w[2][2]*w[3][2] + 0.0888888888888888922812370*var_41 + 0.0417582417582417556034535*var_23; + const double var_49 = -0.0666666666666666657414808*var_48; + const double var_50 = 0.0512820512820512802720785*var_44 + -0.0032885632885632882713156*var_32 + var_45 + -0.0056654456654456654407515*var_25 + var_47 + var_49 + -0.0044607244607244604314711*var_26 + -0.0017582417582417582402332*var_29 + -0.0330484330484330443566954*var_28; + A[68] = 0.0086580086580086580011484*var_19*var_50; + const double var_51 = 0.0049432049432049426224145*w[0][2]*w[1][2]*w[2][2]*w[3][2] + 0.0000735772164343593030548*var_23 + 0.0000740000740000739954923*var_41; + const double var_52 = var_31 + var_25; + const double var_53 = var_28 + var_26; + const double var_54 = 53.0000000000000000000000000*w[0][1]*w[1][1]*w[2][1]*w[3][1]; + const double var_55 = -0.0322943722943722921758791*var_9 + -0.0126406926406926415490384*var_8 + -0.0095238095238095246686250*var_54; + const double var_56 = -1.0000000000000000000000000*var_8; + const double var_57 = -0.0133333333333333341891302*var_9 + 1.5948051948051948922824295*w[0][1]*w[1][1]*w[2][1]*w[3][1] + 0.0017316017316017316002297*var_56; + const double var_58 = -1.0000000000000000000000000*var_29; + const double var_59 = var_35 + var_32; + const double var_60 = -1.0000000000000000000000000*var_21; + const double var_61 = -1.0000000000000000000000000*var_34; + const double var_62 = 0.1333333333333333314829616*var_61 + 0.0017316017316017316002297*var_60 + -0.0064935064935064939345422*var_39; + const double var_63 = -1.0000000000000000000000000*var_23; + const double var_64 = -1.0000000000000000000000000*var_41; + const double var_65 = 0.0051948051948051948006890*var_63 + 0.0043290043290043290005742*var_64; + const double var_66 = var_26 + 2.0000000000000000000000000*var_25; + const double var_67 = 0.0510822510822510830741372*var_66 + var_65 + 0.0259740259740259757381686*var_58 + -0.0133333333333333341891302*var_31 + var_62 + var_57 + -0.0064935064935064939345422*var_28 + -0.0266666666666666683782605*var_59; + A[26] = 0.0009496676163342830483127*var_19*var_67; + const double var_68 = -0.0194916194916194933373088*w[0][2]*w[1][2]*w[2][2]*w[3][2] + 0.0000621600621600621600082*var_23 + -0.0007414807414807414800983*var_41; + const double var_69 = -1.0000000000000000000000000*var_28; + const double var_70 = -1.0000000000000000000000000*var_26; + const double var_71 = 0.0003996003996003996000530*var_64 + -0.0158508158508158525368259*var_35 + 0.0010922410922410922401449*var_23; + const double var_72 = -1.0000000000000000000000000*var_9; + const double var_73 = 0.0014652014652014652001943*var_46 + 0.0003463203463203463200459*var_72 + 0.0001065601065601065600141*var_8; + const double var_74 = 0.8857142857142856762209249*w[0][0]*w[1][0]*w[2][0]*w[3][0]; + const double var_75 = 0.0001998001998001998000265*var_39; + const double var_76 = -0.0009057609057609057601201*var_21 + 0.0046620046620046620006184*var_74 + var_75; + const double var_77 = var_71 + 0.0018648018648018648002473*var_44 + 0.0004262404262404262400565*var_32 + 0.0006660006660006660000883*var_25 + var_76 + 0.0037296037296037296004947*var_69 + var_73 + 0.0017848817848817848802367*var_29 + 0.0001332001332001332000177*var_70; + A[87] = 0.0846560846560846513852994*var_19*var_77; + A[185] = A[87]; + const double var_78 = 0.0000735772164343593030548*var_21 + 0.0049432049432049426224145*w[0][0]*w[1][0]*w[2][0]*w[3][0] + 0.0000740000740000739954923*var_39; + const double var_79 = 0.0000769600769600769645277*var_9 + 0.0000579314865029150730027*var_8 + 0.0018648018648018648002473*var_10; + const double var_80 = 0.0000228343085485942623762*var_35 + 0.0000264285978571692870085*var_41 + 0.0001302401302401302309823*var_23; + const double var_81 = 0.0004292004292004291819869*var_32 + 0.0000238914524628810341275*var_31 + var_80 + 0.0003150288864574578599417*var_25 + 0.0002473716759431045220628*var_26 + var_78 + 0.0005772005772005772000766*var_29 + 0.0000361543218686075857661*var_28 + var_79; + A[145] = -0.6666666666666666296592325*var_19*var_81; + const double var_82 = -1.0000000000000000000000000*var_25; + const double var_83 = 0.0067741782027496309434578*w[0][0]*w[1][0]*w[2][0]*w[3][0] + 0.0002014652014652014650267*var_39; + const double var_84 = 4.0000000000000000000000000*w[0][2]*w[1][2]*w[2][2]*w[3][2]; + const double var_85 = 0.0000019028590457161886019*var_84 + 0.0000832500832500832500110*var_41; + const double var_86 = 0.6666666666666666296592325*var_8 + var_24; + const double var_87 = 0.2435374149659863818317973*var_9 + 0.0285714285714285705364279*var_86 + -20.6666666666666642981908808*w[0][1]*w[1][1]*w[2][1]*w[3][1]; + const double var_88 = 0.0013986013986013986001855*var_87; + const double var_89 = var_85 + 0.0021645021645021645002871*var_82 + 0.0010180295894581608238949*var_32 + 0.0001722087436373150579928*var_31 + var_88 + -0.0009823509823509823501303*var_26 + 0.0011122211122211122201475*var_29 + 0.0000482850482850482850064*var_28 + var_83; + const double var_90 = 0.0203174603174603174426949*var_21 + -0.0019536019536019536002591*w[0][0]*w[1][0]*w[2][0]*w[3][0] + 0.0004395604395604395600583*var_39; + const double var_91 = -1.0000000000000000000000000*var_32; + const double var_92 = 0.0097680097680097680012956*var_72 + 0.0058608058608058608007774*var_8 + 0.0683760683760683829479632*var_10; + const double var_93 = -1.0000000000000000000000000*var_35; + const double var_94 = 0.0001953601953601953600259*var_41 + 0.0062515262515262515208292*var_23 + 0.1230769230769230837552186*var_93; + const double var_95 = var_90 + 0.0273504273504273504036277*var_44 + 0.0046886446886446886406219*var_91 + 0.0166056166056166056022025*var_25 + 0.0278388278388278405384160*var_26 + 0.0025396825396825396803369*var_29 + var_92 + 0.0034188034188034188004535*var_28 + var_94; + A[74] = 0.0173160173160173160022968*var_19*var_95; + A[214] = A[74]; + const double var_96 = 0.0003108003108003108000412*var_34 + 0.0003488574917146345559862*var_21 + 0.0000247371675943104528839*var_39; + const double var_97 = 0.0014652014652014652001943*var_61 + 0.0001065601065601065600141*var_39 + 0.0003463203463203463200459*var_60; + const double var_98 = 0.8857142857142856762209249*w[0][1]*w[1][1]*w[2][1]*w[3][1]; + const double var_99 = 0.0001998001998001998000265*var_8; + const double var_100 = 0.0046620046620046620006184*var_98 + -0.0009057609057609057601201*var_9 + var_99; + const double var_101 = var_71 + 0.0037296037296037296004947*var_44 + 0.0001332001332001332000177*var_91 + 0.0017848817848817848802367*var_25 + var_100 + 0.0018648018648018648002473*var_69 + 0.0004262404262404262400565*var_26 + 0.0006660006660006660000883*var_29 + var_97; + A[133] = 0.0846560846560846513852994*var_101*var_19; + A[203] = A[133]; + const double var_102 = 17.0000000000000000000000000*w[0][2]*w[1][2]*w[2][2]*w[3][2]; + const double var_103 = 0.0003996003996003996000530*var_63 + 0.0004262404262404262400565*var_41 + 0.0009324009324009324001237*var_102; + const double var_104 = 0.0417582417582417556034535*var_9 + 0.0888888888888888922812370*var_8 + 4.8034188034188041172001249*w[0][1]*w[1][1]*w[2][1]*w[3][1]; + const double var_105 = 2.0000000000000000000000000*var_30 + var_42; + const double var_106 = var_36 + 0.4000000000000000222044605*var_33; + const double var_107 = 0.0290598290598290606712162*var_105 + 0.1391941391941391992226329*var_106 + var_104 + 0.6324786324786325630853412*var_27 + 0.1333333333333333314829616*var_24; + const double var_108 = -0.0029748029748029748003946*w[0][2]*w[1][2]*w[2][2]*w[3][2] + 0.0000380571809143237694975*var_41 + 0.0000247371675943104528839*var_23; + const double var_109 = var_29 + var_25; + const double var_110 = 0.0000190285904571618847488*var_21 + 0.0000615257758114901010232*var_39; + const double var_111 = -1.0000000000000000000000000*var_27; + const double var_112 = var_33 + var_56; + const double var_113 = -0.0002220002220002220000294*w[0][1]*w[1][1]*w[2][1]*w[3][1] + -0.0000133200133200133200018*var_42 + -0.0003774003774003774000501*var_30 + 0.0000666000666000666000088*var_112 + 0.0001998001998001998000265*var_111 + 0.0001953601953601953600259*var_9 + -0.0002308802308802308800306*var_24 + -0.0009324009324009324001237*var_36; + const double var_114 = var_35 + var_10; + const double var_115 = var_114 + 0.4000000000000000222044605*var_53; + const double var_116 = -0.0019536019536019536002591*w[0][2]*w[1][2]*w[2][2]*w[3][2] + 0.0004395604395604395600583*var_41 + 0.0203174603174603174426949*var_23; + const double var_117 = -0.0056980056980056982898764*var_9 + -0.0018396418396418394956837*var_8 + 0.0004884004884004884000648*var_10; + const double var_118 = 0.0190476190476190493372499*var_61 + -0.0120797720797720786051199*var_21 + -0.0020350020350020348557096*var_39; + const double var_119 = -0.0044607244607244604314711*var_32 + -0.0330484330484330443566954*var_31 + var_118 + -0.0017582417582417582402332*var_25 + 0.0512820512820512802720785*var_69 + var_49 + -0.0032885632885632882713156*var_26 + -0.0056654456654456654407515*var_29 + var_117; + A[82] = 0.0086580086580086580011484*var_119*var_19; + A[110] = A[82]; + const double var_120 = 0.0067741782027496309434578*w[0][2]*w[1][2]*w[2][2]*w[3][2] + 0.0002014652014652014650267*var_41; + const double var_121 = 4.0000000000000000000000000*w[0][1]*w[1][1]*w[2][1]*w[3][1]; + const double var_122 = 0.0000832500832500832500110*var_8 + 0.0000019028590457161886019*var_121; + const double var_123 = var_9 + var_23; + const double var_124 = var_123 + 0.6666666666666666296592325*var_39; + const double var_125 = 0.2435374149659863818317973*var_21 + -20.6666666666666642981908808*w[0][0]*w[1][0]*w[2][0]*w[3][0] + 0.0285714285714285705364279*var_124; + const double var_126 = 0.0013986013986013986001855*var_125; + const double var_127 = 0.0011122211122211122201475*var_31 + var_122 + 0.0021645021645021645002871*var_91 + var_120 + 0.0000482850482850482850064*var_25 + var_126 + 0.0001722087436373150579928*var_26 + -0.0009823509823509823501303*var_29 + 0.0010180295894581608238949*var_28; + const double var_128 = 0.0004884004884004884000648*var_35 + -0.0018396418396418394956837*var_41 + -0.0056980056980056982898764*var_23; + const double var_129 = 0.0417582417582417556034535*var_21 + 4.8034188034188041172001249*w[0][0]*w[1][0]*w[2][0]*w[3][0] + 0.0888888888888888922812370*var_39; + const double var_130 = -0.0666666666666666657414808*var_129; + const double var_131 = -0.0032885632885632882713156*var_31 + 0.0512820512820512802720785*var_91 + -0.0044607244607244604314711*var_25 + var_47 + var_128 + -0.0056654456654456654407515*var_26 + var_130 + -0.0330484330484330443566954*var_29 + -0.0017582417582417582402332*var_28; + A[100] = 0.0086580086580086580011484*var_131*var_19; + const double var_132 = var_28 + var_31; + const double var_133 = -0.0018648018648018648002473*var_132 + 0.0003463203463203463200459*var_64 + 0.0017848817848817848802367*var_23 + 0.0102564102564102564013604*var_93; + const double var_134 = 17.0000000000000000000000000*w[0][1]*w[1][1]*w[2][1]*w[3][1]; + const double var_135 = 0.0003996003996003996000530*var_72 + 0.0004262404262404262400565*var_8 + 0.0009324009324009324001237*var_134; + const double var_136 = 0.0006660006660006660000883*var_34 + 0.0005860805860805860800777*var_60 + var_75; + const double var_137 = 0.0001065601065601065600141*var_32 + 0.0041292041292041292005477*var_25 + var_136 + 0.0014652014652014652001943*var_26 + var_133 + 0.0010922410922410922401449*var_29 + var_135; + A[88] = 0.0846560846560846513852994*var_137*var_19; + const double var_138 = var_29 + var_32; + const double var_139 = 19.0000000000000000000000000*w[0][0]*w[1][0]*w[2][0]*w[3][0]; + const double var_140 = var_138 + 0.4000000000000000222044605*var_39 + -1.0000000000000000000000000*var_139; + const double var_141 = -0.0028105228105228105203728*var_21 + 0.0003108003108003108000412*var_140; + const double var_142 = 0.0003108003108003108000412*var_9 + -0.0004395604395604395600583*var_8 + 0.0000444000444000444000059*var_134; + const double var_143 = -0.0020868020868020868002768*var_31 + var_141 + -0.0002752802752802752800365*var_25 + var_68 + var_142 + -0.0017227217227217227202285*var_26 + -0.0057720057720057720007656*var_28; + A[14] = 0.0158730158730158721347436*var_143*var_19; + A[210] = A[14]; + const double var_144 = var_9 + var_21; + const double var_145 = var_26 + var_32; + const double var_146 = var_34 + var_10; + const double var_147 = var_8 + var_39; + const double var_148 = -0.0822510822510822553477183*var_146 + -0.0065800865800865800808728*var_109 + 0.0016450216450216450202182*var_23 + -0.0541991341991341982198271*var_145 + 1.1939393939393938559589969*w[0][2]*w[1][2]*w[2][2]*w[3][2] + -0.0410389610389610415275286*var_144 + -0.0038095238095238095205053*var_41 + 0.0666666666666666657414808*var_132 + -0.0083982683982683978274331*var_147; + A[67] = 0.0012210012210012210001620*var_148*var_19; + const double var_149 = -0.0432900432900432882710184*var_41 + -2.2606060606060607298672949*var_35 + -0.0044155844155844160142665*var_23; + const double var_150 = -0.1017316017316017284777274*var_21 + -0.0083116883116883116811024*var_39 + 0.0060606060606060606008039*var_139; + const double var_151 = 2.0000000000000000000000000*var_29 + var_32; + const double var_152 = var_26 + 0.6666666666666666296592325*var_25; + const double var_153 = -0.2268398268398268413648111*var_31 + -0.0024242424242424242403215*var_151 + var_150 + var_149 + -0.0644155844155844120590970*var_152 + -0.4155844155844156118106980*var_28 + var_55; + const double var_154 = var_9 + var_24; + const double var_155 = 0.0000270628842057413493817*var_154*var_19; + const double var_156 = 0.0203174603174603174426949*var_9 + -0.0019536019536019536002591*w[0][1]*w[1][1]*w[2][1]*w[3][1] + 0.0004395604395604395600583*var_8; + const double var_157 = 2.2020202020202019888017730*w[0][2]*w[1][2]*w[2][2]*w[3][2] + 0.0415584415584415584055122*var_41 + 0.0106782106782106790687781*var_23; + const double var_158 = var_28 + var_10; + const double var_159 = 17.0000000000000000000000000*w[0][0]*w[1][0]*w[2][0]*w[3][0]; + const double var_160 = 0.0028860028860028860003828*var_159 + 0.0352092352092352109393936*var_21 + 0.0106782106782106790687781*var_39; + const double var_161 = 0.0917748917748917730774494*var_9 + 0.0124098124098124106690078*var_8; + const double var_162 = 0.3838383838383838675412107*var_31 + 0.0248196248196248213380155*var_32 + var_157 + var_160 + var_161 + 0.0415584415584415584055122*var_25 + 0.0352092352092352109393936*var_26 + 0.0069264069264069264009187*var_29 + 0.2222222222222222098864108*var_158; + A[53] = 0.0006512006512006512362264*var_162*var_19; + const double var_163 = var_41 + var_8; + const double var_164 = 218.5000000000000000000000000*var_138 + 5.9166666666666660745477202*var_163 + 21.8500000000000014210854715*var_53 + 87.4000000000000056843418861*var_114 + 14.5666666666666664298190881*var_21 + 5399.0000000000000000000000000*w[0][0]*w[1][0]*w[2][0]*w[3][0] + 11.8333333333333321490954404*var_39 + 23.6666666666666642981908808*var_123 + 17.7500000000000000000000000*var_52; + const double var_165 = 0.0000621600621600621600082*var_21 + -0.0194916194916194933373088*w[0][0]*w[1][0]*w[2][0]*w[3][0] + -0.0007414807414807414800983*var_39; + const double var_166 = 19.0000000000000000000000000*w[0][2]*w[1][2]*w[2][2]*w[3][2]; + const double var_167 = var_132 + -1.0000000000000000000000000*var_166 + 0.4000000000000000222044605*var_41; + const double var_168 = -0.0028105228105228105203728*var_23 + 0.0003108003108003108000412*var_167; + const double var_169 = -0.0020868020868020868002768*var_32 + -0.0017227217227217227202285*var_25 + var_142 + var_168 + -0.0002752802752802752800365*var_26 + -0.0057720057720057720007656*var_29 + var_165; + const double var_170 = 0.0003463203463203463200459*var_63 + 0.0001065601065601065600141*var_41 + 0.0014652014652014652001943*var_93; + const double var_171 = 0.0106782106782106790687781*var_21 + 2.2020202020202019888017730*w[0][0]*w[1][0]*w[2][0]*w[3][0] + 0.0415584415584415584055122*var_39; + const double var_172 = -1.0000000000000000000000000*var_39; + const double var_173 = var_53 + var_172; + const double var_174 = -0.0133333333333333341891302*var_21 + 1.5948051948051948922824295*w[0][0]*w[1][0]*w[2][0]*w[3][0] + 0.0017316017316017316002297*var_172; + const double var_175 = 0.0017316017316017316002297*var_63 + -0.0064935064935064939345422*var_41 + 0.1333333333333333314829616*var_93; + const double var_176 = 0.0051948051948051948006890*var_72 + 0.0043290043290043290005742*var_56; + const double var_177 = var_29 + 2.0000000000000000000000000*var_32; + const double var_178 = var_176 + 0.0259740259740259757381686*var_44 + var_175 + -0.0064935064935064939345422*var_25 + 0.0510822510822510830741372*var_177 + -0.0133333333333333341891302*var_26 + var_174 + -0.0266666666666666683782605*var_158; + A[6] = 0.0009496676163342830483127*var_178*var_19; + A[90] = A[6]; + const double var_179 = 0.0556776556776556810768319*var_9 + 0.1333333333333333314829616*var_8 + 9.6068376068376082344002498*w[0][1]*w[1][1]*w[2][1]*w[3][1]; + const double var_180 = 0.0290598290598290606712162*var_41 + 0.0556776556776556810768319*var_35 + 0.5333333333333333259318465*var_23; + const double var_181 = 0.8351648351648351953357974*var_34 + 0.0888888888888888922812370*var_21 + 0.0581196581196581213424324*var_39; + const double var_182 = var_179 + 0.1391941391941391992226329*var_32 + 0.0417582417582417556034535*var_31 + 1.8974358974358973561891162*var_25 + var_181 + 0.6324786324786325630853412*var_26 + 0.2905982905982906205899496*var_29 + 0.0290598290598290606712162*var_28 + var_180; + A[176] = 0.0007696007696007695639620*var_182*var_19; + const double var_183 = 0.0016161616161616161602144*var_72 + -0.0107647907647907652151087*var_8 + -0.7434343434343434475763956*w[0][1]*w[1][1]*w[2][1]*w[3][1]; + const double var_184 = 4.0000000000000000000000000*w[0][0]*w[1][0]*w[2][0]*w[3][0]; + const double var_185 = -0.0144300144300144300019140*var_21 + 0.2909090909090908949607979*var_184 + 0.0008080808080808080801072*var_172; + const double var_186 = 0.8857142857142856762209249*w[0][2]*w[1][2]*w[2][2]*w[3][2]; + const double var_187 = -0.0027705627705627705603675*var_41 + 0.0032323232323232323204287*var_23 + -0.0161616161616161616021436*var_186; + const double var_188 = -0.0014718614718614718601952*var_31 + 0.0383838383838383812030060*var_32 + -0.0851948051948051982007470*var_25 + -0.0756132756132756184141996*var_26 + -0.0042135642135642135605589*var_28 + 0.0888888888888888922812370*var_29 + var_183 + var_185 + var_187; + A[11] = 0.0004070004070004069819839*var_188*var_19; + A[165] = A[11]; + const double var_189 = 0.0017316017316017316002297*var_64 + 1.5948051948051948922824295*w[0][2]*w[1][2]*w[2][2]*w[3][2] + -0.0133333333333333341891302*var_23; + const double var_190 = var_29 + var_10; + const double var_191 = var_28 + 2.0000000000000000000000000*var_31; + const double var_192 = var_176 + var_62 + -0.0266666666666666683782605*var_190 + 0.0259740259740259757381686*var_91 + -0.0133333333333333341891302*var_25 + var_189 + -0.0064935064935064939345422*var_26 + 0.0510822510822510830741372*var_191; + A[38] = 0.0009496676163342830483127*var_19*var_192; + const double var_193 = var_132 + var_147 + var_144; + const double var_194 = 0.0106782106782106790687781*var_41 + 0.0352092352092352109393936*var_23 + 0.0028860028860028860003828*var_102; + const double var_195 = var_171 + 0.0248196248196248213380155*var_31 + 0.3838383838383838675412107*var_32 + 0.2222222222222222098864108*var_190 + var_161 + 0.0352092352092352109393936*var_25 + var_194 + 0.0415584415584415584055122*var_26 + 0.0069264069264069264009187*var_28; + A[101] = 0.0006512006512006512362264*var_19*var_195; + const double var_196 = 0.0010922410922410922401449*var_9 + 0.0003996003996003996000530*var_56 + -0.0158508158508158525368259*var_10; + const double var_197 = var_196 + 0.0018648018648018648002473*var_82 + 0.0017848817848817848802367*var_32 + 0.0006660006660006660000883*var_31 + var_170 + var_76 + 0.0001332001332001332000177*var_69 + 0.0004262404262404262400565*var_29 + 0.0037296037296037296004947*var_70; + const double var_198 = var_145 + var_35; + const double var_199 = 0.1025641025641025605441570*var_146 + -0.2124542124542124488240091*var_109 + -0.2402930402930402997707660*var_23 + -0.0498168498168498202760546*var_193 + -0.0439560439560439594752772*var_198 + -0.0285714285714285705364279*var_41; + A[164] = 0.0011544011544011544001531*var_19*var_199; + A[220] = A[164]; + const double var_200 = 0.0000735772164343593030548*var_9 + 0.0000740000740000739954923*var_8 + 0.0049432049432049426224145*w[0][1]*w[1][1]*w[2][1]*w[3][1]; + const double var_201 = 0.0000228343085485942623762*var_34 + 0.0001302401302401302309823*var_21 + 0.0000264285978571692870085*var_39; + const double var_202 = 0.0018648018648018648002473*var_35 + 0.0000769600769600769645277*var_23 + 0.0000579314865029150730027*var_41; + const double var_203 = var_200 + 0.0000361543218686075857661*var_32 + 0.0002473716759431045220628*var_31 + var_201 + 0.0004292004292004291819869*var_25 + 0.0005772005772005772000766*var_26 + 0.0000238914524628810341275*var_29 + 0.0003150288864574578599417*var_28 + var_202; + A[49] = -0.6666666666666666296592325*var_19*var_203; + A[63] = A[49]; + const double var_204 = 0.0011047153904296760397463*var_53 + 0.0009419152276295134204251*var_163 + 0.0052910052910052907115812*var_138 + 0.0022094307808593520794926*var_114 + 0.0008837723123437409402173*var_21 + 0.0017791732077446363764761*var_39 + 0.0170940170940170957369908*var_34 + 0.0023722309436595150240745*var_123 + 0.0015698587127158556645684*var_52; + A[192] = 0.5818181818181817899215957*var_19*var_204; + const double var_205 = 0.0001998001998001998000265*var_41; + const double var_206 = var_205 + -0.0009057609057609057601201*var_23 + 0.0046620046620046620006184*var_186; + const double var_207 = 0.0037296037296037296004947*var_82 + var_196 + 0.0006660006660006660000883*var_32 + 0.0001332001332001332000177*var_58 + 0.0017848817848817848802367*var_31 + var_206 + 0.0004262404262404262400565*var_28 + 0.0018648018648018648002473*var_70 + var_97; + A[179] = 0.0846560846560846513852994*var_19*var_207; + const double var_208 = 0.0022094307808593520794926*var_146 + 0.0011047153904296760397463*var_109 + 0.0008837723123437409402173*var_23 + 0.0015698587127158556645684*var_145 + 0.0023722309436595150240745*var_144 + 0.0017791732077446363764761*var_41 + 0.0170940170940170957369908*var_35 + 0.0009419152276295134204251*var_147 + 0.0052910052910052907115812*var_132; + const double var_209 = 0.0000247371675943104528839*var_9 + 0.0000380571809143237694975*var_8 + -0.0029748029748029748003946*w[0][1]*w[1][1]*w[2][1]*w[3][1]; + const double var_210 = 0.0001302401302401302309823*var_9 + 0.0000264285978571692870085*var_8 + 0.0000228343085485942623762*var_10; + const double var_211 = 0.0018648018648018648002473*var_34 + 0.0000769600769600769645277*var_21 + 0.0000579314865029150730027*var_39; + const double var_212 = 0.0005772005772005772000766*var_31 + 0.0003150288864574578599417*var_32 + 0.0000361543218686075857661*var_25 + var_51 + var_210 + 0.0000238914524628810341275*var_26 + 0.0002473716759431045220628*var_29 + 0.0004292004292004291819869*var_28 + var_211; + A[113] = -0.6666666666666666296592325*var_19*var_212; + A[127] = A[113]; + const double var_213 = 53.0000000000000000000000000*w[0][0]*w[1][0]*w[2][0]*w[3][0]; + const double var_214 = -0.0322943722943722921758791*var_21 + -0.0126406926406926415490384*var_39 + -0.0095238095238095246686250*var_213; + const double var_215 = 19.0000000000000000000000000*w[0][1]*w[1][1]*w[2][1]*w[3][1]; + const double var_216 = -0.1017316017316017284777274*var_9 + -0.0083116883116883116811024*var_8 + 0.0060606060606060606008039*var_215; + const double var_217 = 0.6666666666666666296592325*var_29 + var_32; + const double var_218 = var_214 + -0.0644155844155844120590970*var_217 + -0.0024242424242424242403215*var_66 + -0.4155844155844156118106980*var_31 + var_149 + -0.2268398268398268413648111*var_28 + var_216; + const double var_219 = 53.0000000000000000000000000*w[0][2]*w[1][2]*w[2][2]*w[3][2]; + const double var_220 = -0.0126406926406926415490384*var_41 + -0.0322943722943722921758791*var_23 + -0.0095238095238095246686250*var_219; + const double var_221 = 0.0005860805860805860800777*var_72 + var_99 + 0.0006660006660006660000883*var_10; + const double var_222 = 0.0008080808080808080801072*var_64 + 0.2909090909090908949607979*var_84 + -0.0144300144300144300019140*var_23; + const double var_223 = 0.0032323232323232323204287*var_21 + -0.0161616161616161616021436*var_74 + -0.0027705627705627705603675*var_39; + const double var_224 = 0.0383838383838383812030060*var_31 + -0.0014718614718614718601952*var_32 + -0.0756132756132756184141996*var_25 + var_222 + var_223 + -0.0851948051948051982007470*var_26 + -0.0042135642135642135605589*var_29 + 0.0888888888888888922812370*var_28 + var_183; + A[33] = 0.0004070004070004069819839*var_19*var_224; + A[47] = A[33]; + const double var_225 = 0.0000247371675943104528839*var_21 + -0.0029748029748029748003946*w[0][0]*w[1][0]*w[2][0]*w[3][0] + 0.0000380571809143237694975*var_39; + const double var_226 = 0.0000247371675943104528839*var_41 + 0.0003108003108003108000412*var_35 + 0.0003488574917146345559862*var_23; + const double var_227 = 0.0000190285904571618847488*var_9 + 0.0000615257758114901010232*var_8; + const double var_228 = 0.0000672343529486386725464*var_31 + -0.0002346859489716632610461*var_32 + var_225 + var_227 + 0.0000570857713714856542463*var_190 + 0.0003488574917146345559862*var_25 + 0.0000380571809143237694975*var_26 + var_226 + 0.0000482057624914767810214*var_28; + const double var_229 = var_42 + var_27 + var_24; + const double var_230 = var_30 + var_10; + const double var_231 = -0.0498168498168498202760546*var_229 + -0.2402930402930402997707660*var_9 + -0.0439560439560439594752772*var_230 + -0.0285714285714285705364279*var_8 + 0.1025641025641025605441570*var_36 + -0.2124542124542124488240091*var_33; + A[118] = 0.0011544011544011544001531*var_19*var_231; + const double var_232 = var_147 + 2.0000000000000000000000000*var_145; + const double var_233 = 0.6666666666666666296592325*var_41 + var_144; + const double var_234 = var_146 + 0.4000000000000000222044605*var_109; + const double var_235 = -1.0000000000000000000000000*var_132; + const double var_236 = 0.5111111111111111826588171*var_232 + 1.6857142857142857206298459*var_23 + 0.6666666666666666296592325*var_235 + 5.6190476190476186246769430*var_234 + 0.2222222222222222098864108*var_219 + -0.1333333333333333314829616*var_233; + A[44] = 0.0000222000222000222000029*var_19*var_236; + A[212] = A[44]; + const double var_237 = 0.0043290043290043290005742*var_172 + 0.0051948051948051948006890*var_60; + const double var_238 = 0.0106782106782106790687781*var_9 + 0.0415584415584415584055122*var_8 + 2.2020202020202019888017730*w[0][1]*w[1][1]*w[2][1]*w[3][1]; + const double var_239 = 0.0202397602397602384416420*w[0][1]*w[1][1]*w[2][1]*w[3][1] + -0.0000011100011100011100001*var_42 + -0.0042735042735042739342477*var_30 + 0.0016594516594516594502201*var_27 + -0.0024075924075924078071598*var_9 + 0.0002508602508602508600333*var_8 + 0.0002497502497502497500331*var_24 + -0.1352758352758352822231558*var_36 + -0.0100388500388500397086933*var_33; + A[2] = 0.0006613756613756613389477*var_19*var_239; + A[30] = A[2]; + const double var_240 = -0.1352758352758352822231558*var_146 + -0.0100388500388500397086933*var_109 + -0.0024075924075924078071598*var_23 + -0.0042735042735042739342477*var_145 + 0.0202397602397602384416420*w[0][2]*w[1][2]*w[2][2]*w[3][2] + 0.0002497502497502497500331*var_144 + 0.0002508602508602508600333*var_41 + 0.0016594516594516594502201*var_132 + -0.0000011100011100011100001*var_147; + const double var_241 = -2.2606060606060607298672949*var_34 + -0.0044155844155844160142665*var_21 + -0.0432900432900432882710184*var_39; + const double var_242 = 0.0060606060606060606008039*var_166 + -0.0083116883116883116811024*var_41 + -0.1017316017316017284777274*var_23; + const double var_243 = 2.0000000000000000000000000*var_28 + var_31; + const double var_244 = 0.6666666666666666296592325*var_26 + var_25; + const double var_245 = -0.0024242424242424242403215*var_243 + -0.2268398268398268413648111*var_32 + var_242 + -0.4155844155844156118106980*var_29 + -0.0644155844155844120590970*var_244 + var_241 + var_55; + A[39] = 0.0001356668023334690030297*var_19*var_245; + const double var_246 = 0.0290598290598290606712162*var_232 + var_48 + 0.1391941391941391992226329*var_234 + 0.1333333333333333314829616*var_144 + 0.6324786324786325630853412*var_132; + A[83] = 0.0007696007696007695639620*var_19*var_246; + A[125] = A[83]; + const double var_247 = -0.0158508158508158525368259*var_34 + 0.0010922410922410922401449*var_21 + 0.0003996003996003996000530*var_172; + const double var_248 = 0.0018648018648018648002473*var_58 + 0.0001332001332001332000177*var_44 + 0.0037296037296037296004947*var_91 + var_170 + var_100 + 0.0004262404262404262400565*var_25 + var_247 + 0.0017848817848817848802367*var_26 + 0.0006660006660006660000883*var_28; + A[103] = 0.0846560846560846513852994*var_19*var_248; + A[201] = A[103]; + const double var_249 = 0.0003488574917146345559862*var_9 + 0.0000247371675943104528839*var_8 + 0.0003108003108003108000412*var_10; + const double var_250 = 0.0000615257758114901010232*var_41 + 0.0000190285904571618847488*var_23; + const double var_251 = 0.0003488574917146345559862*var_31 + var_225 + 0.0000672343529486386725464*var_25 + var_250 + var_249 + 0.0000482057624914767810214*var_26 + -0.0002346859489716632610461*var_29 + 0.0000380571809143237694975*var_28 + 0.0000570857713714856542463*var_59; + const double var_252 = var_34 + var_31; + const double var_253 = 2.0000000000000000000000000*var_26 + var_25; + const double var_254 = var_237 + -0.0266666666666666683782605*var_252 + -0.0133333333333333341891302*var_32 + var_175 + 0.0510822510822510830741372*var_253 + 0.0259740259740259757381686*var_69 + var_57 + -0.0064935064935064939345422*var_29; + A[18] = 0.0009496676163342830483127*var_19*var_254; + A[46] = A[18]; + const double var_255 = 0.0017848817848817848802367*var_21 + 0.0102564102564102564013604*var_61 + -0.0018648018648018648002473*var_138 + 0.0003463203463203463200459*var_172; + const double var_256 = var_221 + 0.0014652014652014652001943*var_31 + var_255 + var_103 + 0.0001065601065601065600141*var_25 + 0.0010922410922410922401449*var_26 + 0.0041292041292041292005477*var_28; + A[104] = 0.0846560846560846513852994*var_19*var_256; + const double var_257 = var_163 + var_138 + var_123; + const double var_258 = var_34 + var_52; + const double var_259 = -0.0439560439560439594752772*var_258 + -0.2124542124542124488240091*var_53 + -0.2402930402930402997707660*var_21 + 0.1025641025641025605441570*var_114 + -0.0285714285714285705364279*var_39 + -0.0498168498168498202760546*var_257; + A[72] = 0.0011544011544011544001531*var_19*var_259; + A[184] = A[72]; + const double var_260 = 0.0005860805860805860800777*var_63 + 0.0006660006660006660000883*var_35 + var_205; + const double var_261 = 0.0097680097680097680012956*var_63 + 0.0683760683760683829479632*var_35 + 0.0058608058608058608007774*var_41; + const double var_262 = 0.1230769230769230837552186*var_46 + 0.0062515262515262515208292*var_9 + 0.0001953601953601953600259*var_8; + const double var_263 = var_261 + 0.0273504273504273504036277*var_82 + 0.0025396825396825396803369*var_32 + 0.0046886446886446886406219*var_58 + var_90 + 0.0166056166056166056022025*var_31 + var_262 + 0.0034188034188034188004535*var_26 + 0.0278388278388278405384160*var_28; + const double var_264 = -0.0008163265306122449282283*var_41 + 0.0177777777777777777623580*var_23; + const double var_265 = 0.0002014652014652014650267*var_8 + 0.0067741782027496309434578*w[0][1]*w[1][1]*w[2][1]*w[3][1]; + const double var_266 = -0.7434343434343434475763956*w[0][0]*w[1][0]*w[2][0]*w[3][0] + -0.0107647907647907652151087*var_39 + 0.0016161616161616161602144*var_60; + const double var_267 = -0.0161616161616161616021436*var_98 + 0.0032323232323232323204287*var_9 + -0.0027705627705627705603675*var_8; + const double var_268 = 0.0888888888888888922812370*var_31 + -0.0851948051948051982007470*var_32 + var_222 + -0.0042135642135642135605589*var_25 + var_267 + -0.0014718614718614718601952*var_26 + -0.0756132756132756184141996*var_29 + 0.0383838383838383812030060*var_28 + var_266; + A[36] = 0.0004070004070004069819839*var_19*var_268; + A[92] = A[36]; + const double var_269 = -0.0081632653061224497159643*var_9 + 0.0088888888888888888811790*var_8 + 0.0190476190476190493372499*var_215; + const double var_270 = -0.0408163265306122416409274*var_34 + 0.0088888888888888888811790*var_21 + -0.0010884353741496598320243*var_39; + const double var_271 = -0.0081632653061224497159643*var_31 + var_264 + var_269 + var_270 + -0.0027210884353741494716405*var_29 + -0.0010884353741496598320243*var_28 + 0.0761904761904761973489997*var_244 + -0.0136054421768707477918836*var_59; + A[178] = 0.0124320124320124320016490*var_19*var_271; + const double var_272 = -0.0666666666666666657414808*var_104; + const double var_273 = -0.0056654456654456654407515*var_32 + -0.0017582417582417582402332*var_31 + var_118 + -0.0330484330484330443566954*var_25 + var_128 + -0.0044607244607244604314711*var_29 + -0.0032885632885632882713156*var_28 + 0.0512820512820512802720785*var_70 + var_272; + const double var_274 = -0.0004395604395604395600583*var_41 + 0.0003108003108003108000412*var_23 + 0.0000444000444000444000059*var_102; + A[55] = 0.0086580086580086580011484*var_19*var_273; + A[153] = A[55]; + const double var_275 = 4.2222222222222223209087133*var_146 + 0.4571428571428571285828468*var_109 + 0.1365079365079364948076801*var_23 + 1.0095238095238097120187604*var_145 + 5.8095238095238093123384715*w[0][2]*w[1][2]*w[2][2]*w[3][2] + 0.2730158730158729896153602*var_144 + 0.0761904761904761973489997*var_41 + 0.1174603174603174593482180*var_147 + 0.5396825396825396525812835*var_132; + A[51] = 0.0000592000592000591977491*var_19*var_275; + const double var_276 = 0.6666666666666666296592325*var_28 + var_31; + const double var_277 = -1.0000000000000000000000000*var_215 + 0.4000000000000000222044605*var_8 + var_27; + const double var_278 = -0.0028105228105228105203728*var_9 + 0.0003108003108003108000412*var_277; + const double var_279 = -0.0057720057720057720007656*var_32 + -0.0017227217227217227202285*var_31 + var_278 + var_274 + -0.0020868020868020868002768*var_29 + -0.0002752802752802752800365*var_28 + var_165; + A[27] = 0.0158730158730158721347436*var_19*var_279; + const double var_280 = 0.0000570857713714856542463*var_252 + var_108 + 0.0003488574917146345559862*var_32 + 0.0000482057624914767810214*var_25 + var_110 + 0.0000672343529486386725464*var_26 + var_249 + 0.0000380571809143237694975*var_29 + -0.0002346859489716632610461*var_28; + A[52] = 0.2222222222222222098864108*var_19*var_280; + A[108] = A[52]; + const double var_281 = -0.0351473922902494351205860*var_53 + -0.0081632653061224497159643*var_163 + -0.0010582010582010582724205*var_138 + 0.2537792894935751997209650*var_114 + -0.0605253212396069523171249*var_21 + -0.0029856386999244140939558*var_39 + 0.0277777777777777762358014*var_34 + -0.0019085411942554799009930*var_123 + 0.0181405895691609982123271*var_52; + A[4] = 0.0004662004662004662000618*var_19*var_281; + const double var_282 = 0.0000444000444000444000059*var_159 + 0.0003108003108003108000412*var_21 + -0.0004395604395604395600583*var_39; + const double var_283 = -0.0017227217227217227202285*var_32 + -0.0057720057720057720007656*var_31 + var_278 + var_282 + var_68 + -0.0002752802752802752800365*var_29 + -0.0020868020868020868002768*var_28; + const double var_284 = 0.0124098124098124106690078*var_41 + 0.0917748917748917730774494*var_23; + const double var_285 = 0.0016161616161616161602144*var_63 + -0.7434343434343434475763956*w[0][2]*w[1][2]*w[2][2]*w[3][2] + -0.0107647907647907652151087*var_41; + const double var_286 = var_285 + -0.0851948051948051982007470*var_31 + 0.0888888888888888922812370*var_32 + -0.0014718614718614718601952*var_25 + var_267 + -0.0042135642135642135605589*var_26 + 0.0383838383838383812030060*var_29 + -0.0756132756132756184141996*var_28 + var_185; + const double var_287 = var_108 + -0.0002346859489716632610461*var_31 + 0.0000672343529486386725464*var_32 + var_227 + 0.0000380571809143237694975*var_25 + 0.0003488574917146345559862*var_26 + 0.0000482057624914767810214*var_29 + var_96 + 0.0000570857713714856542463*var_158; + const double var_288 = -0.0044155844155844160142665*var_9 + -0.0432900432900432882710184*var_8 + -2.2606060606060607298672949*var_10; + const double var_289 = var_29 + 0.6666666666666666296592325*var_32; + const double var_290 = var_214 + var_288 + -0.0644155844155844120590970*var_289 + -0.4155844155844156118106980*var_25 + var_242 + -0.2268398268398268413648111*var_26 + -0.0024242424242424242403215*var_191; + A[41] = 0.0001356668023334690030297*var_19*var_290; + A[167] = A[41]; + A[8] = 0.0004070004070004069819839*var_19*var_286; + const double var_291 = -0.0081632653061224497159643*var_21 + 0.0088888888888888888811790*var_39 + 0.0190476190476190493372499*var_139; + const double var_292 = -0.0010884353741496598320243*var_41 + -0.0408163265306122416409274*var_35 + 0.0088888888888888888811790*var_23; + const double var_293 = 0.0177777777777777777623580*var_9 + -0.0008163265306122449282283*var_8; + const double var_294 = var_291 + 0.0761904761904761973489997*var_217 + -0.0027210884353741494716405*var_31 + var_293 + -0.0010884353741496598320243*var_25 + -0.0081632653061224497159643*var_26 + var_292 + -0.0136054421768707477918836*var_158; + A[56] = 0.0007696007696007695639620*var_107*var_19; + const double var_295 = 9.6068376068376082344002498*w[0][2]*w[1][2]*w[2][2]*w[3][2] + 0.0556776556776556810768319*var_23 + 0.1333333333333333314829616*var_41; + const double var_296 = var_26 + var_35; + const double var_297 = var_291 + -0.0010884353741496598320243*var_31 + 0.0761904761904761973489997*var_289 + var_11 + -0.0027210884353741494716405*var_25 + -0.0136054421768707477918836*var_296 + var_264 + -0.0081632653061224497159643*var_28; + A[147] = 0.0124320124320124320016490*var_19*var_297; + A[181] = A[27]; + A[116] = 0.2222222222222222098864108*var_19*var_251; + const double var_298 = 0.0352092352092352109393936*var_9 + 0.0106782106782106790687781*var_8 + 0.0028860028860028860003828*var_134; + const double var_299 = var_171 + var_298 + var_284 + 0.0352092352092352109393936*var_31 + 0.0248196248196248213380155*var_25 + 0.0069264069264069264009187*var_26 + 0.3838383838383838675412107*var_29 + 0.0415584415584415584055122*var_28 + 0.2222222222222222098864108*var_59; + const double var_300 = 0.0005772005772005772000766*var_32 + 0.0003150288864574578599417*var_31 + 0.0000238914524628810341275*var_25 + var_210 + 0.0000361543218686075857661*var_26 + var_78 + 0.0004292004292004291819869*var_29 + 0.0002473716759431045220628*var_28 + var_202; + const double var_301 = 0.5333333333333333259318465*var_9 + 0.0290598290598290606712162*var_8 + 0.0556776556776556810768319*var_10; + const double var_302 = var_301 + 0.2905982905982906205899496*var_32 + 1.8974358974358973561891162*var_31 + 0.0417582417582417556034535*var_25 + var_181 + var_295 + 0.0290598290598290606712162*var_26 + 0.1391941391941391992226329*var_29 + 0.6324786324786325630853412*var_28; + const double var_303 = 87.4000000000000056843418861*var_146 + 21.8500000000000014210854715*var_109 + 14.5666666666666664298190881*var_23 + 17.7500000000000000000000000*var_145 + 5399.0000000000000000000000000*w[0][2]*w[1][2]*w[2][2]*w[3][2] + 23.6666666666666642981908808*var_144 + 11.8333333333333321490954404*var_41 + 5.9166666666666660745477202*var_147 + 218.5000000000000000000000000*var_132; + A[32] = 0.0000003083336416669750059*var_19*var_303; + const double var_304 = 0.0683760683760683829479632*var_34 + 0.0058608058608058608007774*var_39 + 0.0097680097680097680012956*var_60; + const double var_305 = 0.0278388278388278405384160*var_32 + 0.0034188034188034188004535*var_31 + var_304 + 0.0025396825396825396803369*var_25 + 0.0273504273504273504036277*var_69 + var_156 + 0.0166056166056166056022025*var_29 + 0.0046886446886446886406219*var_70 + var_94; + const double var_306 = 0.0177777777777777777623580*var_21 + -0.0008163265306122449282283*var_39; + const double var_307 = -0.0136054421768707477918836*var_252 + -0.0081632653061224497159643*var_32 + 0.0761904761904761973489997*var_152 + var_269 + var_306 + -0.0010884353741496598320243*var_29 + -0.0027210884353741494716405*var_28 + var_292; + A[73] = 0.0173160173160173160022968*var_19*var_263; + A[194] = 1.5238095238095237249353886*var_113*var_19; + const double var_308 = 0.0102564102564102564013604*var_46 + 0.0017848817848817848802367*var_9 + -0.0018648018648018648002473*var_27 + 0.0003463203463203463200459*var_56; + const double var_309 = var_308 + 0.0010922410922410922401449*var_32 + 0.0041292041292041292005477*var_31 + var_103 + var_136 + 0.0001065601065601065600141*var_29 + 0.0014652014652014652001943*var_28; + A[59] = 0.0846560846560846513852994*var_19*var_309; + A[213] = A[59]; + const double var_310 = 0.0556776556776556810768319*var_34 + 0.5333333333333333259318465*var_21 + 0.0290598290598290606712162*var_39; + const double var_311 = var_64 + var_109; + const double var_312 = -0.0009324009324009324001237*var_146 + 0.0001953601953601953600259*var_23 + 0.0001998001998001998000265*var_235 + -0.0003774003774003774000501*var_145 + 0.0000666000666000666000088*var_311 + -0.0002220002220002220000294*w[0][2]*w[1][2]*w[2][2]*w[3][2] + -0.0002308802308802308800306*var_144 + -0.0000133200133200133200018*var_147; + const double var_313 = 0.0581196581196581213424324*var_41 + 0.0888888888888888922812370*var_23 + 0.8351648351648351953357974*var_35; + A[130] = 0.2222222222222222098864108*var_19*var_228; + A[158] = A[130]; + A[25] = 0.0370370370370370349810685*var_19*var_89; + A[151] = A[25]; + const double var_314 = var_34 + var_25; + const double var_315 = 0.0190476190476190493372499*var_166 + 0.0088888888888888888811790*var_41 + -0.0081632653061224497159643*var_23; + const double var_316 = var_28 + 0.6666666666666666296592325*var_31; + const double var_317 = -0.0136054421768707477918836*var_314 + -0.0010884353741496598320243*var_32 + var_11 + var_306 + -0.0027210884353741494716405*var_26 + -0.0081632653061224497159643*var_29 + 0.0761904761904761973489997*var_316 + var_315; + A[89] = 0.0124320124320124320016490*var_19*var_317; + A[215] = A[89]; + A[66] = 0.2222222222222222098864108*var_19*var_287; + const double var_318 = var_163 + 2.0000000000000000000000000*var_52; + const double var_319 = 0.6324786324786325630853412*var_138 + 0.1391941391941391992226329*var_115 + 0.0290598290598290606712162*var_318 + var_129 + 0.1333333333333333314829616*var_123; + A[99] = 0.0007696007696007695639620*var_19*var_319; + const double var_320 = 34.0000000000000000000000000*var_146 + 11.4615384615384616751043723*var_109 + 8.8175824175824182304950227*var_23 + 3.6153846153846154187760931*var_145 + 0.3208791208791209048634130*w[0][2]*w[1][2]*w[2][2]*w[3][2] + 0.8483516483516483353000126*var_144 + 0.3813186813186812962328531*var_41 + 1.2901098901098901894357596*var_147 + 0.3549450549450549607932714*var_132; + const double var_321 = 0.0016594516594516594502201*var_138 + -0.0000011100011100011100001*var_163 + -0.0100388500388500397086933*var_53 + -0.1352758352758352822231558*var_114 + -0.0024075924075924078071598*var_21 + 0.0202397602397602384416420*w[0][0]*w[1][0]*w[2][0]*w[3][0] + 0.0002508602508602508600333*var_39 + 0.0002497502497502497500331*var_123 + -0.0042735042735042739342477*var_52; + A[17] = 0.0006613756613756613389477*var_19*var_321; + const double var_322 = 0.0024642024642024642003268*var_138 + 0.0003996003996003996000530*var_184 + 0.0081252081252081252010777*var_163 + 0.0606060606060606077427622*var_53 + 0.5407925407925407990106237*var_114 + 0.0028638028638028638003798*var_39 + 0.0512820512820512802720785*var_52; + A[50] = var_155 + 0.0028218694885361553931213*var_19*var_322; + A[78] = A[50]; + A[123] = A[53]; + const double var_323 = var_209 + 0.0000570857713714856542463*var_314 + 0.0000482057624914767810214*var_31 + 0.0000380571809143237694975*var_32 + var_110 + var_226 + -0.0002346859489716632610461*var_26 + 0.0003488574917146345559862*var_29 + 0.0000672343529486386725464*var_28; + A[85] = 0.2222222222222222098864108*var_19*var_323; + const double var_324 = -0.0065800865800865800808728*var_53 + -0.0083982683982683978274331*var_163 + 0.0666666666666666657414808*var_138 + -0.0822510822510822553477183*var_114 + 0.0016450216450216450202182*var_21 + 1.1939393939393938559589969*w[0][0]*w[1][0]*w[2][0]*w[3][0] + -0.0038095238095238095205053*var_39 + -0.0410389610389610415275286*var_123 + -0.0541991341991341982198271*var_52; + A[115] = 0.0012210012210012210001620*var_19*var_324; + const double var_325 = 0.0001332001332001332000177*var_82 + var_206 + 0.0004262404262404262400565*var_31 + 0.0037296037296037296004947*var_58 + 0.0018648018648018648002473*var_91 + var_247 + var_73 + 0.0006660006660006660000883*var_26 + 0.0017848817848817848802367*var_28; + A[149] = 0.0846560846560846513852994*var_19*var_325; + A[219] = A[149]; + const double var_326 = -0.4155844155844156118106980*var_32 + -0.0024242424242424242403215*var_253 + -0.0644155844155844120590970*var_276 + var_220 + -0.2268398268398268413648111*var_29 + var_241 + var_216; + const double var_327 = 0.0004292004292004291819869*var_31 + 0.0000238914524628810341275*var_32 + var_201 + 0.0002473716759431045220628*var_25 + var_51 + 0.0003150288864574578599417*var_26 + 0.0000361543218686075857661*var_29 + 0.0005772005772005772000766*var_28 + var_79; + A[7] = 0.0370370370370370349810685*var_127*var_19; + A[105] = A[7]; + const double var_328 = 0.0917748917748917730774494*var_21 + 0.0124098124098124106690078*var_39; + const double var_329 = -0.0081632653061224497159643*var_42 + 0.0277777777777777762358014*var_10 + 0.0181405895691609982123271*var_30 + -0.0010582010582010582724205*var_27 + -0.0605253212396069523171249*var_9 + -0.0029856386999244140939558*var_8 + -0.0019085411942554799009930*var_24 + 0.2537792894935751997209650*var_36 + -0.0351473922902494351205860*var_33; + A[22] = 0.0004662004662004662000618*var_19*var_329; + A[106] = A[22]; + const double var_330 = 0.0000621600621600621600082*var_9 + -0.0007414807414807414800983*var_8 + -0.0194916194916194933373088*w[0][1]*w[1][1]*w[2][1]*w[3][1]; + const double var_331 = var_330 + -0.0002752802752802752800365*var_31 + -0.0020868020868020868002768*var_25 + var_274 + var_141 + -0.0057720057720057720007656*var_26 + -0.0017227217227217227202285*var_28; + A[13] = 0.0158730158730158721347436*var_19*var_331; + A[195] = A[13]; + const double var_332 = 0.0556776556776556810768319*var_21 + 9.6068376068376082344002498*w[0][0]*w[1][0]*w[2][0]*w[3][0] + 0.1333333333333333314829616*var_39; + const double var_333 = 0.0888888888888888922812370*var_9 + 0.0581196581196581213424324*var_8 + 0.8351648351648351953357974*var_10; + const double var_334 = var_333 + 0.0290598290598290606712162*var_31 + 0.6324786324786325630853412*var_32 + 0.2905982905982906205899496*var_25 + var_332 + 0.1391941391941391992226329*var_26 + 1.8974358974358973561891162*var_29 + 0.0417582417582417556034535*var_28 + var_180; + const double var_335 = -0.0020350020350020348557096*var_41 + -0.0120797720797720786051199*var_23 + 0.0190476190476190493372499*var_93; + const double var_336 = 0.3208791208791209048634130*w[0][1]*w[1][1]*w[2][1]*w[3][1] + 1.2901098901098901894357596*var_42 + 3.6153846153846154187760931*var_30 + 0.3549450549450549607932714*var_27 + 8.8175824175824182304950227*var_9 + 0.3813186813186812962328531*var_8 + 0.8483516483516483353000126*var_24 + 34.0000000000000000000000000*var_36 + 11.4615384615384616751043723*var_33; + const double var_337 = var_330 + -0.0002752802752802752800365*var_32 + var_282 + -0.0057720057720057720007656*var_25 + var_168 + -0.0020868020868020868002768*var_26 + -0.0017227217227217227202285*var_29; + const double var_338 = var_85 + var_265 + -0.0009823509823509823501303*var_32 + 0.0000482850482850482850064*var_31 + 0.0021645021645021645002871*var_58 + 0.0011122211122211122201475*var_25 + var_126 + 0.0010180295894581608238949*var_26 + 0.0001722087436373150579928*var_28; + A[10] = 0.0370370370370370349810685*var_19*var_338; + A[193] = 1.5238095238095237249353886*var_19*var_312; + const double var_339 = 0.1333333333333333314829616*var_46 + 0.0017316017316017316002297*var_72 + -0.0064935064935064939345422*var_8; + const double var_340 = 0.0259740259740259757381686*var_82 + var_65 + -0.0064935064935064939345422*var_31 + 0.0510822510822510830741372*var_151 + -0.0266666666666666683782605*var_296 + var_339 + var_174 + -0.0133333333333333341891302*var_28; + A[9] = 0.0009496676163342830483127*var_19*var_340; + const double var_341 = 0.0000019028590457161886019*var_184 + 0.0000832500832500832500110*var_39; + const double var_342 = 0.0285714285714285705364279*var_233 + -20.6666666666666642981908808*w[0][2]*w[1][2]*w[2][2]*w[3][2] + 0.2435374149659863818317973*var_23; + const double var_343 = 0.0013986013986013986001855*var_342; + const double var_344 = var_343 + var_265 + -0.0009823509823509823501303*var_31 + 0.0000482850482850482850064*var_32 + 0.0010180295894581608238949*var_25 + 0.0021645021645021645002871*var_69 + 0.0011122211122211122201475*var_26 + var_341 + 0.0001722087436373150579928*var_29; + A[34] = 0.0370370370370370349810685*var_19*var_344; + A[62] = A[34]; + A[94] = A[66]; + const double var_345 = 0.2222222222222222098864108*var_314 + 0.0069264069264069264009187*var_31 + 0.0415584415584415584055122*var_32 + var_328 + var_238 + var_194 + 0.3838383838383838675412107*var_26 + 0.0352092352092352109393936*var_29 + 0.0248196248196248213380155*var_28; + A[160] = 0.0000962000962000961954953*var_19*var_320; + const double var_346 = 1.1939393939393938559589969*w[0][1]*w[1][1]*w[2][1]*w[3][1] + -0.0083982683982683978274331*var_42 + -0.0541991341991341982198271*var_30 + 0.0666666666666666657414808*var_27 + 0.0016450216450216450202182*var_9 + -0.0038095238095238095205053*var_8 + -0.0410389610389610415275286*var_24 + -0.0822510822510822553477183*var_36 + -0.0065800865800865800808728*var_33; + A[70] = 0.0012210012210012210001620*var_19*var_346; + A[154] = A[70]; + const double var_347 = -1.0000000000000000000000000*var_138; + const double var_348 = 0.0000666000666000666000088*var_173 + -0.0000133200133200133200018*var_163 + 0.0001953601953601953600259*var_21 + -0.0009324009324009324001237*var_114 + -0.0002220002220002220000294*w[0][0]*w[1][0]*w[2][0]*w[3][0] + 0.0001998001998001998000265*var_347 + -0.0002308802308802308800306*var_123 + -0.0003774003774003774000501*var_52; + A[209] = 1.5238095238095237249353886*var_19*var_348; + const double var_349 = 0.0512820512820512802720785*var_58 + -0.0330484330484330443566954*var_32 + -0.0044607244607244604314711*var_31 + var_335 + -0.0032885632885632882713156*var_25 + -0.0017582417582417582402332*var_26 + var_130 + -0.0056654456654456654407515*var_28 + var_117; + A[114] = 0.0086580086580086580011484*var_19*var_349; + A[142] = A[114]; + const double var_350 = var_301 + 1.8974358974358973561891162*var_32 + 0.2905982905982906205899496*var_31 + var_313 + 0.0290598290598290606712162*var_25 + var_332 + 0.0417582417582417556034535*var_26 + 0.6324786324786325630853412*var_29 + 0.1391941391941391992226329*var_28; + A[144] = 0.0007696007696007695639620*var_19*var_334; + const double var_351 = -0.0144300144300144300019140*var_9 + 0.2909090909090908949607979*var_121 + 0.0008080808080808080801072*var_56; + const double var_352 = var_285 + -0.0756132756132756184141996*var_31 + -0.0042135642135642135605589*var_32 + 0.0383838383838383812030060*var_25 + var_223 + 0.0888888888888888922812370*var_26 + -0.0014718614718614718601952*var_29 + -0.0851948051948051982007470*var_28 + var_351; + A[20] = 0.0004070004070004069819839*var_19*var_352; + A[199] = A[73]; + A[224] = 0.5818181818181817899215957*var_19*var_208; + const double var_353 = 0.0001065601065601065600141*var_31 + var_255 + 0.0014652014652014652001943*var_25 + var_260 + 0.0041292041292041292005477*var_26 + 0.0010922410922410922401449*var_28 + var_135; + A[148] = 0.0846560846560846513852994*var_19*var_353; + A[204] = A[148]; + A[42] = 0.0158730158730158721347436*var_169*var_19; + A[182] = A[42]; + const double var_354 = 0.0009324009324009324001237*var_159 + 0.0004262404262404262400565*var_39 + 0.0003996003996003996000530*var_60; + const double var_355 = var_308 + 0.0041292041292041292005477*var_32 + 0.0010922410922410922401449*var_31 + var_260 + 0.0014652014652014652001943*var_29 + 0.0001065601065601065600141*var_28 + var_354; + A[177] = 0.0846560846560846513852994*var_19*var_355; + A[191] = A[177]; + A[31] = A[17]; + A[65] = -0.6666666666666666296592325*var_19*var_327; + A[79] = A[65]; + const double var_356 = 0.5396825396825396525812835*var_138 + 0.1174603174603174593482180*var_163 + 0.4571428571428571285828468*var_53 + 4.2222222222222223209087133*var_114 + 0.1365079365079364948076801*var_21 + 5.8095238095238093123384715*w[0][0]*w[1][0]*w[2][0]*w[3][0] + 0.0761904761904761973489997*var_39 + 0.2730158730158729896153602*var_123 + 1.0095238095238097120187604*var_52; + A[131] = 0.0000592000592000591977491*var_19*var_356; + A[173] = A[131]; + const double var_357 = 0.2222222222222222098864108*var_252 + var_298 + 0.0352092352092352109393936*var_32 + var_157 + var_328 + 0.0069264069264069264009187*var_25 + 0.0248196248196248213380155*var_26 + 0.0415584415584415584055122*var_29 + 0.3838383838383838675412107*var_28; + A[81] = 0.0006512006512006512362264*var_19*var_357; + A[95] = A[81]; + A[119] = 0.0173160173160173160022968*var_19*var_305; + A[217] = A[119]; + A[5] = 0.0001356668023334690030297*var_153*var_19; + A[75] = A[5]; + const double var_358 = 0.0166056166056166056022025*var_32 + 0.0025396825396825396803369*var_31 + var_304 + var_262 + var_116 + 0.0034188034188034188004535*var_25 + 0.0046886446886446886406219*var_69 + 0.0278388278388278405384160*var_29 + 0.0273504273504273504036277*var_70; + const double var_359 = 0.0062515262515262515208292*var_21 + 0.1230769230769230837552186*var_61 + 0.0001953601953601953600259*var_39; + const double var_360 = 0.0512820512820512802720785*var_82 + -0.0017582417582417582402332*var_32 + -0.0056654456654456654407515*var_31 + var_335 + var_45 + -0.0330484330484330443566954*var_26 + -0.0032885632885632882713156*var_29 + -0.0044607244607244604314711*var_28 + var_272; + A[71] = 0.0086580086580086580011484*var_19*var_360; + A[221] = A[179]; + const double var_361 = 5.6190476190476186246769430*var_106 + 0.5111111111111111826588171*var_105 + 0.2222222222222222098864108*var_54 + 1.6857142857142857206298459*var_9 + 0.6666666666666666296592325*var_111 + -0.1333333333333333314829616*var_86; + A[28] = 0.0000222000222000222000029*var_19*var_361; + A[196] = A[28]; + A[189] = A[147]; + A[23] = 0.0001356668023334690030297*var_19*var_218; + A[29] = 0.0158730158730158721347436*var_19*var_283; + A[211] = A[29]; + const double var_362 = 0.0046886446886446886406219*var_44 + 0.0273504273504273504036277*var_91 + var_116 + var_359 + 0.0278388278388278405384160*var_25 + 0.0166056166056166056022025*var_26 + 0.0034188034188034188004535*var_29 + var_92 + 0.0025396825396825396803369*var_28; + A[162] = 0.0173160173160173160022968*var_19*var_362; + const double var_363 = var_179 + 0.0417582417582417556034535*var_32 + 0.1391941391941391992226329*var_31 + var_313 + 0.6324786324786325630853412*var_25 + 1.8974358974358973561891162*var_26 + 0.0290598290598290606712162*var_29 + 0.2905982905982906205899496*var_28 + var_310; + A[129] = 0.0006512006512006512362264*var_19*var_299; + A[143] = A[129]; + const double var_364 = 0.0009419152276295134204251*var_42 + 0.0170940170940170957369908*var_10 + 0.0015698587127158556645684*var_30 + 0.0008837723123437409402173*var_9 + 0.0052910052910052907115812*var_27 + 0.0017791732077446363764761*var_8 + 0.0023722309436595150240745*var_24 + 0.0022094307808593520794926*var_36 + 0.0011047153904296760397463*var_33; + A[102] = 0.0124320124320124320016490*var_19*var_294; + A[121] = A[23]; + A[60] = A[4]; + const double var_365 = 1.6857142857142857206298459*var_21 + 5.6190476190476186246769430*var_115 + 0.5111111111111111826588171*var_318 + 0.2222222222222222098864108*var_213 + 0.6666666666666666296592325*var_347 + -0.1333333333333333314829616*var_124; + const double var_366 = var_200 + 0.0000361543218686075857661*var_31 + 0.0002473716759431045220628*var_32 + var_80 + 0.0005772005772005772000766*var_25 + 0.0004292004292004291819869*var_26 + 0.0003150288864574578599417*var_29 + 0.0000238914524628810341275*var_28 + var_211; + A[161] = -0.6666666666666666296592325*var_19*var_366; + A[175] = A[161]; + const double var_367 = var_343 + 0.0011122211122211122201475*var_32 + 0.0021645021645021645002871*var_44 + var_122 + 0.0001722087436373150579928*var_25 + 0.0000482850482850482850064*var_26 + 0.0010180295894581608238949*var_29 + -0.0009823509823509823501303*var_28 + var_83; + A[12] = 0.0000222000222000222000029*var_19*var_365; + A[180] = A[12]; + A[58] = 0.0124320124320124320016490*var_19*var_307; + const double var_368 = 5.8095238095238093123384715*w[0][1]*w[1][1]*w[2][1]*w[3][1] + 0.1174603174603174593482180*var_42 + 1.0095238095238097120187604*var_30 + 0.1365079365079364948076801*var_9 + 0.5396825396825396525812835*var_27 + 0.0761904761904761973489997*var_8 + 0.2730158730158729896153602*var_24 + 4.2222222222222223209087133*var_36 + 0.4571428571428571285828468*var_33; + A[84] = 0.0000592000592000591977491*var_19*var_368; + A[54] = 0.0006512006512006512362264*var_19*var_345; + A[122] = A[38]; + const double var_369 = var_261 + 0.0046886446886446886406219*var_82 + 0.0273504273504273504036277*var_58 + 0.0034188034188034188004535*var_32 + 0.0278388278388278405384160*var_31 + var_359 + 0.0025396825396825396803369*var_26 + var_156 + 0.0166056166056166056022025*var_28; + A[93] = A[51]; + const double var_370 = 0.2537792894935751997209650*var_146 + -0.0351473922902494351205860*var_109 + -0.0605253212396069523171249*var_23 + 0.0181405895691609982123271*var_145 + -0.0019085411942554799009930*var_144 + 0.0277777777777777762358014*var_35 + -0.0029856386999244140939558*var_41 + -0.0010582010582010582724205*var_132 + -0.0081632653061224497159643*var_147; + A[202] = A[118]; + A[117] = 0.0173160173160173160022968*var_19*var_369; + const double var_371 = 0.5407925407925407990106237*var_146 + 0.0003996003996003996000530*var_84 + 0.0606060606060606077427622*var_109 + 0.0512820512820512802720785*var_145 + 0.0028638028638028638003798*var_41 + 0.0081252081252081252010777*var_147 + 0.0024642024642024642003268*var_132; + A[146] = var_155 + 0.0028218694885361553931213*var_19*var_371; + A[141] = A[99]; + A[76] = A[20]; + A[109] = A[67]; + const double var_372 = var_221 + 0.0014652014652014652001943*var_32 + 0.0010922410922410922401449*var_25 + 0.0001065601065601065600141*var_26 + var_133 + 0.0041292041292041292005477*var_29 + var_354; + const double var_373 = var_284 + 0.0415584415584415584055122*var_31 + 0.0069264069264069264009187*var_32 + var_160 + var_238 + 0.3838383838383838675412107*var_25 + 0.2222222222222222098864108*var_296 + 0.0248196248196248213380155*var_29 + 0.0352092352092352109393936*var_28; + A[86] = 0.0006512006512006512362264*var_19*var_373; + A[170] = A[86]; + A[150] = A[10]; + A[163] = 0.0173160173160173160022968*var_19*var_358; + const double var_374 = var_237 + 0.0510822510822510830741372*var_243 + -0.0266666666666666683782605*var_314 + -0.0064935064935064939345422*var_32 + var_189 + var_339 + -0.0133333333333333341891302*var_29 + 0.0259740259740259757381686*var_70; + A[35] = 0.0009496676163342830483127*var_19*var_374; + A[77] = A[35]; + A[40] = 0.0004662004662004662000618*var_19*var_370; + A[152] = A[40]; + const double var_375 = 0.0081252081252081252010777*var_42 + 0.0003996003996003996000530*var_121 + 0.0512820512820512802720785*var_30 + 0.0024642024642024642003268*var_27 + 0.0028638028638028638003798*var_8 + 0.5407925407925407990106237*var_36 + 0.0606060606060606077427622*var_33; + A[124] = A[68]; + A[198] = A[58]; + const double var_376 = var_333 + 0.0290598290598290606712162*var_32 + 0.6324786324786325630853412*var_31 + 0.1391941391941391992226329*var_25 + var_295 + 0.2905982905982906205899496*var_26 + 0.0417582417582417556034535*var_29 + 1.8974358974358973561891162*var_28 + var_310; + A[140] = A[84]; + const double var_377 = var_288 + var_150 + -0.2268398268398268413648111*var_25 + -0.0024242424242424242403215*var_177 + -0.4155844155844156118106980*var_26 + var_220 + -0.0644155844155844120590970*var_316; + const double var_378 = -0.0756132756132756184141996*var_32 + -0.0042135642135642135605589*var_31 + 0.0888888888888888922812370*var_25 + 0.0383838383838383812030060*var_26 + -0.0014718614718614718601952*var_28 + -0.0851948051948051982007470*var_29 + var_266 + var_351 + var_187; + A[24] = 0.0004070004070004069819839*var_19*var_378; + A[136] = A[24]; + A[208] = 0.5818181818181817899215957*var_19*var_364; + A[200] = A[88]; + A[187] = A[117]; + A[206] = A[178]; + A[48] = 0.0007696007696007695639620*var_19*var_363; + const double var_379 = -0.0027210884353741494716405*var_32 + -0.0136054421768707477918836*var_190 + var_293 + -0.0081632653061224497159643*var_25 + var_270 + -0.0010884353741496598320243*var_26 + 0.0761904761904761973489997*var_276 + var_315; + A[134] = 0.0124320124320124320016490*var_19*var_379; + const double var_380 = 0.0001722087436373150579928*var_32 + 0.0010180295894581608238949*var_31 + var_88 + var_120 + -0.0009823509823509823501303*var_25 + var_341 + 0.0000482850482850482850064*var_29 + 0.0011122211122211122201475*var_28 + 0.0021645021645021645002871*var_70; + A[19] = 0.0370370370370370349810685*var_19*var_380; + A[61] = A[19]; + const double var_381 = var_209 + 0.0000380571809143237694975*var_31 + 0.0000482057624914767810214*var_32 + -0.0002346859489716632610461*var_25 + var_250 + 0.0000570857713714856542463*var_296 + 0.0000672343529486386725464*var_29 + 0.0003488574917146345559862*var_28 + var_96; + A[69] = 0.2222222222222222098864108*var_19*var_381; + A[128] = 0.0007696007696007695639620*var_19*var_302; + A[137] = A[39]; + A[171] = A[101]; + A[97] = -0.6666666666666666296592325*var_19*var_300; + A[111] = A[97]; + A[218] = A[134]; + A[37] = 0.0370370370370370349810685*var_19*var_367; + A[21] = 0.0001356668023334690030297*var_19*var_326; + A[91] = A[21]; + A[1] = 0.0006613756613756613389477*var_19*var_240; + A[174] = A[146]; + A[190] = A[162]; + A[169] = A[71]; + A[132] = 0.0846560846560846513852994*var_19*var_372; + A[186] = A[102]; + A[3] = 0.0001356668023334690030297*var_19*var_377; + A[45] = A[3]; + A[57] = 0.0846560846560846513852994*var_19*var_197; + A[43] = 0.0158730158730158721347436*var_19*var_337; + const double var_382 = 0.3549450549450549607932714*var_138 + 11.4615384615384616751043723*var_53 + 1.2901098901098901894357596*var_163 + 34.0000000000000000000000000*var_114 + 8.8175824175824182304950227*var_21 + 0.3208791208791209048634130*w[0][0]*w[1][0]*w[2][0]*w[3][0] + 0.3813186813186812962328531*var_39 + 0.8483516483516483353000126*var_123 + 3.6153846153846154187760931*var_52; + A[64] = 0.0000962000962000961954953*var_19*var_382; + A[207] = A[193]; + A[205] = A[163]; + A[168] = A[56]; + A[135] = A[9]; + A[15] = A[1]; + A[188] = A[132]; + A[96] = 0.0007696007696007695639620*var_19*var_350; + A[172] = A[116]; + A[80] = 0.0007696007696007695639620*var_19*var_376; + A[216] = A[104]; + A[166] = A[26]; + A[223] = A[209]; + A[197] = A[43]; + A[156] = A[100]; + A[222] = A[194]; + A[107] = A[37]; + A[0] = 0.0000003083336416669750059*var_164*var_19; + A[98] = var_155 + 0.0028218694885361553931213*var_19*var_375; + A[126] = A[98]; + A[112] = 0.0000962000962000961954953*var_19*var_336; + A[139] = A[69]; + A[159] = A[145]; + A[183] = A[57]; + A[120] = A[8]; + A[155] = A[85]; + A[157] = A[115]; + A[138] = A[54]; + } + + 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/mass_matrix_2d/mass_matrix_f4_p1_q4_quadrature.h b/mass_matrix_2d/mass_matrix_f4_p1_q4_quadrature.h new file mode 100644 index 0000000..b7d5f58 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f4_p1_q4_quadrature.h @@ -0,0 +1,6530 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F4_P1_Q4_QUADRATURE_H +#define __MASS_MATRIX_F4_P1_Q4_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f4_p1_q4_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f4_p1_q4_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_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 mass_matrix_f4_p1_q4_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f4_p1_q4_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f4_p1_q4_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_p1_q4_quadrature_finite_element_1() + { + // 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.0224478343233824, 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.0412393049421162, -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.0388807895679869, 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.0439885919382571, 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.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 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.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.00927360943924092, 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.0535412090610519}; + + // 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.0622092633087791, -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.251415744421884, 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.0224478343233824, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0412393049421162, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0388807895679869, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0439885919382571, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.00927360943924092, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0622092633087791, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.251415744421884, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f4_p1_q4_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f4_p1_q4_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f4_p1_q4_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f4_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 mass_matrix_f4_p1_q4_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f4_p1_q4_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f4_p1_q4_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f4_p1_q4_quadrature_dofmap_1() + { + // 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.0*m.num_entities[1] + 3.0*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 mass_matrix_f4_p1_q4_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 mass_matrix_f4_p1_q4_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f4_p1_q4_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Array of quadrature weights. + static const double W49[49] = {0.0036234660797264, 0.00715464377909735, 0.00824760301353097, 0.00693554275373524, 0.00429791008798315, 0.00177448507143835, 0.000337590756711431, 0.00782718664849641, 0.0154550176627367, 0.0178159604006788, 0.0149817292193919, 0.0092840787568901, 0.00383313257348533, 0.000729242610651687, 0.0106850106013168, 0.021097877818156, 0.0243208363749012, 0.0204517846225132, 0.0126738360020949, 0.00523266711568851, 0.000995500091625133, 0.0116960367644213, 0.0230941796709132, 0.0266220977213878, 0.0223869525046108, 0.0138730467715663, 0.00572778720065371, 0.00108969528483177, 0.0106850106013168, 0.021097877818156, 0.0243208363749012, 0.0204517846225133, 0.0126738360020949, 0.00523266711568852, 0.000995500091625133, 0.00782718664849641, 0.0154550176627367, 0.0178159604006788, 0.0149817292193919, 0.0092840787568901, 0.00383313257348533, 0.000729242610651687, 0.00362346607972641, 0.00715464377909737, 0.00824760301353099, 0.00693554275373526, 0.00429791008798316, 0.00177448507143835, 0.000337590756711432}; + // Quadrature points on the UFC reference element: (0.0248740323760607, 0.0224793864387125), (0.0225279156156636, 0.114679053160904), (0.0186827443488427, 0.265789822784589), (0.0139228951565961, 0.452846373669445), (0.00897290400671669, 0.64737528288683), (0.00458641254163789, 0.819759308263108), (0.00143165958133296, 0.943737439463078), (0.126329297019669, 0.0224793864387125), (0.114413927746761, 0.114679053160904), (0.0948852170128628, 0.265789822784589), (0.0707110745463253, 0.452846373669445), (0.045571246280295, 0.64737528288683), (0.0232932989499898, 0.819759308263108), (0.00727105865856026, 0.943737439463078), (0.29039930608799, 0.0224793864387125), (0.263008866575801, 0.114679053160904), (0.218117268350298, 0.265789822784589), (0.16254699001287, 0.452846373669445), (0.104756842708482, 0.64737528288683), (0.0535454404572833, 0.819759308263108), (0.0167143365694675, 0.943737439463078), (0.488760306780644, 0.0224793864387125), (0.442660473419548, 0.114679053160904), (0.367105088607705, 0.265789822784589), (0.273576813165278, 0.452846373669445), (0.176312358556585, 0.64737528288683), (0.0901203458684462, 0.819759308263108), (0.0281312802684611, 0.943737439463078), (0.687121307473297, 0.0224793864387125), (0.622312080263294, 0.114679053160904), (0.516092908865112, 0.265789822784589), (0.384606636317686, 0.452846373669445), (0.247867874404688, 0.64737528288683), (0.126695251279609, 0.819759308263108), (0.0395482239674546, 0.943737439463078), (0.851191316541618, 0.0224793864387125), (0.770907019092334, 0.114679053160904), (0.639324960202548, 0.265789822784589), (0.47644255178423, 0.452846373669445), (0.307053470832875, 0.64737528288683), (0.156947392786903, 0.819759308263108), (0.0489915018783619, 0.943737439463078), (0.952646581185227, 0.0224793864387125), (0.862793031223432, 0.114679053160904), (0.715527432866568, 0.265789822784589), (0.533230731173959, 0.452846373669445), (0.343651813106453, 0.64737528288683), (0.175654279195255, 0.819759308263108), (0.0548309009555892, 0.943737439463078) + + // Value of basis functions at quadrature points. + static const double FE0[49][3] = \ + {{0.952646581185227, 0.0248740323760607, 0.0224793864387125}, + {0.862793031223432, 0.0225279156156635, 0.114679053160904}, + {0.715527432866568, 0.0186827443488428, 0.265789822784589}, + {0.533230731173959, 0.013922895156596, 0.452846373669445}, + {0.343651813106453, 0.00897290400671669, 0.64737528288683}, + {0.175654279195255, 0.00458641254163794, 0.819759308263108}, + {0.0548309009555892, 0.00143165958133301, 0.943737439463078}, + {0.851191316541618, 0.126329297019669, 0.0224793864387125}, + {0.770907019092334, 0.114413927746761, 0.114679053160904}, + {0.639324960202548, 0.0948852170128629, 0.265789822784589}, + {0.47644255178423, 0.0707110745463253, 0.452846373669445}, + {0.307053470832875, 0.0455712462802949, 0.64737528288683}, + {0.156947392786903, 0.0232932989499898, 0.819759308263108}, + {0.0489915018783619, 0.00727105865856031, 0.943737439463078}, + {0.687121307473297, 0.29039930608799, 0.0224793864387125}, + {0.622312080263295, 0.263008866575801, 0.114679053160904}, + {0.516092908865112, 0.218117268350298, 0.265789822784589}, + {0.384606636317686, 0.16254699001287, 0.452846373669445}, + {0.247867874404688, 0.104756842708482, 0.64737528288683}, + {0.126695251279609, 0.0535454404572833, 0.819759308263108}, + {0.0395482239674546, 0.0167143365694676, 0.943737439463078}, + {0.488760306780644, 0.488760306780644, 0.0224793864387125}, + {0.442660473419548, 0.442660473419548, 0.114679053160904}, + {0.367105088607705, 0.367105088607705, 0.265789822784589}, + {0.273576813165278, 0.273576813165278, 0.452846373669445}, + {0.176312358556585, 0.176312358556585, 0.64737528288683}, + {0.0901203458684462, 0.0901203458684462, 0.819759308263107}, + {0.0281312802684611, 0.0281312802684611, 0.943737439463078}, + {0.29039930608799, 0.687121307473297, 0.0224793864387125}, + {0.263008866575801, 0.622312080263295, 0.114679053160904}, + {0.218117268350298, 0.516092908865112, 0.265789822784589}, + {0.16254699001287, 0.384606636317686, 0.452846373669445}, + {0.104756842708482, 0.247867874404688, 0.64737528288683}, + {0.0535454404572833, 0.126695251279609, 0.819759308263108}, + {0.0167143365694675, 0.0395482239674547, 0.943737439463078}, + {0.126329297019669, 0.851191316541618, 0.0224793864387125}, + {0.114413927746761, 0.770907019092335, 0.114679053160904}, + {0.0948852170128627, 0.639324960202548, 0.265789822784589}, + {0.0707110745463252, 0.47644255178423, 0.452846373669445}, + {0.0455712462802949, 0.307053470832875, 0.64737528288683}, + {0.0232932989499898, 0.156947392786903, 0.819759308263108}, + {0.00727105865856026, 0.0489915018783619, 0.943737439463078}, + {0.0248740323760608, 0.952646581185227, 0.0224793864387125}, + {0.0225279156156637, 0.862793031223432, 0.114679053160904}, + {0.0186827443488427, 0.715527432866568, 0.265789822784589}, + {0.0139228951565961, 0.533230731173959, 0.452846373669445}, + {0.00897290400671669, 0.343651813106453, 0.64737528288683}, + {0.00458641254163789, 0.175654279195255, 0.819759308263108}, + {0.00143165958133296, 0.0548309009555892, 0.943737439463078}}; + + static const double FE1[49][15] = \ + {{0.65493168251092, -0.0205789274672045, -0.0189527116015302, 0.00255184165887925, 0.00183297678774451, 0.00259198352982953, 0.290603716006681, -0.219105827318645, 0.0992699619767751, 0.321560655592687, -0.239894622258735, 0.108143664805332, 0.0479081464945106, -0.0153496339773736, -0.0155129067398702}, + {0.230775858060036, -0.0189863795969369, -0.0405222585594037, 0.0119720884518775, 0.00508953632453206, 0.00574753296534107, 0.938538723808041, -0.525109102795761, 0.220123844292779, 0.184369512907595, -0.173400177740129, 0.0900725476951516, 0.174837877403648, -0.0649007648193047, -0.0386088383974671}, + {-0.0263983311889084, -0.0162261198136333, 0.00507672925618625, 0.0235888732361831, -0.0011607649332568, -0.000783521200376718, 0.814143923932396, 0.0894678796271941, -0.0300079529342198, 0.0572273333667857, -0.0921298244490819, 0.0635031309102465, 0.211719351801624, -0.105201833381602, 0.00718112577046323}, + {-0.0116043782850671, -0.0125441321876623, 0.0137291293953672, 0.0308694006898722, -0.0193233108232087, -0.00257306944590875, 0.0969694764122356, 0.887878747410501, -0.0985455745067013, 0.00298135511727236, -0.0317701263137074, 0.0363490005835354, 0.121883793023689, -0.101591987794192, 0.0872916767239754}, + {0.0218099529415095, -0.00839396511637563, -0.0415013584170549, 0.0293325065770879, -0.0356070363345375, 0.0145145425273689, -0.138986464423005, 0.529872971809418, 0.555890139046101, -0.00192641306591023, -0.00445465108536265, 0.0155708278252808, 0.0239295170915481, -0.0615862290518757, 0.101535659675808}, + {-0.0259492611373146, -0.00443369345139607, 0.11113014233463, 0.0195035965961387, -0.0336456931740674, 0.0292255580651792, 0.148148737523861, -0.39036643678642, 1.11930496644439, 0.000828866742906425, 0.00094073305667583, 0.00417914156908884, -0.00628469424034395, -0.0207456373131733, 0.0481636737698413}, + {-0.0353248749092046, -0.00141667572643594, 0.600364037626626, 0.0071441435627288, -0.0149111750403232, 0.0177460160336165, 0.191823296185013, -0.448397033656697, 0.679651825184295, 0.000290997949665299, 0.000243726072526582, 0.000415072891802891, -0.00185070567900358, -0.00235706800659374, 0.00657841751198318}, + {0.19397940489897, -0.038836852447118, -0.0189527116015302, 0.00559929212675889, 0.00511394539374506, 0.0131640681438155, 0.172368070814931, -0.167503953185903, 0.0886978773627891, 0.968671332469604, -0.51167095682965, 0.212019525091192, 0.186010896531717, -0.0382641892907092, -0.0703957494786129}, + {0.0242606988218174, -0.0405525724320025, -0.0405222585594037, 0.0292676684575813, 0.0154071771225109, 0.0291903535434691, 0.532298546745573, -0.398833206249272, 0.196681023714651, 0.531067930789444, -0.398690748637562, 0.196746052784021, 0.674427347852841, -0.175545638211733, -0.175202375741935}, + {-0.0409393785829868, -0.0416654387325616, 0.00507672925618626, 0.067617155738567, -0.00395318666886515, -0.00397931790660805, 0.393269167046055, 0.0668543214935021, -0.0268121562279885, 0.140394503704814, -0.234458308221653, 0.162644810657797, 0.803490563472283, -0.320126570668304, 0.0325871056397637}, + {0.0074160746878218, -0.0394342734932151, 0.0137291293953672, 0.105155064836454, -0.0745313551444684, -0.013068008008114, -0.0491062122584641, 0.634259088040995, -0.088050635944496, -0.00766783889105522, -0.0875365563411642, 0.110634312951984, 0.442198111258687, -0.350116281505072, 0.396119380414741}, + {0.015970300127765, -0.0318100600262602, -0.0415013584170549, 0.116934730443109, -0.153380385402901, 0.0737159108874248, -0.0933636624938861, 0.288425077831199, 0.496688770686045, -0.00657222876685419, -0.0104450119556573, 0.0554627521201485, 0.0661535370784604, -0.237035274833928, 0.460756902722391}, + {-0.0316931436460637, -0.0195134699140883, 0.11113014233463, 0.0880484441685923, -0.157853100866765, 0.148429661486447, 0.175234029467102, -0.436556452191517, 1.00010086302313, 0.00497924036170683, 0.00493580488416056, 0.0168573550942449, -0.0356952130556438, -0.0869652580135685, 0.218561096867636}, + {-0.0332102315466837, -0.00688947855730999, 0.600364037626627, 0.0350160522419851, -0.0739512469766622, 0.0901277965925672, 0.178837996787906, -0.412630630532666, 0.607270044625344, 0.00137786370514668, 0.00111233180701457, 0.00181776087018662, -0.00864955917974902, -0.0104448237879977, 0.029852086324292}, + {-0.0376956175325737, 0.0120551215952569, -0.0189527116015302, -0.00235849719545761, -0.00384020719810918, 0.0302608844064402, 0.0539053418262965, -0.098315178096167, 0.0716010611001644, 0.696374605395548, 0.225519887728122, -0.0720915440033548, 0.250972068421866, 0.0231951571299926, -0.130630371976494}, + {-0.0385978618377363, 0.00421203260995719, -0.0405222585594037, -0.00396748013210338, -0.00339812186399732, 0.0671012869814887, 0.138662020924587, -0.230114751401647, 0.158770090276632, 0.318012225905947, 0.0507347100226551, -0.0215297453751059, 0.894498913320254, 0.0312544707315248, -0.325115531603051}, + {-0.00551401390042556, -0.0111213794704897, 0.00507672925618628, 0.0222300842098284, -0.00186784636347934, -0.00914745182665401, 0.0250624086737194, 0.0368855930425567, -0.0216440223079426, 0.0205671686783165, -0.0611204778385174, 0.0431648913565248, 1.01905954305901, -0.122101720353953, 0.0604704937853235}, + {0.0232837784121718, -0.0300586074517321, 0.0137291293953672, 0.0926843927984531, -0.0835702709051445, -0.030040066295293, -0.115426011167977, 0.304355645490315, -0.0710785776573171, -0.0414316019194668, -0.0470995668315187, 0.0787177167049168, 0.48777893509197, -0.316906634390842, 0.735061738726097}, + {-0.000713687257402987, -0.0413899186446951, -0.0415013584170549, 0.166106745889389, -0.250504204511209, 0.169454353616954, 0.00368049337298404, -0.00870101593638279, 0.400950327956515, 0.000595569332897621, 0.0005146252391984, 0.0635991628291439, -0.00458755739023296, -0.312510351678385, 0.85500681559828}, + {-0.0387733042865956, -0.0348885869800194, 0.11113014233463, 0.164261938052622, -0.314443316341127, 0.341202489964212, 0.203975837927158, -0.466979589938781, 0.807328034545362, 0.0133233937990828, 0.0105173111354129, 0.0253869731120797, -0.0877725996405723, -0.139843173772725, 0.405574450089261}, + {-0.0290420360686864, -0.0147395092155397, 0.600364037626627, 0.075878896205005, -0.163381727865319, 0.207181154389279, 0.154313397085524, -0.348743299107376, 0.490216686828632, 0.00273301232759478, 0.00207700119923646, 0.00317977803574914, -0.016804665702167, -0.0186279615262171, 0.0553952357876583}, + {0.00365494127355517, 0.00365494127355519, -0.0189527116015302, -0.0012580146039302, -0.0381982295649768, 0.0509309727533025, -0.00125801460393015, -0.0381982295649767, 0.0509309727533024, -0.0273525082825465, 0.871557587200981, -0.0273525082825465, 0.164115049695279, 0.164115049695279, -0.156389298140817}, + {0.016031147564392, 0.016031147564392, -0.0405222585594037, -0.0239271120668688, -0.0847017664717951, 0.11293568862906, -0.0239271120668687, -0.0847017664717951, 0.11293568862906, -0.0923585124148332, 0.465486091026599, -0.0923585124148333, 0.554151074489, 0.554151074489, -0.389224871925106}, + {0.0233336587299905, 0.0233336587299905, 0.00507672925618628, -0.0647890461245245, 0.0115468028004737, -0.0153957370672982, -0.0647890461245244, 0.0115468028004738, -0.0153957370672983, -0.0894857006531375, 0.118280272671703, -0.0894857006531375, 0.536914203918825, 0.536914203918825, 0.0723946348634534}, + {0.00742175989654578, 0.00742175989654581, 0.0137291293953672, -0.0282179133868397, 0.0379194914822288, -0.050559321976305, -0.0282179133868396, 0.0379194914822289, -0.0505593219763051, -0.0170472090921069, 0.00266261730549322, -0.0170472090921069, 0.102283254552641, 0.102283254552642, 0.88000813034681}, + {-0.0257340266975475, -0.0257340266975475, -0.0415013584170549, 0.116157794657916, -0.213901755590051, 0.285202340786735, 0.116157794657916, -0.213901755590051, 0.285202340786735, 0.0316355215935064, 0.0108027617072241, 0.0316355215935064, -0.189813129561038, -0.189813129561038, 1.02360510633079}, + {-0.0415686454285033, -0.0415686454285033, 0.11113014233463, 0.20656059818514, -0.43069894669109, 0.574265262254787, 0.20656059818514, -0.43069894669109, 0.574265262254787, 0.0227082661503164, 0.0132865453363341, 0.0227082661503164, -0.136249596901899, -0.136249596901899, 0.485549437191533}, + {-0.0226774234992432, -0.0226774234992431, 0.600364037626627, 0.118589616099474, -0.261524190456717, 0.348698920608956, 0.118589616099474, -0.261524190456716, 0.348698920608955, 0.00353496384473364, 0.00249316558737318, 0.00353496384473372, -0.021209783068402, -0.0212097830684018, 0.0663185897283966}, + {0.0120551215952569, -0.0376956175325737, -0.0189527116015302, 0.0539053418262964, -0.0983151780961671, 0.0716010611001645, -0.00235849719545759, -0.00384020719810907, 0.0302608844064402, -0.0720915440033548, 0.225519887728122, 0.696374605395548, 0.0231951571299925, 0.250972068421866, -0.130630371976494}, + {0.00421203260995724, -0.0385978618377362, -0.0405222585594037, 0.138662020924586, -0.230114751401647, 0.158770090276632, -0.00396748013210343, -0.00339812186399724, 0.0671012869814887, -0.0215297453751062, 0.0507347100226559, 0.318012225905946, 0.0312544707315252, 0.894498913320254, -0.325115531603052}, + {-0.0111213794704897, -0.00551401390042553, 0.00507672925618627, 0.0250624086737194, 0.0368855930425567, -0.0216440223079425, 0.0222300842098284, -0.00186784636347918, -0.009147451826654, 0.0431648913565248, -0.0611204778385175, 0.0205671686783165, -0.122101720353954, 1.01905954305901, 0.0604704937853235}, + {-0.0300586074517321, 0.0232837784121718, 0.0137291293953672, -0.115426011167977, 0.304355645490315, -0.0710785776573171, 0.0926843927984532, -0.0835702709051443, -0.030040066295293, 0.0787177167049168, -0.0470995668315187, -0.0414316019194668, -0.316906634390842, 0.48777893509197, 0.735061738726097}, + {-0.0413899186446951, -0.000713687257402966, -0.0415013584170549, 0.00368049337298409, -0.00870101593638315, 0.400950327956515, 0.166106745889389, -0.250504204511208, 0.169454353616954, 0.0635991628291438, 0.000514625239198445, 0.000595569332897648, -0.312510351678385, -0.00458755739023278, 0.85500681559828}, + {-0.0348885869800194, -0.0387733042865956, 0.11113014233463, 0.203975837927158, -0.466979589938781, 0.807328034545362, 0.164261938052622, -0.314443316341127, 0.341202489964212, 0.0253869731120796, 0.010517311135413, 0.0133233937990828, -0.139843173772725, -0.087772599640572, 0.405574450089261}, + {-0.0147395092155398, -0.0290420360686864, 0.600364037626627, 0.154313397085524, -0.348743299107376, 0.490216686828632, 0.0758788962050049, -0.163381727865318, 0.207181154389279, 0.00317977803574904, 0.0020770011992365, 0.00273301232759483, -0.0186279615262173, -0.0168046657021668, 0.0553952357876583}, + {-0.038836852447118, 0.19397940489897, -0.0189527116015302, 0.172368070814931, -0.167503953185903, 0.0886978773627892, 0.00559929212675891, 0.00511394539374516, 0.0131640681438155, 0.212019525091193, -0.51167095682965, 0.968671332469604, -0.0382641892907092, 0.186010896531717, -0.0703957494786129}, + {-0.0405525724320025, 0.0242606988218175, -0.0405222585594037, 0.532298546745573, -0.398833206249271, 0.196681023714651, 0.0292676684575813, 0.0154071771225112, 0.0291903535434692, 0.196746052784021, -0.398690748637562, 0.531067930789443, -0.175545638211733, 0.674427347852841, -0.175202375741935}, + {-0.0416654387325616, -0.0409393785829868, 0.00507672925618626, 0.393269167046056, 0.0668543214935022, -0.0268121562279884, 0.067617155738567, -0.00395318666886488, -0.00397931790660801, 0.162644810657797, -0.234458308221653, 0.140394503704814, -0.320126570668304, 0.803490563472282, 0.0325871056397638}, + {-0.0394342734932151, 0.00741607468782182, 0.0137291293953672, -0.0491062122584641, 0.634259088040995, -0.088050635944496, 0.105155064836454, -0.0745313551444681, -0.013068008008114, 0.110634312951984, -0.0875365563411642, -0.00766783889105526, -0.350116281505072, 0.442198111258687, 0.396119380414741}, + {-0.0318100600262602, 0.015970300127765, -0.0415013584170549, -0.0933636624938861, 0.288425077831199, 0.496688770686045, 0.116934730443109, -0.153380385402901, 0.0737159108874249, 0.0554627521201484, -0.0104450119556572, -0.00657222876685418, -0.237035274833928, 0.0661535370784606, 0.46075690272239}, + {-0.0195134699140883, -0.0316931436460637, 0.11113014233463, 0.175234029467102, -0.436556452191517, 1.00010086302313, 0.0880484441685923, -0.157853100866765, 0.148429661486447, 0.0168573550942448, 0.0049358048841607, 0.00497924036170686, -0.0869652580135687, -0.0356952130556437, 0.218561096867636}, + {-0.00688947855731001, -0.0332102315466836, 0.600364037626627, 0.178837996787906, -0.412630630532667, 0.607270044625344, 0.035016052241985, -0.0739512469766618, 0.090127796592567, 0.00181776087018654, 0.00111233180701465, 0.00137786370514674, -0.0104448237879978, -0.00864955917974874, 0.0298520863242919}, + {-0.0205789274672046, 0.654931682510919, -0.0189527116015302, 0.290603716006681, -0.219105827318645, 0.0992699619767752, 0.00255184165887931, 0.00183297678774468, 0.00259198352982953, 0.108143664805332, -0.239894622258736, 0.321560655592688, -0.0153496339773739, 0.0479081464945108, -0.0155129067398701}, + {-0.018986379596937, 0.230775858060035, -0.0405222585594037, 0.938538723808041, -0.525109102795761, 0.220123844292779, 0.0119720884518774, 0.0050895363245325, 0.00574753296534108, 0.090072547695152, -0.17340017774013, 0.184369512907596, -0.0649007648193052, 0.17483787740365, -0.0386088383974673}, + {-0.0162261198136334, -0.0263983311889083, 0.00507672925618625, 0.814143923932396, 0.0894678796271942, -0.0300079529342197, 0.0235888732361831, -0.00116076493325639, -0.000783521200376745, 0.0635031309102465, -0.0921298244490819, 0.0572273333667858, -0.105201833381602, 0.211719351801625, 0.00718112577046345}, + {-0.0125441321876624, -0.011604378285067, 0.0137291293953672, 0.0969694764122352, 0.887878747410501, -0.0985455745067012, 0.0308694006898726, -0.0193233108232086, -0.00257306944590875, 0.0363490005835357, -0.0317701263137077, 0.00298135511727235, -0.101591987794193, 0.12188379302369, 0.087291676723976}, + {-0.00839396511637566, 0.0218099529415095, -0.0415013584170549, -0.138986464423005, 0.529872971809417, 0.555890139046101, 0.0293325065770882, -0.0356070363345374, 0.014514542527369, 0.0155708278252808, -0.00445465108536261, -0.00192641306591026, -0.0615862290518763, 0.0239295170915484, 0.101535659675808}, + {-0.00443369345139607, -0.0259492611373146, 0.11113014233463, 0.148148737523861, -0.39036643678642, 1.11930496644439, 0.0195035965961387, -0.033645693174067, 0.0292255580651793, 0.00417914156908869, 0.000940733056676031, 0.000828866742906418, -0.0207456373131734, -0.00628469424034378, 0.0481636737698411}, + {-0.00141667572643595, -0.0353248749092046, 0.600364037626627, 0.191823296185013, -0.448397033656697, 0.679651825184295, 0.00714414356272866, -0.0149111750403226, 0.0177460160336164, 0.000415072891802759, 0.000243726072526686, 0.000290997949665306, -0.00235706800659391, -0.00185070567900331, 0.00657841751198318}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 225; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 34496 + for (unsigned int ip = 0; ip < 49; 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 = 24 + for (unsigned int r = 0; r < 3; r++) + { + F0 += FE0[ip][r]*w[3][r]; + F1 += FE0[ip][r]*w[2][r]; + F2 += FE0[ip][r]*w[0][r]; + F3 += FE0[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 5 + double I[1]; + // Number of operations: 5 + I[0] = F0*F1*F2*F3*W49[ip]*det; + + + // Number of operations for primary indices: 675 + for (unsigned int j = 0; j < 15; j++) + { + for (unsigned int k = 0; k < 15; k++) + { + // Number of operations to compute entry: 3 + A[j*15 + k] += FE1[ip][j]*FE1[ip][k]*I[0]; + }// 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 mass_matrix_f4_p1_q4_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f4_p1_q4_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_p1_q4_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 3), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1))))), 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 4; + } + + /// 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 mass_matrix_f4_p1_q4_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f4_p1_q4_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f4_p1_q4_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f4_p1_q4_quadrature_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f4_p1_q4_quadrature_finite_element_0(); + break; + } + case 5: + { + return new mass_matrix_f4_p1_q4_quadrature_finite_element_0(); + 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 mass_matrix_f4_p1_q4_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f4_p1_q4_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f4_p1_q4_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f4_p1_q4_quadrature_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f4_p1_q4_quadrature_dofmap_0(); + break; + } + case 5: + { + return new mass_matrix_f4_p1_q4_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f4_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/mass_matrix_2d/mass_matrix_f4_p1_q4_tensor.h b/mass_matrix_2d/mass_matrix_f4_p1_q4_tensor.h new file mode 100644 index 0000000..9a46a69 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f4_p1_q4_tensor.h @@ -0,0 +1,6687 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F4_P1_Q4_TENSOR_H +#define __MASS_MATRIX_F4_P1_Q4_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f4_p1_q4_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f4_p1_q4_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_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 mass_matrix_f4_p1_q4_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f4_p1_q4_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f4_p1_q4_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_p1_q4_tensor_finite_element_1() + { + // 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.0224478343233824, 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.0412393049421162, -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.0388807895679869, 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.0439885919382571, 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.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 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.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.00927360943924092, 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.0535412090610519}; + + // 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.0622092633087791, -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.251415744421884, 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.0224478343233824, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0412393049421162, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0388807895679869, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0253968253968254, 0.139104141588614, -0.0718330698348239, 0.0311046316543896, 0.0633508128977598, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527354, 0.0109971479845644, 0.00634920634920633, 0.0, 0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568409, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.125707872210942, -0.131965775814772, -0.0253968253968254, 0.139104141588614, 0.0718330698348239, 0.0311046316543895, -0.0633508128977598, 0.026770604530526, 0.0622092633087791, 0.0478887132232159, 0.0, -0.0566626896277046, -0.0838052481406278, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0314269680527351, -0.0109971479845643, 0.00634920634920644, 0.0, -0.188561808316413, -0.163299316185545, 0.0, 0.0936971158568408, 0.0, -0.0419026240703139, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0439885919382571, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0126984126984127, -0.243432247780074, 0.0, 0.0544331053951818, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.00927360943924092, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0622092633087791, -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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.251415744421884, 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.48683298050514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4, 0.0, 7.07106781186548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5.29150262212918, 0.0, -2.99332590941916, 13.6626010212795, 0.0, 0.611010092660776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 4.38178046004133, 0.0, 0.0, 12.5219806739988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.46410161513776, 0.0, 7.83836717690617, 0.0, 0.0, 8.40000000000001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 10.9544511501033, 0.0, 0.0, -3.83325938999964, 0.0, 17.7482393492989, 0.0, 0.553283335172491, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.73286382647969, 0.0, 3.3466401061363, 4.36435780471985, 0.0, -5.07468037933239, 0.0, 17.0084012854152, 0.0, 1.52127765851133, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 2.44948974278318, 0.0, 0.0, 9.14285714285715, 0.0, 0.0, 0.0, 14.8461497791618, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {3.09838667696593, 0.0, 7.66811580507233, 0.0, 0.0, 10.733126291999, 0.0, 0.0, 0.0, 9.2951600308978, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[15][15] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.64575131106459, 5.18459255872629, -1.49666295470958, 6.83130051063973, -1.05830052442584, 0.305505046330389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.23606797749979, 2.19089023002066, 2.52982212813471, 8.08290376865476, 6.26099033699942, -1.80739222823013, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.73205080756888, -5.09116882454314, 3.91918358845309, 0.0, 9.69948452238572, 4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {5, 0.0, -2.82842712474619, 0.0, 0.0, 12.1243556529821, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.68328157299975, 5.47722557505166, -1.89736659610103, 7.4230748895809, -1.91662969499982, 0.663940002206987, 8.87411967464942, -1.07142857142857, 0.276641667586245, -0.0958314847499915, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.36643191323985, 2.89827534923789, 1.67332005306815, 2.18217890235992, 5.74704893215391, -2.53734018966619, 10.0623058987491, 8.50420064270761, -2.1957751641342, 0.760638829255664, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2, 1.22474487139159, 3.53553390593274, -7.37711113563318, 4.57142857142858, 1.64957219768465, 0.0, 11.4997781699989, 7.4230748895809, -2.57142857142857, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.54919333848296, 6.64078308635359, 3.83405790253616, 0.0, -6.19677335393186, 5.36656314599949, 0.0, 0.0, 13.4164078649987, 4.6475800154489, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.57770876399967, 0.0, 8.85437744847147, 0.0, 0.0, -3.09838667696594, 0.0, 0.0, 0.0, 16.0996894379985, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[15][15] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 15; t++) + { + for (unsigned int u = 0; u < 15; u++) + { + for (unsigned int tu = 0; tu < 15; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 15; s++) + { + for (unsigned int t = 0; t < 15; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f4_p1_q4_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f4_p1_q4_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f4_p1_q4_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f4_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 mass_matrix_f4_p1_q4_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f4_p1_q4_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f4_p1_q4_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f4_p1_q4_tensor_dofmap_1() + { + // 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.0*m.num_entities[1] + 3.0*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 mass_matrix_f4_p1_q4_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 mass_matrix_f4_p1_q4_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f4_p1_q4_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 202 + // Number of operations (multiply-add pairs) for tensor contraction: 6443 + // Total number of operations (multiply-add pairs): 6654 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0_0 = det*w[3][0]*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_0_0_0_1 = det*w[3][0]*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_0_0_0_2 = det*w[3][0]*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_0_0_1_0 = det*w[3][0]*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_0_0_1_1 = det*w[3][0]*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_0_0_1_2 = det*w[3][0]*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_0_0_2_0 = det*w[3][0]*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_0_0_2_1 = det*w[3][0]*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_0_0_2_2 = det*w[3][0]*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_0_1_0_0 = det*w[3][0]*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_0_1_0_1 = det*w[3][0]*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_0_1_0_2 = det*w[3][0]*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_0_1_1_0 = det*w[3][0]*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_0_1_1_1 = det*w[3][0]*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_0_1_1_2 = det*w[3][0]*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_0_1_2_0 = det*w[3][0]*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_0_1_2_1 = det*w[3][0]*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_0_1_2_2 = det*w[3][0]*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_0_2_0_0 = det*w[3][0]*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_0_2_0_1 = det*w[3][0]*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_0_2_0_2 = det*w[3][0]*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_0_2_1_0 = det*w[3][0]*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_0_2_1_1 = det*w[3][0]*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_0_2_1_2 = det*w[3][0]*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_0_2_2_0 = det*w[3][0]*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_0_2_2_1 = det*w[3][0]*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_0_2_2_2 = det*w[3][0]*w[2][2]*w[0][2]*w[1][2]*(1.0); + const double G0_1_0_0_0 = det*w[3][1]*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_1_0_0_1 = det*w[3][1]*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_1_0_0_2 = det*w[3][1]*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_1_0_1_0 = det*w[3][1]*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_1_0_1_1 = det*w[3][1]*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_1_0_1_2 = det*w[3][1]*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_1_0_2_0 = det*w[3][1]*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_1_0_2_1 = det*w[3][1]*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_1_0_2_2 = det*w[3][1]*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_1_1_0_0 = det*w[3][1]*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_1_1_0_1 = det*w[3][1]*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_1_1_0_2 = det*w[3][1]*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_1_1_1_0 = det*w[3][1]*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_1_1_1_1 = det*w[3][1]*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_1_1_1_2 = det*w[3][1]*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_1_1_2_0 = det*w[3][1]*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_1_1_2_1 = det*w[3][1]*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_1_1_2_2 = det*w[3][1]*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_1_2_0_0 = det*w[3][1]*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_1_2_0_1 = det*w[3][1]*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_1_2_0_2 = det*w[3][1]*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_1_2_1_0 = det*w[3][1]*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_1_2_1_1 = det*w[3][1]*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_1_2_1_2 = det*w[3][1]*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_1_2_2_0 = det*w[3][1]*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_1_2_2_1 = det*w[3][1]*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_1_2_2_2 = det*w[3][1]*w[2][2]*w[0][2]*w[1][2]*(1.0); + const double G0_2_0_0_0 = det*w[3][2]*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_2_0_0_1 = det*w[3][2]*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_2_0_0_2 = det*w[3][2]*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_2_0_1_0 = det*w[3][2]*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_2_0_1_1 = det*w[3][2]*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_2_0_1_2 = det*w[3][2]*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_2_0_2_0 = det*w[3][2]*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_2_0_2_1 = det*w[3][2]*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_2_0_2_2 = det*w[3][2]*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_2_1_0_0 = det*w[3][2]*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_2_1_0_1 = det*w[3][2]*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_2_1_0_2 = det*w[3][2]*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_2_1_1_0 = det*w[3][2]*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_2_1_1_1 = det*w[3][2]*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_2_1_1_2 = det*w[3][2]*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_2_1_2_0 = det*w[3][2]*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_2_1_2_1 = det*w[3][2]*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_2_1_2_2 = det*w[3][2]*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_2_2_0_0 = det*w[3][2]*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_2_2_0_1 = det*w[3][2]*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_2_2_0_2 = det*w[3][2]*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_2_2_1_0 = det*w[3][2]*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_2_2_1_1 = det*w[3][2]*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_2_2_1_2 = det*w[3][2]*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_2_2_2_0 = det*w[3][2]*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_2_2_2_1 = det*w[3][2]*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_2_2_2_2 = det*w[3][2]*w[2][2]*w[0][2]*w[1][2]*(1.0); + + // Compute element tensor + A[108] = 1.26857269714437e-05*G0_0_0_0_0 + 8.45715131429566e-06*G0_0_0_0_1 + 7.75238870477095e-05*G0_0_0_0_2 + 8.45715131429565e-06*G0_0_0_1_0 + 5.49714835429218e-06*G0_0_0_1_1 + 1.36723946247779e-05*G0_0_0_1_2 + 7.75238870477095e-05*G0_0_0_2_0 + 1.36723946247779e-05*G0_0_0_2_1 + 7.75238870477095e-05*G0_0_0_2_2 + 8.45715131429565e-06*G0_0_1_0_0 + 5.49714835429218e-06*G0_0_1_0_1 + 1.36723946247779e-05*G0_0_1_0_2 + 5.49714835429218e-06*G0_0_1_1_0 + 1.07123916647747e-05*G0_0_1_1_1 + 5.49714835429218e-06*G0_0_1_1_2 + 1.36723946247779e-05*G0_0_1_2_0 + 5.49714835429218e-06*G0_0_1_2_1 + 8.45715131429561e-06*G0_0_1_2_2 + 7.75238870477095e-05*G0_0_2_0_0 + 1.36723946247779e-05*G0_0_2_0_1 + 7.75238870477095e-05*G0_0_2_0_2 + 1.36723946247779e-05*G0_0_2_1_0 + 5.49714835429218e-06*G0_0_2_1_1 + 8.45715131429561e-06*G0_0_2_1_2 + 7.75238870477095e-05*G0_0_2_2_0 + 8.45715131429561e-06*G0_0_2_2_1 + 1.26857269714435e-05*G0_0_2_2_2 + 8.45715131429566e-06*G0_1_0_0_0 + 5.49714835429218e-06*G0_1_0_0_1 + 1.36723946247779e-05*G0_1_0_0_2 + 5.49714835429218e-06*G0_1_0_1_0 + 1.07123916647746e-05*G0_1_0_1_1 + 5.49714835429218e-06*G0_1_0_1_2 + 1.36723946247779e-05*G0_1_0_2_0 + 5.49714835429218e-06*G0_1_0_2_1 + 8.45715131429561e-06*G0_1_0_2_2 + 5.49714835429218e-06*G0_1_1_0_0 + 1.07123916647746e-05*G0_1_1_0_1 + 5.49714835429218e-06*G0_1_1_0_2 + 1.07123916647747e-05*G0_1_1_1_0 + 6.9066735733417e-05*G0_1_1_1_1 + 1.49409673219228e-05*G0_1_1_1_2 + 5.49714835429217e-06*G0_1_1_2_0 + 1.49409673219228e-05*G0_1_1_2_1 + 4.22857565714795e-06*G0_1_1_2_2 + 1.36723946247779e-05*G0_1_2_0_0 + 5.49714835429217e-06*G0_1_2_0_1 + 8.45715131429561e-06*G0_1_2_0_2 + 5.49714835429218e-06*G0_1_2_1_0 + 1.49409673219228e-05*G0_1_2_1_1 + 4.22857565714795e-06*G0_1_2_1_2 + 8.45715131429561e-06*G0_1_2_2_0 + 4.22857565714795e-06*G0_1_2_2_1 - 5.21524331048227e-05*G0_1_2_2_2 + 7.75238870477095e-05*G0_2_0_0_0 + 1.36723946247779e-05*G0_2_0_0_1 + 7.75238870477095e-05*G0_2_0_0_2 + 1.36723946247779e-05*G0_2_0_1_0 + 5.49714835429218e-06*G0_2_0_1_1 + 8.45715131429561e-06*G0_2_0_1_2 + 7.75238870477095e-05*G0_2_0_2_0 + 8.45715131429561e-06*G0_2_0_2_1 + 1.26857269714435e-05*G0_2_0_2_2 + 1.36723946247779e-05*G0_2_1_0_0 + 5.49714835429218e-06*G0_2_1_0_1 + 8.45715131429561e-06*G0_2_1_0_2 + 5.49714835429218e-06*G0_2_1_1_0 + 1.49409673219228e-05*G0_2_1_1_1 + 4.22857565714795e-06*G0_2_1_1_2 + 8.45715131429561e-06*G0_2_1_2_0 + 4.22857565714795e-06*G0_2_1_2_1 - 5.21524331048227e-05*G0_2_1_2_2 + 7.75238870477095e-05*G0_2_2_0_0 + 8.45715131429561e-06*G0_2_2_0_1 + 1.26857269714435e-05*G0_2_2_0_2 + 8.45715131429561e-06*G0_2_2_1_0 + 4.22857565714794e-06*G0_2_2_1_1 - 5.21524331048227e-05*G0_2_2_1_2 + 1.26857269714435e-05*G0_2_2_2_0 - 5.21524331048227e-05*G0_2_2_2_1 - 0.000661067327734104*G0_2_2_2_2; + A[181] = -0.000309390785581314*G0_0_0_0_0 - 3.31238426476579e-05*G0_0_0_0_1 - 9.16191392382024e-05*G0_0_0_0_2 - 3.31238426476579e-05*G0_0_0_1_0 + 4.93333826667235e-06*G0_0_0_1_1 - 1.17695355790614e-05*G0_0_0_1_2 - 9.16191392382024e-05*G0_0_0_2_0 - 1.17695355790614e-05*G0_0_0_2_1 - 4.46114731829093e-05*G0_0_0_2_2 - 3.31238426476579e-05*G0_0_1_0_0 + 4.93333826667235e-06*G0_0_1_0_1 - 1.17695355790614e-05*G0_0_1_0_2 + 4.93333826667235e-06*G0_0_1_1_0 + 4.93333826667233e-06*G0_0_1_1_1 + 1.97333530666894e-06*G0_0_1_1_2 - 1.17695355790614e-05*G0_0_1_2_0 + 1.97333530666894e-06*G0_0_1_2_1 - 6.9771498342939e-06*G0_0_1_2_2 - 9.16191392382024e-05*G0_0_2_0_0 - 1.17695355790614e-05*G0_0_2_0_1 - 4.46114731829093e-05*G0_0_2_0_2 - 1.17695355790614e-05*G0_0_2_1_0 + 1.97333530666894e-06*G0_0_2_1_1 - 6.9771498342939e-06*G0_0_2_1_2 - 4.46114731829093e-05*G0_0_2_2_0 - 6.9771498342939e-06*G0_0_2_2_1 - 2.73447892495558e-05*G0_0_2_2_2 - 3.31238426476579e-05*G0_1_0_0_0 + 4.93333826667235e-06*G0_1_0_0_1 - 1.17695355790614e-05*G0_1_0_0_2 + 4.93333826667235e-06*G0_1_0_1_0 + 4.93333826667233e-06*G0_1_0_1_1 + 1.97333530666894e-06*G0_1_0_1_2 - 1.17695355790614e-05*G0_1_0_2_0 + 1.97333530666894e-06*G0_1_0_2_1 - 6.9771498342939e-06*G0_1_0_2_2 + 4.93333826667235e-06*G0_1_1_0_0 + 4.93333826667233e-06*G0_1_1_0_1 + 1.97333530666894e-06*G0_1_1_0_2 + 4.93333826667233e-06*G0_1_1_1_0 - 9.37334270667775e-05*G0_1_1_1_1 + 4.93333826667234e-06*G0_1_1_1_2 + 1.97333530666894e-06*G0_1_1_2_0 + 4.93333826667233e-06*G0_1_1_2_1 - 1.17695355790614e-05*G0_1_2_0_0 + 1.97333530666894e-06*G0_1_2_0_1 - 6.9771498342939e-06*G0_1_2_0_2 + 1.97333530666894e-06*G0_1_2_1_0 + 4.93333826667234e-06*G0_1_2_1_1 - 6.9771498342939e-06*G0_1_2_2_0 - 4.36952817905277e-06*G0_1_2_2_2 - 9.16191392382024e-05*G0_2_0_0_0 - 1.17695355790614e-05*G0_2_0_0_1 - 4.46114731829093e-05*G0_2_0_0_2 - 1.17695355790614e-05*G0_2_0_1_0 + 1.97333530666894e-06*G0_2_0_1_1 - 6.9771498342939e-06*G0_2_0_1_2 - 4.46114731829093e-05*G0_2_0_2_0 - 6.9771498342939e-06*G0_2_0_2_1 - 2.73447892495558e-05*G0_2_0_2_2 - 1.17695355790614e-05*G0_2_1_0_0 + 1.97333530666894e-06*G0_2_1_0_1 - 6.9771498342939e-06*G0_2_1_0_2 + 1.97333530666894e-06*G0_2_1_1_0 + 4.93333826667233e-06*G0_2_1_1_1 - 6.9771498342939e-06*G0_2_1_2_0 - 4.36952817905277e-06*G0_2_1_2_2 - 4.46114731829093e-05*G0_2_2_0_0 - 6.9771498342939e-06*G0_2_2_0_1 - 2.73447892495558e-05*G0_2_2_0_2 - 6.9771498342939e-06*G0_2_2_1_0 - 4.36952817905277e-06*G0_2_2_1_2 - 2.73447892495558e-05*G0_2_2_2_0 - 4.36952817905277e-06*G0_2_2_2_1 + 1.19809643619187e-05*G0_2_2_2_2; + A[192] = 0.00994560994561162*G0_0_0_0_0 + 0.0030784030784036*G0_0_0_0_1 + 0.0030784030784036*G0_0_0_0_2 + 0.0030784030784036*G0_0_0_1_0 + 0.00138020709449304*G0_0_0_1_1 + 0.00103515532086978*G0_0_0_1_2 + 0.0030784030784036*G0_0_0_2_0 + 0.00103515532086978*G0_0_0_2_1 + 0.00138020709449304*G0_0_0_2_2 + 0.0030784030784036*G0_0_1_0_0 + 0.00138020709449304*G0_0_1_0_1 + 0.00103515532086978*G0_0_1_0_2 + 0.00138020709449304*G0_0_1_1_0 + 0.000913372341943924*G0_0_1_1_1 + 0.000548023405166354*G0_0_1_1_2 + 0.00103515532086978*G0_0_1_2_0 + 0.000548023405166355*G0_0_1_2_1 + 0.000548023405166354*G0_0_1_2_2 + 0.0030784030784036*G0_0_2_0_0 + 0.00103515532086978*G0_0_2_0_1 + 0.00138020709449304*G0_0_2_0_2 + 0.00103515532086978*G0_0_2_1_0 + 0.000548023405166355*G0_0_2_1_1 + 0.000548023405166354*G0_0_2_1_2 + 0.00138020709449304*G0_0_2_2_0 + 0.000548023405166354*G0_0_2_2_1 + 0.000913372341943924*G0_0_2_2_2 + 0.0030784030784036*G0_1_0_0_0 + 0.00138020709449304*G0_1_0_0_1 + 0.00103515532086978*G0_1_0_0_2 + 0.00138020709449304*G0_1_0_1_0 + 0.000913372341943924*G0_1_0_1_1 + 0.000548023405166355*G0_1_0_1_2 + 0.00103515532086978*G0_1_0_2_0 + 0.000548023405166355*G0_1_0_2_1 + 0.000548023405166354*G0_1_0_2_2 + 0.00138020709449304*G0_1_1_0_0 + 0.000913372341943924*G0_1_1_0_1 + 0.000548023405166355*G0_1_1_0_2 + 0.000913372341943924*G0_1_1_1_0 + 0.00128548699977293*G0_1_1_1_1 + 0.000642743499886466*G0_1_1_1_2 + 0.000548023405166355*G0_1_1_2_0 + 0.000642743499886465*G0_1_1_2_1 + 0.000514194799909172*G0_1_1_2_2 + 0.00103515532086978*G0_1_2_0_0 + 0.000548023405166355*G0_1_2_0_1 + 0.000548023405166354*G0_1_2_0_2 + 0.000548023405166355*G0_1_2_1_0 + 0.000642743499886465*G0_1_2_1_1 + 0.000514194799909172*G0_1_2_1_2 + 0.000548023405166354*G0_1_2_2_0 + 0.000514194799909172*G0_1_2_2_1 + 0.000642743499886465*G0_1_2_2_2 + 0.0030784030784036*G0_2_0_0_0 + 0.00103515532086978*G0_2_0_0_1 + 0.00138020709449304*G0_2_0_0_2 + 0.00103515532086978*G0_2_0_1_0 + 0.000548023405166355*G0_2_0_1_1 + 0.000548023405166354*G0_2_0_1_2 + 0.00138020709449304*G0_2_0_2_0 + 0.000548023405166354*G0_2_0_2_1 + 0.000913372341943924*G0_2_0_2_2 + 0.00103515532086978*G0_2_1_0_0 + 0.000548023405166355*G0_2_1_0_1 + 0.000548023405166354*G0_2_1_0_2 + 0.000548023405166355*G0_2_1_1_0 + 0.000642743499886466*G0_2_1_1_1 + 0.000514194799909172*G0_2_1_1_2 + 0.000548023405166354*G0_2_1_2_0 + 0.000514194799909172*G0_2_1_2_1 + 0.000642743499886465*G0_2_1_2_2 + 0.00138020709449304*G0_2_2_0_0 + 0.000548023405166354*G0_2_2_0_1 + 0.000913372341943924*G0_2_2_0_2 + 0.000548023405166354*G0_2_2_1_0 + 0.000514194799909172*G0_2_2_1_1 + 0.000642743499886465*G0_2_2_1_2 + 0.000913372341943924*G0_2_2_2_0 + 0.000642743499886465*G0_2_2_2_1 + 0.00128548699977293*G0_2_2_2_2; + A[21] = -0.000306689195578136*G0_0_0_0_0 - 3.07746339492423e-05*G0_0_0_0_1 - 5.63810087619707e-05*G0_0_0_0_2 - 3.07746339492423e-05*G0_0_0_1_0 - 4.38127422254481e-06*G0_0_0_1_1 - 5.87302174603861e-06*G0_0_0_1_2 - 5.63810087619707e-05*G0_0_0_2_0 - 5.87302174603861e-06*G0_0_0_2_1 - 1.38016011031907e-05*G0_0_0_2_2 - 3.07746339492423e-05*G0_0_1_0_0 - 4.38127422254481e-06*G0_0_1_0_1 - 5.87302174603861e-06*G0_0_1_0_2 - 4.38127422254481e-06*G0_0_1_1_0 - 1.12762017523941e-06*G0_0_1_1_2 - 5.87302174603861e-06*G0_0_1_2_0 - 1.12762017523941e-06*G0_0_1_2_1 - 1.71492234984327e-06*G0_0_1_2_2 - 5.63810087619707e-05*G0_0_2_0_0 - 5.87302174603861e-06*G0_0_2_0_1 - 1.38016011031907e-05*G0_0_2_0_2 - 5.87302174603861e-06*G0_0_2_1_0 - 1.12762017523941e-06*G0_0_2_1_1 - 1.71492234984327e-06*G0_0_2_1_2 - 1.38016011031907e-05*G0_0_2_2_0 - 1.71492234984327e-06*G0_0_2_2_1 - 8.73905635810544e-06*G0_0_2_2_2 - 3.07746339492423e-05*G0_1_0_0_0 - 4.38127422254481e-06*G0_1_0_0_1 - 5.87302174603861e-06*G0_1_0_0_2 - 4.38127422254481e-06*G0_1_0_1_0 - 1.12762017523941e-06*G0_1_0_1_2 - 5.87302174603861e-06*G0_1_0_2_0 - 1.12762017523941e-06*G0_1_0_2_1 - 1.71492234984327e-06*G0_1_0_2_2 - 4.38127422254481e-06*G0_1_1_0_0 - 1.12762017523941e-06*G0_1_1_0_2 + 1.5622237844462e-05*G0_1_1_1_1 - 1.12762017523941e-06*G0_1_1_2_0 - 5.87302174603861e-06*G0_1_2_0_0 - 1.12762017523941e-06*G0_1_2_0_1 - 1.71492234984327e-06*G0_1_2_0_2 - 1.12762017523941e-06*G0_1_2_1_0 - 1.71492234984327e-06*G0_1_2_2_0 - 5.82603757207028e-06*G0_1_2_2_2 - 5.63810087619707e-05*G0_2_0_0_0 - 5.87302174603861e-06*G0_2_0_0_1 - 1.38016011031907e-05*G0_2_0_0_2 - 5.87302174603861e-06*G0_2_0_1_0 - 1.12762017523941e-06*G0_2_0_1_1 - 1.71492234984327e-06*G0_2_0_1_2 - 1.38016011031907e-05*G0_2_0_2_0 - 1.71492234984327e-06*G0_2_0_2_1 - 8.73905635810544e-06*G0_2_0_2_2 - 5.87302174603861e-06*G0_2_1_0_0 - 1.12762017523941e-06*G0_2_1_0_1 - 1.71492234984327e-06*G0_2_1_0_2 - 1.12762017523941e-06*G0_2_1_1_0 - 1.71492234984327e-06*G0_2_1_2_0 - 5.82603757207028e-06*G0_2_1_2_2 - 1.38016011031907e-05*G0_2_2_0_0 - 1.71492234984327e-06*G0_2_2_0_1 - 8.73905635810544e-06*G0_2_2_0_2 - 1.71492234984327e-06*G0_2_2_1_0 - 5.82603757207028e-06*G0_2_2_1_2 - 8.73905635810544e-06*G0_2_2_2_0 - 5.82603757207028e-06*G0_2_2_2_1 - 6.847943355881e-05*G0_2_2_2_2; + A[117] = -A[21] - 0.00243789132678062*G0_0_0_0_0 - 0.000504375107549795*G0_0_0_0_1 + 2.81905043809863e-06*G0_0_0_0_2 - 0.000504375107549795*G0_0_0_1_0 - 0.000173524300508456*G0_0_0_1_1 + 2.8190504380986e-06*G0_0_0_2_0 + 0.000338015893571506*G0_0_0_2_2 - 0.000504375107549795*G0_0_1_0_0 - 0.000173524300508456*G0_0_1_0_1 - 0.000173524300508456*G0_0_1_1_0 - 8.15175418350158e-05*G0_0_1_1_1 + 9.97708934217038e-05*G0_0_1_2_2 + 2.81905043809859e-06*G0_0_2_0_0 + 0.000338015893571506*G0_0_2_0_2 + 9.97708934217038e-05*G0_0_2_1_2 + 0.000338015893571506*G0_0_2_2_0 + 9.97708934217038e-05*G0_0_2_2_1 + 0.000473318568556743*G0_0_2_2_2 - 0.000504375107549795*G0_1_0_0_0 - 0.000173524300508456*G0_1_0_0_1 - 0.000173524300508456*G0_1_0_1_0 - 8.15175418350157e-05*G0_1_0_1_1 + 9.97708934217038e-05*G0_1_0_2_2 - 0.000173524300508456*G0_1_1_0_0 - 8.15175418350158e-05*G0_1_1_0_1 - 8.15175418350158e-05*G0_1_1_1_0 - 1.82063674127208e-05*G0_1_1_1_1 + 4.33194083987806e-05*G0_1_1_1_2 + 4.33194083987806e-05*G0_1_1_2_1 + 0.000107652488604888*G0_1_1_2_2 + 9.97708934217039e-05*G0_1_2_0_2 + 4.33194083987806e-05*G0_1_2_1_1 + 0.000107652488604888*G0_1_2_1_2 + 9.97708934217038e-05*G0_1_2_2_0 + 0.000107652488604888*G0_1_2_2_1 + 0.000281717107113979*G0_1_2_2_2 + 2.8190504380986e-06*G0_2_0_0_0 + 0.000338015893571506*G0_2_0_0_2 + 9.97708934217038e-05*G0_2_0_1_2 + 0.000338015893571506*G0_2_0_2_0 + 9.97708934217038e-05*G0_2_0_2_1 + 0.000473318568556743*G0_2_0_2_2 + 9.97708934217039e-05*G0_2_1_0_2 + 4.33194083987806e-05*G0_2_1_1_1 + 0.000107652488604888*G0_2_1_1_2 + 9.97708934217038e-05*G0_2_1_2_0 + 0.000107652488604888*G0_2_1_2_1 + 0.000281717107113979*G0_2_1_2_2 + 0.000338015893571506*G0_2_2_0_0 + 9.97708934217038e-05*G0_2_2_0_1 + 0.000473318568556743*G0_2_2_0_2 + 9.97708934217038e-05*G0_2_2_1_0 + 0.000107652488604888*G0_2_2_1_1 + 0.000281717107113979*G0_2_2_1_2 + 0.000473318568556743*G0_2_2_2_0 + 0.000281717107113979*G0_2_2_2_1 + 0.00111552175044257*G0_2_2_2_2; + A[199] = A[117] + 0.0020973735259453*G0_0_0_0_0 + 0.000392411820983315*G0_0_0_0_1 - 1.52228723657322e-05*G0_0_0_0_2 + 0.000392411820983315*G0_0_0_1_0 - 1.52228723657322e-05*G0_0_0_2_0 - 0.000243565957851713*G0_0_0_2_2 + 0.000392411820983315*G0_0_1_0_0 - 0.000392411820983315*G0_0_1_1_1 - 1.52228723657322e-05*G0_0_2_0_0 - 0.000243565957851713*G0_0_2_0_2 - 0.000243565957851713*G0_0_2_2_0 - 0.000194514480228798*G0_0_2_2_2 + 0.000392411820983315*G0_1_0_0_0 - 0.000392411820983315*G0_1_0_1_1 - 0.000392411820983315*G0_1_1_0_1 - 0.000392411820983315*G0_1_1_1_0 - 0.00209737352594531*G0_1_1_1_1 + 1.52228723657328e-05*G0_1_1_1_2 + 1.52228723657328e-05*G0_1_1_2_1 + 0.000243565957851714*G0_1_1_2_2 + 1.52228723657329e-05*G0_1_2_1_1 + 0.000243565957851714*G0_1_2_1_2 + 0.000243565957851714*G0_1_2_2_1 + 0.000194514480228799*G0_1_2_2_2 - 1.52228723657322e-05*G0_2_0_0_0 - 0.000243565957851713*G0_2_0_0_2 - 0.000243565957851713*G0_2_0_2_0 - 0.000194514480228798*G0_2_0_2_2 + 1.52228723657328e-05*G0_2_1_1_1 + 0.000243565957851714*G0_2_1_1_2 + 0.000243565957851714*G0_2_1_2_1 + 0.000194514480228799*G0_2_1_2_2 - 0.000243565957851713*G0_2_2_0_0 - 0.000194514480228798*G0_2_2_0_2 + 0.000243565957851714*G0_2_2_1_1 + 0.000194514480228799*G0_2_2_1_2 - 0.000194514480228798*G0_2_2_2_0 + 0.000194514480228799*G0_2_2_2_1; + A[52] = A[108]; + A[26] = A[21] + 0.000180066846733544*G0_0_0_0_0 + 6.10794261588016e-06*G0_0_0_0_1 + 3.10565389930522e-05*G0_0_0_0_2 + 6.10794261588016e-06*G0_0_0_1_0 + 3.10565389930522e-05*G0_0_0_2_0 + 1.13936621873149e-06*G0_0_0_2_2 + 6.10794261588016e-06*G0_0_1_0_0 + 9.7351208462336e-05*G0_0_1_1_1 + 3.10565389930522e-05*G0_0_2_0_0 + 1.13936621873149e-06*G0_0_2_0_2 + 1.13936621873149e-06*G0_0_2_2_0 - 3.9231785263538e-06*G0_0_2_2_2 + 6.10794261588016e-06*G0_1_0_0_0 + 9.7351208462336e-05*G0_1_0_1_1 + 9.7351208462336e-05*G0_1_1_0_1 + 9.7351208462336e-05*G0_1_1_1_0 + 0.00149891261002398*G0_1_1_1_1 + 4.91689380578354e-05*G0_1_1_1_2 + 4.91689380578354e-05*G0_1_1_2_1 + 4.91689380578354e-05*G0_1_2_1_1 + 3.10565389930522e-05*G0_2_0_0_0 + 1.13936621873149e-06*G0_2_0_0_2 + 1.13936621873149e-06*G0_2_0_2_0 - 3.9231785263538e-06*G0_2_0_2_2 + 4.91689380578354e-05*G0_2_1_1_1 + 1.13936621873149e-06*G0_2_2_0_0 - 3.9231785263538e-06*G0_2_2_0_2 - 3.9231785263538e-06*G0_2_2_2_0 + 4.31549637898916e-05*G0_2_2_2_2; + A[16] = 2.69483602816982e-05*G0_0_0_0_0 + 5.47292213958973e-06*G0_0_0_0_1 + 6.73709007042454e-06*G0_0_0_0_2 + 5.47292213958973e-06*G0_0_0_1_0 + 7.29722951945297e-06*G0_0_0_1_1 + 1.82430737986324e-06*G0_0_0_1_2 + 6.73709007042454e-06*G0_0_0_2_0 + 1.82430737986324e-06*G0_0_0_2_1 + 4.49139338028303e-06*G0_0_0_2_2 + 5.47292213958973e-06*G0_0_1_0_0 + 7.29722951945297e-06*G0_0_1_0_1 + 1.82430737986324e-06*G0_0_1_0_2 + 7.29722951945297e-06*G0_0_1_1_0 + 6.73709007042455e-05*G0_0_1_1_1 + 3.64861475972649e-06*G0_0_1_1_2 + 1.82430737986324e-06*G0_0_1_2_0 + 3.64861475972649e-06*G0_0_1_2_1 + 1.82430737986324e-06*G0_0_1_2_2 + 6.73709007042454e-06*G0_0_2_0_0 + 1.82430737986324e-06*G0_0_2_0_1 + 4.49139338028303e-06*G0_0_2_0_2 + 1.82430737986324e-06*G0_0_2_1_0 + 3.64861475972649e-06*G0_0_2_1_1 + 1.82430737986324e-06*G0_0_2_1_2 + 4.49139338028303e-06*G0_0_2_2_0 + 1.82430737986324e-06*G0_0_2_2_1 + 6.73709007042454e-06*G0_0_2_2_2 + 5.47292213958973e-06*G0_1_0_0_0 + 7.29722951945297e-06*G0_1_0_0_1 + 1.82430737986324e-06*G0_1_0_0_2 + 7.29722951945297e-06*G0_1_0_1_0 + 6.73709007042455e-05*G0_1_0_1_1 + 3.64861475972649e-06*G0_1_0_1_2 + 1.82430737986324e-06*G0_1_0_2_0 + 3.64861475972649e-06*G0_1_0_2_1 + 1.82430737986324e-06*G0_1_0_2_2 + 7.29722951945297e-06*G0_1_1_0_0 + 6.73709007042455e-05*G0_1_1_0_1 + 3.64861475972649e-06*G0_1_1_0_2 + 6.73709007042455e-05*G0_1_1_1_0 + 0.00166469333136028*G0_1_1_1_1 + 6.73709007042455e-05*G0_1_1_1_2 + 3.64861475972649e-06*G0_1_1_2_0 + 6.73709007042455e-05*G0_1_1_2_1 + 7.29722951945297e-06*G0_1_1_2_2 + 1.82430737986324e-06*G0_1_2_0_0 + 3.64861475972649e-06*G0_1_2_0_1 + 1.82430737986324e-06*G0_1_2_0_2 + 3.64861475972649e-06*G0_1_2_1_0 + 6.73709007042455e-05*G0_1_2_1_1 + 7.29722951945297e-06*G0_1_2_1_2 + 1.82430737986324e-06*G0_1_2_2_0 + 7.29722951945297e-06*G0_1_2_2_1 + 5.47292213958973e-06*G0_1_2_2_2 + 6.73709007042454e-06*G0_2_0_0_0 + 1.82430737986324e-06*G0_2_0_0_1 + 4.49139338028303e-06*G0_2_0_0_2 + 1.82430737986324e-06*G0_2_0_1_0 + 3.64861475972649e-06*G0_2_0_1_1 + 1.82430737986324e-06*G0_2_0_1_2 + 4.49139338028303e-06*G0_2_0_2_0 + 1.82430737986324e-06*G0_2_0_2_1 + 6.73709007042454e-06*G0_2_0_2_2 + 1.82430737986324e-06*G0_2_1_0_0 + 3.64861475972649e-06*G0_2_1_0_1 + 1.82430737986324e-06*G0_2_1_0_2 + 3.64861475972649e-06*G0_2_1_1_0 + 6.73709007042455e-05*G0_2_1_1_1 + 7.29722951945297e-06*G0_2_1_1_2 + 1.82430737986324e-06*G0_2_1_2_0 + 7.29722951945297e-06*G0_2_1_2_1 + 5.47292213958973e-06*G0_2_1_2_2 + 4.49139338028303e-06*G0_2_2_0_0 + 1.82430737986324e-06*G0_2_2_0_1 + 6.73709007042454e-06*G0_2_2_0_2 + 1.82430737986324e-06*G0_2_2_1_0 + 7.29722951945297e-06*G0_2_2_1_1 + 5.47292213958973e-06*G0_2_2_1_2 + 6.73709007042454e-06*G0_2_2_2_0 + 5.47292213958973e-06*G0_2_2_2_1 + 2.69483602816981e-05*G0_2_2_2_2; + A[163] = A[16] + 0.00115705282371969*G0_0_0_0_0 + 0.00047658470277526*G0_0_0_0_1 + 0.000280806054615625*G0_0_0_0_2 + 0.00047658470277526*G0_0_0_1_0 + 0.000344520265155244*G0_0_0_1_1 + 9.96615083916839e-05*G0_0_0_1_2 + 0.000280806054615625*G0_0_0_2_0 + 9.96615083916839e-05*G0_0_0_2_1 + 0.000103760143442701*G0_0_0_2_2 + 0.00047658470277526*G0_0_1_0_0 + 0.000344520265155244*G0_0_1_0_1 + 9.96615083916839e-05*G0_0_1_0_2 + 0.000344520265155244*G0_0_1_1_0 - 8.17084150417579e-06*G0_0_1_1_1 + 9.96615083916839e-05*G0_0_1_2_0 + 0.000280806054615625*G0_0_2_0_0 + 9.96615083916839e-05*G0_0_2_0_1 + 0.000103760143442701*G0_0_2_0_2 + 9.96615083916839e-05*G0_0_2_1_0 + 0.0001037601434427*G0_0_2_2_0 + 3.72400967639125e-05*G0_0_2_2_2 + 0.00047658470277526*G0_1_0_0_0 + 0.000344520265155244*G0_1_0_0_1 + 9.96615083916839e-05*G0_1_0_0_2 + 0.000344520265155244*G0_1_0_1_0 - 8.17084150417573e-06*G0_1_0_1_1 + 9.96615083916839e-05*G0_1_0_2_0 + 0.000344520265155244*G0_1_1_0_0 - 8.1708415041758e-06*G0_1_1_0_1 - 8.17084150417583e-06*G0_1_1_1_0 - 0.00379589546256277*G0_1_1_1_1 - 0.000540971374304799*G0_1_1_1_2 - 0.000540971374304799*G0_1_1_2_1 - 0.000176440255805365*G0_1_1_2_2 + 9.96615083916839e-05*G0_1_2_0_0 - 0.000540971374304799*G0_1_2_1_1 - 0.000176440255805365*G0_1_2_1_2 - 0.000176440255805365*G0_1_2_2_1 - 8.66615747568275e-05*G0_1_2_2_2 + 0.000280806054615625*G0_2_0_0_0 + 9.96615083916839e-05*G0_2_0_0_1 + 0.0001037601434427*G0_2_0_0_2 + 9.96615083916839e-05*G0_2_0_1_0 + 0.0001037601434427*G0_2_0_2_0 + 3.72400967639125e-05*G0_2_0_2_2 + 9.96615083916839e-05*G0_2_1_0_0 - 0.000540971374304799*G0_2_1_1_1 - 0.000176440255805365*G0_2_1_1_2 - 0.000176440255805365*G0_2_1_2_1 - 8.66615747568274e-05*G0_2_1_2_2 + 0.000103760143442701*G0_2_2_0_0 + 3.72400967639125e-05*G0_2_2_0_2 - 0.000176440255805365*G0_2_2_1_1 - 8.66615747568274e-05*G0_2_2_1_2 + 3.72400967639125e-05*G0_2_2_2_0 - 8.66615747568275e-05*G0_2_2_2_1 - 6.07769655388807e-05*G0_2_2_2_2; + A[165] = 0.000473600473600553*G0_0_0_0_0 + 3.61778139555978e-05*G0_0_0_0_1 + 1.56222378444627e-05*G0_0_0_0_2 + 3.61778139555978e-05*G0_0_0_1_0 + 1.31555687111265e-06*G0_0_0_1_1 + 1.56222378444627e-05*G0_0_0_2_0 + 3.61778139555978e-05*G0_0_1_0_0 + 1.31555687111265e-06*G0_0_1_0_1 + 1.31555687111266e-06*G0_0_1_1_0 - 3.46743203886119e-05*G0_0_1_1_1 - 4.3812742225448e-06*G0_0_1_1_2 - 4.3812742225448e-06*G0_0_1_2_1 - 1.12762017523941e-06*G0_0_1_2_2 + 1.56222378444627e-05*G0_0_2_0_0 - 4.3812742225448e-06*G0_0_2_1_1 - 1.12762017523941e-06*G0_0_2_1_2 - 1.12762017523941e-06*G0_0_2_2_1 + 3.61778139555978e-05*G0_1_0_0_0 + 1.31555687111265e-06*G0_1_0_0_1 + 1.31555687111265e-06*G0_1_0_1_0 - 3.46743203886119e-05*G0_1_0_1_1 - 4.3812742225448e-06*G0_1_0_1_2 - 4.3812742225448e-06*G0_1_0_2_1 - 1.12762017523941e-06*G0_1_0_2_2 + 1.31555687111265e-06*G0_1_1_0_0 - 3.46743203886119e-05*G0_1_1_0_1 - 4.3812742225448e-06*G0_1_1_0_2 - 3.46743203886119e-05*G0_1_1_1_0 - 0.000302578080355909*G0_1_1_1_1 - 3.07746339492423e-05*G0_1_1_1_2 - 4.3812742225448e-06*G0_1_1_2_0 - 3.07746339492423e-05*G0_1_1_2_1 - 5.87302174603862e-06*G0_1_1_2_2 - 4.3812742225448e-06*G0_1_2_0_1 - 1.12762017523941e-06*G0_1_2_0_2 - 4.3812742225448e-06*G0_1_2_1_0 - 3.07746339492423e-05*G0_1_2_1_1 - 5.87302174603862e-06*G0_1_2_1_2 - 1.12762017523941e-06*G0_1_2_2_0 - 5.87302174603862e-06*G0_1_2_2_1 - 1.71492234984328e-06*G0_1_2_2_2 + 1.56222378444627e-05*G0_2_0_0_0 - 4.3812742225448e-06*G0_2_0_1_1 - 1.12762017523941e-06*G0_2_0_1_2 - 1.12762017523941e-06*G0_2_0_2_1 - 4.3812742225448e-06*G0_2_1_0_1 - 1.12762017523941e-06*G0_2_1_0_2 - 4.3812742225448e-06*G0_2_1_1_0 - 3.07746339492423e-05*G0_2_1_1_1 - 5.87302174603862e-06*G0_2_1_1_2 - 1.12762017523941e-06*G0_2_1_2_0 - 5.87302174603862e-06*G0_2_1_2_1 - 1.71492234984328e-06*G0_2_1_2_2 - 1.12762017523941e-06*G0_2_2_0_1 - 1.12762017523941e-06*G0_2_2_1_0 - 5.87302174603862e-06*G0_2_2_1_1 - 1.71492234984328e-06*G0_2_2_1_2 - 1.71492234984328e-06*G0_2_2_2_1 - 5.82603757207033e-06*G0_2_2_2_2; + A[10] = -A[165] - 0.000596933930267365*G0_0_0_0_0 - 4.39889328778292e-05*G0_0_0_0_1 - 2.07611318722464e-05*G0_0_0_0_2 - 4.39889328778292e-05*G0_0_0_1_0 - 2.07611318722464e-05*G0_0_0_2_0 - 4.39889328778292e-05*G0_0_1_0_0 + 6.51905413810286e-06*G0_0_1_1_1 - 2.07611318722464e-05*G0_0_2_0_0 - 4.39889328778292e-05*G0_1_0_0_0 + 6.51905413810284e-06*G0_1_0_1_1 + 6.51905413810285e-06*G0_1_1_0_1 + 6.51905413810284e-06*G0_1_1_1_0 - 5.16825913651397e-05*G0_1_1_1_1 + 6.93016566032557e-06*G0_1_1_1_2 + 6.93016566032557e-06*G0_1_1_2_1 + 6.74222896445232e-06*G0_1_1_2_2 + 6.93016566032556e-06*G0_1_2_1_1 + 6.74222896445232e-06*G0_1_2_1_2 + 6.74222896445232e-06*G0_1_2_2_1 - 2.07611318722464e-05*G0_2_0_0_0 + 6.93016566032557e-06*G0_2_1_1_1 + 6.74222896445232e-06*G0_2_1_1_2 + 6.74222896445232e-06*G0_2_1_2_1 + 6.74222896445232e-06*G0_2_2_1_1; + A[205] = A[163]; + A[27] = A[181]; + A[208] = A[192] - 0.00866012294583869*G0_0_0_0_0 - 0.00216503073645967*G0_0_0_0_1 - 0.00243565957851713*G0_0_0_0_2 - 0.00216503073645967*G0_0_0_1_0 - 0.000487131915703426*G0_0_0_1_2 - 0.00243565957851713*G0_0_0_2_0 - 0.000487131915703426*G0_0_0_2_1 - 0.000866012294583868*G0_0_0_2_2 - 0.00216503073645967*G0_0_1_0_0 - 0.000487131915703426*G0_0_1_0_2 + 0.00216503073645968*G0_0_1_1_1 + 0.000487131915703427*G0_0_1_1_2 - 0.000487131915703427*G0_0_1_2_0 + 0.000487131915703427*G0_0_1_2_1 - 0.00243565957851713*G0_0_2_0_0 - 0.000487131915703426*G0_0_2_0_1 - 0.000866012294583868*G0_0_2_0_2 - 0.000487131915703426*G0_0_2_1_0 + 0.000487131915703427*G0_0_2_1_1 - 0.000866012294583868*G0_0_2_2_0 - 0.00027062884205746*G0_0_2_2_2 - 0.00216503073645967*G0_1_0_0_0 - 0.000487131915703426*G0_1_0_0_2 + 0.00216503073645968*G0_1_0_1_1 + 0.000487131915703427*G0_1_0_1_2 - 0.000487131915703427*G0_1_0_2_0 + 0.000487131915703427*G0_1_0_2_1 + 0.00216503073645968*G0_1_1_0_1 + 0.000487131915703427*G0_1_1_0_2 + 0.00216503073645968*G0_1_1_1_0 + 0.0086601229458387*G0_1_1_1_1 + 0.00243565957851713*G0_1_1_1_2 + 0.000487131915703427*G0_1_1_2_0 + 0.00243565957851713*G0_1_1_2_1 + 0.000866012294583869*G0_1_1_2_2 - 0.000487131915703427*G0_1_2_0_0 + 0.000487131915703427*G0_1_2_0_1 + 0.000487131915703427*G0_1_2_1_0 + 0.00243565957851713*G0_1_2_1_1 + 0.000866012294583869*G0_1_2_1_2 + 0.000866012294583869*G0_1_2_2_1 + 0.000270628842057459*G0_1_2_2_2 - 0.00243565957851713*G0_2_0_0_0 - 0.000487131915703426*G0_2_0_0_1 - 0.000866012294583868*G0_2_0_0_2 - 0.000487131915703426*G0_2_0_1_0 + 0.000487131915703427*G0_2_0_1_1 - 0.000866012294583868*G0_2_0_2_0 - 0.00027062884205746*G0_2_0_2_2 - 0.000487131915703427*G0_2_1_0_0 + 0.000487131915703427*G0_2_1_0_1 + 0.000487131915703427*G0_2_1_1_0 + 0.00243565957851713*G0_2_1_1_1 + 0.000866012294583869*G0_2_1_1_2 + 0.000866012294583869*G0_2_1_2_1 + 0.000270628842057459*G0_2_1_2_2 - 0.000866012294583868*G0_2_2_0_0 - 0.000270628842057459*G0_2_2_0_2 + 0.000866012294583869*G0_2_2_1_1 + 0.000270628842057459*G0_2_2_1_2 - 0.000270628842057459*G0_2_2_2_0 + 0.000270628842057459*G0_2_2_2_1; + A[76] = -5.82603757207029e-06*G0_0_0_0_0 - 1.71492234984327e-06*G0_0_0_0_2 - 1.12762017523941e-06*G0_0_0_1_2 - 1.71492234984327e-06*G0_0_0_2_0 - 1.12762017523941e-06*G0_0_0_2_1 - 5.8730217460386e-06*G0_0_0_2_2 - 1.12762017523941e-06*G0_0_1_0_2 + 1.56222378444627e-05*G0_0_1_1_1 - 1.12762017523941e-06*G0_0_1_2_0 - 4.3812742225448e-06*G0_0_1_2_2 - 1.71492234984327e-06*G0_0_2_0_0 - 1.12762017523941e-06*G0_0_2_0_1 - 5.8730217460386e-06*G0_0_2_0_2 - 1.12762017523941e-06*G0_0_2_1_0 - 4.3812742225448e-06*G0_0_2_1_2 - 5.8730217460386e-06*G0_0_2_2_0 - 4.3812742225448e-06*G0_0_2_2_1 - 3.07746339492423e-05*G0_0_2_2_2 - 1.12762017523941e-06*G0_1_0_0_2 + 1.56222378444627e-05*G0_1_0_1_1 - 1.12762017523941e-06*G0_1_0_2_0 - 4.3812742225448e-06*G0_1_0_2_2 + 1.56222378444627e-05*G0_1_1_0_1 + 1.56222378444627e-05*G0_1_1_1_0 + 0.000473600473600554*G0_1_1_1_1 + 3.61778139555979e-05*G0_1_1_1_2 + 3.61778139555979e-05*G0_1_1_2_1 + 1.31555687111265e-06*G0_1_1_2_2 - 1.12762017523941e-06*G0_1_2_0_0 - 4.3812742225448e-06*G0_1_2_0_2 + 3.61778139555979e-05*G0_1_2_1_1 + 1.31555687111266e-06*G0_1_2_1_2 - 4.3812742225448e-06*G0_1_2_2_0 + 1.31555687111265e-06*G0_1_2_2_1 - 3.46743203886119e-05*G0_1_2_2_2 - 1.71492234984327e-06*G0_2_0_0_0 - 1.12762017523941e-06*G0_2_0_0_1 - 5.8730217460386e-06*G0_2_0_0_2 - 1.12762017523941e-06*G0_2_0_1_0 - 4.3812742225448e-06*G0_2_0_1_2 - 5.8730217460386e-06*G0_2_0_2_0 - 4.3812742225448e-06*G0_2_0_2_1 - 3.07746339492423e-05*G0_2_0_2_2 - 1.12762017523941e-06*G0_2_1_0_0 - 4.3812742225448e-06*G0_2_1_0_2 + 3.61778139555979e-05*G0_2_1_1_1 + 1.31555687111266e-06*G0_2_1_1_2 - 4.3812742225448e-06*G0_2_1_2_0 + 1.31555687111265e-06*G0_2_1_2_1 - 3.46743203886119e-05*G0_2_1_2_2 - 5.8730217460386e-06*G0_2_2_0_0 - 4.3812742225448e-06*G0_2_2_0_1 - 3.07746339492423e-05*G0_2_2_0_2 - 4.3812742225448e-06*G0_2_2_1_0 + 1.31555687111265e-06*G0_2_2_1_1 - 3.46743203886119e-05*G0_2_2_1_2 - 3.07746339492423e-05*G0_2_2_2_0 - 3.46743203886119e-05*G0_2_2_2_1 - 0.000302578080355909*G0_2_2_2_2; + A[47] = -A[76] - 1.51523961047796e-05*G0_0_1_1_1 - 1.51523961047796e-05*G0_0_2_2_2 - 1.51523961047796e-05*G0_1_0_1_1 - 1.51523961047796e-05*G0_1_1_0_1 - 1.51523961047796e-05*G0_1_1_1_0 + 0.000171022393244644*G0_1_1_1_1 + 1.5034935669859e-06*G0_1_1_1_2 + 1.5034935669859e-06*G0_1_1_2_1 + 1.50349356698591e-06*G0_1_2_1_1 + 1.50349356698591e-06*G0_1_2_2_2 - 1.51523961047796e-05*G0_2_0_2_2 + 1.50349356698591e-06*G0_2_1_1_1 + 1.5034935669859e-06*G0_2_1_2_2 - 1.51523961047796e-05*G0_2_2_0_2 + 1.5034935669859e-06*G0_2_2_1_2 - 1.51523961047796e-05*G0_2_2_2_0 + 1.50349356698591e-06*G0_2_2_2_1 + 0.000171022393244644*G0_2_2_2_2; + A[20] = A[76]; + A[11] = A[165]; + A[51] = -A[21] - 5.67333900667336e-05*G0_0_0_0_0 - 3.71174974349649e-06*G0_0_0_0_1 + 3.38286052571811e-06*G0_0_0_0_2 - 3.71174974349649e-06*G0_0_0_1_0 + 3.38286052571812e-06*G0_0_0_2_0 + 2.36095474190748e-06*G0_0_0_2_2 - 3.71174974349649e-06*G0_0_1_0_0 + 2.67339949879676e-05*G0_0_1_1_1 + 3.38286052571811e-06*G0_0_2_0_0 + 2.36095474190749e-06*G0_0_2_0_2 + 2.36095474190748e-06*G0_0_2_2_0 + 2.32101819403445e-05*G0_0_2_2_2 - 3.71174974349649e-06*G0_1_0_0_0 + 2.67339949879676e-05*G0_1_0_1_1 + 2.67339949879676e-05*G0_1_1_0_1 + 2.67339949879676e-05*G0_1_1_1_0 + 0.000265578043355865*G0_1_1_1_1 + 5.91060908521325e-05*G0_1_1_1_2 + 5.91060908521325e-05*G0_1_1_2_1 + 1.55635076270023e-05*G0_1_1_2_2 + 5.91060908521325e-05*G0_1_2_1_1 + 1.55635076270023e-05*G0_1_2_1_2 + 1.55635076270023e-05*G0_1_2_2_1 + 2.61232007263797e-05*G0_1_2_2_2 + 3.38286052571812e-06*G0_2_0_0_0 + 2.36095474190749e-06*G0_2_0_0_2 + 2.36095474190749e-06*G0_2_0_2_0 + 2.32101819403445e-05*G0_2_0_2_2 + 5.91060908521325e-05*G0_2_1_1_1 + 1.55635076270023e-05*G0_2_1_1_2 + 1.55635076270023e-05*G0_2_1_2_1 + 2.61232007263797e-05*G0_2_1_2_2 + 2.36095474190749e-06*G0_2_2_0_0 + 2.32101819403445e-05*G0_2_2_0_2 + 1.55635076270023e-05*G0_2_2_1_1 + 2.61232007263797e-05*G0_2_2_1_2 + 2.32101819403445e-05*G0_2_2_2_0 + 2.61232007263797e-05*G0_2_2_2_1 + 0.00027544471988921*G0_2_2_2_2; + A[32] = 2.69483602816981e-05*G0_0_0_0_0 + 6.73709007042453e-06*G0_0_0_0_1 + 5.47292213958973e-06*G0_0_0_0_2 + 6.73709007042453e-06*G0_0_0_1_0 + 4.49139338028302e-06*G0_0_0_1_1 + 1.82430737986324e-06*G0_0_0_1_2 + 5.47292213958973e-06*G0_0_0_2_0 + 1.82430737986324e-06*G0_0_0_2_1 + 7.29722951945296e-06*G0_0_0_2_2 + 6.73709007042453e-06*G0_0_1_0_0 + 4.49139338028302e-06*G0_0_1_0_1 + 1.82430737986324e-06*G0_0_1_0_2 + 4.49139338028302e-06*G0_0_1_1_0 + 6.73709007042454e-06*G0_0_1_1_1 + 1.82430737986324e-06*G0_0_1_1_2 + 1.82430737986324e-06*G0_0_1_2_0 + 1.82430737986324e-06*G0_0_1_2_1 + 3.64861475972649e-06*G0_0_1_2_2 + 5.47292213958973e-06*G0_0_2_0_0 + 1.82430737986324e-06*G0_0_2_0_1 + 7.29722951945296e-06*G0_0_2_0_2 + 1.82430737986324e-06*G0_0_2_1_0 + 1.82430737986324e-06*G0_0_2_1_1 + 3.64861475972649e-06*G0_0_2_1_2 + 7.29722951945296e-06*G0_0_2_2_0 + 3.64861475972649e-06*G0_0_2_2_1 + 6.73709007042453e-05*G0_0_2_2_2 + 6.73709007042453e-06*G0_1_0_0_0 + 4.49139338028302e-06*G0_1_0_0_1 + 1.82430737986324e-06*G0_1_0_0_2 + 4.49139338028302e-06*G0_1_0_1_0 + 6.73709007042454e-06*G0_1_0_1_1 + 1.82430737986324e-06*G0_1_0_1_2 + 1.82430737986324e-06*G0_1_0_2_0 + 1.82430737986324e-06*G0_1_0_2_1 + 3.64861475972649e-06*G0_1_0_2_2 + 4.49139338028302e-06*G0_1_1_0_0 + 6.73709007042454e-06*G0_1_1_0_1 + 1.82430737986324e-06*G0_1_1_0_2 + 6.73709007042454e-06*G0_1_1_1_0 + 2.69483602816982e-05*G0_1_1_1_1 + 5.47292213958973e-06*G0_1_1_1_2 + 1.82430737986324e-06*G0_1_1_2_0 + 5.47292213958973e-06*G0_1_1_2_1 + 7.29722951945298e-06*G0_1_1_2_2 + 1.82430737986324e-06*G0_1_2_0_0 + 1.82430737986324e-06*G0_1_2_0_1 + 3.64861475972649e-06*G0_1_2_0_2 + 1.82430737986324e-06*G0_1_2_1_0 + 5.47292213958973e-06*G0_1_2_1_1 + 7.29722951945298e-06*G0_1_2_1_2 + 3.64861475972649e-06*G0_1_2_2_0 + 7.29722951945298e-06*G0_1_2_2_1 + 6.73709007042454e-05*G0_1_2_2_2 + 5.47292213958973e-06*G0_2_0_0_0 + 1.82430737986324e-06*G0_2_0_0_1 + 7.29722951945296e-06*G0_2_0_0_2 + 1.82430737986324e-06*G0_2_0_1_0 + 1.82430737986324e-06*G0_2_0_1_1 + 3.64861475972649e-06*G0_2_0_1_2 + 7.29722951945296e-06*G0_2_0_2_0 + 3.64861475972649e-06*G0_2_0_2_1 + 6.73709007042453e-05*G0_2_0_2_2 + 1.82430737986324e-06*G0_2_1_0_0 + 1.82430737986324e-06*G0_2_1_0_1 + 3.64861475972649e-06*G0_2_1_0_2 + 1.82430737986324e-06*G0_2_1_1_0 + 5.47292213958973e-06*G0_2_1_1_1 + 7.29722951945298e-06*G0_2_1_1_2 + 3.64861475972649e-06*G0_2_1_2_0 + 7.29722951945298e-06*G0_2_1_2_1 + 6.73709007042454e-05*G0_2_1_2_2 + 7.29722951945296e-06*G0_2_2_0_0 + 3.64861475972649e-06*G0_2_2_0_1 + 6.73709007042453e-05*G0_2_2_0_2 + 3.64861475972649e-06*G0_2_2_1_0 + 7.29722951945298e-06*G0_2_2_1_1 + 6.73709007042454e-05*G0_2_2_1_2 + 6.73709007042453e-05*G0_2_2_2_0 + 6.73709007042454e-05*G0_2_2_2_1 + 0.00166469333136028*G0_2_2_2_2; + A[214] = A[32] - 6.07769655388805e-05*G0_0_0_0_0 + 3.72400967639125e-05*G0_0_0_0_1 - 8.66615747568273e-05*G0_0_0_0_2 + 3.72400967639125e-05*G0_0_0_1_0 + 0.0001037601434427*G0_0_0_1_1 - 8.66615747568273e-05*G0_0_0_2_0 - 0.000176440255805365*G0_0_0_2_2 + 3.72400967639125e-05*G0_0_1_0_0 + 0.0001037601434427*G0_0_1_0_1 + 0.0001037601434427*G0_0_1_1_0 + 0.000280806054615625*G0_0_1_1_1 + 9.96615083916838e-05*G0_0_1_1_2 + 9.96615083916838e-05*G0_0_1_2_1 - 8.66615747568273e-05*G0_0_2_0_0 - 0.000176440255805365*G0_0_2_0_2 + 9.96615083916838e-05*G0_0_2_1_1 - 0.000176440255805365*G0_0_2_2_0 - 0.000540971374304798*G0_0_2_2_2 + 3.72400967639125e-05*G0_1_0_0_0 + 0.0001037601434427*G0_1_0_0_1 + 0.0001037601434427*G0_1_0_1_0 + 0.000280806054615625*G0_1_0_1_1 + 9.96615083916838e-05*G0_1_0_1_2 + 9.96615083916838e-05*G0_1_0_2_1 + 0.0001037601434427*G0_1_1_0_0 + 0.000280806054615625*G0_1_1_0_1 + 9.96615083916838e-05*G0_1_1_0_2 + 0.000280806054615625*G0_1_1_1_0 + 0.00115705282371968*G0_1_1_1_1 + 0.000476584702775259*G0_1_1_1_2 + 9.96615083916838e-05*G0_1_1_2_0 + 0.000476584702775259*G0_1_1_2_1 + 0.000344520265155244*G0_1_1_2_2 + 9.96615083916838e-05*G0_1_2_0_1 + 9.96615083916838e-05*G0_1_2_1_0 + 0.000476584702775259*G0_1_2_1_1 + 0.000344520265155244*G0_1_2_1_2 + 0.000344520265155244*G0_1_2_2_1 - 8.170841504176e-06*G0_1_2_2_2 - 8.66615747568273e-05*G0_2_0_0_0 - 0.000176440255805365*G0_2_0_0_2 + 9.96615083916838e-05*G0_2_0_1_1 - 0.000176440255805365*G0_2_0_2_0 - 0.000540971374304798*G0_2_0_2_2 + 9.96615083916838e-05*G0_2_1_0_1 + 9.96615083916838e-05*G0_2_1_1_0 + 0.000476584702775259*G0_2_1_1_1 + 0.000344520265155244*G0_2_1_1_2 + 0.000344520265155244*G0_2_1_2_1 - 8.17084150417598e-06*G0_2_1_2_2 - 0.000176440255805365*G0_2_2_0_0 - 0.000540971374304798*G0_2_2_0_2 + 0.000344520265155244*G0_2_2_1_1 - 8.170841504176e-06*G0_2_2_1_2 - 0.000540971374304798*G0_2_2_2_0 - 8.17084150417602e-06*G0_2_2_2_1 - 0.00379589546256276*G0_2_2_2_2; + A[25] = A[165] - 0.000222704984609784*G0_0_0_0_0 + 5.01556057111697e-06*G0_0_0_0_1 + 2.20825617651052e-05*G0_0_0_0_2 + 5.01556057111697e-06*G0_0_0_1_0 + 2.20825617651052e-05*G0_0_0_2_0 + 1.32730291460473e-05*G0_0_0_2_2 + 5.01556057111698e-06*G0_0_1_0_0 - 4.54924264448152e-05*G0_0_1_1_1 + 2.20825617651052e-05*G0_0_2_0_0 + 1.32730291460473e-05*G0_0_2_0_2 + 1.32730291460473e-05*G0_0_2_2_0 + 5.01556057111697e-06*G0_1_0_0_0 - 4.54924264448152e-05*G0_1_0_1_1 - 4.54924264448152e-05*G0_1_1_0_1 - 4.54924264448152e-05*G0_1_1_1_0 - 0.000767956323512011*G0_1_1_1_1 - 5.60873576746698e-06*G0_1_1_1_2 - 5.60873576746698e-06*G0_1_1_2_1 - 5.60873576746698e-06*G0_1_2_1_1 + 2.20825617651052e-05*G0_2_0_0_0 + 1.32730291460473e-05*G0_2_0_0_2 + 1.32730291460473e-05*G0_2_0_2_0 - 5.60873576746698e-06*G0_2_1_1_1 + 1.32730291460473e-05*G0_2_2_0_0; + A[61] = -A[76] + 6.74222896445233e-06*G0_0_0_2_2 - 2.07611318722465e-05*G0_0_1_1_1 + 6.74222896445233e-06*G0_0_2_0_2 + 6.74222896445233e-06*G0_0_2_2_0 + 6.93016566032558e-06*G0_0_2_2_2 - 2.07611318722465e-05*G0_1_0_1_1 - 2.07611318722465e-05*G0_1_1_0_1 - 2.07611318722465e-05*G0_1_1_1_0 - 0.000596933930267365*G0_1_1_1_1 - 4.39889328778292e-05*G0_1_1_1_2 - 4.39889328778292e-05*G0_1_1_2_1 - 4.39889328778292e-05*G0_1_2_1_1 + 6.51905413810289e-06*G0_1_2_2_2 + 6.74222896445233e-06*G0_2_0_0_2 + 6.74222896445233e-06*G0_2_0_2_0 + 6.93016566032558e-06*G0_2_0_2_2 - 4.39889328778292e-05*G0_2_1_1_1 + 6.51905413810289e-06*G0_2_1_2_2 + 6.74222896445233e-06*G0_2_2_0_0 + 6.93016566032558e-06*G0_2_2_0_2 + 6.5190541381029e-06*G0_2_2_1_2 + 6.93016566032558e-06*G0_2_2_2_0 + 6.5190541381029e-06*G0_2_2_2_1 - 5.16825913651396e-05*G0_2_2_2_2; + A[187] = A[117]; + A[85] = A[108] + 6.90667357334139e-05*G0_0_0_0_1 - 6.90667357334139e-05*G0_0_0_0_2 + 6.9066735733414e-05*G0_0_0_1_0 + 7.20267386934174e-05*G0_0_0_1_1 - 6.90667357334139e-05*G0_0_0_2_0 - 7.20267386934174e-05*G0_0_0_2_2 + 6.9066735733414e-05*G0_0_1_0_0 + 7.20267386934174e-05*G0_0_1_0_1 + 7.20267386934174e-05*G0_0_1_1_0 + 1.97333530666883e-06*G0_0_1_1_1 - 6.90667357334139e-05*G0_0_2_0_0 - 7.20267386934174e-05*G0_0_2_0_2 - 7.20267386934174e-05*G0_0_2_2_0 - 1.97333530666896e-06*G0_0_2_2_2 + 6.90667357334139e-05*G0_1_0_0_0 + 7.20267386934174e-05*G0_1_0_0_1 + 7.20267386934174e-05*G0_1_0_1_0 + 1.97333530666885e-06*G0_1_0_1_1 + 7.20267386934174e-05*G0_1_1_0_0 + 1.97333530666886e-06*G0_1_1_0_1 + 1.97333530666885e-06*G0_1_1_1_0 - 0.000730134063467523*G0_1_1_1_1 - 6.70934004267456e-05*G0_1_1_1_2 - 6.70934004267456e-05*G0_1_1_2_1 - 6.70934004267456e-05*G0_1_2_1_1 + 6.70934004267451e-05*G0_1_2_2_2 - 6.90667357334139e-05*G0_2_0_0_0 - 7.20267386934174e-05*G0_2_0_0_2 - 7.20267386934174e-05*G0_2_0_2_0 - 1.97333530666896e-06*G0_2_0_2_2 - 6.70934004267456e-05*G0_2_1_1_1 + 6.70934004267451e-05*G0_2_1_2_2 - 7.20267386934174e-05*G0_2_2_0_0 - 1.97333530666897e-06*G0_2_2_0_2 + 6.70934004267451e-05*G0_2_2_1_2 - 1.97333530666896e-06*G0_2_2_2_0 + 6.70934004267451e-05*G0_2_2_2_1 + 0.000730134063467519*G0_2_2_2_2; + A[91] = A[21]; + A[109] = A[181] + 0.000208962113724054*G0_0_0_0_0 + 2.50895488990771e-05*G0_0_0_0_1 + 2.54419302038395e-05*G0_0_0_0_2 + 2.50895488990771e-05*G0_0_0_1_0 + 1.51523961047801e-06*G0_0_0_1_2 + 2.54419302038394e-05*G0_0_0_2_0 + 1.51523961047801e-06*G0_0_0_2_1 - 5.49714835429213e-06*G0_0_0_2_2 + 2.50895488990771e-05*G0_0_1_0_0 + 1.51523961047801e-06*G0_0_1_0_2 - 1.22276312752523e-05*G0_0_1_1_2 + 1.51523961047801e-06*G0_0_1_2_0 - 1.22276312752523e-05*G0_0_1_2_1 + 2.54419302038395e-05*G0_0_2_0_0 + 1.51523961047801e-06*G0_0_2_0_1 - 5.49714835429213e-06*G0_0_2_0_2 + 1.51523961047801e-06*G0_0_2_1_0 - 1.22276312752523e-05*G0_0_2_1_1 - 5.49714835429213e-06*G0_0_2_2_0 + 0.00010874487064965*G0_0_2_2_2 + 2.50895488990771e-05*G0_1_0_0_0 + 1.51523961047801e-06*G0_1_0_0_2 - 1.22276312752523e-05*G0_1_0_1_2 + 1.51523961047801e-06*G0_1_0_2_0 - 1.22276312752523e-05*G0_1_0_2_1 - 1.22276312752523e-05*G0_1_1_0_2 - 6.69524479048387e-06*G0_1_1_1_1 - 7.11105473010353e-05*G0_1_1_1_2 - 1.22276312752523e-05*G0_1_1_2_0 - 7.11105473010353e-05*G0_1_1_2_1 - 5.10952891905357e-05*G0_1_1_2_2 + 1.51523961047801e-06*G0_1_2_0_0 - 1.22276312752523e-05*G0_1_2_0_1 - 1.22276312752523e-05*G0_1_2_1_0 - 7.11105473010353e-05*G0_1_2_1_1 - 5.10952891905357e-05*G0_1_2_1_2 - 5.10952891905357e-05*G0_1_2_2_1 + 8.57696095791478e-05*G0_1_2_2_2 + 2.54419302038395e-05*G0_2_0_0_0 + 1.515239610478e-06*G0_2_0_0_1 - 5.49714835429213e-06*G0_2_0_0_2 + 1.51523961047801e-06*G0_2_0_1_0 - 1.22276312752523e-05*G0_2_0_1_1 - 5.49714835429213e-06*G0_2_0_2_0 + 0.00010874487064965*G0_2_0_2_2 + 1.51523961047801e-06*G0_2_1_0_0 - 1.22276312752523e-05*G0_2_1_0_1 - 1.22276312752523e-05*G0_2_1_1_0 - 7.11105473010353e-05*G0_2_1_1_1 - 5.10952891905357e-05*G0_2_1_1_2 - 5.10952891905357e-05*G0_2_1_2_1 + 8.57696095791478e-05*G0_2_1_2_2 - 5.49714835429213e-06*G0_2_2_0_0 + 0.000108744870649651*G0_2_2_0_2 - 5.10952891905357e-05*G0_2_2_1_1 + 8.57696095791478e-05*G0_2_2_1_2 + 0.00010874487064965*G0_2_2_2_0 + 8.57696095791478e-05*G0_2_2_2_1 + 0.00144582049343978*G0_2_2_2_2; + A[2] = -8.94681450237157e-05*G0_0_0_0_0 - 2.82639171528107e-06*G0_0_0_0_1 - 6.63945108389665e-06*G0_0_0_0_2 - 2.82639171528107e-06*G0_0_0_1_0 - 6.63945108389665e-06*G0_0_0_2_0 - 1.59232302089472e-06*G0_0_0_2_2 - 2.82639171528107e-06*G0_0_1_0_0 + 1.09752093879097e-06*G0_0_1_1_1 - 6.63945108389665e-06*G0_0_2_0_0 - 1.59232302089472e-06*G0_0_2_0_2 - 1.59232302089472e-06*G0_0_2_2_0 - 6.63945108389664e-06*G0_0_2_2_2 - 2.82639171528107e-06*G0_1_0_0_0 + 1.09752093879097e-06*G0_1_0_1_1 + 1.09752093879097e-06*G0_1_1_0_1 + 1.09752093879097e-06*G0_1_1_1_0 + 1.33860848146585e-05*G0_1_1_1_1 + 1.09752093879097e-06*G0_1_1_1_2 + 1.09752093879097e-06*G0_1_1_2_1 + 1.09752093879097e-06*G0_1_2_1_1 - 2.82639171528109e-06*G0_1_2_2_2 - 6.63945108389665e-06*G0_2_0_0_0 - 1.59232302089472e-06*G0_2_0_0_2 - 1.59232302089472e-06*G0_2_0_2_0 - 6.63945108389665e-06*G0_2_0_2_2 + 1.09752093879097e-06*G0_2_1_1_1 - 2.82639171528109e-06*G0_2_1_2_2 - 1.59232302089472e-06*G0_2_2_0_0 - 6.63945108389665e-06*G0_2_2_0_2 - 2.82639171528109e-06*G0_2_2_1_2 - 6.63945108389664e-06*G0_2_2_2_0 - 2.82639171528109e-06*G0_2_2_2_1 - 8.94681450237156e-05*G0_2_2_2_2; + A[1] = A[2] - 0.000102854229838374*G0_1_1_1_1 + 0.000102854229838374*G0_2_2_2_2; + A[41] = A[1] + 2.09887114649053e-05*G0_0_0_0_0 - 1.2209278082296e-05*G0_0_0_1_1 - 1.2209278082296e-05*G0_0_1_0_1 - 1.2209278082296e-05*G0_0_1_1_0 - 4.97415576780739e-05*G0_0_1_1_1 - 1.2209278082296e-05*G0_1_0_0_1 - 1.2209278082296e-05*G0_1_0_1_0 - 4.97415576780739e-05*G0_1_0_1_1 - 1.2209278082296e-05*G0_1_1_0_0 - 4.97415576780739e-05*G0_1_1_0_1 - 4.97415576780739e-05*G0_1_1_1_0 - 0.00021722105055442*G0_1_1_1_1 - 2.79482422339612e-05*G0_1_1_1_2 - 2.79482422339612e-05*G0_1_1_2_1 - 2.79482422339612e-05*G0_1_2_1_1 - 2.79482422339612e-05*G0_2_1_1_1 + 2.23615302980435e-06*G0_2_2_2_2; + A[35] = A[41] + 4.31549637898917e-05*G0_0_0_0_0 - 3.92317852635377e-06*G0_0_0_0_1 - 3.92317852635377e-06*G0_0_0_1_0 + 1.13936621873148e-06*G0_0_0_1_1 - 3.92317852635377e-06*G0_0_1_0_0 + 1.13936621873148e-06*G0_0_1_0_1 + 1.13936621873148e-06*G0_0_1_1_0 + 3.10565389930521e-05*G0_0_1_1_1 + 4.91689380578352e-05*G0_0_2_2_2 - 3.92317852635377e-06*G0_1_0_0_0 + 1.13936621873148e-06*G0_1_0_0_1 + 1.13936621873148e-06*G0_1_0_1_0 + 3.10565389930521e-05*G0_1_0_1_1 + 1.13936621873148e-06*G0_1_1_0_0 + 3.10565389930521e-05*G0_1_1_0_1 + 3.10565389930521e-05*G0_1_1_1_0 + 0.000180066846733544*G0_1_1_1_1 + 6.10794261588014e-06*G0_1_1_1_2 + 6.10794261588014e-06*G0_1_1_2_1 + 6.10794261588014e-06*G0_1_2_1_1 + 9.73512084623361e-05*G0_1_2_2_2 + 4.91689380578352e-05*G0_2_0_2_2 + 6.10794261588014e-06*G0_2_1_1_1 + 9.73512084623361e-05*G0_2_1_2_2 + 4.91689380578352e-05*G0_2_2_0_2 + 9.73512084623361e-05*G0_2_2_1_2 + 4.91689380578352e-05*G0_2_2_2_0 + 9.73512084623361e-05*G0_2_2_2_1 + 0.00149891261002397*G0_2_2_2_2; + A[31] = A[2] + 0.000102854229838374*G0_0_0_0_0 - 0.000102854229838374*G0_1_1_1_1; + A[60] = A[31] - 4.36071864643247e-07*G0_0_0_0_0 + 0.000207780168097664*G0_1_1_1_1 - 9.74627958755108e-06*G0_1_1_1_2 - 9.74627958755108e-06*G0_1_1_2_1 - 2.66246099579478e-05*G0_1_1_2_2 - 9.74627958755108e-06*G0_1_2_1_1 - 2.66246099579478e-05*G0_1_2_1_2 - 2.66246099579478e-05*G0_1_2_2_1 - 9.74627958755109e-06*G0_1_2_2_2 - 9.74627958755108e-06*G0_2_1_1_1 - 2.66246099579478e-05*G0_2_1_1_2 - 2.66246099579478e-05*G0_2_1_2_1 - 9.74627958755109e-06*G0_2_1_2_2 - 2.66246099579478e-05*G0_2_2_1_1 - 9.74627958755109e-06*G0_2_2_1_2 - 9.74627958755109e-06*G0_2_2_2_1 + 0.000207780168097663*G0_2_2_2_2; + A[170] = -A[60] + 4.48992512484651e-05*G0_0_0_0_0 + 1.5669222018431e-05*G0_0_0_0_1 + 1.5669222018431e-05*G0_0_0_1_0 + 5.88741064931639e-05*G0_0_0_1_1 + 1.5669222018431e-05*G0_0_1_0_0 + 5.88741064931639e-05*G0_0_1_0_1 + 5.88741064931639e-05*G0_0_1_1_0 + 0.000258412956825698*G0_0_1_1_1 + 2.32571661143128e-05*G0_0_1_1_2 + 2.32571661143128e-05*G0_0_1_2_1 + 2.32571661143128e-05*G0_0_2_1_1 + 3.55200355200415e-05*G0_0_2_2_2 + 1.5669222018431e-05*G0_1_0_0_0 + 5.88741064931639e-05*G0_1_0_0_1 + 5.88741064931639e-05*G0_1_0_1_0 + 0.000258412956825698*G0_1_0_1_1 + 2.32571661143128e-05*G0_1_0_1_2 + 2.32571661143128e-05*G0_1_0_2_1 + 5.88741064931639e-05*G0_1_1_0_0 + 0.000258412956825698*G0_1_1_0_1 + 2.32571661143128e-05*G0_1_1_0_2 + 0.000258412956825698*G0_1_1_1_0 + 0.00155226901258673*G0_1_1_1_1 + 0.000128325525150943*G0_1_1_1_2 + 2.32571661143128e-05*G0_1_1_2_0 + 0.000128325525150943*G0_1_1_2_1 - 5.2886560823078e-06*G0_1_1_2_2 + 2.32571661143128e-05*G0_1_2_0_1 + 2.32571661143128e-05*G0_1_2_1_0 + 0.000128325525150943*G0_1_2_1_1 - 5.28865608230781e-06*G0_1_2_1_2 - 5.28865608230781e-06*G0_1_2_2_1 + 6.54254622508704e-06*G0_1_2_2_2 + 2.32571661143128e-05*G0_2_0_1_1 + 3.55200355200415e-05*G0_2_0_2_2 + 2.32571661143128e-05*G0_2_1_0_1 + 2.32571661143128e-05*G0_2_1_1_0 + 0.000128325525150943*G0_2_1_1_1 - 5.28865608230781e-06*G0_2_1_1_2 - 5.28865608230781e-06*G0_2_1_2_1 + 6.54254622508705e-06*G0_2_1_2_2 + 3.55200355200415e-05*G0_2_2_0_2 - 5.28865608230781e-06*G0_2_2_1_1 + 6.54254622508705e-06*G0_2_2_1_2 + 3.55200355200415e-05*G0_2_2_2_0 + 6.54254622508705e-06*G0_2_2_2_1 + 0.000263023278896339*G0_2_2_2_2; + A[4] = A[60]; + A[86] = A[170]; + A[138] = A[170] + 0.00011276201752394*G0_0_0_0_0 + 6.76572105143626e-06*G0_0_0_0_1 + 2.25524035047882e-05*G0_0_0_0_2 + 6.76572105143626e-06*G0_0_0_1_0 - 3.68355923911541e-05*G0_0_0_1_1 + 2.25524035047882e-05*G0_0_0_2_0 + 6.76572105143625e-06*G0_0_1_0_0 - 3.68355923911541e-05*G0_0_1_0_1 - 3.68355923911541e-05*G0_0_1_1_0 - 0.000105244549689011*G0_0_1_1_1 + 2.25524035047882e-05*G0_0_2_0_0 - 2.25524035047883e-05*G0_0_2_2_2 + 6.76572105143626e-06*G0_1_0_0_0 - 3.68355923911541e-05*G0_1_0_0_1 - 3.68355923911541e-05*G0_1_0_1_0 - 0.000105244549689011*G0_1_0_1_1 - 3.68355923911541e-05*G0_1_1_0_0 - 0.000105244549689011*G0_1_1_0_1 - 0.000105244549689011*G0_1_1_1_0 + 0.000105244549689012*G0_1_1_1_2 + 0.000105244549689012*G0_1_1_2_1 + 3.68355923911542e-05*G0_1_1_2_2 + 0.000105244549689012*G0_1_2_1_1 + 3.68355923911542e-05*G0_1_2_1_2 + 3.68355923911542e-05*G0_1_2_2_1 - 6.76572105143651e-06*G0_1_2_2_2 + 2.25524035047882e-05*G0_2_0_0_0 - 2.25524035047883e-05*G0_2_0_2_2 + 0.000105244549689012*G0_2_1_1_1 + 3.68355923911542e-05*G0_2_1_1_2 + 3.68355923911543e-05*G0_2_1_2_1 - 6.76572105143651e-06*G0_2_1_2_2 - 2.25524035047883e-05*G0_2_2_0_2 + 3.68355923911542e-05*G0_2_2_1_1 - 6.76572105143651e-06*G0_2_2_1_2 - 2.25524035047883e-05*G0_2_2_2_0 - 6.76572105143652e-06*G0_2_2_2_1 - 0.000112762017523942*G0_2_2_2_2; + A[57] = -A[138] + 0.000494273510146606*G0_0_0_0_0 + 5.90121225041954e-05*G0_0_0_0_1 + 0.000178163987687827*G0_0_0_0_2 + 5.90121225041954e-05*G0_0_0_1_0 - 6.38984765969018e-06*G0_0_0_1_1 + 2.49955805511402e-05*G0_0_0_1_2 + 0.000178163987687827*G0_0_0_2_0 + 2.49955805511402e-05*G0_0_0_2_1 + 9.94185121169414e-05*G0_0_0_2_2 + 5.90121225041954e-05*G0_0_1_0_0 - 6.38984765969018e-06*G0_0_1_0_1 + 2.49955805511402e-05*G0_0_1_0_2 - 6.38984765969018e-06*G0_0_1_1_0 - 1.31555687111265e-05*G0_0_1_1_1 - 6.7657210514365e-06*G0_0_1_1_2 + 2.49955805511402e-05*G0_0_1_2_0 - 6.7657210514365e-06*G0_0_1_2_1 + 0.000178163987687827*G0_0_2_0_0 + 2.49955805511402e-05*G0_0_2_0_1 + 9.94185121169414e-05*G0_0_2_0_2 + 2.49955805511402e-05*G0_0_2_1_0 - 6.76572105143651e-06*G0_0_2_1_1 + 9.94185121169414e-05*G0_0_2_2_0 + 6.08914894629282e-05*G0_0_2_2_2 + 5.90121225041954e-05*G0_1_0_0_0 - 6.38984765969018e-06*G0_1_0_0_1 + 2.49955805511402e-05*G0_1_0_0_2 - 6.38984765969018e-06*G0_1_0_1_0 - 1.31555687111265e-05*G0_1_0_1_1 - 6.7657210514365e-06*G0_1_0_1_2 + 2.49955805511402e-05*G0_1_0_2_0 - 6.7657210514365e-06*G0_1_0_2_1 - 6.38984765969019e-06*G0_1_1_0_0 - 1.31555687111265e-05*G0_1_1_0_1 - 6.76572105143651e-06*G0_1_1_0_2 - 1.31555687111265e-05*G0_1_1_1_0 + 9.20889809778854e-05*G0_1_1_1_1 - 6.57778435556326e-05*G0_1_1_1_2 - 6.76572105143651e-06*G0_1_1_2_0 - 6.57778435556326e-05*G0_1_1_2_1 - 1.69143026285913e-05*G0_1_1_2_2 + 2.49955805511402e-05*G0_1_2_0_0 - 6.76572105143651e-06*G0_1_2_0_1 - 6.76572105143651e-06*G0_1_2_1_0 - 6.57778435556326e-05*G0_1_2_1_1 - 1.69143026285913e-05*G0_1_2_1_2 - 1.69143026285913e-05*G0_1_2_2_1 + 4.88635409270406e-06*G0_1_2_2_2 + 0.000178163987687827*G0_2_0_0_0 + 2.49955805511402e-05*G0_2_0_0_1 + 9.94185121169414e-05*G0_2_0_0_2 + 2.49955805511402e-05*G0_2_0_1_0 - 6.7657210514365e-06*G0_2_0_1_1 + 9.94185121169414e-05*G0_2_0_2_0 + 6.08914894629282e-05*G0_2_0_2_2 + 2.49955805511402e-05*G0_2_1_0_0 - 6.76572105143651e-06*G0_2_1_0_1 - 6.7657210514365e-06*G0_2_1_1_0 - 6.57778435556326e-05*G0_2_1_1_1 - 1.69143026285913e-05*G0_2_1_1_2 - 1.69143026285913e-05*G0_2_1_2_1 + 4.88635409270406e-06*G0_2_1_2_2 + 9.94185121169414e-05*G0_2_2_0_0 + 6.08914894629282e-05*G0_2_2_0_2 - 1.69143026285913e-05*G0_2_2_1_1 + 4.88635409270406e-06*G0_2_2_1_2 + 6.08914894629282e-05*G0_2_2_2_0 + 4.88635409270406e-06*G0_2_2_2_1 - 9.20889809778856e-05*G0_2_2_2_2; + A[106] = A[2] + 0.000207780168097663*G0_0_0_0_0 - 9.74627958755107e-06*G0_0_0_0_2 - 9.74627958755107e-06*G0_0_0_2_0 - 2.66246099579478e-05*G0_0_0_2_2 - 9.74627958755107e-06*G0_0_2_0_0 - 2.66246099579478e-05*G0_0_2_0_2 - 2.66246099579478e-05*G0_0_2_2_0 - 9.74627958755111e-06*G0_0_2_2_2 - 4.36071864642489e-07*G0_1_1_1_1 - 9.74627958755107e-06*G0_2_0_0_0 - 2.66246099579478e-05*G0_2_0_0_2 - 2.66246099579478e-05*G0_2_0_2_0 - 9.74627958755111e-06*G0_2_0_2_2 - 2.66246099579478e-05*G0_2_2_0_0 - 9.7462795875511e-06*G0_2_2_0_2 - 9.74627958755111e-06*G0_2_2_2_0 + 0.000207780168097663*G0_2_2_2_2; + A[129] = -A[106] + 0.00155226901258673*G0_0_0_0_0 + 0.000258412956825698*G0_0_0_0_1 + 0.000128325525150943*G0_0_0_0_2 + 0.000258412956825698*G0_0_0_1_0 + 5.88741064931639e-05*G0_0_0_1_1 + 2.32571661143128e-05*G0_0_0_1_2 + 0.000128325525150943*G0_0_0_2_0 + 2.32571661143128e-05*G0_0_0_2_1 - 5.28865608230782e-06*G0_0_0_2_2 + 0.000258412956825698*G0_0_1_0_0 + 5.88741064931639e-05*G0_0_1_0_1 + 2.32571661143128e-05*G0_0_1_0_2 + 5.88741064931639e-05*G0_0_1_1_0 + 1.5669222018431e-05*G0_0_1_1_1 + 2.32571661143128e-05*G0_0_1_2_0 + 0.000128325525150943*G0_0_2_0_0 + 2.32571661143128e-05*G0_0_2_0_1 - 5.28865608230782e-06*G0_0_2_0_2 + 2.32571661143128e-05*G0_0_2_1_0 - 5.28865608230782e-06*G0_0_2_2_0 + 6.54254622508694e-06*G0_0_2_2_2 + 0.000258412956825698*G0_1_0_0_0 + 5.88741064931639e-05*G0_1_0_0_1 + 2.32571661143128e-05*G0_1_0_0_2 + 5.88741064931639e-05*G0_1_0_1_0 + 1.5669222018431e-05*G0_1_0_1_1 + 2.32571661143128e-05*G0_1_0_2_0 + 5.88741064931639e-05*G0_1_1_0_0 + 1.5669222018431e-05*G0_1_1_0_1 + 1.5669222018431e-05*G0_1_1_1_0 + 4.4899251248466e-05*G0_1_1_1_1 + 2.32571661143128e-05*G0_1_2_0_0 + 3.55200355200414e-05*G0_1_2_2_2 + 0.000128325525150943*G0_2_0_0_0 + 2.32571661143128e-05*G0_2_0_0_1 - 5.28865608230781e-06*G0_2_0_0_2 + 2.32571661143128e-05*G0_2_0_1_0 - 5.28865608230782e-06*G0_2_0_2_0 + 6.54254622508694e-06*G0_2_0_2_2 + 2.32571661143128e-05*G0_2_1_0_0 + 3.55200355200414e-05*G0_2_1_2_2 - 5.28865608230781e-06*G0_2_2_0_0 + 6.54254622508695e-06*G0_2_2_0_2 + 3.55200355200414e-05*G0_2_2_1_2 + 6.54254622508694e-06*G0_2_2_2_0 + 3.55200355200414e-05*G0_2_2_2_1 + 0.000263023278896338*G0_2_2_2_2; + A[149] = -A[129] + 9.20889809778857e-05*G0_0_0_0_0 - 6.57778435556324e-05*G0_0_0_0_1 - 1.31555687111266e-05*G0_0_0_0_2 - 6.57778435556324e-05*G0_0_0_1_0 - 1.69143026285911e-05*G0_0_0_1_1 - 6.76572105143647e-06*G0_0_0_1_2 - 1.31555687111266e-05*G0_0_0_2_0 - 6.76572105143647e-06*G0_0_0_2_1 - 6.38984765968997e-06*G0_0_0_2_2 - 6.57778435556323e-05*G0_0_1_0_0 - 1.69143026285911e-05*G0_0_1_0_1 - 6.76572105143647e-06*G0_0_1_0_2 - 1.69143026285911e-05*G0_0_1_1_0 + 4.88635409270421e-06*G0_0_1_1_1 - 6.76572105143647e-06*G0_0_1_2_0 + 2.49955805511403e-05*G0_0_1_2_2 - 1.31555687111266e-05*G0_0_2_0_0 - 6.76572105143646e-06*G0_0_2_0_1 - 6.38984765968997e-06*G0_0_2_0_2 - 6.76572105143647e-06*G0_0_2_1_0 + 2.49955805511403e-05*G0_0_2_1_2 - 6.38984765968996e-06*G0_0_2_2_0 + 2.49955805511403e-05*G0_0_2_2_1 + 5.90121225041959e-05*G0_0_2_2_2 - 6.57778435556324e-05*G0_1_0_0_0 - 1.69143026285911e-05*G0_1_0_0_1 - 6.76572105143646e-06*G0_1_0_0_2 - 1.69143026285911e-05*G0_1_0_1_0 + 4.88635409270422e-06*G0_1_0_1_1 - 6.76572105143646e-06*G0_1_0_2_0 + 2.49955805511403e-05*G0_1_0_2_2 - 1.69143026285911e-05*G0_1_1_0_0 + 4.88635409270422e-06*G0_1_1_0_1 + 4.88635409270422e-06*G0_1_1_1_0 - 9.20889809778852e-05*G0_1_1_1_1 + 6.08914894629283e-05*G0_1_1_1_2 + 6.08914894629283e-05*G0_1_1_2_1 + 9.94185121169415e-05*G0_1_1_2_2 - 6.76572105143647e-06*G0_1_2_0_0 + 2.49955805511403e-05*G0_1_2_0_2 + 6.08914894629283e-05*G0_1_2_1_1 + 9.94185121169415e-05*G0_1_2_1_2 + 2.49955805511403e-05*G0_1_2_2_0 + 9.94185121169415e-05*G0_1_2_2_1 + 0.000178163987687827*G0_1_2_2_2 - 1.31555687111266e-05*G0_2_0_0_0 - 6.76572105143646e-06*G0_2_0_0_1 - 6.38984765968997e-06*G0_2_0_0_2 - 6.76572105143647e-06*G0_2_0_1_0 + 2.49955805511403e-05*G0_2_0_1_2 - 6.38984765968997e-06*G0_2_0_2_0 + 2.49955805511403e-05*G0_2_0_2_1 + 5.90121225041959e-05*G0_2_0_2_2 - 6.76572105143647e-06*G0_2_1_0_0 + 2.49955805511403e-05*G0_2_1_0_2 + 6.08914894629283e-05*G0_2_1_1_1 + 9.94185121169415e-05*G0_2_1_1_2 + 2.49955805511403e-05*G0_2_1_2_0 + 9.94185121169415e-05*G0_2_1_2_1 + 0.000178163987687827*G0_2_1_2_2 - 6.38984765968997e-06*G0_2_2_0_0 + 2.49955805511403e-05*G0_2_2_0_1 + 5.90121225041959e-05*G0_2_2_0_2 + 2.49955805511403e-05*G0_2_2_1_0 + 9.94185121169415e-05*G0_2_2_1_1 + 0.000178163987687827*G0_2_2_1_2 + 5.90121225041959e-05*G0_2_2_2_0 + 0.000178163987687827*G0_2_2_2_1 + 0.000494273510146608*G0_2_2_2_2; + A[126] = A[129] + 9.20889809778874e-05*G0_0_0_0_0 - 0.000105244549689012*G0_0_0_0_1 + 2.6311137422253e-05*G0_0_0_0_2 - 0.000105244549689012*G0_0_0_1_0 - 3.27009850819429e-05*G0_0_0_1_1 - 4.13460730921117e-06*G0_0_0_1_2 + 2.6311137422253e-05*G0_0_0_2_0 - 4.13460730921116e-06*G0_0_0_2_1 + 4.13460730921113e-06*G0_0_0_2_2 - 0.000105244549689012*G0_0_1_0_0 - 3.27009850819429e-05*G0_0_1_0_1 - 4.13460730921116e-06*G0_0_1_0_2 - 3.27009850819429e-05*G0_0_1_1_0 - 9.2088980977885e-06*G0_0_1_1_1 - 4.13460730921117e-06*G0_0_1_2_0 + 1.48469989739856e-05*G0_0_1_2_2 + 2.6311137422253e-05*G0_0_2_0_0 - 4.13460730921116e-06*G0_0_2_0_1 + 4.13460730921112e-06*G0_0_2_0_2 - 4.13460730921117e-06*G0_0_2_1_0 + 1.48469989739856e-05*G0_0_2_1_2 + 4.13460730921113e-06*G0_0_2_2_0 + 1.48469989739856e-05*G0_0_2_2_1 + 0.000148094116348109*G0_0_2_2_2 - 0.000105244549689012*G0_1_0_0_0 - 3.27009850819429e-05*G0_1_0_0_1 - 4.13460730921116e-06*G0_1_0_0_2 - 3.27009850819429e-05*G0_1_0_1_0 - 9.2088980977885e-06*G0_1_0_1_1 - 4.13460730921116e-06*G0_1_0_2_0 + 1.48469989739856e-05*G0_1_0_2_2 - 3.27009850819429e-05*G0_1_1_0_0 - 9.2088980977885e-06*G0_1_1_0_1 - 9.2088980977885e-06*G0_1_1_1_0 - 2.74387575974923e-05*G0_1_1_1_1 + 2.01092264584362e-05*G0_1_1_2_2 - 4.13460730921116e-06*G0_1_2_0_0 + 1.48469989739856e-05*G0_1_2_0_2 + 2.01092264584362e-05*G0_1_2_1_2 + 1.48469989739856e-05*G0_1_2_2_0 + 2.01092264584362e-05*G0_1_2_2_1 + 0.000117648371616645*G0_1_2_2_2 + 2.6311137422253e-05*G0_2_0_0_0 - 4.13460730921116e-06*G0_2_0_0_1 + 4.13460730921113e-06*G0_2_0_0_2 - 4.13460730921117e-06*G0_2_0_1_0 + 1.48469989739856e-05*G0_2_0_1_2 + 4.13460730921113e-06*G0_2_0_2_0 + 1.48469989739856e-05*G0_2_0_2_1 + 0.000148094116348109*G0_2_0_2_2 - 4.13460730921117e-06*G0_2_1_0_0 + 1.48469989739856e-05*G0_2_1_0_2 + 2.01092264584362e-05*G0_2_1_1_2 + 1.48469989739856e-05*G0_2_1_2_0 + 2.01092264584362e-05*G0_2_1_2_1 + 0.000117648371616645*G0_2_1_2_2 + 4.13460730921112e-06*G0_2_2_0_0 + 1.48469989739856e-05*G0_2_2_0_1 + 0.000148094116348109*G0_2_2_0_2 + 1.48469989739856e-05*G0_2_2_1_0 + 2.01092264584362e-05*G0_2_2_1_1 + 0.000117648371616645*G0_2_2_1_2 + 0.000148094116348109*G0_2_2_2_0 + 0.000117648371616645*G0_2_2_2_1 + 0.00138133471466828*G0_2_2_2_2; + A[101] = A[129] - 0.000105244549689011*G0_0_0_0_1 + 0.000105244549689012*G0_0_0_0_2 - 0.000105244549689011*G0_0_0_1_0 - 3.68355923911541e-05*G0_0_0_1_1 + 0.000105244549689012*G0_0_0_2_0 + 3.68355923911541e-05*G0_0_0_2_2 - 0.000105244549689011*G0_0_1_0_0 - 3.68355923911541e-05*G0_0_1_0_1 - 3.68355923911541e-05*G0_0_1_1_0 + 6.76572105143627e-06*G0_0_1_1_1 + 0.000105244549689012*G0_0_2_0_0 + 3.68355923911541e-05*G0_0_2_0_2 + 3.68355923911541e-05*G0_0_2_2_0 - 6.76572105143647e-06*G0_0_2_2_2 - 0.000105244549689011*G0_1_0_0_0 - 3.68355923911541e-05*G0_1_0_0_1 - 3.68355923911541e-05*G0_1_0_1_0 + 6.76572105143627e-06*G0_1_0_1_1 - 3.68355923911541e-05*G0_1_1_0_0 + 6.76572105143627e-06*G0_1_1_0_1 + 6.76572105143627e-06*G0_1_1_1_0 + 0.00011276201752394*G0_1_1_1_1 + 2.25524035047882e-05*G0_1_1_1_2 + 2.25524035047882e-05*G0_1_1_2_1 + 2.25524035047882e-05*G0_1_2_1_1 - 2.25524035047882e-05*G0_1_2_2_2 + 0.000105244549689012*G0_2_0_0_0 + 3.68355923911541e-05*G0_2_0_0_2 + 3.68355923911541e-05*G0_2_0_2_0 - 6.76572105143647e-06*G0_2_0_2_2 + 2.25524035047882e-05*G0_2_1_1_1 - 2.25524035047882e-05*G0_2_1_2_2 + 3.68355923911541e-05*G0_2_2_0_0 - 6.76572105143647e-06*G0_2_2_0_2 - 2.25524035047882e-05*G0_2_2_1_2 - 6.76572105143647e-06*G0_2_2_2_0 - 2.25524035047882e-05*G0_2_2_2_1 - 0.000112762017523941*G0_2_2_2_2; + A[103] = -A[101] + 9.20889809778861e-05*G0_0_0_0_0 - 1.31555687111266e-05*G0_0_0_0_1 - 6.57778435556321e-05*G0_0_0_0_2 - 1.31555687111266e-05*G0_0_0_1_0 - 6.38984765969013e-06*G0_0_0_1_1 - 6.76572105143647e-06*G0_0_0_1_2 - 6.57778435556321e-05*G0_0_0_2_0 - 6.76572105143647e-06*G0_0_0_2_1 - 1.69143026285911e-05*G0_0_0_2_2 - 1.31555687111266e-05*G0_0_1_0_0 - 6.38984765969013e-06*G0_0_1_0_1 - 6.76572105143647e-06*G0_0_1_0_2 - 6.38984765969013e-06*G0_0_1_1_0 + 5.90121225041954e-05*G0_0_1_1_1 + 2.49955805511402e-05*G0_0_1_1_2 - 6.76572105143647e-06*G0_0_1_2_0 + 2.49955805511402e-05*G0_0_1_2_1 - 6.57778435556321e-05*G0_0_2_0_0 - 6.76572105143647e-06*G0_0_2_0_1 - 1.69143026285911e-05*G0_0_2_0_2 - 6.76572105143647e-06*G0_0_2_1_0 + 2.49955805511402e-05*G0_0_2_1_1 - 1.69143026285911e-05*G0_0_2_2_0 + 4.88635409270415e-06*G0_0_2_2_2 - 1.31555687111266e-05*G0_1_0_0_0 - 6.38984765969013e-06*G0_1_0_0_1 - 6.76572105143647e-06*G0_1_0_0_2 - 6.38984765969014e-06*G0_1_0_1_0 + 5.90121225041954e-05*G0_1_0_1_1 + 2.49955805511402e-05*G0_1_0_1_2 - 6.76572105143647e-06*G0_1_0_2_0 + 2.49955805511402e-05*G0_1_0_2_1 - 6.38984765969013e-06*G0_1_1_0_0 + 5.90121225041954e-05*G0_1_1_0_1 + 2.49955805511402e-05*G0_1_1_0_2 + 5.90121225041954e-05*G0_1_1_1_0 + 0.000494273510146607*G0_1_1_1_1 + 0.000178163987687827*G0_1_1_1_2 + 2.49955805511402e-05*G0_1_1_2_0 + 0.000178163987687827*G0_1_1_2_1 + 9.94185121169415e-05*G0_1_1_2_2 - 6.76572105143647e-06*G0_1_2_0_0 + 2.49955805511402e-05*G0_1_2_0_1 + 2.49955805511402e-05*G0_1_2_1_0 + 0.000178163987687827*G0_1_2_1_1 + 9.94185121169415e-05*G0_1_2_1_2 + 9.94185121169415e-05*G0_1_2_2_1 + 6.08914894629284e-05*G0_1_2_2_2 - 6.57778435556321e-05*G0_2_0_0_0 - 6.76572105143648e-06*G0_2_0_0_1 - 1.69143026285911e-05*G0_2_0_0_2 - 6.76572105143647e-06*G0_2_0_1_0 + 2.49955805511402e-05*G0_2_0_1_1 - 1.69143026285911e-05*G0_2_0_2_0 + 4.88635409270416e-06*G0_2_0_2_2 - 6.76572105143647e-06*G0_2_1_0_0 + 2.49955805511402e-05*G0_2_1_0_1 + 2.49955805511402e-05*G0_2_1_1_0 + 0.000178163987687827*G0_2_1_1_1 + 9.94185121169415e-05*G0_2_1_1_2 + 9.94185121169415e-05*G0_2_1_2_1 + 6.08914894629284e-05*G0_2_1_2_2 - 1.69143026285911e-05*G0_2_2_0_0 + 4.88635409270416e-06*G0_2_2_0_2 + 9.94185121169415e-05*G0_2_2_1_1 + 6.08914894629284e-05*G0_2_2_1_2 + 4.88635409270417e-06*G0_2_2_2_0 + 6.08914894629284e-05*G0_2_2_2_1 - 9.20889809778846e-05*G0_2_2_2_2; + A[104] = A[103] + 0.000473600473600552*G0_0_0_0_0 + 0.000157866824533517*G0_0_0_0_2 - 4.51048070095755e-06*G0_0_0_1_1 + 4.51048070095764e-06*G0_0_0_1_2 + 0.000157866824533517*G0_0_0_2_0 + 4.51048070095765e-06*G0_0_0_2_1 + 2.70628842057458e-05*G0_0_0_2_2 - 4.51048070095755e-06*G0_0_1_0_1 + 4.51048070095765e-06*G0_0_1_0_2 - 4.51048070095755e-06*G0_0_1_1_0 - 2.70628842057456e-05*G0_0_1_1_1 + 4.51048070095765e-06*G0_0_1_2_0 + 2.70628842057459e-05*G0_0_1_2_2 + 0.000157866824533517*G0_0_2_0_0 + 4.51048070095765e-06*G0_0_2_0_1 + 2.70628842057458e-05*G0_0_2_0_2 + 4.51048070095765e-06*G0_0_2_1_0 + 2.70628842057459e-05*G0_0_2_1_2 + 2.70628842057458e-05*G0_0_2_2_0 + 2.70628842057459e-05*G0_0_2_2_1 + 0.000135314421028729*G0_0_2_2_2 - 4.51048070095755e-06*G0_1_0_0_1 + 4.51048070095765e-06*G0_1_0_0_2 - 4.51048070095755e-06*G0_1_0_1_0 - 2.70628842057456e-05*G0_1_0_1_1 + 4.51048070095765e-06*G0_1_0_2_0 + 2.70628842057459e-05*G0_1_0_2_2 - 4.51048070095755e-06*G0_1_1_0_0 - 2.70628842057456e-05*G0_1_1_0_1 - 2.70628842057456e-05*G0_1_1_1_0 - 0.000293181245562246*G0_1_1_1_1 - 5.86362491124494e-05*G0_1_1_1_2 - 5.86362491124494e-05*G0_1_1_2_1 + 5.86362491124494e-05*G0_1_1_2_2 + 4.51048070095764e-06*G0_1_2_0_0 + 2.70628842057459e-05*G0_1_2_0_2 - 5.86362491124494e-05*G0_1_2_1_1 + 5.86362491124494e-05*G0_1_2_1_2 + 2.70628842057459e-05*G0_1_2_2_0 + 5.86362491124494e-05*G0_1_2_2_1 + 0.000293181245562247*G0_1_2_2_2 + 0.000157866824533517*G0_2_0_0_0 + 4.51048070095765e-06*G0_2_0_0_1 + 2.70628842057458e-05*G0_2_0_0_2 + 4.51048070095765e-06*G0_2_0_1_0 + 2.70628842057459e-05*G0_2_0_1_2 + 2.70628842057458e-05*G0_2_0_2_0 + 2.70628842057459e-05*G0_2_0_2_1 + 0.000135314421028729*G0_2_0_2_2 + 4.51048070095765e-06*G0_2_1_0_0 + 2.70628842057459e-05*G0_2_1_0_2 - 5.86362491124494e-05*G0_2_1_1_1 + 5.86362491124494e-05*G0_2_1_1_2 + 2.70628842057459e-05*G0_2_1_2_0 + 5.86362491124494e-05*G0_2_1_2_1 + 0.000293181245562247*G0_2_1_2_2 + 2.70628842057458e-05*G0_2_2_0_0 + 2.70628842057459e-05*G0_2_2_0_1 + 0.000135314421028729*G0_2_2_0_2 + 2.70628842057459e-05*G0_2_2_1_0 + 5.86362491124494e-05*G0_2_2_1_1 + 0.000293181245562247*G0_2_2_1_2 + 0.000135314421028729*G0_2_2_2_0 + 0.000293181245562247*G0_2_2_2_1 + 0.00146590622781123*G0_2_2_2_2; + A[174] = A[170] + 0.00149409673219222*G0_0_0_0_0 + 0.000154859837399546*G0_0_0_0_1 + 0.000140200775121434*G0_0_0_0_2 + 0.000154859837399546*G0_0_0_1_0 - 3.27009850819429e-05*G0_0_0_1_1 + 1.5974619149225e-05*G0_0_0_1_2 + 0.000140200775121434*G0_0_0_2_0 + 1.5974619149225e-05*G0_0_0_2_1 + 2.01092264584362e-05*G0_0_0_2_2 + 0.000154859837399546*G0_0_1_0_0 - 3.27009850819429e-05*G0_0_1_0_1 + 1.5974619149225e-05*G0_0_1_0_2 - 3.27009850819429e-05*G0_0_1_1_0 - 7.89334122667585e-05*G0_0_1_1_1 - 4.13460730921114e-06*G0_0_1_1_2 + 1.5974619149225e-05*G0_0_1_2_0 - 4.13460730921114e-06*G0_0_1_2_1 + 0.000140200775121434*G0_0_2_0_0 + 1.5974619149225e-05*G0_0_2_0_1 + 2.01092264584362e-05*G0_0_2_0_2 + 1.5974619149225e-05*G0_0_2_1_0 - 4.13460730921114e-06*G0_0_2_1_1 + 2.01092264584362e-05*G0_0_2_2_0 - 2.01092264584362e-05*G0_0_2_2_2 + 0.000154859837399546*G0_1_0_0_0 - 3.27009850819429e-05*G0_1_0_0_1 + 1.5974619149225e-05*G0_1_0_0_2 - 3.27009850819429e-05*G0_1_0_1_0 - 7.89334122667586e-05*G0_1_0_1_1 - 4.13460730921114e-06*G0_1_0_1_2 + 1.5974619149225e-05*G0_1_0_2_0 - 4.13460730921115e-06*G0_1_0_2_1 - 3.27009850819429e-05*G0_1_1_0_0 - 7.89334122667585e-05*G0_1_1_0_1 - 4.13460730921115e-06*G0_1_1_0_2 - 7.89334122667585e-05*G0_1_1_1_0 + 9.2088980977888e-05*G0_1_1_1_1 - 4.13460730921115e-06*G0_1_1_2_0 + 4.1346073092112e-06*G0_1_1_2_2 + 1.5974619149225e-05*G0_1_2_0_0 - 4.13460730921114e-06*G0_1_2_0_1 - 4.13460730921114e-06*G0_1_2_1_0 + 4.1346073092112e-06*G0_1_2_1_2 + 4.1346073092112e-06*G0_1_2_2_1 - 1.59746191492251e-05*G0_1_2_2_2 + 0.000140200775121434*G0_2_0_0_0 + 1.5974619149225e-05*G0_2_0_0_1 + 2.01092264584362e-05*G0_2_0_0_2 + 1.5974619149225e-05*G0_2_0_1_0 - 4.13460730921115e-06*G0_2_0_1_1 + 2.01092264584362e-05*G0_2_0_2_0 - 2.01092264584362e-05*G0_2_0_2_2 + 1.5974619149225e-05*G0_2_1_0_0 - 4.13460730921114e-06*G0_2_1_0_1 - 4.13460730921115e-06*G0_2_1_1_0 + 4.1346073092112e-06*G0_2_1_1_2 + 4.1346073092112e-06*G0_2_1_2_1 - 1.59746191492251e-05*G0_2_1_2_2 + 2.01092264584362e-05*G0_2_2_0_0 - 2.01092264584362e-05*G0_2_2_0_2 + 4.1346073092112e-06*G0_2_2_1_1 - 1.59746191492251e-05*G0_2_2_1_2 - 2.01092264584362e-05*G0_2_2_2_0 - 1.59746191492251e-05*G0_2_2_2_1 - 0.000140200775121434*G0_2_2_2_2; + A[216] = A[104]; + A[201] = A[103]; + A[5] = A[31] + 2.23615302980389e-06*G0_0_0_0_0 - 2.79482422339612e-05*G0_0_2_2_2 + 2.09887114649055e-05*G0_1_1_1_1 - 1.2209278082296e-05*G0_1_1_2_2 - 1.2209278082296e-05*G0_1_2_1_2 - 1.2209278082296e-05*G0_1_2_2_1 - 4.9741557678074e-05*G0_1_2_2_2 - 2.79482422339612e-05*G0_2_0_2_2 - 1.2209278082296e-05*G0_2_1_1_2 - 1.2209278082296e-05*G0_2_1_2_1 - 4.9741557678074e-05*G0_2_1_2_2 - 2.79482422339612e-05*G0_2_2_0_2 - 1.2209278082296e-05*G0_2_2_1_1 - 4.9741557678074e-05*G0_2_2_1_2 - 2.79482422339612e-05*G0_2_2_2_0 - 4.9741557678074e-05*G0_2_2_2_1 - 0.000217221050554421*G0_2_2_2_2; + A[7] = -A[5] - 0.00105491216602346*G0_0_0_0_0 - 3.70411481522654e-05*G0_0_0_0_1 - 8.04956360512052e-05*G0_0_0_0_2 - 3.70411481522654e-05*G0_0_0_1_0 - 8.04956360512052e-05*G0_0_0_2_0 - 3.70411481522654e-05*G0_0_1_0_0 - 8.04956360512052e-05*G0_0_2_0_0 + 1.04187405774725e-05*G0_0_2_2_2 - 3.70411481522654e-05*G0_1_0_0_0 - 6.81975285150006e-05*G0_1_1_1_1 - 1.18635039269983e-06*G0_1_1_2_2 - 1.18635039269983e-06*G0_1_2_1_2 - 1.18635039269983e-06*G0_1_2_2_1 - 1.86762091524028e-05*G0_1_2_2_2 - 8.04956360512052e-05*G0_2_0_0_0 + 1.04187405774725e-05*G0_2_0_2_2 - 1.18635039269983e-06*G0_2_1_1_2 - 1.18635039269983e-06*G0_2_1_2_1 - 1.86762091524028e-05*G0_2_1_2_2 + 1.04187405774725e-05*G0_2_2_0_2 - 1.18635039269982e-06*G0_2_2_1_1 - 1.86762091524028e-05*G0_2_2_1_2 + 1.04187405774725e-05*G0_2_2_2_0 - 1.86762091524028e-05*G0_2_2_2_1 - 5.5793706587367e-05*G0_2_2_2_2; + A[36] = A[7] + 0.000767956323512008*G0_0_0_0_0 + 5.60873576746676e-06*G0_0_0_0_1 + 4.54924264448151e-05*G0_0_0_0_2 + 5.60873576746676e-06*G0_0_0_1_0 + 4.54924264448151e-05*G0_0_0_2_0 + 5.60873576746677e-06*G0_0_1_0_0 + 4.54924264448151e-05*G0_0_2_0_0 - 5.015560571117e-06*G0_0_2_2_2 + 5.60873576746677e-06*G0_1_0_0_0 - 1.32730291460472e-05*G0_1_1_2_2 - 1.32730291460472e-05*G0_1_2_1_2 - 1.32730291460472e-05*G0_1_2_2_1 - 2.20825617651051e-05*G0_1_2_2_2 + 4.54924264448151e-05*G0_2_0_0_0 - 5.015560571117e-06*G0_2_0_2_2 - 1.32730291460472e-05*G0_2_1_1_2 - 1.32730291460472e-05*G0_2_1_2_1 - 2.20825617651051e-05*G0_2_1_2_2 - 5.015560571117e-06*G0_2_2_0_2 - 1.32730291460472e-05*G0_2_2_1_1 - 2.20825617651051e-05*G0_2_2_1_2 - 5.01556057111701e-06*G0_2_2_2_0 - 2.20825617651051e-05*G0_2_2_2_1 + 0.000222704984609783*G0_2_2_2_2; + A[90] = A[5] + 0.00149891261002398*G0_0_0_0_0 + 4.91689380578351e-05*G0_0_0_0_1 + 9.73512084623362e-05*G0_0_0_0_2 + 4.91689380578351e-05*G0_0_0_1_0 + 9.73512084623362e-05*G0_0_0_2_0 + 4.91689380578351e-05*G0_0_1_0_0 + 9.73512084623362e-05*G0_0_2_0_0 + 6.10794261588014e-06*G0_0_2_2_2 + 4.91689380578351e-05*G0_1_0_0_0 + 4.31549637898918e-05*G0_1_1_1_1 - 3.92317852635378e-06*G0_1_1_1_2 - 3.92317852635378e-06*G0_1_1_2_1 + 1.13936621873149e-06*G0_1_1_2_2 - 3.92317852635378e-06*G0_1_2_1_1 + 1.13936621873149e-06*G0_1_2_1_2 + 1.13936621873149e-06*G0_1_2_2_1 + 3.10565389930522e-05*G0_1_2_2_2 + 9.73512084623361e-05*G0_2_0_0_0 + 6.10794261588014e-06*G0_2_0_2_2 - 3.92317852635378e-06*G0_2_1_1_1 + 1.13936621873149e-06*G0_2_1_1_2 + 1.13936621873149e-06*G0_2_1_2_1 + 3.10565389930522e-05*G0_2_1_2_2 + 6.10794261588013e-06*G0_2_2_0_2 + 1.13936621873149e-06*G0_2_2_1_1 + 3.10565389930522e-05*G0_2_2_1_2 + 6.10794261588014e-06*G0_2_2_2_0 + 3.10565389930522e-05*G0_2_2_2_1 + 0.000180066846733544*G0_2_2_2_2; + A[14] = A[5] - 0.000109355664911238*G0_0_0_0_0 - 5.89651383302277e-06*G0_0_1_2_2 - 5.89651383302277e-06*G0_0_2_1_2 - 5.89651383302277e-06*G0_0_2_2_1 - 2.34920869841544e-06*G0_0_2_2_2 - 5.89651383302277e-06*G0_1_0_2_2 + 8.0460397920729e-05*G0_1_1_1_1 - 1.86057328914503e-05*G0_1_1_1_2 - 1.86057328914503e-05*G0_1_1_2_1 - 3.08098720797185e-05*G0_1_1_2_2 - 5.89651383302277e-06*G0_1_2_0_2 - 1.86057328914503e-05*G0_1_2_1_1 - 3.08098720797185e-05*G0_1_2_1_2 - 5.89651383302277e-06*G0_1_2_2_0 - 3.08098720797185e-05*G0_1_2_2_1 - 3.52381304762316e-05*G0_1_2_2_2 - 5.89651383302277e-06*G0_2_0_1_2 - 5.89651383302277e-06*G0_2_0_2_1 - 2.34920869841543e-06*G0_2_0_2_2 - 5.89651383302277e-06*G0_2_1_0_2 - 1.86057328914503e-05*G0_2_1_1_1 - 3.08098720797185e-05*G0_2_1_1_2 - 5.89651383302277e-06*G0_2_1_2_0 - 3.08098720797185e-05*G0_2_1_2_1 - 3.52381304762316e-05*G0_2_1_2_2 - 5.89651383302277e-06*G0_2_2_0_1 - 2.34920869841544e-06*G0_2_2_0_2 - 5.89651383302277e-06*G0_2_2_1_0 - 3.08098720797185e-05*G0_2_2_1_1 - 3.52381304762316e-05*G0_2_2_1_2 - 2.34920869841544e-06*G0_2_2_2_0 - 3.52381304762316e-05*G0_2_2_2_1 - 2.70159000317769e-06*G0_2_2_2_2; + A[70] = A[14] - 6.69524479048434e-06*G0_0_0_0_0 - 7.11105473010354e-05*G0_0_0_0_1 - 7.11105473010354e-05*G0_0_0_1_0 - 5.10952891905359e-05*G0_0_0_1_1 - 1.22276312752524e-05*G0_0_0_1_2 - 1.22276312752524e-05*G0_0_0_2_1 - 7.11105473010354e-05*G0_0_1_0_0 - 5.10952891905359e-05*G0_0_1_0_1 - 1.22276312752524e-05*G0_0_1_0_2 - 5.10952891905359e-05*G0_0_1_1_0 + 8.57696095791477e-05*G0_0_1_1_1 - 1.22276312752524e-05*G0_0_1_2_0 + 1.51523961047796e-06*G0_0_1_2_2 - 1.22276312752524e-05*G0_0_2_0_1 - 1.22276312752524e-05*G0_0_2_1_0 + 1.51523961047797e-06*G0_0_2_1_2 + 1.51523961047797e-06*G0_0_2_2_1 + 2.50895488990769e-05*G0_0_2_2_2 - 7.11105473010354e-05*G0_1_0_0_0 - 5.10952891905359e-05*G0_1_0_0_1 - 1.22276312752524e-05*G0_1_0_0_2 - 5.10952891905359e-05*G0_1_0_1_0 + 8.57696095791477e-05*G0_1_0_1_1 - 1.22276312752524e-05*G0_1_0_2_0 + 1.51523961047796e-06*G0_1_0_2_2 - 5.10952891905359e-05*G0_1_1_0_0 + 8.57696095791477e-05*G0_1_1_0_1 + 8.57696095791477e-05*G0_1_1_1_0 + 0.00144582049343978*G0_1_1_1_1 + 0.000108744870649651*G0_1_1_1_2 + 0.000108744870649651*G0_1_1_2_1 - 5.49714835429225e-06*G0_1_1_2_2 - 1.22276312752524e-05*G0_1_2_0_0 + 1.51523961047796e-06*G0_1_2_0_2 + 0.000108744870649651*G0_1_2_1_1 - 5.49714835429225e-06*G0_1_2_1_2 + 1.51523961047796e-06*G0_1_2_2_0 - 5.49714835429225e-06*G0_1_2_2_1 + 2.54419302038391e-05*G0_1_2_2_2 - 1.22276312752524e-05*G0_2_0_0_1 - 1.22276312752524e-05*G0_2_0_1_0 + 1.51523961047796e-06*G0_2_0_1_2 + 1.51523961047796e-06*G0_2_0_2_1 + 2.50895488990769e-05*G0_2_0_2_2 - 1.22276312752524e-05*G0_2_1_0_0 + 1.51523961047796e-06*G0_2_1_0_2 + 0.000108744870649651*G0_2_1_1_1 - 5.49714835429225e-06*G0_2_1_1_2 + 1.51523961047796e-06*G0_2_1_2_0 - 5.49714835429224e-06*G0_2_1_2_1 + 2.54419302038391e-05*G0_2_1_2_2 + 1.51523961047796e-06*G0_2_2_0_1 + 2.50895488990769e-05*G0_2_2_0_2 + 1.51523961047796e-06*G0_2_2_1_0 - 5.49714835429225e-06*G0_2_2_1_1 + 2.54419302038391e-05*G0_2_2_1_2 + 2.50895488990769e-05*G0_2_2_2_0 + 2.54419302038391e-05*G0_2_2_2_1 + 0.000208962113724053*G0_2_2_2_2; + A[139] = -A[14] - 2.46666913333612e-05*G0_0_0_0_0 + 1.98743055885948e-05*G0_0_0_0_1 + 1.56457299314468e-05*G0_0_0_0_2 + 1.98743055885948e-05*G0_0_0_1_0 + 1.56457299314468e-05*G0_0_0_2_0 + 1.98743055885948e-05*G0_0_1_0_0 - 5.65219612838755e-05*G0_0_1_1_1 + 1.9028590457165e-06*G0_0_1_2_2 + 1.56457299314468e-05*G0_0_2_0_0 + 1.90285904571649e-06*G0_0_2_1_2 + 1.90285904571649e-06*G0_0_2_2_1 - 2.46666913333621e-05*G0_0_2_2_2 + 1.98743055885948e-05*G0_1_0_0_0 - 5.65219612838755e-05*G0_1_0_1_1 + 1.9028590457165e-06*G0_1_0_2_2 - 5.65219612838755e-05*G0_1_1_0_1 - 5.65219612838755e-05*G0_1_1_1_0 - 0.000649086363372187*G0_1_1_1_1 - 1.46590622781123e-05*G0_1_1_1_2 - 1.46590622781123e-05*G0_1_1_2_1 + 3.29124138648004e-05*G0_1_1_2_2 + 1.9028590457165e-06*G0_1_2_0_2 - 1.46590622781123e-05*G0_1_2_1_1 + 3.29124138648005e-05*G0_1_2_1_2 + 1.9028590457165e-06*G0_1_2_2_0 + 3.29124138648004e-05*G0_1_2_2_1 - 1.40952521904926e-05*G0_1_2_2_2 + 1.56457299314468e-05*G0_2_0_0_0 + 1.90285904571649e-06*G0_2_0_1_2 + 1.90285904571649e-06*G0_2_0_2_1 - 2.46666913333621e-05*G0_2_0_2_2 + 1.9028590457165e-06*G0_2_1_0_2 - 1.46590622781123e-05*G0_2_1_1_1 + 3.29124138648005e-05*G0_2_1_1_2 + 1.9028590457165e-06*G0_2_1_2_0 + 3.29124138648004e-05*G0_2_1_2_1 - 1.40952521904926e-05*G0_2_1_2_2 + 1.90285904571649e-06*G0_2_2_0_1 - 2.46666913333621e-05*G0_2_2_0_2 + 1.9028590457165e-06*G0_2_2_1_0 + 3.29124138648004e-05*G0_2_2_1_1 - 1.40952521904926e-05*G0_2_2_1_2 - 2.46666913333621e-05*G0_2_2_2_0 - 1.40952521904925e-05*G0_2_2_2_1 - 0.00029670505860987*G0_2_2_2_2; + A[107] = -A[36] - 5.16825913651401e-05*G0_0_0_0_0 + 6.93016566032551e-06*G0_0_0_0_1 + 6.5190541381028e-06*G0_0_0_0_2 + 6.93016566032551e-06*G0_0_0_1_0 + 6.7422289644523e-06*G0_0_0_1_1 + 6.5190541381028e-06*G0_0_0_2_0 + 6.93016566032551e-06*G0_0_1_0_0 + 6.7422289644523e-06*G0_0_1_0_1 + 6.7422289644523e-06*G0_0_1_1_0 + 6.5190541381028e-06*G0_0_2_0_0 - 4.39889328778291e-05*G0_0_2_2_2 + 6.93016566032551e-06*G0_1_0_0_0 + 6.7422289644523e-06*G0_1_0_0_1 + 6.7422289644523e-06*G0_1_0_1_0 + 6.7422289644523e-06*G0_1_1_0_0 - 2.07611318722464e-05*G0_1_2_2_2 + 6.5190541381028e-06*G0_2_0_0_0 - 4.39889328778291e-05*G0_2_0_2_2 - 2.07611318722464e-05*G0_2_1_2_2 - 4.39889328778291e-05*G0_2_2_0_2 - 2.07611318722465e-05*G0_2_2_1_2 - 4.39889328778291e-05*G0_2_2_2_0 - 2.07611318722465e-05*G0_2_2_2_1 - 0.000596933930267362*G0_2_2_2_2; + A[154] = A[70]; + A[15] = A[1]; + A[8] = -A[36] + 0.000171022393244644*G0_0_0_0_0 - 1.51523961047797e-05*G0_0_0_0_1 + 1.50349356698585e-06*G0_0_0_0_2 - 1.51523961047797e-05*G0_0_0_1_0 + 1.50349356698585e-06*G0_0_0_2_0 - 1.51523961047797e-05*G0_0_1_0_0 + 1.50349356698585e-06*G0_0_2_0_0 + 1.50349356698585e-06*G0_0_2_2_2 - 1.51523961047797e-05*G0_1_0_0_0 - 1.51523961047796e-05*G0_1_2_2_2 + 1.50349356698584e-06*G0_2_0_0_0 + 1.50349356698585e-06*G0_2_0_2_2 - 1.51523961047796e-05*G0_2_1_2_2 + 1.50349356698586e-06*G0_2_2_0_2 - 1.51523961047796e-05*G0_2_2_1_2 + 1.50349356698585e-06*G0_2_2_2_0 - 1.51523961047796e-05*G0_2_2_2_1 + 0.000171022393244643*G0_2_2_2_2; + A[50] = A[170] - 2.74387575974923e-05*G0_0_0_0_0 - 9.20889809778854e-06*G0_0_0_0_1 - 9.20889809778854e-06*G0_0_0_1_0 - 3.27009850819429e-05*G0_0_0_1_1 + 2.01092264584362e-05*G0_0_0_2_2 - 9.20889809778854e-06*G0_0_1_0_0 - 3.27009850819429e-05*G0_0_1_0_1 - 3.27009850819429e-05*G0_0_1_1_0 - 0.000105244549689012*G0_0_1_1_1 - 4.13460730921115e-06*G0_0_1_1_2 - 4.13460730921114e-06*G0_0_1_2_1 + 1.48469989739856e-05*G0_0_1_2_2 + 2.01092264584362e-05*G0_0_2_0_2 - 4.13460730921114e-06*G0_0_2_1_1 + 1.48469989739856e-05*G0_0_2_1_2 + 2.01092264584362e-05*G0_0_2_2_0 + 1.48469989739856e-05*G0_0_2_2_1 + 0.000117648371616645*G0_0_2_2_2 - 9.20889809778854e-06*G0_1_0_0_0 - 3.27009850819429e-05*G0_1_0_0_1 - 3.27009850819429e-05*G0_1_0_1_0 - 0.000105244549689012*G0_1_0_1_1 - 4.13460730921115e-06*G0_1_0_1_2 - 4.13460730921115e-06*G0_1_0_2_1 + 1.48469989739856e-05*G0_1_0_2_2 - 3.27009850819429e-05*G0_1_1_0_0 - 0.000105244549689012*G0_1_1_0_1 - 4.13460730921115e-06*G0_1_1_0_2 - 0.000105244549689012*G0_1_1_1_0 + 9.20889809778878e-05*G0_1_1_1_1 + 2.63111374222532e-05*G0_1_1_1_2 - 4.13460730921115e-06*G0_1_1_2_0 + 2.63111374222532e-05*G0_1_1_2_1 + 4.13460730921121e-06*G0_1_1_2_2 - 4.13460730921115e-06*G0_1_2_0_1 + 1.48469989739856e-05*G0_1_2_0_2 - 4.13460730921114e-06*G0_1_2_1_0 + 2.63111374222532e-05*G0_1_2_1_1 + 4.13460730921121e-06*G0_1_2_1_2 + 1.48469989739856e-05*G0_1_2_2_0 + 4.13460730921121e-06*G0_1_2_2_1 + 0.00014809411634811*G0_1_2_2_2 + 2.01092264584362e-05*G0_2_0_0_2 - 4.13460730921115e-06*G0_2_0_1_1 + 1.48469989739856e-05*G0_2_0_1_2 + 2.01092264584362e-05*G0_2_0_2_0 + 1.48469989739856e-05*G0_2_0_2_1 + 0.000117648371616645*G0_2_0_2_2 - 4.13460730921114e-06*G0_2_1_0_1 + 1.48469989739856e-05*G0_2_1_0_2 - 4.13460730921115e-06*G0_2_1_1_0 + 2.63111374222532e-05*G0_2_1_1_1 + 4.13460730921121e-06*G0_2_1_1_2 + 1.48469989739856e-05*G0_2_1_2_0 + 4.13460730921121e-06*G0_2_1_2_1 + 0.00014809411634811*G0_2_1_2_2 + 2.01092264584362e-05*G0_2_2_0_0 + 1.48469989739856e-05*G0_2_2_0_1 + 0.000117648371616645*G0_2_2_0_2 + 1.48469989739856e-05*G0_2_2_1_0 + 4.13460730921121e-06*G0_2_2_1_1 + 0.00014809411634811*G0_2_2_1_2 + 0.000117648371616645*G0_2_2_2_0 + 0.00014809411634811*G0_2_2_2_1 + 0.00138133471466828*G0_2_2_2_2; + A[37] = A[107]; + A[148] = A[149] + 0.00047360047360055*G0_0_0_0_0 + 0.000157866824533517*G0_0_0_0_1 + 0.000157866824533517*G0_0_0_1_0 + 2.70628842057456e-05*G0_0_0_1_1 + 4.51048070095755e-06*G0_0_0_1_2 + 4.51048070095755e-06*G0_0_0_2_1 - 4.51048070095774e-06*G0_0_0_2_2 + 0.000157866824533517*G0_0_1_0_0 + 2.70628842057456e-05*G0_0_1_0_1 + 4.51048070095755e-06*G0_0_1_0_2 + 2.70628842057456e-05*G0_0_1_1_0 + 0.000135314421028729*G0_0_1_1_1 + 2.70628842057458e-05*G0_0_1_1_2 + 4.51048070095755e-06*G0_0_1_2_0 + 2.70628842057458e-05*G0_0_1_2_1 + 4.51048070095755e-06*G0_0_2_0_1 - 4.51048070095774e-06*G0_0_2_0_2 + 4.51048070095755e-06*G0_0_2_1_0 + 2.70628842057458e-05*G0_0_2_1_1 - 4.51048070095775e-06*G0_0_2_2_0 - 2.7062884205746e-05*G0_0_2_2_2 + 0.000157866824533517*G0_1_0_0_0 + 2.70628842057456e-05*G0_1_0_0_1 + 4.51048070095755e-06*G0_1_0_0_2 + 2.70628842057455e-05*G0_1_0_1_0 + 0.000135314421028729*G0_1_0_1_1 + 2.70628842057458e-05*G0_1_0_1_2 + 4.51048070095755e-06*G0_1_0_2_0 + 2.70628842057458e-05*G0_1_0_2_1 + 2.70628842057455e-05*G0_1_1_0_0 + 0.000135314421028729*G0_1_1_0_1 + 2.70628842057458e-05*G0_1_1_0_2 + 0.000135314421028729*G0_1_1_1_0 + 0.00146590622781124*G0_1_1_1_1 + 0.000293181245562247*G0_1_1_1_2 + 2.70628842057458e-05*G0_1_1_2_0 + 0.000293181245562247*G0_1_1_2_1 + 5.86362491124496e-05*G0_1_1_2_2 + 4.51048070095755e-06*G0_1_2_0_0 + 2.70628842057458e-05*G0_1_2_0_1 + 2.70628842057458e-05*G0_1_2_1_0 + 0.000293181245562247*G0_1_2_1_1 + 5.86362491124496e-05*G0_1_2_1_2 + 5.86362491124496e-05*G0_1_2_2_1 - 5.86362491124493e-05*G0_1_2_2_2 + 4.51048070095755e-06*G0_2_0_0_1 - 4.51048070095774e-06*G0_2_0_0_2 + 4.51048070095755e-06*G0_2_0_1_0 + 2.70628842057458e-05*G0_2_0_1_1 - 4.51048070095774e-06*G0_2_0_2_0 - 2.7062884205746e-05*G0_2_0_2_2 + 4.51048070095755e-06*G0_2_1_0_0 + 2.70628842057458e-05*G0_2_1_0_1 + 2.70628842057458e-05*G0_2_1_1_0 + 0.000293181245562247*G0_2_1_1_1 + 5.86362491124496e-05*G0_2_1_1_2 + 5.86362491124496e-05*G0_2_1_2_1 - 5.86362491124493e-05*G0_2_1_2_2 - 4.51048070095774e-06*G0_2_2_0_0 - 2.7062884205746e-05*G0_2_2_0_2 + 5.86362491124496e-05*G0_2_2_1_1 - 5.86362491124494e-05*G0_2_2_1_2 - 2.7062884205746e-05*G0_2_2_2_0 - 5.86362491124494e-05*G0_2_2_2_1 - 0.000293181245562247*G0_2_2_2_2; + A[123] = -A[60] + 4.4899251248465e-05*G0_0_0_0_0 + 1.56692220184309e-05*G0_0_0_0_2 + 1.56692220184309e-05*G0_0_0_2_0 + 5.88741064931639e-05*G0_0_0_2_2 + 3.55200355200414e-05*G0_0_1_1_1 + 2.32571661143129e-05*G0_0_1_2_2 + 1.56692220184309e-05*G0_0_2_0_0 + 5.88741064931639e-05*G0_0_2_0_2 + 2.32571661143129e-05*G0_0_2_1_2 + 5.88741064931639e-05*G0_0_2_2_0 + 2.32571661143129e-05*G0_0_2_2_1 + 0.000258412956825698*G0_0_2_2_2 + 3.55200355200414e-05*G0_1_0_1_1 + 2.32571661143129e-05*G0_1_0_2_2 + 3.55200355200414e-05*G0_1_1_0_1 + 3.55200355200414e-05*G0_1_1_1_0 + 0.000263023278896339*G0_1_1_1_1 + 6.54254622508702e-06*G0_1_1_1_2 + 6.54254622508702e-06*G0_1_1_2_1 - 5.28865608230779e-06*G0_1_1_2_2 + 2.32571661143129e-05*G0_1_2_0_2 + 6.54254622508702e-06*G0_1_2_1_1 - 5.28865608230779e-06*G0_1_2_1_2 + 2.32571661143129e-05*G0_1_2_2_0 - 5.28865608230779e-06*G0_1_2_2_1 + 0.000128325525150943*G0_1_2_2_2 + 1.56692220184309e-05*G0_2_0_0_0 + 5.88741064931639e-05*G0_2_0_0_2 + 2.32571661143129e-05*G0_2_0_1_2 + 5.88741064931639e-05*G0_2_0_2_0 + 2.32571661143129e-05*G0_2_0_2_1 + 0.000258412956825698*G0_2_0_2_2 + 2.32571661143129e-05*G0_2_1_0_2 + 6.54254622508702e-06*G0_2_1_1_1 - 5.28865608230779e-06*G0_2_1_1_2 + 2.32571661143129e-05*G0_2_1_2_0 - 5.28865608230779e-06*G0_2_1_2_1 + 0.000128325525150943*G0_2_1_2_2 + 5.88741064931639e-05*G0_2_2_0_0 + 2.32571661143129e-05*G0_2_2_0_1 + 0.000258412956825698*G0_2_2_0_2 + 2.32571661143129e-05*G0_2_2_1_0 - 5.28865608230779e-06*G0_2_2_1_1 + 0.000128325525150943*G0_2_2_1_2 + 0.000258412956825698*G0_2_2_2_0 + 0.000128325525150944*G0_2_2_2_1 + 0.00155226901258673*G0_2_2_2_2; + A[137] = A[1] - 0.00021722105055442*G0_0_0_0_0 - 4.97415576780739e-05*G0_0_0_0_1 - 2.79482422339612e-05*G0_0_0_0_2 - 4.97415576780739e-05*G0_0_0_1_0 - 1.2209278082296e-05*G0_0_0_1_1 - 2.79482422339612e-05*G0_0_0_2_0 - 4.97415576780739e-05*G0_0_1_0_0 - 1.2209278082296e-05*G0_0_1_0_1 - 1.2209278082296e-05*G0_0_1_1_0 - 2.79482422339612e-05*G0_0_2_0_0 - 4.97415576780739e-05*G0_1_0_0_0 - 1.2209278082296e-05*G0_1_0_0_1 - 1.2209278082296e-05*G0_1_0_1_0 - 1.2209278082296e-05*G0_1_1_0_0 + 2.09887114649056e-05*G0_1_1_1_1 - 2.79482422339612e-05*G0_2_0_0_0 + 2.23615302980407e-06*G0_2_2_2_2; + A[122] = A[137] + 0.000180066846733543*G0_0_0_0_0 + 3.10565389930521e-05*G0_0_0_0_1 + 6.10794261588015e-06*G0_0_0_0_2 + 3.10565389930521e-05*G0_0_0_1_0 + 1.13936621873148e-06*G0_0_0_1_1 + 6.10794261588014e-06*G0_0_0_2_0 + 3.10565389930521e-05*G0_0_1_0_0 + 1.13936621873148e-06*G0_0_1_0_1 + 1.13936621873148e-06*G0_0_1_1_0 - 3.92317852635378e-06*G0_0_1_1_1 + 6.10794261588014e-06*G0_0_2_0_0 + 9.73512084623359e-05*G0_0_2_2_2 + 3.10565389930521e-05*G0_1_0_0_0 + 1.13936621873148e-06*G0_1_0_0_1 + 1.13936621873148e-06*G0_1_0_1_0 - 3.92317852635378e-06*G0_1_0_1_1 + 1.13936621873148e-06*G0_1_1_0_0 - 3.92317852635378e-06*G0_1_1_0_1 - 3.92317852635378e-06*G0_1_1_1_0 + 4.31549637898918e-05*G0_1_1_1_1 + 4.91689380578352e-05*G0_1_2_2_2 + 6.10794261588014e-06*G0_2_0_0_0 + 9.73512084623359e-05*G0_2_0_2_2 + 4.91689380578352e-05*G0_2_1_2_2 + 9.73512084623359e-05*G0_2_2_0_2 + 4.91689380578352e-05*G0_2_2_1_2 + 9.73512084623359e-05*G0_2_2_2_0 + 4.91689380578352e-05*G0_2_2_2_1 + 0.00149891261002397*G0_2_2_2_2; + A[42] = A[137] - 2.7015900031778e-06*G0_0_0_0_0 - 3.52381304762316e-05*G0_0_0_0_1 - 2.34920869841544e-06*G0_0_0_0_2 - 3.52381304762316e-05*G0_0_0_1_0 - 3.08098720797185e-05*G0_0_0_1_1 - 5.89651383302275e-06*G0_0_0_1_2 - 2.34920869841544e-06*G0_0_0_2_0 - 5.89651383302275e-06*G0_0_0_2_1 - 3.52381304762317e-05*G0_0_1_0_0 - 3.08098720797185e-05*G0_0_1_0_1 - 5.89651383302275e-06*G0_0_1_0_2 - 3.08098720797185e-05*G0_0_1_1_0 - 1.86057328914503e-05*G0_0_1_1_1 - 5.89651383302275e-06*G0_0_1_2_0 - 2.34920869841545e-06*G0_0_2_0_0 - 5.89651383302276e-06*G0_0_2_0_1 - 5.89651383302276e-06*G0_0_2_1_0 - 3.52381304762317e-05*G0_1_0_0_0 - 3.08098720797185e-05*G0_1_0_0_1 - 5.89651383302276e-06*G0_1_0_0_2 - 3.08098720797185e-05*G0_1_0_1_0 - 1.86057328914503e-05*G0_1_0_1_1 - 5.89651383302276e-06*G0_1_0_2_0 - 3.08098720797185e-05*G0_1_1_0_0 - 1.86057328914503e-05*G0_1_1_0_1 - 1.86057328914503e-05*G0_1_1_1_0 + 8.04603979207291e-05*G0_1_1_1_1 - 5.89651383302275e-06*G0_1_2_0_0 - 2.34920869841545e-06*G0_2_0_0_0 - 5.89651383302276e-06*G0_2_0_0_1 - 5.89651383302275e-06*G0_2_0_1_0 - 5.89651383302275e-06*G0_2_1_0_0 - 0.000109355664911239*G0_2_2_2_2; + A[212] = -A[42] - 0.000184647803695454*G0_0_0_0_0 - 4.17219464838582e-05*G0_0_0_0_1 - 1.04304866209645e-05*G0_0_0_0_2 - 4.17219464838582e-05*G0_0_0_1_0 - 7.18857861715123e-06*G0_0_0_1_1 - 4.22857565714769e-07*G0_0_0_1_2 - 1.04304866209645e-05*G0_0_0_2_0 - 4.22857565714772e-07*G0_0_0_2_1 - 4.17219464838583e-05*G0_0_1_0_0 - 7.18857861715123e-06*G0_0_1_0_1 - 4.22857565714769e-07*G0_0_1_0_2 - 7.18857861715123e-06*G0_0_1_1_0 + 2.25524035047883e-05*G0_0_1_1_1 + 4.36952817905273e-06*G0_0_1_1_2 - 4.2285756571477e-07*G0_0_1_2_0 + 4.36952817905273e-06*G0_0_1_2_1 - 1.04304866209646e-05*G0_0_2_0_0 - 4.22857565714775e-07*G0_0_2_0_1 - 4.22857565714775e-07*G0_0_2_1_0 + 4.36952817905273e-06*G0_0_2_1_1 - 9.86667653334483e-06*G0_0_2_2_2 - 4.17219464838583e-05*G0_1_0_0_0 - 7.18857861715124e-06*G0_1_0_0_1 - 4.22857565714772e-07*G0_1_0_0_2 - 7.18857861715123e-06*G0_1_0_1_0 + 2.25524035047883e-05*G0_1_0_1_1 + 4.36952817905273e-06*G0_1_0_1_2 - 4.22857565714774e-07*G0_1_0_2_0 + 4.36952817905273e-06*G0_1_0_2_1 - 7.18857861715123e-06*G0_1_1_0_0 + 2.25524035047883e-05*G0_1_1_0_1 + 4.36952817905273e-06*G0_1_1_0_2 + 2.25524035047883e-05*G0_1_1_1_0 + 0.000136723946247779*G0_1_1_1_1 + 1.83238278476405e-05*G0_1_1_1_2 + 4.36952817905273e-06*G0_1_1_2_0 + 1.83238278476405e-05*G0_1_1_2_1 - 4.2285756571477e-07*G0_1_2_0_0 + 4.36952817905273e-06*G0_1_2_0_1 + 4.36952817905273e-06*G0_1_2_1_0 + 1.83238278476405e-05*G0_1_2_1_1 - 9.86667653334485e-06*G0_1_2_2_2 - 1.04304866209646e-05*G0_2_0_0_0 - 4.22857565714772e-07*G0_2_0_0_1 - 4.22857565714769e-07*G0_2_0_1_0 + 4.36952817905273e-06*G0_2_0_1_1 - 9.86667653334485e-06*G0_2_0_2_2 - 4.22857565714769e-07*G0_2_1_0_0 + 4.36952817905273e-06*G0_2_1_0_1 + 4.36952817905273e-06*G0_2_1_1_0 + 1.83238278476405e-05*G0_2_1_1_1 - 9.86667653334485e-06*G0_2_1_2_2 - 9.86667653334484e-06*G0_2_2_0_2 - 9.86667653334485e-06*G0_2_2_1_2 - 9.86667653334485e-06*G0_2_2_2_0 - 9.86667653334485e-06*G0_2_2_2_1 + 0.000167733501066862*G0_2_2_2_2; + A[182] = A[42]; + A[193] = -A[212] - 0.0012960584389158*G0_0_0_0_0 + 0.000151383008525891*G0_0_0_0_1 - 0.000552392933345407*G0_0_0_0_2 + 0.000151383008525891*G0_0_0_1_0 + 0.000335114620828963*G0_0_0_1_1 - 8.95048514096293e-06*G0_0_0_1_2 - 0.000552392933345407*G0_0_0_2_0 - 8.95048514096294e-06*G0_0_0_2_1 - 0.0003547774976347*G0_0_0_2_2 + 0.000151383008525891*G0_0_1_0_0 + 0.000335114620828963*G0_0_1_0_1 - 8.9504851409629e-06*G0_0_1_0_2 + 0.000335114620828963*G0_0_1_1_0 + 0.000151383008525891*G0_0_1_1_1 - 8.95048514096292e-06*G0_0_1_1_2 - 8.9504851409629e-06*G0_0_1_2_0 - 8.95048514096295e-06*G0_0_1_2_1 - 0.000103459151078216*G0_0_1_2_2 - 0.000552392933345407*G0_0_2_0_0 - 8.95048514096291e-06*G0_0_2_0_1 - 0.0003547774976347*G0_0_2_0_2 - 8.95048514096295e-06*G0_0_2_1_0 - 8.95048514096295e-06*G0_0_2_1_1 - 0.000103459151078216*G0_0_2_1_2 - 0.0003547774976347*G0_0_2_2_0 - 0.000103459151078216*G0_0_2_2_1 - 0.000319257462114659*G0_0_2_2_2 + 0.000151383008525891*G0_1_0_0_0 + 0.000335114620828963*G0_1_0_0_1 - 8.9504851409629e-06*G0_1_0_0_2 + 0.000335114620828963*G0_1_0_1_0 + 0.000151383008525891*G0_1_0_1_1 - 8.95048514096293e-06*G0_1_0_1_2 - 8.9504851409629e-06*G0_1_0_2_0 - 8.95048514096295e-06*G0_1_0_2_1 - 0.000103459151078216*G0_1_0_2_2 + 0.000335114620828963*G0_1_1_0_0 + 0.000151383008525891*G0_1_1_0_1 - 8.95048514096295e-06*G0_1_1_0_2 + 0.000151383008525891*G0_1_1_1_0 - 0.0012960584389158*G0_1_1_1_1 - 0.000552392933345408*G0_1_1_1_2 - 8.95048514096295e-06*G0_1_1_2_0 - 0.000552392933345408*G0_1_1_2_1 - 0.000354777497634701*G0_1_1_2_2 - 8.95048514096292e-06*G0_1_2_0_0 - 8.95048514096294e-06*G0_1_2_0_1 - 0.000103459151078216*G0_1_2_0_2 - 8.95048514096292e-06*G0_1_2_1_0 - 0.000552392933345408*G0_1_2_1_1 - 0.000354777497634701*G0_1_2_1_2 - 0.000103459151078216*G0_1_2_2_0 - 0.000354777497634701*G0_1_2_2_1 - 0.000319257462114659*G0_1_2_2_2 - 0.000552392933345407*G0_2_0_0_0 - 8.95048514096291e-06*G0_2_0_0_1 - 0.0003547774976347*G0_2_0_0_2 - 8.95048514096289e-06*G0_2_0_1_0 - 8.95048514096293e-06*G0_2_0_1_1 - 0.000103459151078216*G0_2_0_1_2 - 0.0003547774976347*G0_2_0_2_0 - 0.000103459151078216*G0_2_0_2_1 - 0.000319257462114659*G0_2_0_2_2 - 8.9504851409629e-06*G0_2_1_0_0 - 8.95048514096292e-06*G0_2_1_0_1 - 0.000103459151078216*G0_2_1_0_2 - 8.95048514096295e-06*G0_2_1_1_0 - 0.000552392933345408*G0_2_1_1_1 - 0.000354777497634701*G0_2_1_1_2 - 0.000103459151078216*G0_2_1_2_0 - 0.000354777497634701*G0_2_1_2_1 - 0.000319257462114659*G0_2_1_2_2 - 0.0003547774976347*G0_2_2_0_0 - 0.000103459151078216*G0_2_2_0_1 - 0.000319257462114659*G0_2_2_0_2 - 0.000103459151078216*G0_2_2_1_0 - 0.000354777497634701*G0_2_2_1_1 - 0.000319257462114659*G0_2_2_1_2 - 0.000319257462114659*G0_2_2_2_0 - 0.000319257462114659*G0_2_2_2_1 - 7.68191244381863e-05*G0_2_2_2_2; + A[213] = A[57] - 0.000293181245562246*G0_0_0_0_0 - 2.70628842057456e-05*G0_0_0_0_1 - 5.86362491124493e-05*G0_0_0_0_2 - 2.70628842057456e-05*G0_0_0_1_0 - 4.51048070095745e-06*G0_0_0_1_1 - 5.86362491124493e-05*G0_0_0_2_0 + 5.86362491124493e-05*G0_0_0_2_2 - 2.70628842057456e-05*G0_0_1_0_0 - 4.51048070095745e-06*G0_0_1_0_1 - 4.51048070095745e-06*G0_0_1_1_0 + 4.51048070095769e-06*G0_0_1_1_2 + 4.51048070095769e-06*G0_0_1_2_1 + 2.70628842057459e-05*G0_0_1_2_2 - 5.86362491124493e-05*G0_0_2_0_0 + 5.86362491124493e-05*G0_0_2_0_2 + 4.5104807009577e-06*G0_0_2_1_1 + 2.70628842057459e-05*G0_0_2_1_2 + 5.86362491124493e-05*G0_0_2_2_0 + 2.70628842057458e-05*G0_0_2_2_1 + 0.000293181245562247*G0_0_2_2_2 - 2.70628842057456e-05*G0_1_0_0_0 - 4.51048070095744e-06*G0_1_0_0_1 - 4.51048070095745e-06*G0_1_0_1_0 + 4.51048070095769e-06*G0_1_0_1_2 + 4.51048070095769e-06*G0_1_0_2_1 + 2.70628842057459e-05*G0_1_0_2_2 - 4.51048070095744e-06*G0_1_1_0_0 + 4.5104807009577e-06*G0_1_1_0_2 + 0.000473600473600555*G0_1_1_1_1 + 0.000157866824533518*G0_1_1_1_2 + 4.5104807009577e-06*G0_1_1_2_0 + 0.000157866824533518*G0_1_1_2_1 + 2.70628842057461e-05*G0_1_1_2_2 + 4.51048070095769e-06*G0_1_2_0_1 + 2.70628842057459e-05*G0_1_2_0_2 + 4.51048070095769e-06*G0_1_2_1_0 + 0.000157866824533518*G0_1_2_1_1 + 2.7062884205746e-05*G0_1_2_1_2 + 2.70628842057459e-05*G0_1_2_2_0 + 2.70628842057461e-05*G0_1_2_2_1 + 0.000135314421028729*G0_1_2_2_2 - 5.86362491124493e-05*G0_2_0_0_0 + 5.86362491124493e-05*G0_2_0_0_2 + 4.51048070095769e-06*G0_2_0_1_1 + 2.70628842057459e-05*G0_2_0_1_2 + 5.86362491124493e-05*G0_2_0_2_0 + 2.70628842057458e-05*G0_2_0_2_1 + 0.000293181245562247*G0_2_0_2_2 + 4.51048070095769e-06*G0_2_1_0_1 + 2.70628842057458e-05*G0_2_1_0_2 + 4.51048070095769e-06*G0_2_1_1_0 + 0.000157866824533518*G0_2_1_1_1 + 2.7062884205746e-05*G0_2_1_1_2 + 2.70628842057459e-05*G0_2_1_2_0 + 2.70628842057461e-05*G0_2_1_2_1 + 0.000135314421028729*G0_2_1_2_2 + 5.86362491124493e-05*G0_2_2_0_0 + 2.70628842057458e-05*G0_2_2_0_1 + 0.000293181245562247*G0_2_2_0_2 + 2.70628842057458e-05*G0_2_2_1_0 + 2.7062884205746e-05*G0_2_2_1_1 + 0.000135314421028729*G0_2_2_1_2 + 0.000293181245562247*G0_2_2_2_0 + 0.000135314421028729*G0_2_2_2_1 + 0.00146590622781123*G0_2_2_2_2; + A[204] = A[148]; + A[133] = -A[123] - 9.2088980977885e-05*G0_0_0_0_0 + 6.08914894629282e-05*G0_0_0_0_1 + 4.88635409270424e-06*G0_0_0_0_2 + 6.08914894629282e-05*G0_0_0_1_0 + 9.94185121169415e-05*G0_0_0_1_1 + 4.88635409270423e-06*G0_0_0_2_0 - 1.69143026285911e-05*G0_0_0_2_2 + 6.08914894629282e-05*G0_0_1_0_0 + 9.94185121169415e-05*G0_0_1_0_1 + 9.94185121169415e-05*G0_0_1_1_0 + 0.000178163987687827*G0_0_1_1_1 + 2.49955805511403e-05*G0_0_1_1_2 + 2.49955805511403e-05*G0_0_1_2_1 - 6.76572105143644e-06*G0_0_1_2_2 + 4.88635409270422e-06*G0_0_2_0_0 - 1.69143026285911e-05*G0_0_2_0_2 + 2.49955805511403e-05*G0_0_2_1_1 - 6.76572105143643e-06*G0_0_2_1_2 - 1.69143026285911e-05*G0_0_2_2_0 - 6.76572105143644e-06*G0_0_2_2_1 - 6.5777843555632e-05*G0_0_2_2_2 + 6.08914894629282e-05*G0_1_0_0_0 + 9.94185121169415e-05*G0_1_0_0_1 + 9.94185121169415e-05*G0_1_0_1_0 + 0.000178163987687827*G0_1_0_1_1 + 2.49955805511403e-05*G0_1_0_1_2 + 2.49955805511403e-05*G0_1_0_2_1 - 6.76572105143643e-06*G0_1_0_2_2 + 9.94185121169415e-05*G0_1_1_0_0 + 0.000178163987687827*G0_1_1_0_1 + 2.49955805511403e-05*G0_1_1_0_2 + 0.000178163987687827*G0_1_1_1_0 + 0.000494273510146609*G0_1_1_1_1 + 5.9012122504196e-05*G0_1_1_1_2 + 2.49955805511403e-05*G0_1_1_2_0 + 5.9012122504196e-05*G0_1_1_2_1 - 6.38984765968995e-06*G0_1_1_2_2 + 2.49955805511403e-05*G0_1_2_0_1 - 6.76572105143644e-06*G0_1_2_0_2 + 2.49955805511403e-05*G0_1_2_1_0 + 5.9012122504196e-05*G0_1_2_1_1 - 6.38984765968995e-06*G0_1_2_1_2 - 6.76572105143644e-06*G0_1_2_2_0 - 6.38984765968995e-06*G0_1_2_2_1 - 1.31555687111262e-05*G0_1_2_2_2 + 4.88635409270422e-06*G0_2_0_0_0 - 1.69143026285911e-05*G0_2_0_0_2 + 2.49955805511403e-05*G0_2_0_1_1 - 6.76572105143643e-06*G0_2_0_1_2 - 1.69143026285911e-05*G0_2_0_2_0 - 6.76572105143644e-06*G0_2_0_2_1 - 6.5777843555632e-05*G0_2_0_2_2 + 2.49955805511403e-05*G0_2_1_0_1 - 6.76572105143644e-06*G0_2_1_0_2 + 2.49955805511403e-05*G0_2_1_1_0 + 5.9012122504196e-05*G0_2_1_1_1 - 6.38984765968995e-06*G0_2_1_1_2 - 6.76572105143643e-06*G0_2_1_2_0 - 6.38984765968995e-06*G0_2_1_2_1 - 1.31555687111262e-05*G0_2_1_2_2 - 1.69143026285911e-05*G0_2_2_0_0 - 6.76572105143643e-06*G0_2_2_0_1 - 6.5777843555632e-05*G0_2_2_0_2 - 6.76572105143643e-06*G0_2_2_1_0 - 6.38984765968995e-06*G0_2_2_1_1 - 1.31555687111262e-05*G0_2_2_1_2 - 6.5777843555632e-05*G0_2_2_2_0 - 1.31555687111262e-05*G0_2_2_2_1 + 9.20889809778865e-05*G0_2_2_2_2; + A[132] = A[133] + 0.00146590622781123*G0_0_0_0_0 + 0.000293181245562247*G0_0_0_0_1 + 0.000135314421028729*G0_0_0_0_2 + 0.000293181245562247*G0_0_0_1_0 + 5.86362491124493e-05*G0_0_0_1_1 + 2.70628842057458e-05*G0_0_0_1_2 + 0.000135314421028729*G0_0_0_2_0 + 2.70628842057458e-05*G0_0_0_2_1 + 2.70628842057456e-05*G0_0_0_2_2 + 0.000293181245562247*G0_0_1_0_0 + 5.86362491124493e-05*G0_0_1_0_1 + 2.70628842057458e-05*G0_0_1_0_2 + 5.86362491124493e-05*G0_0_1_1_0 - 5.86362491124495e-05*G0_0_1_1_1 + 2.70628842057458e-05*G0_0_1_2_0 + 4.51048070095756e-06*G0_0_1_2_2 + 0.000135314421028729*G0_0_2_0_0 + 2.70628842057458e-05*G0_0_2_0_1 + 2.70628842057456e-05*G0_0_2_0_2 + 2.70628842057458e-05*G0_0_2_1_0 + 4.51048070095756e-06*G0_0_2_1_2 + 2.70628842057456e-05*G0_0_2_2_0 + 4.51048070095756e-06*G0_0_2_2_1 + 0.000157866824533517*G0_0_2_2_2 + 0.000293181245562247*G0_1_0_0_0 + 5.86362491124493e-05*G0_1_0_0_1 + 2.70628842057458e-05*G0_1_0_0_2 + 5.86362491124493e-05*G0_1_0_1_0 - 5.86362491124495e-05*G0_1_0_1_1 + 2.70628842057458e-05*G0_1_0_2_0 + 4.51048070095757e-06*G0_1_0_2_2 + 5.86362491124493e-05*G0_1_1_0_0 - 5.86362491124495e-05*G0_1_1_0_1 - 5.86362491124495e-05*G0_1_1_1_0 - 0.000293181245562247*G0_1_1_1_1 - 2.70628842057459e-05*G0_1_1_1_2 - 2.7062884205746e-05*G0_1_1_2_1 - 4.51048070095771e-06*G0_1_1_2_2 + 2.70628842057458e-05*G0_1_2_0_0 + 4.51048070095756e-06*G0_1_2_0_2 - 2.70628842057459e-05*G0_1_2_1_1 - 4.51048070095771e-06*G0_1_2_1_2 + 4.51048070095756e-06*G0_1_2_2_0 - 4.51048070095771e-06*G0_1_2_2_1 + 0.000135314421028729*G0_2_0_0_0 + 2.70628842057458e-05*G0_2_0_0_1 + 2.70628842057456e-05*G0_2_0_0_2 + 2.70628842057458e-05*G0_2_0_1_0 + 4.51048070095756e-06*G0_2_0_1_2 + 2.70628842057456e-05*G0_2_0_2_0 + 4.51048070095756e-06*G0_2_0_2_1 + 0.000157866824533517*G0_2_0_2_2 + 2.70628842057458e-05*G0_2_1_0_0 + 4.51048070095756e-06*G0_2_1_0_2 - 2.7062884205746e-05*G0_2_1_1_1 - 4.51048070095771e-06*G0_2_1_1_2 + 4.51048070095756e-06*G0_2_1_2_0 - 4.51048070095771e-06*G0_2_1_2_1 + 2.70628842057456e-05*G0_2_2_0_0 + 4.51048070095756e-06*G0_2_2_0_1 + 0.000157866824533517*G0_2_2_0_2 + 4.51048070095756e-06*G0_2_2_1_0 - 4.51048070095771e-06*G0_2_2_1_1 + 0.000157866824533517*G0_2_2_2_0 + 0.00047360047360055*G0_2_2_2_2; + A[188] = A[132]; + A[160] = -A[133] + 0.00314676505152748*G0_0_0_0_0 + 0.00115898211136326*G0_0_0_0_1 + 0.000336524146048012*G0_0_0_0_2 + 0.00115898211136326*G0_0_0_1_0 + 0.00094071713119348*G0_0_0_1_1 + 0.000133129656939203*G0_0_0_1_2 + 0.000336524146048012*G0_0_0_2_0 + 0.000133129656939203*G0_0_0_2_1 + 4.9333382666726e-06*G0_0_0_2_2 + 0.00115898211136326*G0_0_1_0_0 + 0.00094071713119348*G0_0_1_0_1 + 0.000133129656939203*G0_0_1_0_2 + 0.00094071713119348*G0_0_1_1_0 + 0.00125370220608337*G0_0_1_1_1 + 0.000141022998165879*G0_0_1_1_2 + 0.000133129656939203*G0_0_1_2_0 + 0.000141022998165879*G0_0_1_2_1 + 2.85428856857483e-06*G0_0_1_2_2 + 0.000336524146048012*G0_0_2_0_0 + 0.000133129656939203*G0_0_2_0_1 + 4.9333382666726e-06*G0_0_2_0_2 + 0.000133129656939203*G0_0_2_1_0 + 0.000141022998165879*G0_0_2_1_1 + 2.85428856857484e-06*G0_0_2_1_2 + 4.93333826667261e-06*G0_0_2_2_0 + 2.85428856857484e-06*G0_0_2_2_1 - 0.000281587900635566*G0_0_2_2_2 + 0.00115898211136326*G0_1_0_0_0 + 0.00094071713119348*G0_1_0_0_1 + 0.000133129656939203*G0_1_0_0_2 + 0.00094071713119348*G0_1_0_1_0 + 0.00125370220608337*G0_1_0_1_1 + 0.000141022998165879*G0_1_0_1_2 + 0.000133129656939203*G0_1_0_2_0 + 0.000141022998165879*G0_1_0_2_1 + 2.85428856857483e-06*G0_1_0_2_2 + 0.00094071713119348*G0_1_1_0_0 + 0.00125370220608337*G0_1_1_0_1 + 0.000141022998165879*G0_1_1_0_2 + 0.00125370220608337*G0_1_1_1_0 + 0.00362036552512804*G0_1_1_1_1 + 0.000383884193408068*G0_1_1_1_2 + 0.000141022998165879*G0_1_1_2_0 + 0.000383884193408068*G0_1_1_2_1 + 5.22933856267278e-05*G0_1_1_2_2 + 0.000133129656939203*G0_1_2_0_0 + 0.000141022998165879*G0_1_2_0_1 + 2.85428856857483e-06*G0_1_2_0_2 + 0.000141022998165879*G0_1_2_1_0 + 0.000383884193408068*G0_1_2_1_1 + 5.22933856267278e-05*G0_1_2_1_2 + 2.85428856857483e-06*G0_1_2_2_0 + 5.22933856267278e-05*G0_1_2_2_1 - 0.000123721076102049*G0_1_2_2_2 + 0.000336524146048012*G0_2_0_0_0 + 0.000133129656939203*G0_2_0_0_1 + 4.93333826667258e-06*G0_2_0_0_2 + 0.000133129656939203*G0_2_0_1_0 + 0.000141022998165879*G0_2_0_1_1 + 2.85428856857483e-06*G0_2_0_1_2 + 4.9333382666726e-06*G0_2_0_2_0 + 2.85428856857483e-06*G0_2_0_2_1 - 0.000281587900635566*G0_2_0_2_2 + 0.000133129656939203*G0_2_1_0_0 + 0.000141022998165879*G0_2_1_0_1 + 2.85428856857484e-06*G0_2_1_0_2 + 0.000141022998165879*G0_2_1_1_0 + 0.000383884193408068*G0_2_1_1_1 + 5.22933856267278e-05*G0_2_1_1_2 + 2.85428856857484e-06*G0_2_1_2_0 + 5.22933856267278e-05*G0_2_1_2_1 - 0.000123721076102049*G0_2_1_2_2 + 4.93333826667258e-06*G0_2_2_0_0 + 2.85428856857484e-06*G0_2_2_0_1 - 0.000281587900635566*G0_2_2_0_2 + 2.85428856857483e-06*G0_2_2_1_0 + 5.22933856267278e-05*G0_2_2_1_1 - 0.000123721076102049*G0_2_2_1_2 - 0.000281587900635566*G0_2_2_2_0 - 0.000123721076102049*G0_2_2_2_1 - 0.00131099940623772*G0_2_2_2_2; + A[45] = A[31] + 2.23615302980346e-06*G0_0_0_0_0 - 2.79482422339612e-05*G0_0_1_1_1 - 2.79482422339613e-05*G0_1_0_1_1 - 2.79482422339613e-05*G0_1_1_0_1 - 2.79482422339613e-05*G0_1_1_1_0 - 0.000217221050554421*G0_1_1_1_1 - 4.97415576780741e-05*G0_1_1_1_2 - 4.97415576780741e-05*G0_1_1_2_1 - 1.22092780822961e-05*G0_1_1_2_2 - 4.97415576780741e-05*G0_1_2_1_1 - 1.22092780822961e-05*G0_1_2_1_2 - 1.22092780822961e-05*G0_1_2_2_1 - 4.97415576780741e-05*G0_2_1_1_1 - 1.22092780822961e-05*G0_2_1_1_2 - 1.22092780822961e-05*G0_2_1_2_1 - 1.22092780822961e-05*G0_2_2_1_1 + 2.09887114649053e-05*G0_2_2_2_2; + A[135] = A[45] + 0.00149891261002397*G0_0_0_0_0 + 9.73512084623359e-05*G0_0_0_0_1 + 4.91689380578351e-05*G0_0_0_0_2 + 9.73512084623359e-05*G0_0_0_1_0 + 4.91689380578351e-05*G0_0_0_2_0 + 9.73512084623359e-05*G0_0_1_0_0 + 6.10794261588017e-06*G0_0_1_1_1 + 4.91689380578351e-05*G0_0_2_0_0 + 9.73512084623359e-05*G0_1_0_0_0 + 6.10794261588018e-06*G0_1_0_1_1 + 6.10794261588018e-06*G0_1_1_0_1 + 6.10794261588018e-06*G0_1_1_1_0 + 0.000180066846733544*G0_1_1_1_1 + 3.10565389930523e-05*G0_1_1_1_2 + 3.10565389930523e-05*G0_1_1_2_1 + 1.13936621873152e-06*G0_1_1_2_2 + 3.10565389930523e-05*G0_1_2_1_1 + 1.13936621873152e-06*G0_1_2_1_2 + 1.13936621873153e-06*G0_1_2_2_1 - 3.92317852635377e-06*G0_1_2_2_2 + 4.91689380578351e-05*G0_2_0_0_0 + 3.10565389930523e-05*G0_2_1_1_1 + 1.13936621873152e-06*G0_2_1_1_2 + 1.13936621873152e-06*G0_2_1_2_1 - 3.92317852635377e-06*G0_2_1_2_2 + 1.13936621873152e-06*G0_2_2_1_1 - 3.92317852635377e-06*G0_2_2_1_2 - 3.92317852635377e-06*G0_2_2_2_1 + 4.31549637898917e-05*G0_2_2_2_2; + A[195] = A[45] - 0.000109355664911238*G0_0_0_0_0 - 2.3492086984155e-06*G0_0_1_1_1 - 5.89651383302278e-06*G0_0_1_1_2 - 5.89651383302278e-06*G0_0_1_2_1 - 5.89651383302278e-06*G0_0_2_1_1 - 2.3492086984155e-06*G0_1_0_1_1 - 5.89651383302278e-06*G0_1_0_1_2 - 5.89651383302278e-06*G0_1_0_2_1 - 2.3492086984155e-06*G0_1_1_0_1 - 5.89651383302278e-06*G0_1_1_0_2 - 2.34920869841549e-06*G0_1_1_1_0 - 2.70159000317753e-06*G0_1_1_1_1 - 3.52381304762317e-05*G0_1_1_1_2 - 5.89651383302278e-06*G0_1_1_2_0 - 3.52381304762317e-05*G0_1_1_2_1 - 3.08098720797186e-05*G0_1_1_2_2 - 5.89651383302278e-06*G0_1_2_0_1 - 5.89651383302278e-06*G0_1_2_1_0 - 3.52381304762317e-05*G0_1_2_1_1 - 3.08098720797186e-05*G0_1_2_1_2 - 3.08098720797186e-05*G0_1_2_2_1 - 1.86057328914503e-05*G0_1_2_2_2 - 5.89651383302278e-06*G0_2_0_1_1 - 5.89651383302278e-06*G0_2_1_0_1 - 5.89651383302278e-06*G0_2_1_1_0 - 3.52381304762317e-05*G0_2_1_1_1 - 3.08098720797186e-05*G0_2_1_1_2 - 3.08098720797186e-05*G0_2_1_2_1 - 1.86057328914503e-05*G0_2_1_2_2 - 3.08098720797186e-05*G0_2_2_1_1 - 1.86057328914503e-05*G0_2_2_1_2 - 1.86057328914503e-05*G0_2_2_2_1 + 8.04603979207288e-05*G0_2_2_2_2; + A[38] = A[122]; + A[143] = A[129]; + A[120] = A[8]; + A[92] = A[36]; + A[179] = -A[170] - 9.20889809778855e-05*G0_0_0_0_0 + 4.88635409270409e-06*G0_0_0_0_1 + 6.08914894629282e-05*G0_0_0_0_2 + 4.8863540927041e-06*G0_0_0_1_0 - 1.69143026285911e-05*G0_0_0_1_1 + 6.08914894629282e-05*G0_0_0_2_0 + 9.94185121169415e-05*G0_0_0_2_2 + 4.8863540927041e-06*G0_0_1_0_0 - 1.69143026285911e-05*G0_0_1_0_1 - 1.69143026285911e-05*G0_0_1_1_0 - 6.57778435556322e-05*G0_0_1_1_1 - 6.76572105143643e-06*G0_0_1_1_2 - 6.76572105143643e-06*G0_0_1_2_1 + 2.49955805511404e-05*G0_0_1_2_2 + 6.08914894629282e-05*G0_0_2_0_0 + 9.94185121169415e-05*G0_0_2_0_2 - 6.76572105143644e-06*G0_0_2_1_1 + 2.49955805511404e-05*G0_0_2_1_2 + 9.94185121169415e-05*G0_0_2_2_0 + 2.49955805511404e-05*G0_0_2_2_1 + 0.000178163987687827*G0_0_2_2_2 + 4.88635409270409e-06*G0_1_0_0_0 - 1.69143026285911e-05*G0_1_0_0_1 - 1.69143026285911e-05*G0_1_0_1_0 - 6.57778435556322e-05*G0_1_0_1_1 - 6.76572105143644e-06*G0_1_0_1_2 - 6.76572105143644e-06*G0_1_0_2_1 + 2.49955805511404e-05*G0_1_0_2_2 - 1.69143026285911e-05*G0_1_1_0_0 - 6.57778435556321e-05*G0_1_1_0_1 - 6.76572105143643e-06*G0_1_1_0_2 - 6.57778435556322e-05*G0_1_1_1_0 + 9.2088980977887e-05*G0_1_1_1_1 - 1.31555687111264e-05*G0_1_1_1_2 - 6.76572105143644e-06*G0_1_1_2_0 - 1.31555687111264e-05*G0_1_1_2_1 - 6.38984765968991e-06*G0_1_1_2_2 - 6.76572105143643e-06*G0_1_2_0_1 + 2.49955805511404e-05*G0_1_2_0_2 - 6.76572105143643e-06*G0_1_2_1_0 - 1.31555687111264e-05*G0_1_2_1_1 - 6.38984765968991e-06*G0_1_2_1_2 + 2.49955805511404e-05*G0_1_2_2_0 - 6.3898476596899e-06*G0_1_2_2_1 + 5.90121225041961e-05*G0_1_2_2_2 + 6.08914894629282e-05*G0_2_0_0_0 + 9.94185121169415e-05*G0_2_0_0_2 - 6.76572105143643e-06*G0_2_0_1_1 + 2.49955805511404e-05*G0_2_0_1_2 + 9.94185121169415e-05*G0_2_0_2_0 + 2.49955805511404e-05*G0_2_0_2_1 + 0.000178163987687827*G0_2_0_2_2 - 6.76572105143644e-06*G0_2_1_0_1 + 2.49955805511404e-05*G0_2_1_0_2 - 6.76572105143644e-06*G0_2_1_1_0 - 1.31555687111264e-05*G0_2_1_1_1 - 6.38984765968992e-06*G0_2_1_1_2 + 2.49955805511404e-05*G0_2_1_2_0 - 6.38984765968991e-06*G0_2_1_2_1 + 5.90121225041961e-05*G0_2_1_2_2 + 9.94185121169415e-05*G0_2_2_0_0 + 2.49955805511404e-05*G0_2_2_0_1 + 0.000178163987687827*G0_2_2_0_2 + 2.49955805511404e-05*G0_2_2_1_0 - 6.3898476596899e-06*G0_2_2_1_1 + 5.90121225041961e-05*G0_2_2_1_2 + 0.000178163987687827*G0_2_2_2_0 + 5.90121225041961e-05*G0_2_2_2_1 + 0.00049427351014661*G0_2_2_2_2; + A[191] = A[179] + 0.00146590622781124*G0_0_0_0_0 + 0.00013531442102873*G0_0_0_0_1 + 0.000293181245562247*G0_0_0_0_2 + 0.00013531442102873*G0_0_0_1_0 + 2.70628842057458e-05*G0_0_0_1_1 + 2.7062884205746e-05*G0_0_0_1_2 + 0.000293181245562247*G0_0_0_2_0 + 2.7062884205746e-05*G0_0_0_2_1 + 5.86362491124495e-05*G0_0_0_2_2 + 0.00013531442102873*G0_0_1_0_0 + 2.70628842057458e-05*G0_0_1_0_1 + 2.7062884205746e-05*G0_0_1_0_2 + 2.70628842057458e-05*G0_0_1_1_0 + 0.000157866824533517*G0_0_1_1_1 + 4.51048070095762e-06*G0_0_1_1_2 + 2.7062884205746e-05*G0_0_1_2_0 + 4.51048070095762e-06*G0_0_1_2_1 + 0.000293181245562247*G0_0_2_0_0 + 2.7062884205746e-05*G0_0_2_0_1 + 5.86362491124494e-05*G0_0_2_0_2 + 2.7062884205746e-05*G0_0_2_1_0 + 4.51048070095763e-06*G0_0_2_1_1 + 5.86362491124494e-05*G0_0_2_2_0 - 5.86362491124495e-05*G0_0_2_2_2 + 0.00013531442102873*G0_1_0_0_0 + 2.70628842057458e-05*G0_1_0_0_1 + 2.7062884205746e-05*G0_1_0_0_2 + 2.70628842057458e-05*G0_1_0_1_0 + 0.000157866824533517*G0_1_0_1_1 + 4.51048070095762e-06*G0_1_0_1_2 + 2.7062884205746e-05*G0_1_0_2_0 + 4.51048070095763e-06*G0_1_0_2_1 + 2.70628842057458e-05*G0_1_1_0_0 + 0.000157866824533517*G0_1_1_0_1 + 4.51048070095762e-06*G0_1_1_0_2 + 0.000157866824533517*G0_1_1_1_0 + 0.000473600473600549*G0_1_1_1_1 + 4.51048070095763e-06*G0_1_1_2_0 - 4.51048070095775e-06*G0_1_1_2_2 + 2.7062884205746e-05*G0_1_2_0_0 + 4.51048070095762e-06*G0_1_2_0_1 + 4.51048070095762e-06*G0_1_2_1_0 - 4.51048070095776e-06*G0_1_2_1_2 - 4.51048070095776e-06*G0_1_2_2_1 - 2.70628842057461e-05*G0_1_2_2_2 + 0.000293181245562247*G0_2_0_0_0 + 2.7062884205746e-05*G0_2_0_0_1 + 5.86362491124495e-05*G0_2_0_0_2 + 2.7062884205746e-05*G0_2_0_1_0 + 4.51048070095763e-06*G0_2_0_1_1 + 5.86362491124495e-05*G0_2_0_2_0 - 5.86362491124495e-05*G0_2_0_2_2 + 2.7062884205746e-05*G0_2_1_0_0 + 4.51048070095763e-06*G0_2_1_0_1 + 4.51048070095763e-06*G0_2_1_1_0 - 4.51048070095775e-06*G0_2_1_1_2 - 4.51048070095776e-06*G0_2_1_2_1 - 2.70628842057461e-05*G0_2_1_2_2 + 5.86362491124495e-05*G0_2_2_0_0 - 5.86362491124495e-05*G0_2_2_0_2 - 4.51048070095777e-06*G0_2_2_1_1 - 2.70628842057461e-05*G0_2_2_1_2 - 5.86362491124495e-05*G0_2_2_2_0 - 2.70628842057461e-05*G0_2_2_2_1 - 0.000293181245562248*G0_2_2_2_2; + A[116] = A[139] - 0.000730134063467519*G0_0_0_0_0 - 6.70934004267451e-05*G0_0_0_0_1 + 1.97333530666912e-06*G0_0_0_0_2 - 6.70934004267451e-05*G0_0_0_1_0 + 1.97333530666912e-06*G0_0_0_2_0 + 7.20267386934175e-05*G0_0_0_2_2 - 6.70934004267451e-05*G0_0_1_0_0 + 6.70934004267454e-05*G0_0_1_1_1 + 1.97333530666913e-06*G0_0_2_0_0 + 7.20267386934175e-05*G0_0_2_0_2 + 7.20267386934175e-05*G0_0_2_2_0 + 6.9066735733414e-05*G0_0_2_2_2 - 6.70934004267451e-05*G0_1_0_0_0 + 6.70934004267454e-05*G0_1_0_1_1 + 6.70934004267454e-05*G0_1_1_0_1 + 6.70934004267454e-05*G0_1_1_1_0 + 0.000730134063467523*G0_1_1_1_1 - 1.97333530666886e-06*G0_1_1_1_2 - 1.97333530666886e-06*G0_1_1_2_1 - 7.20267386934176e-05*G0_1_1_2_2 - 1.97333530666886e-06*G0_1_2_1_1 - 7.20267386934176e-05*G0_1_2_1_2 - 7.20267386934176e-05*G0_1_2_2_1 - 6.90667357334141e-05*G0_1_2_2_2 + 1.97333530666913e-06*G0_2_0_0_0 + 7.20267386934175e-05*G0_2_0_0_2 + 7.20267386934175e-05*G0_2_0_2_0 + 6.9066735733414e-05*G0_2_0_2_2 - 1.97333530666886e-06*G0_2_1_1_1 - 7.20267386934176e-05*G0_2_1_1_2 - 7.20267386934176e-05*G0_2_1_2_1 - 6.90667357334141e-05*G0_2_1_2_2 + 7.20267386934175e-05*G0_2_2_0_0 + 6.9066735733414e-05*G0_2_2_0_2 - 7.20267386934176e-05*G0_2_2_1_1 - 6.90667357334141e-05*G0_2_2_1_2 + 6.9066735733414e-05*G0_2_2_2_0 - 6.90667357334141e-05*G0_2_2_2_1; + A[219] = A[149]; + A[207] = A[193]; + A[73] = A[199]; + A[43] = A[41] + 8.04603979207289e-05*G0_0_0_0_0 - 1.86057328914503e-05*G0_0_0_0_1 - 1.86057328914503e-05*G0_0_0_1_0 - 3.08098720797186e-05*G0_0_0_1_1 - 1.86057328914503e-05*G0_0_1_0_0 - 3.08098720797186e-05*G0_0_1_0_1 - 3.08098720797186e-05*G0_0_1_1_0 - 3.52381304762317e-05*G0_0_1_1_1 - 5.89651383302277e-06*G0_0_1_1_2 - 5.89651383302277e-06*G0_0_1_2_1 - 5.89651383302277e-06*G0_0_2_1_1 - 1.86057328914503e-05*G0_1_0_0_0 - 3.08098720797186e-05*G0_1_0_0_1 - 3.08098720797186e-05*G0_1_0_1_0 - 3.52381304762317e-05*G0_1_0_1_1 - 5.89651383302277e-06*G0_1_0_1_2 - 5.89651383302277e-06*G0_1_0_2_1 - 3.08098720797186e-05*G0_1_1_0_0 - 3.52381304762317e-05*G0_1_1_0_1 - 5.89651383302277e-06*G0_1_1_0_2 - 3.52381304762317e-05*G0_1_1_1_0 - 2.70159000317807e-06*G0_1_1_1_1 - 2.34920869841546e-06*G0_1_1_1_2 - 5.89651383302277e-06*G0_1_1_2_0 - 2.34920869841546e-06*G0_1_1_2_1 - 5.89651383302277e-06*G0_1_2_0_1 - 5.89651383302277e-06*G0_1_2_1_0 - 2.34920869841546e-06*G0_1_2_1_1 - 5.89651383302277e-06*G0_2_0_1_1 - 5.89651383302277e-06*G0_2_1_0_1 - 5.89651383302277e-06*G0_2_1_1_0 - 2.34920869841545e-06*G0_2_1_1_1 - 0.000109355664911238*G0_2_2_2_2; + A[158] = -A[43] - 0.000649086363372186*G0_0_0_0_0 - 1.46590622781124e-05*G0_0_0_0_1 - 5.65219612838754e-05*G0_0_0_0_2 - 1.46590622781124e-05*G0_0_0_1_0 + 3.29124138648003e-05*G0_0_0_1_1 - 5.65219612838754e-05*G0_0_0_2_0 - 1.46590622781123e-05*G0_0_1_0_0 + 3.29124138648003e-05*G0_0_1_0_1 + 3.29124138648003e-05*G0_0_1_1_0 - 1.40952521904927e-05*G0_0_1_1_1 + 1.9028590457165e-06*G0_0_1_1_2 + 1.9028590457165e-06*G0_0_1_2_1 - 5.65219612838754e-05*G0_0_2_0_0 + 1.9028590457165e-06*G0_0_2_1_1 + 1.98743055885947e-05*G0_0_2_2_2 - 1.46590622781124e-05*G0_1_0_0_0 + 3.29124138648003e-05*G0_1_0_0_1 + 3.29124138648003e-05*G0_1_0_1_0 - 1.40952521904927e-05*G0_1_0_1_1 + 1.9028590457165e-06*G0_1_0_1_2 + 1.9028590457165e-06*G0_1_0_2_1 + 3.29124138648003e-05*G0_1_1_0_0 - 1.40952521904927e-05*G0_1_1_0_1 + 1.9028590457165e-06*G0_1_1_0_2 - 1.40952521904927e-05*G0_1_1_1_0 - 0.000296705058609871*G0_1_1_1_1 - 2.46666913333622e-05*G0_1_1_1_2 + 1.9028590457165e-06*G0_1_1_2_0 - 2.46666913333622e-05*G0_1_1_2_1 + 1.9028590457165e-06*G0_1_2_0_1 + 1.9028590457165e-06*G0_1_2_1_0 - 2.46666913333622e-05*G0_1_2_1_1 + 1.56457299314469e-05*G0_1_2_2_2 - 5.65219612838754e-05*G0_2_0_0_0 + 1.9028590457165e-06*G0_2_0_1_1 + 1.98743055885947e-05*G0_2_0_2_2 + 1.9028590457165e-06*G0_2_1_0_1 + 1.9028590457165e-06*G0_2_1_1_0 - 2.46666913333622e-05*G0_2_1_1_1 + 1.56457299314469e-05*G0_2_1_2_2 + 1.98743055885947e-05*G0_2_2_0_2 + 1.5645729931447e-05*G0_2_2_1_2 + 1.98743055885947e-05*G0_2_2_2_0 + 1.56457299314469e-05*G0_2_2_2_1 - 2.4666691333361e-05*G0_2_2_2_2; + A[94] = A[158] + 0.000730134063467518*G0_0_0_0_0 - 1.97333530666899e-06*G0_0_0_0_1 + 6.70934004267447e-05*G0_0_0_0_2 - 1.97333530666901e-06*G0_0_0_1_0 - 7.20267386934174e-05*G0_0_0_1_1 + 6.70934004267447e-05*G0_0_0_2_0 - 1.97333530666901e-06*G0_0_1_0_0 - 7.20267386934174e-05*G0_0_1_0_1 - 7.20267386934174e-05*G0_0_1_1_0 - 6.90667357334139e-05*G0_0_1_1_1 + 6.70934004267447e-05*G0_0_2_0_0 - 6.7093400426745e-05*G0_0_2_2_2 - 1.97333530666899e-06*G0_1_0_0_0 - 7.20267386934174e-05*G0_1_0_0_1 - 7.20267386934174e-05*G0_1_0_1_0 - 6.90667357334139e-05*G0_1_0_1_1 - 7.20267386934174e-05*G0_1_1_0_0 - 6.90667357334139e-05*G0_1_1_0_1 - 6.90667357334139e-05*G0_1_1_1_0 + 6.90667357334142e-05*G0_1_1_1_2 + 6.90667357334142e-05*G0_1_1_2_1 + 7.20267386934176e-05*G0_1_1_2_2 + 6.90667357334142e-05*G0_1_2_1_1 + 7.20267386934176e-05*G0_1_2_1_2 + 7.20267386934175e-05*G0_1_2_2_1 + 1.97333530666901e-06*G0_1_2_2_2 + 6.70934004267447e-05*G0_2_0_0_0 - 6.7093400426745e-05*G0_2_0_2_2 + 6.90667357334142e-05*G0_2_1_1_1 + 7.20267386934175e-05*G0_2_1_1_2 + 7.20267386934176e-05*G0_2_1_2_1 + 1.97333530666901e-06*G0_2_1_2_2 - 6.7093400426745e-05*G0_2_2_0_2 + 7.20267386934176e-05*G0_2_2_1_1 + 1.97333530666901e-06*G0_2_2_1_2 - 6.7093400426745e-05*G0_2_2_2_0 + 1.97333530666902e-06*G0_2_2_2_1 - 0.000730134063467519*G0_2_2_2_2; + A[66] = A[94]; + A[130] = A[158]; + A[146] = A[174]; + A[75] = A[5]; + A[150] = A[10]; + A[183] = A[57]; + A[119] = A[163] - 0.000194514480228799*G0_0_0_0_1 + 0.000194514480228798*G0_0_0_0_2 - 0.000194514480228799*G0_0_0_1_0 - 0.000243565957851714*G0_0_0_1_1 + 0.000194514480228798*G0_0_0_2_0 + 0.000243565957851713*G0_0_0_2_2 - 0.000194514480228799*G0_0_1_0_0 - 0.000243565957851714*G0_0_1_0_1 - 0.000243565957851714*G0_0_1_1_0 - 1.52228723657327e-05*G0_0_1_1_1 + 0.000194514480228798*G0_0_2_0_0 + 0.000243565957851713*G0_0_2_0_2 + 0.000243565957851713*G0_0_2_2_0 + 1.5222872365733e-05*G0_0_2_2_2 - 0.000194514480228799*G0_1_0_0_0 - 0.000243565957851714*G0_1_0_0_1 - 0.000243565957851714*G0_1_0_1_0 - 1.52228723657328e-05*G0_1_0_1_1 - 0.000243565957851714*G0_1_1_0_0 - 1.52228723657327e-05*G0_1_1_0_1 - 1.52228723657327e-05*G0_1_1_1_0 + 0.00209737352594531*G0_1_1_1_1 + 0.000392411820983316*G0_1_1_1_2 + 0.000392411820983316*G0_1_1_2_1 + 0.000392411820983316*G0_1_2_1_1 - 0.000392411820983314*G0_1_2_2_2 + 0.000194514480228798*G0_2_0_0_0 + 0.000243565957851713*G0_2_0_0_2 + 0.000243565957851713*G0_2_0_2_0 + 1.5222872365733e-05*G0_2_0_2_2 + 0.000392411820983316*G0_2_1_1_1 - 0.000392411820983314*G0_2_1_2_2 + 0.000243565957851713*G0_2_2_0_0 + 1.52228723657331e-05*G0_2_2_0_2 - 0.000392411820983314*G0_2_2_1_2 + 1.52228723657331e-05*G0_2_2_2_0 - 0.000392411820983314*G0_2_2_2_1 - 0.0020973735259453*G0_2_2_2_2; + A[197] = A[43]; + A[19] = A[61]; + A[12] = -A[195] + 0.000167733501066862*G0_0_0_0_0 - 9.86667653334499e-06*G0_0_0_0_1 - 9.86667653334495e-06*G0_0_0_0_2 - 9.866676533345e-06*G0_0_0_1_0 - 9.86667653334495e-06*G0_0_0_2_0 - 9.86667653334499e-06*G0_0_1_0_0 - 1.04304866209646e-05*G0_0_1_1_1 - 4.22857565714804e-07*G0_0_1_1_2 - 4.22857565714803e-07*G0_0_1_2_1 + 4.3695281790527e-06*G0_0_1_2_2 - 9.86667653334496e-06*G0_0_2_0_0 - 4.22857565714801e-07*G0_0_2_1_1 + 4.3695281790527e-06*G0_0_2_1_2 + 4.3695281790527e-06*G0_0_2_2_1 + 1.83238278476404e-05*G0_0_2_2_2 - 9.86667653334499e-06*G0_1_0_0_0 - 1.04304866209646e-05*G0_1_0_1_1 - 4.22857565714799e-07*G0_1_0_1_2 - 4.22857565714796e-07*G0_1_0_2_1 + 4.36952817905271e-06*G0_1_0_2_2 - 1.04304866209646e-05*G0_1_1_0_1 - 4.22857565714801e-07*G0_1_1_0_2 - 1.04304866209646e-05*G0_1_1_1_0 - 0.000184647803695454*G0_1_1_1_1 - 4.17219464838584e-05*G0_1_1_1_2 - 4.22857565714799e-07*G0_1_1_2_0 - 4.17219464838584e-05*G0_1_1_2_1 - 7.1885786171513e-06*G0_1_1_2_2 - 4.22857565714799e-07*G0_1_2_0_1 + 4.36952817905271e-06*G0_1_2_0_2 - 4.22857565714799e-07*G0_1_2_1_0 - 4.17219464838584e-05*G0_1_2_1_1 - 7.18857861715129e-06*G0_1_2_1_2 + 4.36952817905271e-06*G0_1_2_2_0 - 7.18857861715129e-06*G0_1_2_2_1 + 2.25524035047883e-05*G0_1_2_2_2 - 9.86667653334496e-06*G0_2_0_0_0 - 4.22857565714801e-07*G0_2_0_1_1 + 4.3695281790527e-06*G0_2_0_1_2 + 4.3695281790527e-06*G0_2_0_2_1 + 1.83238278476404e-05*G0_2_0_2_2 - 4.22857565714803e-07*G0_2_1_0_1 + 4.36952817905271e-06*G0_2_1_0_2 - 4.22857565714801e-07*G0_2_1_1_0 - 4.17219464838584e-05*G0_2_1_1_1 - 7.18857861715129e-06*G0_2_1_1_2 + 4.36952817905271e-06*G0_2_1_2_0 - 7.18857861715129e-06*G0_2_1_2_1 + 2.25524035047883e-05*G0_2_1_2_2 + 4.3695281790527e-06*G0_2_2_0_1 + 1.83238278476404e-05*G0_2_2_0_2 + 4.36952817905271e-06*G0_2_2_1_0 - 7.1885786171513e-06*G0_2_2_1_1 + 2.25524035047882e-05*G0_2_2_1_2 + 1.83238278476404e-05*G0_2_2_2_0 + 2.25524035047882e-05*G0_2_2_2_1 + 0.000136723946247779*G0_2_2_2_2; + A[100] = -A[12] - 0.00251106917773627*G0_0_0_0_0 - 0.000300933634267018*G0_0_0_0_1 - 0.000458800458800536*G0_0_0_0_2 - 0.000300933634267018*G0_0_0_1_0 - 5.22933856267278e-05*G0_0_0_1_1 - 5.32800532800623e-05*G0_0_0_1_2 - 0.000458800458800536*G0_0_0_2_0 - 5.32800532800623e-05*G0_0_0_2_1 - 0.000107546774213459*G0_0_0_2_2 - 0.000300933634267018*G0_0_1_0_0 - 5.22933856267278e-05*G0_0_1_0_1 - 5.32800532800623e-05*G0_0_1_0_2 - 5.22933856267278e-05*G0_0_1_1_0 - 1.59276349752566e-05*G0_0_1_1_1 - 6.27238722476923e-06*G0_0_1_1_2 - 5.32800532800623e-05*G0_0_1_2_0 - 6.27238722476923e-06*G0_0_1_2_1 - 4.58095696191012e-06*G0_0_1_2_2 - 0.000458800458800536*G0_0_2_0_0 - 5.32800532800623e-05*G0_0_2_0_1 - 0.000107546774213459*G0_0_2_0_2 - 5.32800532800623e-05*G0_0_2_1_0 - 6.27238722476923e-06*G0_0_2_1_1 - 4.58095696191012e-06*G0_0_2_1_2 - 0.000107546774213459*G0_0_2_2_0 - 4.58095696191012e-06*G0_0_2_2_1 - 5.77905339810194e-06*G0_0_2_2_2 - 0.000300933634267018*G0_1_0_0_0 - 5.22933856267278e-05*G0_1_0_0_1 - 5.32800532800623e-05*G0_1_0_0_2 - 5.22933856267278e-05*G0_1_0_1_0 - 1.59276349752566e-05*G0_1_0_1_1 - 6.27238722476923e-06*G0_1_0_1_2 - 5.32800532800623e-05*G0_1_0_2_0 - 6.27238722476923e-06*G0_1_0_2_1 - 4.58095696191012e-06*G0_1_0_2_2 - 5.22933856267278e-05*G0_1_1_0_0 - 1.59276349752566e-05*G0_1_1_0_1 - 6.27238722476923e-06*G0_1_1_0_2 - 1.59276349752566e-05*G0_1_1_1_0 - 4.01714687429032e-05*G0_1_1_1_1 + 8.45715131429663e-07*G0_1_1_1_2 - 6.27238722476923e-06*G0_1_1_2_0 + 8.45715131429663e-07*G0_1_1_2_1 + 1.33200133200156e-05*G0_1_1_2_2 - 5.32800532800623e-05*G0_1_2_0_0 - 6.27238722476923e-06*G0_1_2_0_1 - 4.58095696191012e-06*G0_1_2_0_2 - 6.27238722476923e-06*G0_1_2_1_0 + 8.45715131429663e-07*G0_1_2_1_1 + 1.33200133200156e-05*G0_1_2_1_2 - 4.58095696191012e-06*G0_1_2_2_0 + 1.33200133200156e-05*G0_1_2_2_1 + 3.4674320388612e-05*G0_1_2_2_2 - 0.000458800458800536*G0_2_0_0_0 - 5.32800532800623e-05*G0_2_0_0_1 - 0.000107546774213459*G0_2_0_0_2 - 5.32800532800623e-05*G0_2_0_1_0 - 6.27238722476923e-06*G0_2_0_1_1 - 4.58095696191012e-06*G0_2_0_1_2 - 0.000107546774213459*G0_2_0_2_0 - 4.58095696191012e-06*G0_2_0_2_1 - 5.77905339810194e-06*G0_2_0_2_2 - 5.32800532800623e-05*G0_2_1_0_0 - 6.27238722476923e-06*G0_2_1_0_1 - 4.58095696191012e-06*G0_2_1_0_2 - 6.27238722476923e-06*G0_2_1_1_0 + 8.45715131429663e-07*G0_2_1_1_1 + 1.33200133200156e-05*G0_2_1_1_2 - 4.58095696191012e-06*G0_2_1_2_0 + 1.33200133200156e-05*G0_2_1_2_1 + 3.4674320388612e-05*G0_2_1_2_2 - 0.000107546774213459*G0_2_2_0_0 - 4.58095696191012e-06*G0_2_2_0_1 - 5.77905339810194e-06*G0_2_2_0_2 - 4.58095696191012e-06*G0_2_2_1_0 + 1.33200133200156e-05*G0_2_2_1_1 + 3.4674320388612e-05*G0_2_2_1_2 - 5.77905339810194e-06*G0_2_2_2_0 + 3.4674320388612e-05*G0_2_2_2_1 + 0.000128971557543008*G0_2_2_2_2; + A[99] = -A[100] + 0.000924178701956634*G0_0_0_0_0 + 0.000200622422844678*G0_0_0_0_1 + 4.27555983111607e-05*G0_0_0_0_2 + 0.000200622422844678*G0_0_0_1_0 + 5.32800532800622e-05*G0_0_0_1_1 + 1.71022393244644e-05*G0_0_0_1_2 + 4.27555983111606e-05*G0_0_0_2_0 + 1.71022393244644e-05*G0_0_0_2_1 - 1.97333530666902e-06*G0_0_0_2_2 + 0.000200622422844678*G0_0_1_0_0 + 5.32800532800622e-05*G0_0_1_0_1 + 1.71022393244644e-05*G0_0_1_0_2 + 5.32800532800622e-05*G0_0_1_1_0 + 6.10794261588023e-06*G0_0_1_1_1 + 4.74540157079919e-06*G0_0_1_1_2 + 1.71022393244644e-05*G0_0_1_2_0 + 4.74540157079919e-06*G0_0_1_2_1 + 6.43683183365831e-06*G0_0_1_2_2 + 4.27555983111607e-05*G0_0_2_0_0 + 1.71022393244644e-05*G0_0_2_0_1 - 1.97333530666904e-06*G0_0_2_0_2 + 1.71022393244644e-05*G0_0_2_1_0 + 4.74540157079919e-06*G0_0_2_1_1 + 6.43683183365831e-06*G0_0_2_1_2 - 1.97333530666902e-06*G0_0_2_2_0 + 6.43683183365831e-06*G0_0_2_2_1 + 1.62565241930349e-05*G0_0_2_2_2 + 0.000200622422844678*G0_1_0_0_0 + 5.32800532800622e-05*G0_1_0_0_1 + 1.71022393244644e-05*G0_1_0_0_2 + 5.32800532800622e-05*G0_1_0_1_0 + 6.10794261588023e-06*G0_1_0_1_1 + 4.74540157079919e-06*G0_1_0_1_2 + 1.71022393244644e-05*G0_1_0_2_0 + 4.74540157079919e-06*G0_1_0_2_1 + 6.43683183365831e-06*G0_1_0_2_2 + 5.32800532800622e-05*G0_1_1_0_0 + 6.10794261588023e-06*G0_1_1_0_1 + 4.74540157079919e-06*G0_1_1_0_2 + 6.10794261588022e-06*G0_1_1_1_0 - 5.77905339810195e-05*G0_1_1_1_1 - 6.20191096381674e-06*G0_1_1_1_2 + 4.74540157079919e-06*G0_1_1_2_0 - 6.20191096381674e-06*G0_1_1_2_1 + 8.03429374858081e-06*G0_1_1_2_2 + 1.71022393244644e-05*G0_1_2_0_0 + 4.74540157079919e-06*G0_1_2_0_1 + 6.43683183365831e-06*G0_1_2_0_2 + 4.74540157079919e-06*G0_1_2_1_0 - 6.20191096381674e-06*G0_1_2_1_1 + 8.03429374858081e-06*G0_1_2_1_2 + 6.43683183365831e-06*G0_1_2_2_0 + 8.03429374858081e-06*G0_1_2_2_1 + 2.76266942933656e-05*G0_1_2_2_2 + 4.27555983111607e-05*G0_2_0_0_0 + 1.71022393244644e-05*G0_2_0_0_1 - 1.97333530666904e-06*G0_2_0_0_2 + 1.71022393244644e-05*G0_2_0_1_0 + 4.74540157079919e-06*G0_2_0_1_1 + 6.43683183365831e-06*G0_2_0_1_2 - 1.97333530666903e-06*G0_2_0_2_0 + 6.43683183365831e-06*G0_2_0_2_1 + 1.62565241930349e-05*G0_2_0_2_2 + 1.71022393244644e-05*G0_2_1_0_0 + 4.74540157079919e-06*G0_2_1_0_1 + 6.43683183365831e-06*G0_2_1_0_2 + 4.74540157079919e-06*G0_2_1_1_0 - 6.20191096381674e-06*G0_2_1_1_1 + 8.03429374858081e-06*G0_2_1_1_2 + 6.43683183365831e-06*G0_2_1_2_0 + 8.03429374858081e-06*G0_2_1_2_1 + 2.76266942933656e-05*G0_2_1_2_2 - 1.97333530666904e-06*G0_2_2_0_0 + 6.43683183365831e-06*G0_2_2_0_1 + 1.62565241930349e-05*G0_2_2_0_2 + 6.4368318336583e-06*G0_2_2_1_0 + 8.03429374858081e-06*G0_2_2_1_1 + 2.76266942933656e-05*G0_2_2_1_2 + 1.62565241930349e-05*G0_2_2_2_0 + 2.76266942933656e-05*G0_2_2_2_1 + 0.000111352492304892*G0_2_2_2_2; + A[97] = A[100] - 0.000522933856267278*G0_0_0_0_0 + 5.92000592000692e-05*G0_0_0_0_2 - 1.97333530666896e-06*G0_0_0_1_1 + 1.97333530666903e-06*G0_0_0_1_2 + 5.92000592000692e-05*G0_0_0_2_0 + 1.97333530666904e-06*G0_0_0_2_1 + 1.7760017760021e-05*G0_0_0_2_2 - 1.97333530666894e-06*G0_0_1_0_1 + 1.97333530666904e-06*G0_0_1_0_2 - 1.97333530666896e-06*G0_0_1_1_0 + 2.26933560266931e-05*G0_0_1_1_1 + 1.97333530666902e-06*G0_0_1_2_0 - 2.26933560266931e-05*G0_0_1_2_2 + 5.92000592000692e-05*G0_0_2_0_0 + 1.97333530666903e-06*G0_0_2_0_1 + 1.7760017760021e-05*G0_0_2_0_2 + 1.97333530666904e-06*G0_0_2_1_0 - 2.26933560266931e-05*G0_0_2_1_2 + 1.7760017760021e-05*G0_0_2_2_0 - 2.26933560266931e-05*G0_0_2_2_1 - 0.000181546848213545*G0_0_2_2_2 - 1.97333530666895e-06*G0_1_0_0_1 + 1.97333530666903e-06*G0_1_0_0_2 - 1.97333530666896e-06*G0_1_0_1_0 + 2.26933560266931e-05*G0_1_0_1_1 + 1.97333530666902e-06*G0_1_0_2_0 - 2.26933560266931e-05*G0_1_0_2_2 - 1.97333530666897e-06*G0_1_1_0_0 + 2.26933560266931e-05*G0_1_1_0_1 + 2.26933560266931e-05*G0_1_1_1_0 + 0.000149691578263032*G0_1_1_1_1 + 2.49485963771721e-05*G0_1_1_1_2 + 2.49485963771721e-05*G0_1_1_2_1 - 2.49485963771719e-05*G0_1_1_2_2 + 1.97333530666903e-06*G0_1_2_0_0 - 2.26933560266931e-05*G0_1_2_0_2 + 2.49485963771721e-05*G0_1_2_1_1 - 2.49485963771719e-05*G0_1_2_1_2 - 2.26933560266931e-05*G0_1_2_2_0 - 2.49485963771719e-05*G0_1_2_2_1 - 0.000149691578263032*G0_1_2_2_2 + 5.92000592000693e-05*G0_2_0_0_0 + 1.97333530666904e-06*G0_2_0_0_1 + 1.7760017760021e-05*G0_2_0_0_2 + 1.97333530666904e-06*G0_2_0_1_0 - 2.26933560266931e-05*G0_2_0_1_2 + 1.7760017760021e-05*G0_2_0_2_0 - 2.26933560266931e-05*G0_2_0_2_1 - 0.000181546848213545*G0_2_0_2_2 + 1.97333530666904e-06*G0_2_1_0_0 - 2.26933560266931e-05*G0_2_1_0_2 + 2.49485963771721e-05*G0_2_1_1_1 - 2.49485963771719e-05*G0_2_1_1_2 - 2.26933560266931e-05*G0_2_1_2_0 - 2.49485963771719e-05*G0_2_1_2_1 - 0.000149691578263032*G0_2_1_2_2 + 1.7760017760021e-05*G0_2_2_0_0 - 2.26933560266931e-05*G0_2_2_0_1 - 0.000181546848213545*G0_2_2_0_2 - 2.26933560266931e-05*G0_2_2_1_0 - 2.49485963771719e-05*G0_2_2_1_1 - 0.000149691578263032*G0_2_2_1_2 - 0.000181546848213545*G0_2_2_2_0 - 0.000149691578263032*G0_2_2_2_1 - 0.0012474298188586*G0_2_2_2_2; + A[111] = A[97]; + A[186] = A[100] + 0.00727174060507516*G0_0_0_0_0 + 0.000917600917601073*G0_0_0_0_1 + 0.00139120139120163*G0_0_0_0_2 + 0.000917600917601073*G0_0_0_1_0 + 0.000159840159840187*G0_0_0_1_1 + 0.000161813495146856*G0_0_0_1_2 + 0.00139120139120163*G0_0_0_2_0 + 0.000161813495146856*G0_0_0_2_1 + 0.00032560032560038*G0_0_0_2_2 + 0.000917600917601073*G0_0_1_0_0 + 0.000159840159840187*G0_0_1_0_1 + 0.000161813495146856*G0_0_1_0_2 + 0.000159840159840187*G0_0_1_1_0 + 2.50895488990769e-05*G0_0_1_1_1 + 7.47048366096116e-06*G0_0_1_1_2 + 0.000161813495146856*G0_0_1_2_0 + 7.47048366096116e-06*G0_0_1_2_1 + 2.39619287238382e-06*G0_0_1_2_2 + 0.00139120139120163*G0_0_2_0_0 + 0.000161813495146856*G0_0_2_0_1 + 0.00032560032560038*G0_0_2_0_2 + 0.000161813495146856*G0_0_2_1_0 + 7.47048366096116e-06*G0_0_2_1_1 + 2.39619287238382e-06*G0_0_2_1_2 + 0.00032560032560038*G0_0_2_2_0 + 2.39619287238382e-06*G0_0_2_2_1 - 5.35619583238714e-06*G0_0_2_2_2 + 0.000917600917601073*G0_1_0_0_0 + 0.000159840159840187*G0_1_0_0_1 + 0.000161813495146856*G0_1_0_0_2 + 0.000159840159840187*G0_1_0_1_0 + 2.50895488990769e-05*G0_1_0_1_1 + 7.47048366096116e-06*G0_1_0_1_2 + 0.000161813495146856*G0_1_0_2_0 + 7.47048366096116e-06*G0_1_0_2_1 + 2.39619287238382e-06*G0_1_0_2_2 + 0.000159840159840187*G0_1_1_0_0 + 2.50895488990769e-05*G0_1_1_0_1 + 7.47048366096116e-06*G0_1_1_0_2 + 2.50895488990769e-05*G0_1_1_1_0 - 4.22857565714844e-06*G0_1_1_1_1 - 5.24343381486328e-05*G0_1_1_1_2 + 7.47048366096116e-06*G0_1_1_2_0 - 5.24343381486328e-05*G0_1_1_2_1 - 7.73829345258047e-05*G0_1_1_2_2 + 0.000161813495146856*G0_1_2_0_0 + 7.47048366096116e-06*G0_1_2_0_1 + 2.39619287238382e-06*G0_1_2_0_2 + 7.47048366096116e-06*G0_1_2_1_0 - 5.24343381486328e-05*G0_1_2_1_1 - 7.73829345258047e-05*G0_1_2_1_2 + 2.39619287238382e-06*G0_1_2_2_0 - 7.73829345258047e-05*G0_1_2_2_1 - 0.00015392015392018*G0_1_2_2_2 + 0.00139120139120163*G0_2_0_0_0 + 0.000161813495146856*G0_2_0_0_1 + 0.00032560032560038*G0_2_0_0_2 + 0.000161813495146856*G0_2_0_1_0 + 7.47048366096116e-06*G0_2_0_1_1 + 2.39619287238382e-06*G0_2_0_1_2 + 0.00032560032560038*G0_2_0_2_0 + 2.39619287238382e-06*G0_2_0_2_1 - 5.35619583238714e-06*G0_2_0_2_2 + 0.000161813495146856*G0_2_1_0_0 + 7.47048366096116e-06*G0_2_1_0_1 + 2.39619287238382e-06*G0_2_1_0_2 + 7.47048366096116e-06*G0_2_1_1_0 - 5.24343381486328e-05*G0_2_1_1_1 - 7.73829345258047e-05*G0_2_1_1_2 + 2.39619287238382e-06*G0_2_1_2_0 - 7.73829345258047e-05*G0_2_1_2_1 - 0.00015392015392018*G0_2_1_2_2 + 0.00032560032560038*G0_2_2_0_0 + 2.39619287238382e-06*G0_2_2_0_1 - 5.35619583238715e-06*G0_2_2_0_2 + 2.39619287238382e-06*G0_2_2_1_0 - 7.73829345258047e-05*G0_2_2_1_1 - 0.00015392015392018*G0_2_2_1_2 - 5.35619583238715e-06*G0_2_2_2_0 - 0.00015392015392018*G0_2_2_2_1 - 0.000511657654514883*G0_2_2_2_2; + A[164] = A[97] + 0.00341387008053732*G0_0_0_0_0 + 4.08762313524288e-05*G0_0_0_0_1 + 0.000334057476914676*G0_0_0_0_2 + 4.08762313524288e-05*G0_0_0_1_0 - 0.000226087845135502*G0_0_0_1_1 - 8.17524627048572e-06*G0_0_0_1_2 + 0.000334057476914676*G0_0_0_2_0 - 8.17524627048572e-06*G0_0_0_2_1 + 2.93181245562247e-05*G0_0_0_2_2 + 4.08762313524287e-05*G0_0_1_0_0 - 0.000226087845135502*G0_0_1_0_1 - 8.17524627048573e-06*G0_0_1_0_2 - 0.000226087845135502*G0_0_1_1_0 - 0.000229329753139316*G0_0_1_1_1 - 3.98895636990942e-05*G0_0_1_1_2 - 8.17524627048572e-06*G0_0_1_2_0 - 3.98895636990942e-05*G0_0_1_2_1 + 5.63810087619709e-06*G0_0_1_2_2 + 0.000334057476914676*G0_0_2_0_0 - 8.17524627048572e-06*G0_0_2_0_1 + 2.93181245562247e-05*G0_0_2_0_2 - 8.17524627048572e-06*G0_0_2_1_0 - 3.98895636990942e-05*G0_0_2_1_1 + 5.6381008761971e-06*G0_0_2_1_2 + 2.93181245562247e-05*G0_0_2_2_0 + 5.63810087619709e-06*G0_0_2_2_1 + 0.00015251062870113*G0_0_2_2_2 + 4.08762313524287e-05*G0_1_0_0_0 - 0.000226087845135502*G0_1_0_0_1 - 8.17524627048572e-06*G0_1_0_0_2 - 0.000226087845135502*G0_1_0_1_0 - 0.000229329753139316*G0_1_0_1_1 - 3.98895636990942e-05*G0_1_0_1_2 - 8.17524627048572e-06*G0_1_0_2_0 - 3.98895636990942e-05*G0_1_0_2_1 + 5.63810087619709e-06*G0_1_0_2_2 - 0.000226087845135502*G0_1_1_0_0 - 0.000229329753139316*G0_1_1_0_1 - 3.98895636990942e-05*G0_1_1_0_2 - 0.000229329753139316*G0_1_1_1_0 + 0.000133622990765869*G0_1_1_1_1 - 2.66400266400312e-05*G0_1_1_1_2 - 3.98895636990942e-05*G0_1_1_2_0 - 2.66400266400312e-05*G0_1_1_2_1 - 8.45715131429559e-06*G0_1_1_2_2 - 8.17524627048572e-06*G0_1_2_0_0 - 3.98895636990942e-05*G0_1_2_0_1 + 5.6381008761971e-06*G0_1_2_0_2 - 3.98895636990942e-05*G0_1_2_1_0 - 2.66400266400312e-05*G0_1_2_1_1 - 8.45715131429559e-06*G0_1_2_1_2 + 5.63810087619709e-06*G0_1_2_2_0 - 8.45715131429559e-06*G0_1_2_2_1 + 0.000107405821691554*G0_1_2_2_2 + 0.000334057476914676*G0_2_0_0_0 - 8.17524627048572e-06*G0_2_0_0_1 + 2.93181245562247e-05*G0_2_0_0_2 - 8.17524627048572e-06*G0_2_0_1_0 - 3.98895636990942e-05*G0_2_0_1_1 + 5.63810087619711e-06*G0_2_0_1_2 + 2.93181245562247e-05*G0_2_0_2_0 + 5.6381008761971e-06*G0_2_0_2_1 + 0.00015251062870113*G0_2_0_2_2 - 8.17524627048572e-06*G0_2_1_0_0 - 3.98895636990942e-05*G0_2_1_0_1 + 5.6381008761971e-06*G0_2_1_0_2 - 3.98895636990942e-05*G0_2_1_1_0 - 2.66400266400312e-05*G0_2_1_1_1 - 8.45715131429559e-06*G0_2_1_1_2 + 5.63810087619709e-06*G0_2_1_2_0 - 8.45715131429561e-06*G0_2_1_2_1 + 0.000107405821691554*G0_2_1_2_2 + 2.93181245562247e-05*G0_2_2_0_0 + 5.63810087619709e-06*G0_2_2_0_1 + 0.00015251062870113*G0_2_2_0_2 + 5.6381008761971e-06*G0_2_2_1_0 - 8.4571513142956e-06*G0_2_2_1_1 + 0.000107405821691554*G0_2_2_1_2 + 0.00015251062870113*G0_2_2_2_0 + 0.000107405821691554*G0_2_2_2_1 + 0.00119245833531568*G0_2_2_2_2; + A[113] = A[97] + 0.00205226871893573*G0_0_0_0_0 + 0.000121219168838237*G0_0_0_0_1 + 0.000174781127162109*G0_0_0_0_2 + 0.000121219168838237*G0_0_0_1_0 + 2.25524035047893e-06*G0_0_0_1_1 + 1.07123916647744e-05*G0_0_0_1_2 + 0.000174781127162109*G0_0_0_2_0 + 1.07123916647744e-05*G0_0_0_2_1 + 0.000121219168838237*G0_0_1_0_0 + 2.25524035047892e-06*G0_0_1_0_1 + 1.07123916647744e-05*G0_0_1_0_2 + 2.25524035047892e-06*G0_0_1_1_0 - 8.17524627048567e-06*G0_0_1_1_1 + 1.07123916647744e-05*G0_0_1_2_0 - 1.07123916647744e-05*G0_0_1_2_2 + 0.000174781127162109*G0_0_2_0_0 + 1.07123916647744e-05*G0_0_2_0_1 + 1.07123916647744e-05*G0_0_2_1_0 - 1.07123916647744e-05*G0_0_2_1_2 - 1.07123916647744e-05*G0_0_2_2_1 - 0.000174781127162108*G0_0_2_2_2 + 0.000121219168838237*G0_1_0_0_0 + 2.25524035047892e-06*G0_1_0_0_1 + 1.07123916647744e-05*G0_1_0_0_2 + 2.25524035047892e-06*G0_1_0_1_0 - 8.17524627048567e-06*G0_1_0_1_1 + 1.07123916647744e-05*G0_1_0_2_0 - 1.07123916647744e-05*G0_1_0_2_2 + 2.25524035047893e-06*G0_1_1_0_0 - 8.17524627048567e-06*G0_1_1_0_1 - 8.17524627048567e-06*G0_1_1_1_0 + 8.1752462704857e-06*G0_1_1_1_2 + 8.1752462704857e-06*G0_1_1_2_1 - 2.25524035047884e-06*G0_1_1_2_2 + 1.07123916647744e-05*G0_1_2_0_0 - 1.07123916647744e-05*G0_1_2_0_2 + 8.1752462704857e-06*G0_1_2_1_1 - 2.25524035047884e-06*G0_1_2_1_2 - 1.07123916647744e-05*G0_1_2_2_0 - 2.25524035047884e-06*G0_1_2_2_1 - 0.000121219168838237*G0_1_2_2_2 + 0.000174781127162109*G0_2_0_0_0 + 1.07123916647744e-05*G0_2_0_0_1 + 1.07123916647744e-05*G0_2_0_1_0 - 1.07123916647744e-05*G0_2_0_1_2 - 1.07123916647744e-05*G0_2_0_2_1 - 0.000174781127162108*G0_2_0_2_2 + 1.07123916647744e-05*G0_2_1_0_0 - 1.07123916647744e-05*G0_2_1_0_2 + 8.1752462704857e-06*G0_2_1_1_1 - 2.25524035047884e-06*G0_2_1_1_2 - 1.07123916647744e-05*G0_2_1_2_0 - 2.25524035047884e-06*G0_2_1_2_1 - 0.000121219168838237*G0_2_1_2_2 - 1.07123916647744e-05*G0_2_2_0_1 - 0.000174781127162108*G0_2_2_0_2 - 1.07123916647744e-05*G0_2_2_1_0 - 2.25524035047884e-06*G0_2_2_1_1 - 0.000121219168838237*G0_2_2_1_2 - 0.000174781127162108*G0_2_2_2_0 - 0.000121219168838237*G0_2_2_2_1 - 0.00205226871893573*G0_2_2_2_2; + A[142] = -A[99] + 0.000924178701956636*G0_0_0_0_0 + 4.27555983111614e-05*G0_0_0_0_1 + 0.000200622422844679*G0_0_0_0_2 + 4.27555983111614e-05*G0_0_0_1_0 - 1.9733353066688e-06*G0_0_0_1_1 + 1.71022393244645e-05*G0_0_0_1_2 + 0.000200622422844679*G0_0_0_2_0 + 1.71022393244645e-05*G0_0_0_2_1 + 5.32800532800624e-05*G0_0_0_2_2 + 4.27555983111614e-05*G0_0_1_0_0 - 1.97333530666881e-06*G0_0_1_0_1 + 1.71022393244645e-05*G0_0_1_0_2 - 1.97333530666881e-06*G0_0_1_1_0 + 1.6256524193035e-05*G0_0_1_1_1 + 6.43683183365834e-06*G0_0_1_1_2 + 1.71022393244645e-05*G0_0_1_2_0 + 6.43683183365834e-06*G0_0_1_2_1 + 4.74540157079924e-06*G0_0_1_2_2 + 0.000200622422844679*G0_0_2_0_0 + 1.71022393244645e-05*G0_0_2_0_1 + 5.32800532800624e-05*G0_0_2_0_2 + 1.71022393244645e-05*G0_0_2_1_0 + 6.43683183365834e-06*G0_0_2_1_1 + 4.74540157079924e-06*G0_0_2_1_2 + 5.32800532800624e-05*G0_0_2_2_0 + 4.74540157079924e-06*G0_0_2_2_1 + 6.10794261588031e-06*G0_0_2_2_2 + 4.27555983111614e-05*G0_1_0_0_0 - 1.97333530666881e-06*G0_1_0_0_1 + 1.71022393244645e-05*G0_1_0_0_2 - 1.97333530666881e-06*G0_1_0_1_0 + 1.6256524193035e-05*G0_1_0_1_1 + 6.43683183365834e-06*G0_1_0_1_2 + 1.71022393244645e-05*G0_1_0_2_0 + 6.43683183365834e-06*G0_1_0_2_1 + 4.74540157079924e-06*G0_1_0_2_2 - 1.9733353066688e-06*G0_1_1_0_0 + 1.6256524193035e-05*G0_1_1_0_1 + 6.43683183365834e-06*G0_1_1_0_2 + 1.6256524193035e-05*G0_1_1_1_0 + 0.000111352492304892*G0_1_1_1_1 + 2.76266942933658e-05*G0_1_1_1_2 + 6.43683183365834e-06*G0_1_1_2_0 + 2.76266942933658e-05*G0_1_1_2_1 + 8.03429374858089e-06*G0_1_1_2_2 + 1.71022393244645e-05*G0_1_2_0_0 + 6.43683183365834e-06*G0_1_2_0_1 + 4.74540157079924e-06*G0_1_2_0_2 + 6.43683183365834e-06*G0_1_2_1_0 + 2.76266942933658e-05*G0_1_2_1_1 + 8.03429374858089e-06*G0_1_2_1_2 + 4.74540157079924e-06*G0_1_2_2_0 + 8.03429374858089e-06*G0_1_2_2_1 - 6.20191096381665e-06*G0_1_2_2_2 + 0.000200622422844679*G0_2_0_0_0 + 1.71022393244645e-05*G0_2_0_0_1 + 5.32800532800624e-05*G0_2_0_0_2 + 1.71022393244645e-05*G0_2_0_1_0 + 6.43683183365834e-06*G0_2_0_1_1 + 4.74540157079924e-06*G0_2_0_1_2 + 5.32800532800624e-05*G0_2_0_2_0 + 4.74540157079924e-06*G0_2_0_2_1 + 6.10794261588031e-06*G0_2_0_2_2 + 1.71022393244645e-05*G0_2_1_0_0 + 6.43683183365834e-06*G0_2_1_0_1 + 4.74540157079924e-06*G0_2_1_0_2 + 6.43683183365834e-06*G0_2_1_1_0 + 2.76266942933658e-05*G0_2_1_1_1 + 8.03429374858089e-06*G0_2_1_1_2 + 4.74540157079924e-06*G0_2_1_2_0 + 8.03429374858089e-06*G0_2_1_2_1 - 6.20191096381665e-06*G0_2_1_2_2 + 5.32800532800624e-05*G0_2_2_0_0 + 4.74540157079924e-06*G0_2_2_0_1 + 6.10794261588031e-06*G0_2_2_0_2 + 4.74540157079924e-06*G0_2_2_1_0 + 8.03429374858089e-06*G0_2_2_1_1 - 6.20191096381664e-06*G0_2_2_1_2 + 6.10794261588031e-06*G0_2_2_2_0 - 6.20191096381665e-06*G0_2_2_2_1 - 5.77905339810194e-05*G0_2_2_2_2; + A[176] = -A[142] - 0.00212979260598344*G0_0_0_0_0 - 0.000220355775911368*G0_0_0_0_1 - 0.000179009702819256*G0_0_0_0_2 - 0.000220355775911368*G0_0_0_1_0 + 0.000305866972533691*G0_0_0_1_1 - 6.5777843555632e-06*G0_0_0_1_2 - 0.000179009702819256*G0_0_0_2_0 - 6.57778435556321e-06*G0_0_0_2_1 - 6.48381600762644e-06*G0_0_0_2_2 - 0.000220355775911368*G0_0_1_0_0 + 0.00030586697253369*G0_0_1_0_1 - 6.57778435556321e-06*G0_0_1_0_2 + 0.00030586697253369*G0_0_1_1_0 + 0.00143179571751024*G0_0_1_1_1 + 8.66858009715297e-05*G0_0_1_1_2 - 6.57778435556321e-06*G0_0_1_2_0 + 8.66858009715297e-05*G0_0_1_2_1 + 4.74540157079922e-06*G0_0_1_2_2 - 0.000179009702819256*G0_0_2_0_0 - 6.57778435556321e-06*G0_0_2_0_1 - 6.48381600762643e-06*G0_0_2_0_2 - 6.57778435556321e-06*G0_0_2_1_0 + 8.66858009715297e-05*G0_0_2_1_1 + 4.74540157079922e-06*G0_0_2_1_2 - 6.48381600762643e-06*G0_0_2_2_0 + 4.74540157079922e-06*G0_0_2_2_1 - 6.48381600762641e-06*G0_0_2_2_2 - 0.000220355775911368*G0_1_0_0_0 + 0.00030586697253369*G0_1_0_0_1 - 6.57778435556321e-06*G0_1_0_0_2 + 0.00030586697253369*G0_1_0_1_0 + 0.00143179571751024*G0_1_0_1_1 + 8.66858009715297e-05*G0_1_0_1_2 - 6.57778435556321e-06*G0_1_0_2_0 + 8.66858009715297e-05*G0_1_0_2_1 + 4.74540157079922e-06*G0_1_0_2_2 + 0.00030586697253369*G0_1_1_0_0 + 0.00143179571751024*G0_1_1_0_1 + 8.66858009715297e-05*G0_1_1_0_2 + 0.00143179571751024*G0_1_1_1_0 + 0.00739765819131023*G0_1_1_1_1 + 0.000471533169945947*G0_1_1_1_2 + 8.66858009715297e-05*G0_1_1_2_0 + 0.000471533169945947*G0_1_1_2_1 + 4.43060760521152e-05*G0_1_1_2_2 - 6.57778435556321e-06*G0_1_2_0_0 + 8.66858009715297e-05*G0_1_2_0_1 + 4.74540157079922e-06*G0_1_2_0_2 + 8.66858009715297e-05*G0_1_2_1_0 + 0.000471533169945947*G0_1_2_1_1 + 4.43060760521152e-05*G0_1_2_1_2 + 4.74540157079922e-06*G0_1_2_2_0 + 4.43060760521152e-05*G0_1_2_2_1 - 2.66870108139993e-05*G0_1_2_2_2 - 0.000179009702819256*G0_2_0_0_0 - 6.57778435556321e-06*G0_2_0_0_1 - 6.48381600762643e-06*G0_2_0_0_2 - 6.57778435556321e-06*G0_2_0_1_0 + 8.66858009715297e-05*G0_2_0_1_1 + 4.74540157079922e-06*G0_2_0_1_2 - 6.48381600762643e-06*G0_2_0_2_0 + 4.74540157079922e-06*G0_2_0_2_1 - 6.48381600762641e-06*G0_2_0_2_2 - 6.5777843555632e-06*G0_2_1_0_0 + 8.66858009715297e-05*G0_2_1_0_1 + 4.74540157079922e-06*G0_2_1_0_2 + 8.66858009715297e-05*G0_2_1_1_0 + 0.000471533169945947*G0_2_1_1_1 + 4.43060760521152e-05*G0_2_1_1_2 + 4.74540157079922e-06*G0_2_1_2_0 + 4.43060760521152e-05*G0_2_1_2_1 - 2.66870108139993e-05*G0_2_1_2_2 - 6.48381600762642e-06*G0_2_2_0_0 + 4.74540157079922e-06*G0_2_2_0_1 - 6.48381600762641e-06*G0_2_2_0_2 + 4.74540157079922e-06*G0_2_2_1_0 + 4.43060760521152e-05*G0_2_2_1_1 - 2.66870108139993e-05*G0_2_2_1_2 - 6.4838160076264e-06*G0_2_2_2_0 - 2.66870108139993e-05*G0_2_2_2_1 - 0.000122064883969666*G0_2_2_2_2; + A[175] = -A[176] - 0.000600457743314987*G0_0_0_0_0 + 1.36254104508097e-05*G0_0_0_0_1 - 5.77905339810199e-05*G0_0_0_0_2 + 1.36254104508097e-05*G0_0_0_1_0 + 0.000323626990293711*G0_0_0_1_1 + 6.10794261588012e-06*G0_0_0_1_2 - 5.77905339810199e-05*G0_0_0_2_0 + 6.10794261588012e-06*G0_0_0_2_1 - 6.20191096381675e-06*G0_0_0_2_2 + 1.36254104508097e-05*G0_0_1_0_0 + 0.000323626990293711*G0_0_1_0_1 + 6.10794261588012e-06*G0_0_1_0_2 + 0.000323626990293711*G0_0_1_1_0 + 0.00107546774213459*G0_0_1_1_1 + 5.32800532800621e-05*G0_0_1_1_2 + 6.10794261588012e-06*G0_0_1_2_0 + 5.32800532800621e-05*G0_0_1_2_1 + 4.74540157079919e-06*G0_0_1_2_2 - 5.77905339810199e-05*G0_0_2_0_0 + 6.10794261588012e-06*G0_0_2_0_1 - 6.20191096381676e-06*G0_0_2_0_2 + 6.10794261588012e-06*G0_0_2_1_0 + 5.32800532800621e-05*G0_0_2_1_1 + 4.74540157079918e-06*G0_0_2_1_2 - 6.20191096381676e-06*G0_0_2_2_0 + 4.74540157079919e-06*G0_0_2_2_1 + 8.03429374858085e-06*G0_0_2_2_2 + 1.36254104508097e-05*G0_1_0_0_0 + 0.000323626990293711*G0_1_0_0_1 + 6.10794261588012e-06*G0_1_0_0_2 + 0.000323626990293711*G0_1_0_1_0 + 0.00107546774213459*G0_1_0_1_1 + 5.32800532800621e-05*G0_1_0_1_2 + 6.10794261588012e-06*G0_1_0_2_0 + 5.32800532800622e-05*G0_1_0_2_1 + 4.74540157079919e-06*G0_1_0_2_2 + 0.000323626990293711*G0_1_1_0_0 + 0.00107546774213459*G0_1_1_0_1 + 5.32800532800621e-05*G0_1_1_0_2 + 0.00107546774213459*G0_1_1_1_0 + 0.0040979596535159*G0_1_1_1_1 + 0.000200622422844678*G0_1_1_1_2 + 5.32800532800622e-05*G0_1_1_2_0 + 0.000200622422844678*G0_1_1_2_1 + 1.71022393244643e-05*G0_1_1_2_2 + 6.10794261588012e-06*G0_1_2_0_0 + 5.32800532800621e-05*G0_1_2_0_1 + 4.74540157079919e-06*G0_1_2_0_2 + 5.32800532800621e-05*G0_1_2_1_0 + 0.000200622422844678*G0_1_2_1_1 + 1.71022393244643e-05*G0_1_2_1_2 + 4.74540157079919e-06*G0_1_2_2_0 + 1.71022393244643e-05*G0_1_2_2_1 + 6.4368318336583e-06*G0_1_2_2_2 - 5.77905339810199e-05*G0_2_0_0_0 + 6.10794261588012e-06*G0_2_0_0_1 - 6.20191096381676e-06*G0_2_0_0_2 + 6.10794261588012e-06*G0_2_0_1_0 + 5.32800532800622e-05*G0_2_0_1_1 + 4.74540157079918e-06*G0_2_0_1_2 - 6.20191096381675e-06*G0_2_0_2_0 + 4.74540157079919e-06*G0_2_0_2_1 + 8.03429374858085e-06*G0_2_0_2_2 + 6.10794261588013e-06*G0_2_1_0_0 + 5.32800532800622e-05*G0_2_1_0_1 + 4.74540157079919e-06*G0_2_1_0_2 + 5.32800532800622e-05*G0_2_1_1_0 + 0.000200622422844678*G0_2_1_1_1 + 1.71022393244643e-05*G0_2_1_1_2 + 4.74540157079919e-06*G0_2_1_2_0 + 1.71022393244643e-05*G0_2_1_2_1 + 6.4368318336583e-06*G0_2_1_2_2 - 6.20191096381675e-06*G0_2_2_0_0 + 4.74540157079919e-06*G0_2_2_0_1 + 8.03429374858085e-06*G0_2_2_0_2 + 4.74540157079919e-06*G0_2_2_1_0 + 1.71022393244643e-05*G0_2_2_1_1 + 6.4368318336583e-06*G0_2_2_1_2 + 8.03429374858085e-06*G0_2_2_2_0 + 6.4368318336583e-06*G0_2_2_2_1 + 2.76266942933657e-05*G0_2_2_2_2; + A[72] = A[175] + 0.00119245833531568*G0_0_0_0_0 + 0.000152510628701131*G0_0_0_0_1 + 0.000107405821691554*G0_0_0_0_2 + 0.000152510628701131*G0_0_0_1_0 + 2.93181245562245e-05*G0_0_0_1_1 + 5.63810087619709e-06*G0_0_0_1_2 + 0.000107405821691554*G0_0_0_2_0 + 5.63810087619709e-06*G0_0_0_2_1 - 8.4571513142956e-06*G0_0_0_2_2 + 0.000152510628701131*G0_0_1_0_0 + 2.93181245562245e-05*G0_0_1_0_1 + 5.63810087619709e-06*G0_0_1_0_2 + 2.93181245562245e-05*G0_0_1_1_0 + 0.000334057476914675*G0_0_1_1_1 - 8.17524627048579e-06*G0_0_1_1_2 + 5.63810087619709e-06*G0_0_1_2_0 - 8.17524627048579e-06*G0_0_1_2_1 - 3.98895636990942e-05*G0_0_1_2_2 + 0.000107405821691554*G0_0_2_0_0 + 5.63810087619709e-06*G0_0_2_0_1 - 8.45715131429559e-06*G0_0_2_0_2 + 5.63810087619709e-06*G0_0_2_1_0 - 8.17524627048579e-06*G0_0_2_1_1 - 3.98895636990942e-05*G0_0_2_1_2 - 8.4571513142956e-06*G0_0_2_2_0 - 3.98895636990942e-05*G0_0_2_2_1 - 2.66400266400311e-05*G0_0_2_2_2 + 0.000152510628701131*G0_1_0_0_0 + 2.93181245562245e-05*G0_1_0_0_1 + 5.63810087619709e-06*G0_1_0_0_2 + 2.93181245562245e-05*G0_1_0_1_0 + 0.000334057476914675*G0_1_0_1_1 - 8.17524627048579e-06*G0_1_0_1_2 + 5.63810087619709e-06*G0_1_0_2_0 - 8.1752462704858e-06*G0_1_0_2_1 - 3.98895636990942e-05*G0_1_0_2_2 + 2.93181245562245e-05*G0_1_1_0_0 + 0.000334057476914675*G0_1_1_0_1 - 8.17524627048579e-06*G0_1_1_0_2 + 0.000334057476914675*G0_1_1_1_0 + 0.00341387008053732*G0_1_1_1_1 + 4.08762313524283e-05*G0_1_1_1_2 - 8.17524627048579e-06*G0_1_1_2_0 + 4.08762313524283e-05*G0_1_1_2_1 - 0.000226087845135502*G0_1_1_2_2 + 5.63810087619709e-06*G0_1_2_0_0 - 8.1752462704858e-06*G0_1_2_0_1 - 3.98895636990942e-05*G0_1_2_0_2 - 8.1752462704858e-06*G0_1_2_1_0 + 4.08762313524283e-05*G0_1_2_1_1 - 0.000226087845135502*G0_1_2_1_2 - 3.98895636990942e-05*G0_1_2_2_0 - 0.000226087845135502*G0_1_2_2_1 - 0.000229329753139316*G0_1_2_2_2 + 0.000107405821691554*G0_2_0_0_0 + 5.63810087619709e-06*G0_2_0_0_1 - 8.45715131429558e-06*G0_2_0_0_2 + 5.63810087619709e-06*G0_2_0_1_0 - 8.17524627048579e-06*G0_2_0_1_1 - 3.98895636990942e-05*G0_2_0_1_2 - 8.4571513142956e-06*G0_2_0_2_0 - 3.98895636990942e-05*G0_2_0_2_1 - 2.66400266400311e-05*G0_2_0_2_2 + 5.63810087619709e-06*G0_2_1_0_0 - 8.17524627048579e-06*G0_2_1_0_1 - 3.98895636990942e-05*G0_2_1_0_2 - 8.1752462704858e-06*G0_2_1_1_0 + 4.08762313524283e-05*G0_2_1_1_1 - 0.000226087845135502*G0_2_1_1_2 - 3.98895636990942e-05*G0_2_1_2_0 - 0.000226087845135502*G0_2_1_2_1 - 0.000229329753139316*G0_2_1_2_2 - 8.4571513142956e-06*G0_2_2_0_0 - 3.98895636990942e-05*G0_2_2_0_1 - 2.66400266400311e-05*G0_2_2_0_2 - 3.98895636990942e-05*G0_2_2_1_0 - 0.000226087845135502*G0_2_2_1_1 - 0.000229329753139316*G0_2_2_1_2 - 2.66400266400311e-05*G0_2_2_2_0 - 0.000229329753139316*G0_2_2_2_1 + 0.00013362299076587*G0_2_2_2_2; + A[159] = A[175] - 0.00205226871893573*G0_0_0_0_0 - 0.000174781127162109*G0_0_0_0_1 - 0.000121219168838237*G0_0_0_0_2 - 0.000174781127162109*G0_0_0_1_0 - 1.07123916647744e-05*G0_0_0_1_2 - 0.000121219168838237*G0_0_0_2_0 - 1.07123916647744e-05*G0_0_0_2_1 - 2.25524035047884e-06*G0_0_0_2_2 - 0.000174781127162109*G0_0_1_0_0 - 1.07123916647744e-05*G0_0_1_0_2 + 0.000174781127162108*G0_0_1_1_1 + 1.07123916647743e-05*G0_0_1_1_2 - 1.07123916647744e-05*G0_0_1_2_0 + 1.07123916647743e-05*G0_0_1_2_1 - 0.000121219168838237*G0_0_2_0_0 - 1.07123916647745e-05*G0_0_2_0_1 - 2.25524035047884e-06*G0_0_2_0_2 - 1.07123916647744e-05*G0_0_2_1_0 + 1.07123916647743e-05*G0_0_2_1_1 - 2.25524035047883e-06*G0_0_2_2_0 + 8.17524627048571e-06*G0_0_2_2_2 - 0.000174781127162109*G0_1_0_0_0 - 1.07123916647744e-05*G0_1_0_0_2 + 0.000174781127162108*G0_1_0_1_1 + 1.07123916647743e-05*G0_1_0_1_2 - 1.07123916647744e-05*G0_1_0_2_0 + 1.07123916647743e-05*G0_1_0_2_1 + 0.000174781127162108*G0_1_1_0_1 + 1.07123916647743e-05*G0_1_1_0_2 + 0.000174781127162108*G0_1_1_1_0 + 0.00205226871893573*G0_1_1_1_1 + 0.000121219168838237*G0_1_1_1_2 + 1.07123916647743e-05*G0_1_1_2_0 + 0.000121219168838237*G0_1_1_2_1 + 2.2552403504788e-06*G0_1_1_2_2 - 1.07123916647744e-05*G0_1_2_0_0 + 1.07123916647743e-05*G0_1_2_0_1 + 1.07123916647743e-05*G0_1_2_1_0 + 0.000121219168838237*G0_1_2_1_1 + 2.25524035047881e-06*G0_1_2_1_2 + 2.2552403504788e-06*G0_1_2_2_1 - 8.17524627048574e-06*G0_1_2_2_2 - 0.000121219168838237*G0_2_0_0_0 - 1.07123916647745e-05*G0_2_0_0_1 - 2.25524035047884e-06*G0_2_0_0_2 - 1.07123916647744e-05*G0_2_0_1_0 + 1.07123916647743e-05*G0_2_0_1_1 - 2.25524035047882e-06*G0_2_0_2_0 + 8.17524627048571e-06*G0_2_0_2_2 - 1.07123916647745e-05*G0_2_1_0_0 + 1.07123916647743e-05*G0_2_1_0_1 + 1.07123916647743e-05*G0_2_1_1_0 + 0.000121219168838237*G0_2_1_1_1 + 2.2552403504788e-06*G0_2_1_1_2 + 2.2552403504788e-06*G0_2_1_2_1 - 8.17524627048574e-06*G0_2_1_2_2 - 2.25524035047884e-06*G0_2_2_0_0 + 8.17524627048571e-06*G0_2_2_0_2 + 2.25524035047881e-06*G0_2_2_1_1 - 8.17524627048574e-06*G0_2_2_1_2 + 8.17524627048571e-06*G0_2_2_2_0 - 8.17524627048574e-06*G0_2_2_2_1; + A[202] = A[159] + 0.00341387008053732*G0_0_0_0_0 + 0.000334057476914676*G0_0_0_0_1 + 4.08762313524289e-05*G0_0_0_0_2 + 0.000334057476914676*G0_0_0_1_0 + 2.9318124556225e-05*G0_0_0_1_1 - 8.17524627048563e-06*G0_0_0_1_2 + 4.08762313524289e-05*G0_0_0_2_0 - 8.17524627048562e-06*G0_0_0_2_1 - 0.000226087845135502*G0_0_0_2_2 + 0.000334057476914676*G0_0_1_0_0 + 2.9318124556225e-05*G0_0_1_0_1 - 8.17524627048562e-06*G0_0_1_0_2 + 2.9318124556225e-05*G0_0_1_1_0 + 0.000152510628701131*G0_0_1_1_1 + 5.63810087619733e-06*G0_0_1_1_2 - 8.17524627048562e-06*G0_0_1_2_0 + 5.63810087619733e-06*G0_0_1_2_1 - 3.98895636990941e-05*G0_0_1_2_2 + 4.08762313524289e-05*G0_0_2_0_0 - 8.17524627048561e-06*G0_0_2_0_1 - 0.000226087845135502*G0_0_2_0_2 - 8.17524627048562e-06*G0_0_2_1_0 + 5.63810087619733e-06*G0_0_2_1_1 - 3.98895636990941e-05*G0_0_2_1_2 - 0.000226087845135502*G0_0_2_2_0 - 3.98895636990941e-05*G0_0_2_2_1 - 0.000229329753139315*G0_0_2_2_2 + 0.000334057476914676*G0_1_0_0_0 + 2.9318124556225e-05*G0_1_0_0_1 - 8.17524627048561e-06*G0_1_0_0_2 + 2.9318124556225e-05*G0_1_0_1_0 + 0.000152510628701131*G0_1_0_1_1 + 5.63810087619734e-06*G0_1_0_1_2 - 8.17524627048561e-06*G0_1_0_2_0 + 5.63810087619734e-06*G0_1_0_2_1 - 3.98895636990941e-05*G0_1_0_2_2 + 2.9318124556225e-05*G0_1_1_0_0 + 0.000152510628701131*G0_1_1_0_1 + 5.63810087619733e-06*G0_1_1_0_2 + 0.000152510628701131*G0_1_1_1_0 + 0.00119245833531568*G0_1_1_1_1 + 0.000107405821691555*G0_1_1_1_2 + 5.63810087619733e-06*G0_1_1_2_0 + 0.000107405821691555*G0_1_1_2_1 - 8.45715131429522e-06*G0_1_1_2_2 - 8.17524627048562e-06*G0_1_2_0_0 + 5.63810087619733e-06*G0_1_2_0_1 - 3.98895636990941e-05*G0_1_2_0_2 + 5.63810087619733e-06*G0_1_2_1_0 + 0.000107405821691555*G0_1_2_1_1 - 8.45715131429522e-06*G0_1_2_1_2 - 3.98895636990941e-05*G0_1_2_2_0 - 8.45715131429522e-06*G0_1_2_2_1 - 2.66400266400311e-05*G0_1_2_2_2 + 4.08762313524289e-05*G0_2_0_0_0 - 8.17524627048561e-06*G0_2_0_0_1 - 0.000226087845135502*G0_2_0_0_2 - 8.17524627048562e-06*G0_2_0_1_0 + 5.63810087619734e-06*G0_2_0_1_1 - 3.98895636990941e-05*G0_2_0_1_2 - 0.000226087845135502*G0_2_0_2_0 - 3.98895636990941e-05*G0_2_0_2_1 - 0.000229329753139315*G0_2_0_2_2 - 8.17524627048561e-06*G0_2_1_0_0 + 5.63810087619733e-06*G0_2_1_0_1 - 3.98895636990941e-05*G0_2_1_0_2 + 5.63810087619733e-06*G0_2_1_1_0 + 0.000107405821691555*G0_2_1_1_1 - 8.45715131429522e-06*G0_2_1_1_2 - 3.98895636990941e-05*G0_2_1_2_0 - 8.45715131429523e-06*G0_2_1_2_1 - 2.66400266400311e-05*G0_2_1_2_2 - 0.000226087845135502*G0_2_2_0_0 - 3.98895636990941e-05*G0_2_2_0_1 - 0.000229329753139315*G0_2_2_0_2 - 3.98895636990941e-05*G0_2_2_1_0 - 8.45715131429523e-06*G0_2_2_1_1 - 2.66400266400311e-05*G0_2_2_1_2 - 0.000229329753139315*G0_2_2_2_0 - 2.66400266400311e-05*G0_2_2_2_1 + 0.000133622990765869*G0_2_2_2_2; + A[144] = -A[159] + 0.0040979596535159*G0_0_0_0_0 + 0.00107546774213459*G0_0_0_0_1 + 0.000200622422844678*G0_0_0_0_2 + 0.00107546774213459*G0_0_0_1_0 + 0.000323626990293712*G0_0_0_1_1 + 5.32800532800622e-05*G0_0_0_1_2 + 0.000200622422844678*G0_0_0_2_0 + 5.32800532800622e-05*G0_0_0_2_1 + 1.71022393244644e-05*G0_0_0_2_2 + 0.00107546774213459*G0_0_1_0_0 + 0.000323626990293712*G0_0_1_0_1 + 5.32800532800622e-05*G0_0_1_0_2 + 0.000323626990293712*G0_0_1_1_0 + 1.36254104508096e-05*G0_0_1_1_1 + 6.10794261588015e-06*G0_0_1_1_2 + 5.32800532800622e-05*G0_0_1_2_0 + 6.10794261588015e-06*G0_0_1_2_1 + 4.74540157079917e-06*G0_0_1_2_2 + 0.000200622422844678*G0_0_2_0_0 + 5.32800532800622e-05*G0_0_2_0_1 + 1.71022393244644e-05*G0_0_2_0_2 + 5.32800532800622e-05*G0_0_2_1_0 + 6.10794261588015e-06*G0_0_2_1_1 + 4.74540157079918e-06*G0_0_2_1_2 + 1.71022393244644e-05*G0_0_2_2_0 + 4.74540157079917e-06*G0_0_2_2_1 + 6.43683183365829e-06*G0_0_2_2_2 + 0.00107546774213459*G0_1_0_0_0 + 0.000323626990293712*G0_1_0_0_1 + 5.32800532800622e-05*G0_1_0_0_2 + 0.000323626990293712*G0_1_0_1_0 + 1.36254104508096e-05*G0_1_0_1_1 + 6.10794261588015e-06*G0_1_0_1_2 + 5.32800532800622e-05*G0_1_0_2_0 + 6.10794261588015e-06*G0_1_0_2_1 + 4.74540157079917e-06*G0_1_0_2_2 + 0.000323626990293711*G0_1_1_0_0 + 1.36254104508096e-05*G0_1_1_0_1 + 6.10794261588015e-06*G0_1_1_0_2 + 1.36254104508096e-05*G0_1_1_1_0 - 0.000600457743314987*G0_1_1_1_1 - 5.779053398102e-05*G0_1_1_1_2 + 6.10794261588015e-06*G0_1_1_2_0 - 5.779053398102e-05*G0_1_1_2_1 - 6.20191096381677e-06*G0_1_1_2_2 + 5.32800532800622e-05*G0_1_2_0_0 + 6.10794261588015e-06*G0_1_2_0_1 + 4.74540157079917e-06*G0_1_2_0_2 + 6.10794261588015e-06*G0_1_2_1_0 - 5.779053398102e-05*G0_1_2_1_1 - 6.20191096381675e-06*G0_1_2_1_2 + 4.74540157079917e-06*G0_1_2_2_0 - 6.20191096381676e-06*G0_1_2_2_1 + 8.0342937485808e-06*G0_1_2_2_2 + 0.000200622422844678*G0_2_0_0_0 + 5.32800532800622e-05*G0_2_0_0_1 + 1.71022393244644e-05*G0_2_0_0_2 + 5.32800532800622e-05*G0_2_0_1_0 + 6.10794261588015e-06*G0_2_0_1_1 + 4.74540157079918e-06*G0_2_0_1_2 + 1.71022393244644e-05*G0_2_0_2_0 + 4.74540157079918e-06*G0_2_0_2_1 + 6.43683183365829e-06*G0_2_0_2_2 + 5.32800532800622e-05*G0_2_1_0_0 + 6.10794261588015e-06*G0_2_1_0_1 + 4.74540157079917e-06*G0_2_1_0_2 + 6.10794261588015e-06*G0_2_1_1_0 - 5.779053398102e-05*G0_2_1_1_1 - 6.20191096381676e-06*G0_2_1_1_2 + 4.74540157079917e-06*G0_2_1_2_0 - 6.20191096381676e-06*G0_2_1_2_1 + 8.0342937485808e-06*G0_2_1_2_2 + 1.71022393244644e-05*G0_2_2_0_0 + 4.74540157079917e-06*G0_2_2_0_1 + 6.43683183365829e-06*G0_2_2_0_2 + 4.74540157079917e-06*G0_2_2_1_0 - 6.20191096381675e-06*G0_2_2_1_1 + 8.03429374858081e-06*G0_2_2_1_2 + 6.43683183365829e-06*G0_2_2_2_0 + 8.0342937485808e-06*G0_2_2_2_1 + 2.76266942933656e-05*G0_2_2_2_2; + A[169] = A[175] + 0.0012474298188586*G0_0_0_0_0 + 0.000181546848213545*G0_0_0_0_1 + 0.000149691578263032*G0_0_0_0_2 + 0.000181546848213545*G0_0_0_1_0 - 1.77600177600208e-05*G0_0_0_1_1 + 2.26933560266932e-05*G0_0_0_1_2 + 0.000149691578263032*G0_0_0_2_0 + 2.26933560266932e-05*G0_0_0_2_1 + 2.4948596377172e-05*G0_0_0_2_2 + 0.000181546848213545*G0_0_1_0_0 - 1.77600177600208e-05*G0_0_1_0_1 + 2.26933560266932e-05*G0_0_1_0_2 - 1.77600177600208e-05*G0_0_1_1_0 - 5.92000592000689e-05*G0_0_1_1_1 - 1.97333530666894e-06*G0_0_1_1_2 + 2.26933560266932e-05*G0_0_1_2_0 - 1.97333530666894e-06*G0_0_1_2_1 + 0.000149691578263032*G0_0_2_0_0 + 2.26933560266932e-05*G0_0_2_0_1 + 2.4948596377172e-05*G0_0_2_0_2 + 2.26933560266932e-05*G0_0_2_1_0 - 1.97333530666894e-06*G0_0_2_1_1 + 2.4948596377172e-05*G0_0_2_2_0 - 2.4948596377172e-05*G0_0_2_2_2 + 0.000181546848213545*G0_1_0_0_0 - 1.77600177600207e-05*G0_1_0_0_1 + 2.26933560266932e-05*G0_1_0_0_2 - 1.77600177600208e-05*G0_1_0_1_0 - 5.92000592000689e-05*G0_1_0_1_1 - 1.97333530666894e-06*G0_1_0_1_2 + 2.26933560266932e-05*G0_1_0_2_0 - 1.97333530666894e-06*G0_1_0_2_1 - 1.77600177600207e-05*G0_1_1_0_0 - 5.92000592000689e-05*G0_1_1_0_1 - 1.97333530666894e-06*G0_1_1_0_2 - 5.92000592000689e-05*G0_1_1_1_0 + 0.000522933856267281*G0_1_1_1_1 - 1.97333530666894e-06*G0_1_1_2_0 + 1.9733353066691e-06*G0_1_1_2_2 + 2.26933560266932e-05*G0_1_2_0_0 - 1.97333530666894e-06*G0_1_2_0_1 - 1.97333530666893e-06*G0_1_2_1_0 + 1.9733353066691e-06*G0_1_2_1_2 + 1.9733353066691e-06*G0_1_2_2_1 - 2.26933560266931e-05*G0_1_2_2_2 + 0.000149691578263032*G0_2_0_0_0 + 2.26933560266932e-05*G0_2_0_0_1 + 2.4948596377172e-05*G0_2_0_0_2 + 2.26933560266932e-05*G0_2_0_1_0 - 1.97333530666894e-06*G0_2_0_1_1 + 2.4948596377172e-05*G0_2_0_2_0 - 2.4948596377172e-05*G0_2_0_2_2 + 2.26933560266932e-05*G0_2_1_0_0 - 1.97333530666894e-06*G0_2_1_0_1 - 1.97333530666895e-06*G0_2_1_1_0 + 1.97333530666909e-06*G0_2_1_1_2 + 1.97333530666909e-06*G0_2_1_2_1 - 2.26933560266931e-05*G0_2_1_2_2 + 2.4948596377172e-05*G0_2_2_0_0 - 2.4948596377172e-05*G0_2_2_0_2 + 1.9733353066691e-06*G0_2_2_1_1 - 2.26933560266931e-05*G0_2_2_1_2 - 2.4948596377172e-05*G0_2_2_2_0 - 2.26933560266931e-05*G0_2_2_2_1 - 0.000149691578263032*G0_2_2_2_2; + A[56] = -A[169] + 0.000111352492304892*G0_0_0_0_0 + 1.62565241930348e-05*G0_0_0_0_1 + 2.76266942933655e-05*G0_0_0_0_2 + 1.62565241930348e-05*G0_0_0_1_0 - 1.97333530666891e-06*G0_0_0_1_1 + 6.43683183365831e-06*G0_0_0_1_2 + 2.76266942933655e-05*G0_0_0_2_0 + 6.43683183365831e-06*G0_0_0_2_1 + 8.03429374858081e-06*G0_0_0_2_2 + 1.62565241930348e-05*G0_0_1_0_0 - 1.97333530666892e-06*G0_0_1_0_1 + 6.43683183365831e-06*G0_0_1_0_2 - 1.97333530666892e-06*G0_0_1_1_0 + 4.27555983111614e-05*G0_0_1_1_1 + 1.71022393244644e-05*G0_0_1_1_2 + 6.43683183365831e-06*G0_0_1_2_0 + 1.71022393244644e-05*G0_0_1_2_1 + 4.7454015707992e-06*G0_0_1_2_2 + 2.76266942933655e-05*G0_0_2_0_0 + 6.43683183365831e-06*G0_0_2_0_1 + 8.0342937485808e-06*G0_0_2_0_2 + 6.43683183365831e-06*G0_0_2_1_0 + 1.71022393244644e-05*G0_0_2_1_1 + 4.74540157079919e-06*G0_0_2_1_2 + 8.0342937485808e-06*G0_0_2_2_0 + 4.74540157079919e-06*G0_0_2_2_1 - 6.20191096381676e-06*G0_0_2_2_2 + 1.62565241930348e-05*G0_1_0_0_0 - 1.97333530666891e-06*G0_1_0_0_1 + 6.43683183365831e-06*G0_1_0_0_2 - 1.97333530666891e-06*G0_1_0_1_0 + 4.27555983111615e-05*G0_1_0_1_1 + 1.71022393244644e-05*G0_1_0_1_2 + 6.43683183365831e-06*G0_1_0_2_0 + 1.71022393244645e-05*G0_1_0_2_1 + 4.7454015707992e-06*G0_1_0_2_2 - 1.97333530666891e-06*G0_1_1_0_0 + 4.27555983111614e-05*G0_1_1_0_1 + 1.71022393244644e-05*G0_1_1_0_2 + 4.27555983111615e-05*G0_1_1_1_0 + 0.000924178701956641*G0_1_1_1_1 + 0.000200622422844679*G0_1_1_1_2 + 1.71022393244644e-05*G0_1_1_2_0 + 0.000200622422844679*G0_1_1_2_1 + 5.32800532800624e-05*G0_1_1_2_2 + 6.43683183365831e-06*G0_1_2_0_0 + 1.71022393244644e-05*G0_1_2_0_1 + 4.7454015707992e-06*G0_1_2_0_2 + 1.71022393244645e-05*G0_1_2_1_0 + 0.000200622422844679*G0_1_2_1_1 + 5.32800532800625e-05*G0_1_2_1_2 + 4.74540157079919e-06*G0_1_2_2_0 + 5.32800532800625e-05*G0_1_2_2_1 + 6.10794261588026e-06*G0_1_2_2_2 + 2.76266942933655e-05*G0_2_0_0_0 + 6.43683183365831e-06*G0_2_0_0_1 + 8.0342937485808e-06*G0_2_0_0_2 + 6.43683183365831e-06*G0_2_0_1_0 + 1.71022393244644e-05*G0_2_0_1_1 + 4.74540157079919e-06*G0_2_0_1_2 + 8.0342937485808e-06*G0_2_0_2_0 + 4.74540157079919e-06*G0_2_0_2_1 - 6.20191096381677e-06*G0_2_0_2_2 + 6.43683183365831e-06*G0_2_1_0_0 + 1.71022393244644e-05*G0_2_1_0_1 + 4.7454015707992e-06*G0_2_1_0_2 + 1.71022393244644e-05*G0_2_1_1_0 + 0.000200622422844679*G0_2_1_1_1 + 5.32800532800624e-05*G0_2_1_1_2 + 4.74540157079919e-06*G0_2_1_2_0 + 5.32800532800624e-05*G0_2_1_2_1 + 6.10794261588027e-06*G0_2_1_2_2 + 8.0342937485808e-06*G0_2_2_0_0 + 4.74540157079919e-06*G0_2_2_0_1 - 6.20191096381677e-06*G0_2_2_0_2 + 4.74540157079919e-06*G0_2_2_1_0 + 5.32800532800624e-05*G0_2_2_1_1 + 6.10794261588027e-06*G0_2_2_1_2 - 6.20191096381676e-06*G0_2_2_2_0 + 6.10794261588026e-06*G0_2_2_2_1 - 5.77905339810198e-05*G0_2_2_2_2; + A[153] = -A[56] - 5.77905339810196e-05*G0_0_0_0_0 + 6.10794261588011e-06*G0_0_0_0_1 - 6.20191096381675e-06*G0_0_0_0_2 + 6.1079426158801e-06*G0_0_0_1_0 + 5.3280053280062e-05*G0_0_0_1_1 + 4.74540157079917e-06*G0_0_0_1_2 - 6.20191096381675e-06*G0_0_0_2_0 + 4.74540157079917e-06*G0_0_0_2_1 + 8.03429374858084e-06*G0_0_0_2_2 + 6.10794261588011e-06*G0_0_1_0_0 + 5.3280053280062e-05*G0_0_1_0_1 + 4.74540157079917e-06*G0_0_1_0_2 + 5.3280053280062e-05*G0_0_1_1_0 + 0.000200622422844678*G0_0_1_1_1 + 1.71022393244643e-05*G0_0_1_1_2 + 4.74540157079918e-06*G0_0_1_2_0 + 1.71022393244643e-05*G0_0_1_2_1 + 6.43683183365831e-06*G0_0_1_2_2 - 6.20191096381675e-06*G0_0_2_0_0 + 4.74540157079917e-06*G0_0_2_0_1 + 8.03429374858083e-06*G0_0_2_0_2 + 4.74540157079917e-06*G0_0_2_1_0 + 1.71022393244643e-05*G0_0_2_1_1 + 6.4368318336583e-06*G0_0_2_1_2 + 8.03429374858083e-06*G0_0_2_2_0 + 6.4368318336583e-06*G0_0_2_2_1 + 2.76266942933656e-05*G0_0_2_2_2 + 6.10794261588011e-06*G0_1_0_0_0 + 5.3280053280062e-05*G0_1_0_0_1 + 4.74540157079917e-06*G0_1_0_0_2 + 5.3280053280062e-05*G0_1_0_1_0 + 0.000200622422844678*G0_1_0_1_1 + 1.71022393244643e-05*G0_1_0_1_2 + 4.74540157079918e-06*G0_1_0_2_0 + 1.71022393244643e-05*G0_1_0_2_1 + 6.43683183365831e-06*G0_1_0_2_2 + 5.3280053280062e-05*G0_1_1_0_0 + 0.000200622422844678*G0_1_1_0_1 + 1.71022393244643e-05*G0_1_1_0_2 + 0.000200622422844678*G0_1_1_1_0 + 0.000924178701956633*G0_1_1_1_1 + 4.27555983111608e-05*G0_1_1_1_2 + 1.71022393244643e-05*G0_1_1_2_0 + 4.27555983111608e-05*G0_1_1_2_1 - 1.97333530666907e-06*G0_1_1_2_2 + 4.74540157079918e-06*G0_1_2_0_0 + 1.71022393244643e-05*G0_1_2_0_1 + 6.43683183365831e-06*G0_1_2_0_2 + 1.71022393244643e-05*G0_1_2_1_0 + 4.27555983111608e-05*G0_1_2_1_1 - 1.97333530666906e-06*G0_1_2_1_2 + 6.4368318336583e-06*G0_1_2_2_0 - 1.97333530666906e-06*G0_1_2_2_1 + 1.62565241930349e-05*G0_1_2_2_2 - 6.20191096381675e-06*G0_2_0_0_0 + 4.74540157079918e-06*G0_2_0_0_1 + 8.03429374858083e-06*G0_2_0_0_2 + 4.74540157079917e-06*G0_2_0_1_0 + 1.71022393244643e-05*G0_2_0_1_1 + 6.4368318336583e-06*G0_2_0_1_2 + 8.03429374858083e-06*G0_2_0_2_0 + 6.4368318336583e-06*G0_2_0_2_1 + 2.76266942933657e-05*G0_2_0_2_2 + 4.74540157079918e-06*G0_2_1_0_0 + 1.71022393244643e-05*G0_2_1_0_1 + 6.43683183365831e-06*G0_2_1_0_2 + 1.71022393244643e-05*G0_2_1_1_0 + 4.27555983111607e-05*G0_2_1_1_1 - 1.97333530666906e-06*G0_2_1_1_2 + 6.4368318336583e-06*G0_2_1_2_0 - 1.97333530666906e-06*G0_2_1_2_1 + 1.62565241930349e-05*G0_2_1_2_2 + 8.03429374858083e-06*G0_2_2_0_0 + 6.4368318336583e-06*G0_2_2_0_1 + 2.76266942933656e-05*G0_2_2_0_2 + 6.4368318336583e-06*G0_2_2_1_0 - 1.97333530666907e-06*G0_2_2_1_1 + 1.62565241930349e-05*G0_2_2_1_2 + 2.76266942933657e-05*G0_2_2_2_0 + 1.62565241930349e-05*G0_2_2_2_1 + 0.000111352492304892*G0_2_2_2_2; + A[80] = -A[153] - 0.000122064883969666*G0_0_0_0_0 - 6.48381600762663e-06*G0_0_0_0_1 - 2.66870108139994e-05*G0_0_0_0_2 - 6.48381600762663e-06*G0_0_0_1_0 - 6.48381600762666e-06*G0_0_0_1_1 + 4.74540157079918e-06*G0_0_0_1_2 - 2.66870108139994e-05*G0_0_0_2_0 + 4.74540157079918e-06*G0_0_0_2_1 + 4.43060760521152e-05*G0_0_0_2_2 - 6.48381600762663e-06*G0_0_1_0_0 - 6.48381600762667e-06*G0_0_1_0_1 + 4.74540157079917e-06*G0_0_1_0_2 - 6.48381600762668e-06*G0_0_1_1_0 - 0.000179009702819257*G0_0_1_1_1 - 6.5777843555633e-06*G0_0_1_1_2 + 4.74540157079917e-06*G0_0_1_2_0 - 6.5777843555633e-06*G0_0_1_2_1 + 8.66858009715297e-05*G0_0_1_2_2 - 2.66870108139994e-05*G0_0_2_0_0 + 4.74540157079918e-06*G0_0_2_0_1 + 4.43060760521152e-05*G0_0_2_0_2 + 4.74540157079918e-06*G0_0_2_1_0 - 6.5777843555633e-06*G0_0_2_1_1 + 8.66858009715297e-05*G0_0_2_1_2 + 4.43060760521152e-05*G0_0_2_2_0 + 8.66858009715297e-05*G0_0_2_2_1 + 0.000471533169945947*G0_0_2_2_2 - 6.48381600762663e-06*G0_1_0_0_0 - 6.48381600762667e-06*G0_1_0_0_1 + 4.74540157079917e-06*G0_1_0_0_2 - 6.48381600762666e-06*G0_1_0_1_0 - 0.000179009702819257*G0_1_0_1_1 - 6.57778435556329e-06*G0_1_0_1_2 + 4.74540157079917e-06*G0_1_0_2_0 - 6.57778435556329e-06*G0_1_0_2_1 + 8.66858009715297e-05*G0_1_0_2_2 - 6.48381600762668e-06*G0_1_1_0_0 - 0.000179009702819257*G0_1_1_0_1 - 6.57778435556329e-06*G0_1_1_0_2 - 0.000179009702819257*G0_1_1_1_0 - 0.00212979260598344*G0_1_1_1_1 - 0.000220355775911369*G0_1_1_1_2 - 6.57778435556329e-06*G0_1_1_2_0 - 0.000220355775911369*G0_1_1_2_1 + 0.000305866972533691*G0_1_1_2_2 + 4.74540157079918e-06*G0_1_2_0_0 - 6.57778435556328e-06*G0_1_2_0_1 + 8.66858009715297e-05*G0_1_2_0_2 - 6.57778435556329e-06*G0_1_2_1_0 - 0.000220355775911369*G0_1_2_1_1 + 0.000305866972533691*G0_1_2_1_2 + 8.66858009715297e-05*G0_1_2_2_0 + 0.000305866972533691*G0_1_2_2_1 + 0.00143179571751025*G0_1_2_2_2 - 2.66870108139994e-05*G0_2_0_0_0 + 4.74540157079917e-06*G0_2_0_0_1 + 4.43060760521152e-05*G0_2_0_0_2 + 4.74540157079917e-06*G0_2_0_1_0 - 6.57778435556329e-06*G0_2_0_1_1 + 8.66858009715297e-05*G0_2_0_1_2 + 4.43060760521152e-05*G0_2_0_2_0 + 8.66858009715297e-05*G0_2_0_2_1 + 0.000471533169945947*G0_2_0_2_2 + 4.74540157079917e-06*G0_2_1_0_0 - 6.57778435556329e-06*G0_2_1_0_1 + 8.66858009715297e-05*G0_2_1_0_2 - 6.57778435556329e-06*G0_2_1_1_0 - 0.000220355775911369*G0_2_1_1_1 + 0.000305866972533691*G0_2_1_1_2 + 8.66858009715297e-05*G0_2_1_2_0 + 0.000305866972533691*G0_2_1_2_1 + 0.00143179571751025*G0_2_1_2_2 + 4.43060760521152e-05*G0_2_2_0_0 + 8.66858009715297e-05*G0_2_2_0_1 + 0.000471533169945947*G0_2_2_0_2 + 8.66858009715297e-05*G0_2_2_1_0 + 0.000305866972533691*G0_2_2_1_1 + 0.00143179571751025*G0_2_2_1_2 + 0.000471533169945947*G0_2_2_2_0 + 0.00143179571751025*G0_2_2_2_1 + 0.00739765819131023*G0_2_2_2_2; + A[65] = -A[80] + 2.76266942933655e-05*G0_0_0_0_0 + 8.0342937485808e-06*G0_0_0_0_1 + 6.43683183365829e-06*G0_0_0_0_2 + 8.0342937485808e-06*G0_0_0_1_0 - 6.20191096381676e-06*G0_0_0_1_1 + 4.74540157079919e-06*G0_0_0_1_2 + 6.43683183365829e-06*G0_0_0_2_0 + 4.74540157079919e-06*G0_0_0_2_1 + 1.71022393244644e-05*G0_0_0_2_2 + 8.0342937485808e-06*G0_0_1_0_0 - 6.20191096381677e-06*G0_0_1_0_1 + 4.74540157079919e-06*G0_0_1_0_2 - 6.20191096381677e-06*G0_0_1_1_0 - 5.77905339810198e-05*G0_0_1_1_1 + 6.10794261588015e-06*G0_0_1_1_2 + 4.74540157079918e-06*G0_0_1_2_0 + 6.10794261588015e-06*G0_0_1_2_1 + 5.32800532800621e-05*G0_0_1_2_2 + 6.43683183365829e-06*G0_0_2_0_0 + 4.74540157079919e-06*G0_0_2_0_1 + 1.71022393244644e-05*G0_0_2_0_2 + 4.74540157079919e-06*G0_0_2_1_0 + 6.10794261588015e-06*G0_0_2_1_1 + 5.32800532800621e-05*G0_0_2_1_2 + 1.71022393244644e-05*G0_0_2_2_0 + 5.32800532800621e-05*G0_0_2_2_1 + 0.000200622422844679*G0_0_2_2_2 + 8.0342937485808e-06*G0_1_0_0_0 - 6.20191096381677e-06*G0_1_0_0_1 + 4.74540157079919e-06*G0_1_0_0_2 - 6.20191096381676e-06*G0_1_0_1_0 - 5.77905339810198e-05*G0_1_0_1_1 + 6.10794261588015e-06*G0_1_0_1_2 + 4.74540157079918e-06*G0_1_0_2_0 + 6.10794261588015e-06*G0_1_0_2_1 + 5.32800532800621e-05*G0_1_0_2_2 - 6.20191096381677e-06*G0_1_1_0_0 - 5.77905339810199e-05*G0_1_1_0_1 + 6.10794261588015e-06*G0_1_1_0_2 - 5.77905339810199e-05*G0_1_1_1_0 - 0.000600457743314987*G0_1_1_1_1 + 1.36254104508095e-05*G0_1_1_1_2 + 6.10794261588015e-06*G0_1_1_2_0 + 1.36254104508096e-05*G0_1_1_2_1 + 0.000323626990293712*G0_1_1_2_2 + 4.74540157079919e-06*G0_1_2_0_0 + 6.10794261588015e-06*G0_1_2_0_1 + 5.32800532800621e-05*G0_1_2_0_2 + 6.10794261588015e-06*G0_1_2_1_0 + 1.36254104508096e-05*G0_1_2_1_1 + 0.000323626990293712*G0_1_2_1_2 + 5.32800532800621e-05*G0_1_2_2_0 + 0.000323626990293712*G0_1_2_2_1 + 0.00107546774213459*G0_1_2_2_2 + 6.43683183365829e-06*G0_2_0_0_0 + 4.74540157079918e-06*G0_2_0_0_1 + 1.71022393244644e-05*G0_2_0_0_2 + 4.74540157079918e-06*G0_2_0_1_0 + 6.10794261588015e-06*G0_2_0_1_1 + 5.32800532800621e-05*G0_2_0_1_2 + 1.71022393244644e-05*G0_2_0_2_0 + 5.32800532800621e-05*G0_2_0_2_1 + 0.000200622422844679*G0_2_0_2_2 + 4.74540157079918e-06*G0_2_1_0_0 + 6.10794261588015e-06*G0_2_1_0_1 + 5.32800532800621e-05*G0_2_1_0_2 + 6.10794261588015e-06*G0_2_1_1_0 + 1.36254104508096e-05*G0_2_1_1_1 + 0.000323626990293712*G0_2_1_1_2 + 5.32800532800621e-05*G0_2_1_2_0 + 0.000323626990293712*G0_2_1_2_1 + 0.00107546774213459*G0_2_1_2_2 + 1.71022393244644e-05*G0_2_2_0_0 + 5.32800532800621e-05*G0_2_2_0_1 + 0.000200622422844679*G0_2_2_0_2 + 5.32800532800621e-05*G0_2_2_1_0 + 0.000323626990293712*G0_2_2_1_1 + 0.00107546774213459*G0_2_2_1_2 + 0.000200622422844679*G0_2_2_2_0 + 0.00107546774213459*G0_2_2_2_1 + 0.0040979596535159*G0_2_2_2_2; + A[110] = A[65] - 0.000149691578263032*G0_0_0_0_0 - 2.49485963771719e-05*G0_0_0_0_1 - 2.26933560266931e-05*G0_0_0_0_2 - 2.49485963771719e-05*G0_0_0_1_0 + 2.4948596377172e-05*G0_0_0_1_1 - 2.26933560266931e-05*G0_0_0_2_0 + 1.97333530666907e-06*G0_0_0_2_2 - 2.49485963771719e-05*G0_0_1_0_0 + 2.4948596377172e-05*G0_0_1_0_1 + 2.4948596377172e-05*G0_0_1_1_0 + 0.000149691578263032*G0_0_1_1_1 + 2.26933560266932e-05*G0_0_1_1_2 + 2.26933560266932e-05*G0_0_1_2_1 - 1.9733353066689e-06*G0_0_1_2_2 - 2.26933560266931e-05*G0_0_2_0_0 + 1.97333530666907e-06*G0_0_2_0_2 + 2.26933560266932e-05*G0_0_2_1_1 - 1.9733353066689e-06*G0_0_2_1_2 + 1.97333530666906e-06*G0_0_2_2_0 - 1.9733353066689e-06*G0_0_2_2_1 - 2.49485963771719e-05*G0_1_0_0_0 + 2.4948596377172e-05*G0_1_0_0_1 + 2.4948596377172e-05*G0_1_0_1_0 + 0.000149691578263032*G0_1_0_1_1 + 2.26933560266932e-05*G0_1_0_1_2 + 2.26933560266932e-05*G0_1_0_2_1 - 1.97333530666889e-06*G0_1_0_2_2 + 2.4948596377172e-05*G0_1_1_0_0 + 0.000149691578263032*G0_1_1_0_1 + 2.26933560266932e-05*G0_1_1_0_2 + 0.000149691578263032*G0_1_1_1_0 + 0.0012474298188586*G0_1_1_1_1 + 0.000181546848213546*G0_1_1_1_2 + 2.26933560266932e-05*G0_1_1_2_0 + 0.000181546848213546*G0_1_1_2_1 - 1.77600177600205e-05*G0_1_1_2_2 + 2.26933560266932e-05*G0_1_2_0_1 - 1.9733353066689e-06*G0_1_2_0_2 + 2.26933560266932e-05*G0_1_2_1_0 + 0.000181546848213546*G0_1_2_1_1 - 1.77600177600205e-05*G0_1_2_1_2 - 1.9733353066689e-06*G0_1_2_2_0 - 1.77600177600204e-05*G0_1_2_2_1 - 5.92000592000682e-05*G0_1_2_2_2 - 2.26933560266931e-05*G0_2_0_0_0 + 1.97333530666906e-06*G0_2_0_0_2 + 2.26933560266932e-05*G0_2_0_1_1 - 1.9733353066689e-06*G0_2_0_1_2 + 1.97333530666905e-06*G0_2_0_2_0 - 1.9733353066689e-06*G0_2_0_2_1 + 2.26933560266932e-05*G0_2_1_0_1 - 1.9733353066689e-06*G0_2_1_0_2 + 2.26933560266932e-05*G0_2_1_1_0 + 0.000181546848213546*G0_2_1_1_1 - 1.77600177600205e-05*G0_2_1_1_2 - 1.9733353066689e-06*G0_2_1_2_0 - 1.77600177600204e-05*G0_2_1_2_1 - 5.92000592000682e-05*G0_2_1_2_2 + 1.97333530666906e-06*G0_2_2_0_0 - 1.97333530666889e-06*G0_2_2_0_1 - 1.9733353066689e-06*G0_2_2_1_0 - 1.77600177600205e-05*G0_2_2_1_1 - 5.92000592000682e-05*G0_2_2_1_2 - 5.92000592000682e-05*G0_2_2_2_1 + 0.000522933856267284*G0_2_2_2_2; + A[125] = -A[110] - 5.77905339810197e-05*G0_0_0_0_0 - 6.20191096381674e-06*G0_0_0_0_1 + 6.10794261588017e-06*G0_0_0_0_2 - 6.20191096381673e-06*G0_0_0_1_0 + 8.03429374858084e-06*G0_0_0_1_1 + 4.7454015707992e-06*G0_0_0_1_2 + 6.10794261588017e-06*G0_0_0_2_0 + 4.74540157079921e-06*G0_0_0_2_1 + 5.32800532800623e-05*G0_0_0_2_2 - 6.20191096381672e-06*G0_0_1_0_0 + 8.03429374858085e-06*G0_0_1_0_1 + 4.74540157079921e-06*G0_0_1_0_2 + 8.03429374858085e-06*G0_0_1_1_0 + 2.76266942933657e-05*G0_0_1_1_1 + 6.43683183365833e-06*G0_0_1_1_2 + 4.7454015707992e-06*G0_0_1_2_0 + 6.43683183365833e-06*G0_0_1_2_1 + 1.71022393244644e-05*G0_0_1_2_2 + 6.10794261588017e-06*G0_0_2_0_0 + 4.74540157079921e-06*G0_0_2_0_1 + 5.32800532800623e-05*G0_0_2_0_2 + 4.7454015707992e-06*G0_0_2_1_0 + 6.43683183365833e-06*G0_0_2_1_1 + 1.71022393244644e-05*G0_0_2_1_2 + 5.32800532800623e-05*G0_0_2_2_0 + 1.71022393244644e-05*G0_0_2_2_1 + 0.000200622422844679*G0_0_2_2_2 - 6.20191096381673e-06*G0_1_0_0_0 + 8.03429374858084e-06*G0_1_0_0_1 + 4.7454015707992e-06*G0_1_0_0_2 + 8.03429374858085e-06*G0_1_0_1_0 + 2.76266942933656e-05*G0_1_0_1_1 + 6.43683183365833e-06*G0_1_0_1_2 + 4.74540157079921e-06*G0_1_0_2_0 + 6.43683183365833e-06*G0_1_0_2_1 + 1.71022393244645e-05*G0_1_0_2_2 + 8.03429374858085e-06*G0_1_1_0_0 + 2.76266942933656e-05*G0_1_1_0_1 + 6.43683183365833e-06*G0_1_1_0_2 + 2.76266942933656e-05*G0_1_1_1_0 + 0.000111352492304893*G0_1_1_1_1 + 1.6256524193035e-05*G0_1_1_1_2 + 6.43683183365833e-06*G0_1_1_2_0 + 1.6256524193035e-05*G0_1_1_2_1 - 1.97333530666885e-06*G0_1_1_2_2 + 4.7454015707992e-06*G0_1_2_0_0 + 6.43683183365833e-06*G0_1_2_0_1 + 1.71022393244645e-05*G0_1_2_0_2 + 6.43683183365832e-06*G0_1_2_1_0 + 1.6256524193035e-05*G0_1_2_1_1 - 1.97333530666885e-06*G0_1_2_1_2 + 1.71022393244645e-05*G0_1_2_2_0 - 1.97333530666884e-06*G0_1_2_2_1 + 4.27555983111615e-05*G0_1_2_2_2 + 6.10794261588017e-06*G0_2_0_0_0 + 4.74540157079921e-06*G0_2_0_0_1 + 5.32800532800623e-05*G0_2_0_0_2 + 4.7454015707992e-06*G0_2_0_1_0 + 6.43683183365832e-06*G0_2_0_1_1 + 1.71022393244645e-05*G0_2_0_1_2 + 5.32800532800623e-05*G0_2_0_2_0 + 1.71022393244645e-05*G0_2_0_2_1 + 0.000200622422844679*G0_2_0_2_2 + 4.7454015707992e-06*G0_2_1_0_0 + 6.43683183365833e-06*G0_2_1_0_1 + 1.71022393244645e-05*G0_2_1_0_2 + 6.43683183365833e-06*G0_2_1_1_0 + 1.6256524193035e-05*G0_2_1_1_1 - 1.97333530666885e-06*G0_2_1_1_2 + 1.71022393244645e-05*G0_2_1_2_0 - 1.97333530666884e-06*G0_2_1_2_1 + 4.27555983111615e-05*G0_2_1_2_2 + 5.32800532800623e-05*G0_2_2_0_0 + 1.71022393244645e-05*G0_2_2_0_1 + 0.000200622422844679*G0_2_2_0_2 + 1.71022393244645e-05*G0_2_2_1_0 - 1.97333530666884e-06*G0_2_2_1_1 + 4.27555983111615e-05*G0_2_2_1_2 + 0.000200622422844679*G0_2_2_2_0 + 4.27555983111615e-05*G0_2_2_2_1 + 0.000924178701956638*G0_2_2_2_2; + A[83] = A[125]; + A[89] = A[110] - 4.22857565714801e-06*G0_0_0_0_0 - 5.24343381486327e-05*G0_0_0_0_1 + 2.50895488990768e-05*G0_0_0_0_2 - 5.24343381486327e-05*G0_0_0_1_0 - 7.73829345258047e-05*G0_0_0_1_1 + 7.47048366096105e-06*G0_0_0_1_2 + 2.50895488990768e-05*G0_0_0_2_0 + 7.47048366096104e-06*G0_0_0_2_1 + 0.000159840159840186*G0_0_0_2_2 - 5.24343381486327e-05*G0_0_1_0_0 - 7.73829345258047e-05*G0_0_1_0_1 + 7.47048366096105e-06*G0_0_1_0_2 - 7.73829345258047e-05*G0_0_1_1_0 - 0.00015392015392018*G0_0_1_1_1 + 2.39619287238369e-06*G0_0_1_1_2 + 7.47048366096105e-06*G0_0_1_2_0 + 2.39619287238369e-06*G0_0_1_2_1 + 0.000161813495146855*G0_0_1_2_2 + 2.50895488990768e-05*G0_0_2_0_0 + 7.47048366096105e-06*G0_0_2_0_1 + 0.000159840159840186*G0_0_2_0_2 + 7.47048366096105e-06*G0_0_2_1_0 + 2.39619287238369e-06*G0_0_2_1_1 + 0.000161813495146855*G0_0_2_1_2 + 0.000159840159840186*G0_0_2_2_0 + 0.000161813495146855*G0_0_2_2_1 + 0.00091760091760107*G0_0_2_2_2 - 5.24343381486327e-05*G0_1_0_0_0 - 7.73829345258047e-05*G0_1_0_0_1 + 7.47048366096105e-06*G0_1_0_0_2 - 7.73829345258047e-05*G0_1_0_1_0 - 0.00015392015392018*G0_1_0_1_1 + 2.39619287238369e-06*G0_1_0_1_2 + 7.47048366096105e-06*G0_1_0_2_0 + 2.39619287238369e-06*G0_1_0_2_1 + 0.000161813495146855*G0_1_0_2_2 - 7.73829345258047e-05*G0_1_1_0_0 - 0.00015392015392018*G0_1_1_0_1 + 2.39619287238369e-06*G0_1_1_0_2 - 0.00015392015392018*G0_1_1_1_0 - 0.000511657654514884*G0_1_1_1_1 - 5.3561958323874e-06*G0_1_1_1_2 + 2.39619287238369e-06*G0_1_1_2_0 - 5.35619583238739e-06*G0_1_1_2_1 + 0.00032560032560038*G0_1_1_2_2 + 7.47048366096105e-06*G0_1_2_0_0 + 2.39619287238369e-06*G0_1_2_0_1 + 0.000161813495146855*G0_1_2_0_2 + 2.3961928723837e-06*G0_1_2_1_0 - 5.35619583238737e-06*G0_1_2_1_1 + 0.00032560032560038*G0_1_2_1_2 + 0.000161813495146855*G0_1_2_2_0 + 0.00032560032560038*G0_1_2_2_1 + 0.00139120139120162*G0_1_2_2_2 + 2.50895488990768e-05*G0_2_0_0_0 + 7.47048366096105e-06*G0_2_0_0_1 + 0.000159840159840186*G0_2_0_0_2 + 7.47048366096105e-06*G0_2_0_1_0 + 2.39619287238369e-06*G0_2_0_1_1 + 0.000161813495146855*G0_2_0_1_2 + 0.000159840159840186*G0_2_0_2_0 + 0.000161813495146855*G0_2_0_2_1 + 0.00091760091760107*G0_2_0_2_2 + 7.47048366096105e-06*G0_2_1_0_0 + 2.39619287238369e-06*G0_2_1_0_1 + 0.000161813495146855*G0_2_1_0_2 + 2.3961928723837e-06*G0_2_1_1_0 - 5.35619583238738e-06*G0_2_1_1_1 + 0.00032560032560038*G0_2_1_1_2 + 0.000161813495146855*G0_2_1_2_0 + 0.00032560032560038*G0_2_1_2_1 + 0.00139120139120162*G0_2_1_2_2 + 0.000159840159840186*G0_2_2_0_0 + 0.000161813495146855*G0_2_2_0_1 + 0.00091760091760107*G0_2_2_0_2 + 0.000161813495146855*G0_2_2_1_0 + 0.00032560032560038*G0_2_2_1_1 + 0.00139120139120162*G0_2_2_1_2 + 0.00091760091760107*G0_2_2_2_0 + 0.00139120139120162*G0_2_2_2_1 + 0.00727174060507515*G0_2_2_2_2; + A[218] = A[89] - 0.000338286052571823*G0_0_0_0_0 - 6.76572105143646e-05*G0_0_0_0_1 - 2.02971631543094e-05*G0_0_0_0_2 - 6.76572105143646e-05*G0_0_0_1_0 - 3.38286052571823e-06*G0_0_0_1_2 - 2.02971631543094e-05*G0_0_0_2_0 - 3.38286052571824e-06*G0_0_0_2_1 + 0.000110506777173462*G0_0_0_2_2 - 6.76572105143646e-05*G0_0_1_0_0 - 3.38286052571823e-06*G0_0_1_0_2 + 6.76572105143648e-05*G0_0_1_1_1 + 3.38286052571824e-06*G0_0_1_1_2 - 3.38286052571823e-06*G0_0_1_2_0 + 3.38286052571824e-06*G0_0_1_2_1 - 2.02971631543094e-05*G0_0_2_0_0 - 3.38286052571824e-06*G0_0_2_0_1 + 0.000110506777173462*G0_0_2_0_2 - 3.38286052571823e-06*G0_0_2_1_0 + 3.38286052571824e-06*G0_0_2_1_1 + 0.000110506777173462*G0_0_2_2_0 + 0.000315733649067035*G0_0_2_2_2 - 6.76572105143646e-05*G0_1_0_0_0 - 3.38286052571822e-06*G0_1_0_0_2 + 6.76572105143648e-05*G0_1_0_1_1 + 3.38286052571825e-06*G0_1_0_1_2 - 3.38286052571823e-06*G0_1_0_2_0 + 3.38286052571825e-06*G0_1_0_2_1 + 6.76572105143648e-05*G0_1_1_0_1 + 3.38286052571824e-06*G0_1_1_0_2 + 6.76572105143648e-05*G0_1_1_1_0 + 0.000338286052571824*G0_1_1_1_1 + 2.02971631543095e-05*G0_1_1_1_2 + 3.38286052571824e-06*G0_1_1_2_0 + 2.02971631543095e-05*G0_1_1_2_1 - 0.000110506777173462*G0_1_1_2_2 - 3.38286052571823e-06*G0_1_2_0_0 + 3.38286052571824e-06*G0_1_2_0_1 + 3.38286052571824e-06*G0_1_2_1_0 + 2.02971631543095e-05*G0_1_2_1_1 - 0.000110506777173462*G0_1_2_1_2 - 0.000110506777173462*G0_1_2_2_1 - 0.000315733649067035*G0_1_2_2_2 - 2.02971631543094e-05*G0_2_0_0_0 - 3.38286052571824e-06*G0_2_0_0_1 + 0.000110506777173462*G0_2_0_0_2 - 3.38286052571823e-06*G0_2_0_1_0 + 3.38286052571824e-06*G0_2_0_1_1 + 0.000110506777173462*G0_2_0_2_0 + 0.000315733649067035*G0_2_0_2_2 - 3.38286052571824e-06*G0_2_1_0_0 + 3.38286052571824e-06*G0_2_1_0_1 + 3.38286052571824e-06*G0_2_1_1_0 + 2.02971631543095e-05*G0_2_1_1_1 - 0.000110506777173462*G0_2_1_1_2 - 0.000110506777173462*G0_2_1_2_1 - 0.000315733649067035*G0_2_1_2_2 + 0.000110506777173462*G0_2_2_0_0 + 0.000315733649067035*G0_2_2_0_2 - 0.000110506777173462*G0_2_2_1_1 - 0.000315733649067035*G0_2_2_1_2 + 0.000315733649067035*G0_2_2_2_0 - 0.000315733649067035*G0_2_2_2_1; + A[215] = A[89]; + A[198] = A[153] - 4.22857565714828e-06*G0_0_0_0_0 + 2.50895488990768e-05*G0_0_0_0_1 - 5.24343381486326e-05*G0_0_0_0_2 + 2.50895488990768e-05*G0_0_0_1_0 + 0.000159840159840187*G0_0_0_1_1 + 7.47048366096108e-06*G0_0_0_1_2 - 5.24343381486326e-05*G0_0_0_2_0 + 7.47048366096108e-06*G0_0_0_2_1 - 7.73829345258046e-05*G0_0_0_2_2 + 2.50895488990768e-05*G0_0_1_0_0 + 0.000159840159840187*G0_0_1_0_1 + 7.47048366096108e-06*G0_0_1_0_2 + 0.000159840159840187*G0_0_1_1_0 + 0.000917600917601072*G0_0_1_1_1 + 0.000161813495146856*G0_0_1_1_2 + 7.47048366096108e-06*G0_0_1_2_0 + 0.000161813495146856*G0_0_1_2_1 + 2.39619287238375e-06*G0_0_1_2_2 - 5.24343381486326e-05*G0_0_2_0_0 + 7.47048366096109e-06*G0_0_2_0_1 - 7.73829345258046e-05*G0_0_2_0_2 + 7.47048366096108e-06*G0_0_2_1_0 + 0.000161813495146856*G0_0_2_1_1 + 2.39619287238374e-06*G0_0_2_1_2 - 7.73829345258046e-05*G0_0_2_2_0 + 2.39619287238375e-06*G0_0_2_2_1 - 0.00015392015392018*G0_0_2_2_2 + 2.50895488990768e-05*G0_1_0_0_0 + 0.000159840159840187*G0_1_0_0_1 + 7.47048366096108e-06*G0_1_0_0_2 + 0.000159840159840187*G0_1_0_1_0 + 0.000917600917601072*G0_1_0_1_1 + 0.000161813495146856*G0_1_0_1_2 + 7.47048366096109e-06*G0_1_0_2_0 + 0.000161813495146856*G0_1_0_2_1 + 2.39619287238375e-06*G0_1_0_2_2 + 0.000159840159840187*G0_1_1_0_0 + 0.000917600917601072*G0_1_1_0_1 + 0.000161813495146856*G0_1_1_0_2 + 0.000917600917601072*G0_1_1_1_0 + 0.00727174060507517*G0_1_1_1_1 + 0.00139120139120163*G0_1_1_1_2 + 0.000161813495146856*G0_1_1_2_0 + 0.00139120139120163*G0_1_1_2_1 + 0.000325600325600381*G0_1_1_2_2 + 7.47048366096108e-06*G0_1_2_0_0 + 0.000161813495146856*G0_1_2_0_1 + 2.39619287238374e-06*G0_1_2_0_2 + 0.000161813495146856*G0_1_2_1_0 + 0.00139120139120163*G0_1_2_1_1 + 0.000325600325600381*G0_1_2_1_2 + 2.39619287238375e-06*G0_1_2_2_0 + 0.000325600325600381*G0_1_2_2_1 - 5.35619583238698e-06*G0_1_2_2_2 - 5.24343381486326e-05*G0_2_0_0_0 + 7.47048366096108e-06*G0_2_0_0_1 - 7.73829345258046e-05*G0_2_0_0_2 + 7.47048366096108e-06*G0_2_0_1_0 + 0.000161813495146856*G0_2_0_1_1 + 2.39619287238376e-06*G0_2_0_1_2 - 7.73829345258046e-05*G0_2_0_2_0 + 2.39619287238376e-06*G0_2_0_2_1 - 0.00015392015392018*G0_2_0_2_2 + 7.47048366096108e-06*G0_2_1_0_0 + 0.000161813495146856*G0_2_1_0_1 + 2.39619287238374e-06*G0_2_1_0_2 + 0.000161813495146856*G0_2_1_1_0 + 0.00139120139120163*G0_2_1_1_1 + 0.000325600325600381*G0_2_1_1_2 + 2.39619287238375e-06*G0_2_1_2_0 + 0.000325600325600381*G0_2_1_2_1 - 5.35619583238699e-06*G0_2_1_2_2 - 7.73829345258046e-05*G0_2_2_0_0 + 2.39619287238375e-06*G0_2_2_0_1 - 0.00015392015392018*G0_2_2_0_2 + 2.39619287238375e-06*G0_2_2_1_0 + 0.000325600325600381*G0_2_2_1_1 - 5.35619583238702e-06*G0_2_2_1_2 - 0.00015392015392018*G0_2_2_2_0 - 5.35619583238703e-06*G0_2_2_2_1 - 0.000511657654514883*G0_2_2_2_2; + A[79] = A[65]; + A[71] = A[169]; + A[82] = A[110]; + A[168] = A[56]; + A[184] = A[72]; + A[68] = -A[125] + 0.000111352492304892*G0_0_0_0_0 + 2.76266942933655e-05*G0_0_0_0_1 + 1.62565241930348e-05*G0_0_0_0_2 + 2.76266942933655e-05*G0_0_0_1_0 + 8.0342937485808e-06*G0_0_0_1_1 + 6.4368318336583e-06*G0_0_0_1_2 + 1.62565241930348e-05*G0_0_0_2_0 + 6.4368318336583e-06*G0_0_0_2_1 - 1.97333530666898e-06*G0_0_0_2_2 + 2.76266942933655e-05*G0_0_1_0_0 + 8.0342937485808e-06*G0_0_1_0_1 + 6.4368318336583e-06*G0_0_1_0_2 + 8.03429374858081e-06*G0_0_1_1_0 - 6.20191096381676e-06*G0_0_1_1_1 + 4.74540157079919e-06*G0_0_1_1_2 + 6.4368318336583e-06*G0_0_1_2_0 + 4.74540157079919e-06*G0_0_1_2_1 + 1.71022393244644e-05*G0_0_1_2_2 + 1.62565241930348e-05*G0_0_2_0_0 + 6.4368318336583e-06*G0_0_2_0_1 - 1.97333530666896e-06*G0_0_2_0_2 + 6.4368318336583e-06*G0_0_2_1_0 + 4.74540157079919e-06*G0_0_2_1_1 + 1.71022393244644e-05*G0_0_2_1_2 - 1.97333530666898e-06*G0_0_2_2_0 + 1.71022393244644e-05*G0_0_2_2_1 + 4.2755598311161e-05*G0_0_2_2_2 + 2.76266942933655e-05*G0_1_0_0_0 + 8.0342937485808e-06*G0_1_0_0_1 + 6.4368318336583e-06*G0_1_0_0_2 + 8.03429374858081e-06*G0_1_0_1_0 - 6.20191096381677e-06*G0_1_0_1_1 + 4.74540157079919e-06*G0_1_0_1_2 + 6.4368318336583e-06*G0_1_0_2_0 + 4.74540157079919e-06*G0_1_0_2_1 + 1.71022393244644e-05*G0_1_0_2_2 + 8.0342937485808e-06*G0_1_1_0_0 - 6.20191096381677e-06*G0_1_1_0_1 + 4.74540157079919e-06*G0_1_1_0_2 - 6.20191096381676e-06*G0_1_1_1_0 - 5.77905339810197e-05*G0_1_1_1_1 + 6.10794261588019e-06*G0_1_1_1_2 + 4.74540157079919e-06*G0_1_1_2_0 + 6.10794261588019e-06*G0_1_1_2_1 + 5.32800532800622e-05*G0_1_1_2_2 + 6.4368318336583e-06*G0_1_2_0_0 + 4.74540157079919e-06*G0_1_2_0_1 + 1.71022393244644e-05*G0_1_2_0_2 + 4.74540157079919e-06*G0_1_2_1_0 + 6.10794261588019e-06*G0_1_2_1_1 + 5.32800532800622e-05*G0_1_2_1_2 + 1.71022393244644e-05*G0_1_2_2_0 + 5.32800532800622e-05*G0_1_2_2_1 + 0.000200622422844679*G0_1_2_2_2 + 1.62565241930348e-05*G0_2_0_0_0 + 6.4368318336583e-06*G0_2_0_0_1 - 1.97333530666895e-06*G0_2_0_0_2 + 6.4368318336583e-06*G0_2_0_1_0 + 4.74540157079919e-06*G0_2_0_1_1 + 1.71022393244644e-05*G0_2_0_1_2 - 1.97333530666898e-06*G0_2_0_2_0 + 1.71022393244644e-05*G0_2_0_2_1 + 4.2755598311161e-05*G0_2_0_2_2 + 6.4368318336583e-06*G0_2_1_0_0 + 4.74540157079919e-06*G0_2_1_0_1 + 1.71022393244644e-05*G0_2_1_0_2 + 4.7454015707992e-06*G0_2_1_1_0 + 6.10794261588019e-06*G0_2_1_1_1 + 5.32800532800622e-05*G0_2_1_1_2 + 1.71022393244644e-05*G0_2_1_2_0 + 5.32800532800622e-05*G0_2_1_2_1 + 0.000200622422844679*G0_2_1_2_2 - 1.97333530666894e-06*G0_2_2_0_0 + 1.71022393244644e-05*G0_2_2_0_1 + 4.27555983111611e-05*G0_2_2_0_2 + 1.71022393244644e-05*G0_2_2_1_0 + 5.32800532800622e-05*G0_2_2_1_1 + 0.000200622422844679*G0_2_2_1_2 + 4.27555983111611e-05*G0_2_2_2_0 + 0.000200622422844679*G0_2_2_2_1 + 0.000924178701956634*G0_2_2_2_2; + A[189] = A[186] + 0.000315733649067035*G0_0_0_0_1 - 0.000315733649067035*G0_0_0_0_2 + 0.000315733649067035*G0_0_0_1_0 + 0.000110506777173462*G0_0_0_1_1 - 0.000315733649067035*G0_0_0_2_0 - 0.000110506777173462*G0_0_0_2_2 + 0.000315733649067035*G0_0_1_0_0 + 0.000110506777173462*G0_0_1_0_1 + 0.000110506777173462*G0_0_1_1_0 - 2.02971631543096e-05*G0_0_1_1_1 - 3.38286052571828e-06*G0_0_1_1_2 - 3.38286052571828e-06*G0_0_1_2_1 + 3.38286052571821e-06*G0_0_1_2_2 - 0.000315733649067035*G0_0_2_0_0 - 0.000110506777173462*G0_0_2_0_2 - 3.38286052571829e-06*G0_0_2_1_1 + 3.38286052571822e-06*G0_0_2_1_2 - 0.000110506777173462*G0_0_2_2_0 + 3.38286052571821e-06*G0_0_2_2_1 + 2.02971631543094e-05*G0_0_2_2_2 + 0.000315733649067035*G0_1_0_0_0 + 0.000110506777173462*G0_1_0_0_1 + 0.000110506777173462*G0_1_0_1_0 - 2.02971631543096e-05*G0_1_0_1_1 - 3.38286052571829e-06*G0_1_0_1_2 - 3.38286052571829e-06*G0_1_0_2_1 + 3.38286052571821e-06*G0_1_0_2_2 + 0.000110506777173462*G0_1_1_0_0 - 2.02971631543096e-05*G0_1_1_0_1 - 3.38286052571829e-06*G0_1_1_0_2 - 2.02971631543096e-05*G0_1_1_1_0 - 0.000338286052571825*G0_1_1_1_1 - 6.76572105143649e-05*G0_1_1_1_2 - 3.3828605257183e-06*G0_1_1_2_0 - 6.76572105143649e-05*G0_1_1_2_1 - 3.3828605257183e-06*G0_1_2_0_1 + 3.38286052571821e-06*G0_1_2_0_2 - 3.3828605257183e-06*G0_1_2_1_0 - 6.76572105143649e-05*G0_1_2_1_1 + 3.3828605257182e-06*G0_1_2_2_0 + 6.76572105143647e-05*G0_1_2_2_2 - 0.000315733649067036*G0_2_0_0_0 - 0.000110506777173462*G0_2_0_0_2 - 3.38286052571829e-06*G0_2_0_1_1 + 3.38286052571821e-06*G0_2_0_1_2 - 0.000110506777173462*G0_2_0_2_0 + 3.3828605257182e-06*G0_2_0_2_1 + 2.02971631543094e-05*G0_2_0_2_2 - 3.38286052571829e-06*G0_2_1_0_1 + 3.3828605257182e-06*G0_2_1_0_2 - 3.38286052571829e-06*G0_2_1_1_0 - 6.76572105143649e-05*G0_2_1_1_1 + 3.38286052571821e-06*G0_2_1_2_0 + 6.76572105143647e-05*G0_2_1_2_2 - 0.000110506777173462*G0_2_2_0_0 + 3.3828605257182e-06*G0_2_2_0_1 + 2.02971631543094e-05*G0_2_2_0_2 + 3.38286052571821e-06*G0_2_2_1_0 + 6.76572105143647e-05*G0_2_2_1_2 + 2.02971631543094e-05*G0_2_2_2_0 + 6.76572105143647e-05*G0_2_2_2_1 + 0.000338286052571824*G0_2_2_2_2; + A[55] = A[153]; + A[178] = A[198] - 0.000338286052571824*G0_0_0_0_0 - 2.02971631543094e-05*G0_0_0_0_1 - 6.76572105143648e-05*G0_0_0_0_2 - 2.02971631543094e-05*G0_0_0_1_0 + 0.000110506777173462*G0_0_0_1_1 - 3.38286052571826e-06*G0_0_0_1_2 - 6.76572105143648e-05*G0_0_0_2_0 - 3.38286052571825e-06*G0_0_0_2_1 - 2.02971631543094e-05*G0_0_1_0_0 + 0.000110506777173462*G0_0_1_0_1 - 3.38286052571825e-06*G0_0_1_0_2 + 0.000110506777173462*G0_0_1_1_0 + 0.000315733649067035*G0_0_1_1_1 - 3.38286052571825e-06*G0_0_1_2_0 + 3.38286052571821e-06*G0_0_1_2_2 - 6.76572105143647e-05*G0_0_2_0_0 - 3.38286052571826e-06*G0_0_2_0_1 - 3.38286052571826e-06*G0_0_2_1_0 + 3.38286052571822e-06*G0_0_2_1_2 + 3.38286052571821e-06*G0_0_2_2_1 + 6.76572105143645e-05*G0_0_2_2_2 - 2.02971631543094e-05*G0_1_0_0_0 + 0.000110506777173462*G0_1_0_0_1 - 3.38286052571826e-06*G0_1_0_0_2 + 0.000110506777173462*G0_1_0_1_0 + 0.000315733649067035*G0_1_0_1_1 - 3.38286052571826e-06*G0_1_0_2_0 + 3.3828605257182e-06*G0_1_0_2_2 + 0.000110506777173462*G0_1_1_0_0 + 0.000315733649067035*G0_1_1_0_1 + 0.000315733649067035*G0_1_1_1_0 - 0.000315733649067037*G0_1_1_1_2 - 0.000315733649067037*G0_1_1_2_1 - 0.000110506777173463*G0_1_1_2_2 - 3.38286052571826e-06*G0_1_2_0_0 + 3.38286052571822e-06*G0_1_2_0_2 - 0.000315733649067037*G0_1_2_1_1 - 0.000110506777173463*G0_1_2_1_2 + 3.38286052571822e-06*G0_1_2_2_0 - 0.000110506777173463*G0_1_2_2_1 + 2.02971631543092e-05*G0_1_2_2_2 - 6.76572105143648e-05*G0_2_0_0_0 - 3.38286052571826e-06*G0_2_0_0_1 - 3.38286052571826e-06*G0_2_0_1_0 + 3.38286052571821e-06*G0_2_0_1_2 + 3.38286052571821e-06*G0_2_0_2_1 + 6.76572105143646e-05*G0_2_0_2_2 - 3.38286052571826e-06*G0_2_1_0_0 + 3.38286052571822e-06*G0_2_1_0_2 - 0.000315733649067037*G0_2_1_1_1 - 0.000110506777173463*G0_2_1_1_2 + 3.38286052571822e-06*G0_2_1_2_0 - 0.000110506777173463*G0_2_1_2_1 + 2.02971631543093e-05*G0_2_1_2_2 + 3.38286052571822e-06*G0_2_2_0_1 + 6.76572105143645e-05*G0_2_2_0_2 + 3.38286052571822e-06*G0_2_2_1_0 - 0.000110506777173463*G0_2_2_1_1 + 2.02971631543093e-05*G0_2_2_1_2 + 6.76572105143645e-05*G0_2_2_2_0 + 2.02971631543093e-05*G0_2_2_2_1 + 0.000338286052571823*G0_2_2_2_2; + A[220] = A[164]; + A[54] = A[138]; + A[33] = A[47]; + A[24] = -A[165] + 0.000171022393244644*G0_0_0_0_0 + 1.50349356698585e-06*G0_0_0_0_1 - 1.51523961047796e-05*G0_0_0_0_2 + 1.50349356698585e-06*G0_0_0_1_0 - 1.51523961047796e-05*G0_0_0_2_0 + 1.50349356698584e-06*G0_0_1_0_0 + 1.50349356698597e-06*G0_0_1_1_1 - 1.51523961047796e-05*G0_0_2_0_0 + 1.50349356698585e-06*G0_1_0_0_0 + 1.50349356698596e-06*G0_1_0_1_1 + 1.50349356698596e-06*G0_1_1_0_1 + 1.50349356698595e-06*G0_1_1_1_0 + 0.000171022393244646*G0_1_1_1_1 - 1.51523961047796e-05*G0_1_1_1_2 - 1.51523961047796e-05*G0_1_1_2_1 - 1.51523961047796e-05*G0_1_2_1_1 - 1.51523961047796e-05*G0_2_0_0_0 - 1.51523961047796e-05*G0_2_1_1_1; + A[127] = A[113]; + A[62] = A[76] + 1.32730291460472e-05*G0_0_0_1_1 + 1.32730291460472e-05*G0_0_1_0_1 + 1.32730291460472e-05*G0_0_1_1_0 + 2.20825617651051e-05*G0_0_1_1_1 - 5.60873576746685e-06*G0_0_2_2_2 + 1.32730291460472e-05*G0_1_0_0_1 + 1.32730291460472e-05*G0_1_0_1_0 + 2.20825617651051e-05*G0_1_0_1_1 + 1.32730291460472e-05*G0_1_1_0_0 + 2.20825617651051e-05*G0_1_1_0_1 + 2.20825617651051e-05*G0_1_1_1_0 - 0.000222704984609785*G0_1_1_1_1 + 5.01556057111692e-06*G0_1_1_1_2 + 5.01556057111692e-06*G0_1_1_2_1 + 5.01556057111692e-06*G0_1_2_1_1 - 4.54924264448151e-05*G0_1_2_2_2 - 5.60873576746685e-06*G0_2_0_2_2 + 5.01556057111693e-06*G0_2_1_1_1 - 4.54924264448151e-05*G0_2_1_2_2 - 5.60873576746685e-06*G0_2_2_0_2 - 4.54924264448151e-05*G0_2_2_1_2 - 5.60873576746686e-06*G0_2_2_2_0 - 4.54924264448151e-05*G0_2_2_2_1 - 0.000767956323512007*G0_2_2_2_2; + A[44] = A[212]; + A[141] = A[99]; + A[95] = A[123] + 0.000112762017523941*G0_0_0_0_0 + 2.25524035047883e-05*G0_0_0_0_1 + 6.76572105143654e-06*G0_0_0_0_2 + 2.25524035047883e-05*G0_0_0_1_0 + 6.76572105143655e-06*G0_0_0_2_0 - 3.6835592391154e-05*G0_0_0_2_2 + 2.25524035047883e-05*G0_0_1_0_0 - 2.25524035047882e-05*G0_0_1_1_1 + 6.76572105143655e-06*G0_0_2_0_0 - 3.6835592391154e-05*G0_0_2_0_2 - 3.6835592391154e-05*G0_0_2_2_0 - 0.000105244549689012*G0_0_2_2_2 + 2.25524035047883e-05*G0_1_0_0_0 - 2.25524035047882e-05*G0_1_0_1_1 - 2.25524035047882e-05*G0_1_1_0_1 - 2.25524035047882e-05*G0_1_1_1_0 - 0.000112762017523942*G0_1_1_1_1 - 6.76572105143656e-06*G0_1_1_1_2 - 6.76572105143655e-06*G0_1_1_2_1 + 3.68355923911541e-05*G0_1_1_2_2 - 6.76572105143656e-06*G0_1_2_1_1 + 3.68355923911541e-05*G0_1_2_1_2 + 3.68355923911541e-05*G0_1_2_2_1 + 0.000105244549689012*G0_1_2_2_2 + 6.76572105143655e-06*G0_2_0_0_0 - 3.6835592391154e-05*G0_2_0_0_2 - 3.6835592391154e-05*G0_2_0_2_0 - 0.000105244549689012*G0_2_0_2_2 - 6.76572105143656e-06*G0_2_1_1_1 + 3.68355923911541e-05*G0_2_1_1_2 + 3.68355923911541e-05*G0_2_1_2_1 + 0.000105244549689012*G0_2_1_2_2 - 3.6835592391154e-05*G0_2_2_0_0 - 0.000105244549689012*G0_2_2_0_2 + 3.68355923911541e-05*G0_2_2_1_1 + 0.000105244549689012*G0_2_2_1_2 - 0.000105244549689012*G0_2_2_2_0 + 0.000105244549689012*G0_2_2_2_1; + A[78] = A[50]; + A[172] = A[116]; + A[155] = A[85]; + A[105] = A[7]; + A[98] = A[126]; + A[180] = A[12]; + A[173] = -A[41] + 0.00027544471988921*G0_0_0_0_0 + 2.32101819403445e-05*G0_0_0_0_1 + 2.61232007263796e-05*G0_0_0_0_2 + 2.32101819403445e-05*G0_0_0_1_0 + 2.36095474190749e-06*G0_0_0_1_1 + 2.61232007263796e-05*G0_0_0_2_0 + 1.55635076270023e-05*G0_0_0_2_2 + 2.32101819403445e-05*G0_0_1_0_0 + 2.36095474190749e-06*G0_0_1_0_1 + 2.36095474190749e-06*G0_0_1_1_0 + 3.38286052571812e-06*G0_0_1_1_1 + 2.61232007263796e-05*G0_0_2_0_0 + 1.55635076270023e-05*G0_0_2_0_2 + 1.55635076270023e-05*G0_0_2_2_0 + 5.91060908521326e-05*G0_0_2_2_2 + 2.32101819403445e-05*G0_1_0_0_0 + 2.36095474190749e-06*G0_1_0_0_1 + 2.36095474190749e-06*G0_1_0_1_0 + 3.38286052571812e-06*G0_1_0_1_1 + 2.36095474190749e-06*G0_1_1_0_0 + 3.38286052571812e-06*G0_1_1_0_1 + 3.3828605257181e-06*G0_1_1_1_0 - 5.67333900667338e-05*G0_1_1_1_1 - 3.71174974349644e-06*G0_1_1_1_2 - 3.71174974349644e-06*G0_1_1_2_1 - 3.71174974349643e-06*G0_1_2_1_1 + 2.67339949879678e-05*G0_1_2_2_2 + 2.61232007263797e-05*G0_2_0_0_0 + 1.55635076270023e-05*G0_2_0_0_2 + 1.55635076270023e-05*G0_2_0_2_0 + 5.91060908521326e-05*G0_2_0_2_2 - 3.71174974349643e-06*G0_2_1_1_1 + 2.67339949879678e-05*G0_2_1_2_2 + 1.55635076270023e-05*G0_2_2_0_0 + 5.91060908521326e-05*G0_2_2_0_2 + 2.67339949879678e-05*G0_2_2_1_2 + 5.91060908521326e-05*G0_2_2_2_0 + 2.67339949879678e-05*G0_2_2_2_1 + 0.000265578043355866*G0_2_2_2_2; + A[118] = A[202]; + A[217] = A[119]; + A[6] = A[90]; + A[22] = A[106]; + A[9] = A[135]; + A[49] = A[65] + 8.17524627048574e-06*G0_0_0_0_1 - 8.17524627048573e-06*G0_0_0_0_2 + 8.17524627048574e-06*G0_0_0_1_0 - 2.2552403504788e-06*G0_0_0_1_1 - 8.17524627048573e-06*G0_0_0_2_0 + 2.25524035047881e-06*G0_0_0_2_2 + 8.17524627048574e-06*G0_0_1_0_0 - 2.2552403504788e-06*G0_0_1_0_1 - 2.2552403504788e-06*G0_0_1_1_0 - 0.000121219168838237*G0_0_1_1_1 - 1.07123916647744e-05*G0_0_1_1_2 - 1.07123916647744e-05*G0_0_1_2_1 + 1.07123916647744e-05*G0_0_1_2_2 - 8.17524627048573e-06*G0_0_2_0_0 + 2.25524035047881e-06*G0_0_2_0_2 - 1.07123916647744e-05*G0_0_2_1_1 + 1.07123916647744e-05*G0_0_2_1_2 + 2.25524035047881e-06*G0_0_2_2_0 + 1.07123916647744e-05*G0_0_2_2_1 + 0.000121219168838237*G0_0_2_2_2 + 8.17524627048574e-06*G0_1_0_0_0 - 2.2552403504788e-06*G0_1_0_0_1 - 2.2552403504788e-06*G0_1_0_1_0 - 0.000121219168838237*G0_1_0_1_1 - 1.07123916647744e-05*G0_1_0_1_2 - 1.07123916647744e-05*G0_1_0_2_1 + 1.07123916647744e-05*G0_1_0_2_2 - 2.2552403504788e-06*G0_1_1_0_0 - 0.000121219168838237*G0_1_1_0_1 - 1.07123916647744e-05*G0_1_1_0_2 - 0.000121219168838237*G0_1_1_1_0 - 0.00205226871893573*G0_1_1_1_1 - 0.000174781127162109*G0_1_1_1_2 - 1.07123916647744e-05*G0_1_1_2_0 - 0.000174781127162109*G0_1_1_2_1 - 1.07123916647744e-05*G0_1_2_0_1 + 1.07123916647744e-05*G0_1_2_0_2 - 1.07123916647744e-05*G0_1_2_1_0 - 0.000174781127162109*G0_1_2_1_1 + 1.07123916647744e-05*G0_1_2_2_0 + 0.000174781127162109*G0_1_2_2_2 - 8.17524627048573e-06*G0_2_0_0_0 + 2.25524035047881e-06*G0_2_0_0_2 - 1.07123916647744e-05*G0_2_0_1_1 + 1.07123916647744e-05*G0_2_0_1_2 + 2.2552403504788e-06*G0_2_0_2_0 + 1.07123916647744e-05*G0_2_0_2_1 + 0.000121219168838237*G0_2_0_2_2 - 1.07123916647744e-05*G0_2_1_0_1 + 1.07123916647744e-05*G0_2_1_0_2 - 1.07123916647744e-05*G0_2_1_1_0 - 0.000174781127162109*G0_2_1_1_1 + 1.07123916647744e-05*G0_2_1_2_0 + 0.000174781127162109*G0_2_1_2_2 + 2.25524035047881e-06*G0_2_2_0_0 + 1.07123916647744e-05*G0_2_2_0_1 + 0.000121219168838237*G0_2_2_0_2 + 1.07123916647744e-05*G0_2_2_1_0 + 0.000174781127162109*G0_2_2_1_2 + 0.000121219168838237*G0_2_2_2_0 + 0.000174781127162109*G0_2_2_2_1 + 0.00205226871893573*G0_2_2_2_2; + A[34] = A[62]; + A[147] = A[189]; + A[124] = A[68]; + A[84] = -A[5] + 0.000265578043355865*G0_0_0_0_0 + 5.91060908521323e-05*G0_0_0_0_1 + 2.67339949879677e-05*G0_0_0_0_2 + 5.91060908521323e-05*G0_0_0_1_0 + 1.55635076270022e-05*G0_0_0_1_1 + 2.67339949879677e-05*G0_0_0_2_0 + 5.91060908521323e-05*G0_0_1_0_0 + 1.55635076270022e-05*G0_0_1_0_1 + 1.55635076270022e-05*G0_0_1_1_0 + 2.61232007263797e-05*G0_0_1_1_1 + 2.67339949879677e-05*G0_0_2_0_0 - 3.71174974349646e-06*G0_0_2_2_2 + 5.91060908521323e-05*G0_1_0_0_0 + 1.55635076270022e-05*G0_1_0_0_1 + 1.55635076270022e-05*G0_1_0_1_0 + 2.61232007263797e-05*G0_1_0_1_1 + 1.55635076270022e-05*G0_1_1_0_0 + 2.61232007263797e-05*G0_1_1_0_1 + 2.61232007263797e-05*G0_1_1_1_0 + 0.000275444719889211*G0_1_1_1_1 + 2.32101819403446e-05*G0_1_1_1_2 + 2.32101819403446e-05*G0_1_1_2_1 + 2.36095474190749e-06*G0_1_1_2_2 + 2.32101819403446e-05*G0_1_2_1_1 + 2.36095474190748e-06*G0_1_2_1_2 + 2.36095474190749e-06*G0_1_2_2_1 + 3.38286052571811e-06*G0_1_2_2_2 + 2.67339949879677e-05*G0_2_0_0_0 - 3.71174974349646e-06*G0_2_0_2_2 + 2.32101819403446e-05*G0_2_1_1_1 + 2.36095474190748e-06*G0_2_1_1_2 + 2.36095474190749e-06*G0_2_1_2_1 + 3.38286052571811e-06*G0_2_1_2_2 - 3.71174974349646e-06*G0_2_2_0_2 + 2.36095474190749e-06*G0_2_2_1_1 + 3.38286052571811e-06*G0_2_2_1_2 - 3.71174974349645e-06*G0_2_2_2_0 + 3.38286052571811e-06*G0_2_2_2_1 - 5.67333900667334e-05*G0_2_2_2_2; + A[67] = A[109]; + A[161] = A[175]; + A[136] = A[24]; + A[96] = -A[97] + 0.00409795965351591*G0_0_0_0_0 + 0.000200622422844679*G0_0_0_0_1 + 0.00107546774213459*G0_0_0_0_2 + 0.000200622422844679*G0_0_0_1_0 + 1.71022393244645e-05*G0_0_0_1_1 + 5.32800532800623e-05*G0_0_0_1_2 + 0.00107546774213459*G0_0_0_2_0 + 5.32800532800623e-05*G0_0_0_2_1 + 0.000323626990293712*G0_0_0_2_2 + 0.000200622422844679*G0_0_1_0_0 + 1.71022393244645e-05*G0_0_1_0_1 + 5.32800532800623e-05*G0_0_1_0_2 + 1.71022393244645e-05*G0_0_1_1_0 + 6.43683183365833e-06*G0_0_1_1_1 + 4.74540157079922e-06*G0_0_1_1_2 + 5.32800532800623e-05*G0_0_1_2_0 + 4.74540157079922e-06*G0_0_1_2_1 + 6.10794261588019e-06*G0_0_1_2_2 + 0.00107546774213459*G0_0_2_0_0 + 5.32800532800623e-05*G0_0_2_0_1 + 0.000323626990293712*G0_0_2_0_2 + 5.32800532800623e-05*G0_0_2_1_0 + 4.74540157079922e-06*G0_0_2_1_1 + 6.10794261588019e-06*G0_0_2_1_2 + 0.000323626990293712*G0_0_2_2_0 + 6.10794261588019e-06*G0_0_2_2_1 + 1.36254104508101e-05*G0_0_2_2_2 + 0.000200622422844679*G0_1_0_0_0 + 1.71022393244645e-05*G0_1_0_0_1 + 5.32800532800623e-05*G0_1_0_0_2 + 1.71022393244645e-05*G0_1_0_1_0 + 6.43683183365833e-06*G0_1_0_1_1 + 4.74540157079922e-06*G0_1_0_1_2 + 5.32800532800623e-05*G0_1_0_2_0 + 4.74540157079922e-06*G0_1_0_2_1 + 6.10794261588019e-06*G0_1_0_2_2 + 1.71022393244645e-05*G0_1_1_0_0 + 6.43683183365833e-06*G0_1_1_0_1 + 4.74540157079922e-06*G0_1_1_0_2 + 6.43683183365833e-06*G0_1_1_1_0 + 2.76266942933657e-05*G0_1_1_1_1 + 8.03429374858089e-06*G0_1_1_1_2 + 4.74540157079922e-06*G0_1_1_2_0 + 8.03429374858088e-06*G0_1_1_2_1 - 6.20191096381668e-06*G0_1_1_2_2 + 5.32800532800623e-05*G0_1_2_0_0 + 4.74540157079922e-06*G0_1_2_0_1 + 6.10794261588019e-06*G0_1_2_0_2 + 4.74540157079922e-06*G0_1_2_1_0 + 8.03429374858088e-06*G0_1_2_1_1 - 6.20191096381668e-06*G0_1_2_1_2 + 6.1079426158802e-06*G0_1_2_2_0 - 6.20191096381668e-06*G0_1_2_2_1 - 5.77905339810197e-05*G0_1_2_2_2 + 0.00107546774213459*G0_2_0_0_0 + 5.32800532800623e-05*G0_2_0_0_1 + 0.000323626990293712*G0_2_0_0_2 + 5.32800532800623e-05*G0_2_0_1_0 + 4.74540157079922e-06*G0_2_0_1_1 + 6.10794261588019e-06*G0_2_0_1_2 + 0.000323626990293712*G0_2_0_2_0 + 6.10794261588019e-06*G0_2_0_2_1 + 1.36254104508101e-05*G0_2_0_2_2 + 5.32800532800623e-05*G0_2_1_0_0 + 4.74540157079922e-06*G0_2_1_0_1 + 6.1079426158802e-06*G0_2_1_0_2 + 4.74540157079922e-06*G0_2_1_1_0 + 8.03429374858088e-06*G0_2_1_1_1 - 6.20191096381668e-06*G0_2_1_1_2 + 6.1079426158802e-06*G0_2_1_2_0 - 6.20191096381667e-06*G0_2_1_2_1 - 5.77905339810197e-05*G0_2_1_2_2 + 0.000323626990293712*G0_2_2_0_0 + 6.1079426158802e-06*G0_2_2_0_1 + 1.362541045081e-05*G0_2_2_0_2 + 6.10794261588019e-06*G0_2_2_1_0 - 6.20191096381667e-06*G0_2_2_1_1 - 5.77905339810196e-05*G0_2_2_1_2 + 1.362541045081e-05*G0_2_2_2_0 - 5.77905339810196e-05*G0_2_2_2_1 - 0.000600457743314985*G0_2_2_2_2; + A[81] = A[95]; + A[167] = A[41]; + A[156] = A[100]; + A[112] = A[160] - 0.000754800754800882*G0_0_0_0_1 + 0.000754800754800883*G0_0_0_0_2 - 0.000754800754800882*G0_0_0_1_0 - 0.000766640766640896*G0_0_0_1_1 + 0.000754800754800883*G0_0_0_2_0 + 0.000766640766640895*G0_0_0_2_2 - 0.000754800754800882*G0_0_1_0_0 - 0.000766640766640896*G0_0_1_0_1 - 0.000766640766640896*G0_0_1_1_0 - 0.00106845535416982*G0_0_1_1_1 - 8.74258017115308e-05*G0_0_1_1_2 - 8.74258017115308e-05*G0_0_1_2_1 + 8.74258017115305e-05*G0_0_1_2_2 + 0.000754800754800883*G0_0_2_0_0 + 0.000766640766640895*G0_0_2_0_2 - 8.74258017115308e-05*G0_0_2_1_1 + 8.74258017115305e-05*G0_0_2_1_2 + 0.000766640766640895*G0_0_2_2_0 + 8.74258017115305e-05*G0_0_2_2_1 + 0.00106845535416982*G0_0_2_2_2 - 0.000754800754800882*G0_1_0_0_0 - 0.000766640766640896*G0_1_0_0_1 - 0.000766640766640896*G0_1_0_1_0 - 0.00106845535416982*G0_1_0_1_1 - 8.74258017115308e-05*G0_1_0_1_2 - 8.74258017115308e-05*G0_1_0_2_1 + 8.74258017115305e-05*G0_1_0_2_2 - 0.000766640766640896*G0_1_1_0_0 - 0.00106845535416982*G0_1_1_0_1 - 8.74258017115308e-05*G0_1_1_0_2 - 0.00106845535416982*G0_1_1_1_0 - 0.00323993466850664*G0_1_1_1_1 - 0.000313654599368938*G0_1_1_1_2 - 8.74258017115308e-05*G0_1_1_2_0 - 0.000313654599368938*G0_1_1_2_1 - 8.74258017115308e-05*G0_1_2_0_1 + 8.74258017115305e-05*G0_1_2_0_2 - 8.74258017115308e-05*G0_1_2_1_0 - 0.000313654599368938*G0_1_2_1_1 + 8.74258017115305e-05*G0_1_2_2_0 + 0.000313654599368937*G0_1_2_2_2 + 0.000754800754800883*G0_2_0_0_0 + 0.000766640766640895*G0_2_0_0_2 - 8.74258017115308e-05*G0_2_0_1_1 + 8.74258017115305e-05*G0_2_0_1_2 + 0.000766640766640895*G0_2_0_2_0 + 8.74258017115305e-05*G0_2_0_2_1 + 0.00106845535416982*G0_2_0_2_2 - 8.74258017115308e-05*G0_2_1_0_1 + 8.74258017115304e-05*G0_2_1_0_2 - 8.74258017115308e-05*G0_2_1_1_0 - 0.000313654599368938*G0_2_1_1_1 + 8.74258017115305e-05*G0_2_1_2_0 + 0.000313654599368937*G0_2_1_2_2 + 0.000766640766640895*G0_2_2_0_0 + 8.74258017115304e-05*G0_2_2_0_1 + 0.00106845535416982*G0_2_2_0_2 + 8.74258017115304e-05*G0_2_2_1_0 + 0.000313654599368937*G0_2_2_1_2 + 0.00106845535416982*G0_2_2_2_0 + 0.000313654599368937*G0_2_2_2_1 + 0.00323993466850663*G0_2_2_2_2; + A[223] = -A[12] - 7.68191244381851e-05*G0_0_0_0_0 - 0.000319257462114659*G0_0_0_0_1 - 0.000319257462114658*G0_0_0_0_2 - 0.000319257462114659*G0_0_0_1_0 - 0.0003547774976347*G0_0_0_1_1 - 0.000103459151078216*G0_0_0_1_2 - 0.000319257462114658*G0_0_0_2_0 - 0.000103459151078216*G0_0_0_2_1 - 0.0003547774976347*G0_0_0_2_2 - 0.000319257462114659*G0_0_1_0_0 - 0.0003547774976347*G0_0_1_0_1 - 0.000103459151078216*G0_0_1_0_2 - 0.0003547774976347*G0_0_1_1_0 - 0.000552392933345408*G0_0_1_1_1 - 8.95048514096285e-06*G0_0_1_1_2 - 0.000103459151078216*G0_0_1_2_0 - 8.95048514096285e-06*G0_0_1_2_1 - 8.95048514096267e-06*G0_0_1_2_2 - 0.000319257462114658*G0_0_2_0_0 - 0.000103459151078216*G0_0_2_0_1 - 0.0003547774976347*G0_0_2_0_2 - 0.000103459151078216*G0_0_2_1_0 - 8.95048514096282e-06*G0_0_2_1_1 - 8.95048514096267e-06*G0_0_2_1_2 - 0.0003547774976347*G0_0_2_2_0 - 8.95048514096267e-06*G0_0_2_2_1 - 0.000552392933345406*G0_0_2_2_2 - 0.000319257462114659*G0_1_0_0_0 - 0.0003547774976347*G0_1_0_0_1 - 0.000103459151078216*G0_1_0_0_2 - 0.0003547774976347*G0_1_0_1_0 - 0.000552392933345408*G0_1_0_1_1 - 8.95048514096287e-06*G0_1_0_1_2 - 0.000103459151078216*G0_1_0_2_0 - 8.95048514096284e-06*G0_1_0_2_1 - 8.95048514096266e-06*G0_1_0_2_2 - 0.0003547774976347*G0_1_1_0_0 - 0.000552392933345408*G0_1_1_0_1 - 8.95048514096284e-06*G0_1_1_0_2 - 0.000552392933345408*G0_1_1_1_0 - 0.0012960584389158*G0_1_1_1_1 + 0.000151383008525891*G0_1_1_1_2 - 8.95048514096282e-06*G0_1_1_2_0 + 0.000151383008525891*G0_1_1_2_1 + 0.000335114620828963*G0_1_1_2_2 - 0.000103459151078216*G0_1_2_0_0 - 8.95048514096284e-06*G0_1_2_0_1 - 8.95048514096269e-06*G0_1_2_0_2 - 8.95048514096281e-06*G0_1_2_1_0 + 0.000151383008525891*G0_1_2_1_1 + 0.000335114620828963*G0_1_2_1_2 - 8.95048514096269e-06*G0_1_2_2_0 + 0.000335114620828963*G0_1_2_2_1 + 0.000151383008525892*G0_1_2_2_2 - 0.000319257462114658*G0_2_0_0_0 - 0.000103459151078216*G0_2_0_0_1 - 0.0003547774976347*G0_2_0_0_2 - 0.000103459151078216*G0_2_0_1_0 - 8.95048514096282e-06*G0_2_0_1_1 - 8.95048514096267e-06*G0_2_0_1_2 - 0.0003547774976347*G0_2_0_2_0 - 8.95048514096267e-06*G0_2_0_2_1 - 0.000552392933345406*G0_2_0_2_2 - 0.000103459151078216*G0_2_1_0_0 - 8.95048514096283e-06*G0_2_1_0_1 - 8.95048514096268e-06*G0_2_1_0_2 - 8.95048514096283e-06*G0_2_1_1_0 + 0.000151383008525891*G0_2_1_1_1 + 0.000335114620828963*G0_2_1_1_2 - 8.95048514096268e-06*G0_2_1_2_0 + 0.000335114620828963*G0_2_1_2_1 + 0.000151383008525892*G0_2_1_2_2 - 0.0003547774976347*G0_2_2_0_0 - 8.95048514096269e-06*G0_2_2_0_1 - 0.000552392933345406*G0_2_2_0_2 - 8.95048514096269e-06*G0_2_2_1_0 + 0.000335114620828963*G0_2_2_1_1 + 0.000151383008525892*G0_2_2_1_2 - 0.000552392933345406*G0_2_2_2_0 + 0.000151383008525892*G0_2_2_2_1 - 0.0012960584389158*G0_2_2_2_2; + A[185] = -A[95] + 0.000494273510146608*G0_0_0_0_0 + 0.000178163987687827*G0_0_0_0_1 + 5.90121225041959e-05*G0_0_0_0_2 + 0.000178163987687827*G0_0_0_1_0 + 9.94185121169415e-05*G0_0_0_1_1 + 2.49955805511403e-05*G0_0_0_1_2 + 5.90121225041959e-05*G0_0_0_2_0 + 2.49955805511403e-05*G0_0_0_2_1 - 6.38984765969003e-06*G0_0_0_2_2 + 0.000178163987687827*G0_0_1_0_0 + 9.94185121169415e-05*G0_0_1_0_1 + 2.49955805511403e-05*G0_0_1_0_2 + 9.94185121169415e-05*G0_0_1_1_0 + 6.08914894629282e-05*G0_0_1_1_1 + 2.49955805511403e-05*G0_0_1_2_0 - 6.7657210514365e-06*G0_0_1_2_2 + 5.90121225041959e-05*G0_0_2_0_0 + 2.49955805511403e-05*G0_0_2_0_1 - 6.38984765969003e-06*G0_0_2_0_2 + 2.49955805511403e-05*G0_0_2_1_0 - 6.7657210514365e-06*G0_0_2_1_2 - 6.38984765969003e-06*G0_0_2_2_0 - 6.7657210514365e-06*G0_0_2_2_1 - 1.31555687111266e-05*G0_0_2_2_2 + 0.000178163987687827*G0_1_0_0_0 + 9.94185121169415e-05*G0_1_0_0_1 + 2.49955805511403e-05*G0_1_0_0_2 + 9.94185121169415e-05*G0_1_0_1_0 + 6.08914894629282e-05*G0_1_0_1_1 + 2.49955805511403e-05*G0_1_0_2_0 - 6.7657210514365e-06*G0_1_0_2_2 + 9.94185121169415e-05*G0_1_1_0_0 + 6.08914894629282e-05*G0_1_1_0_1 + 6.08914894629282e-05*G0_1_1_1_0 - 9.2088980977886e-05*G0_1_1_1_1 + 4.88635409270407e-06*G0_1_1_1_2 + 4.88635409270407e-06*G0_1_1_2_1 - 1.69143026285913e-05*G0_1_1_2_2 + 2.49955805511403e-05*G0_1_2_0_0 - 6.7657210514365e-06*G0_1_2_0_2 + 4.88635409270407e-06*G0_1_2_1_1 - 1.69143026285912e-05*G0_1_2_1_2 - 6.7657210514365e-06*G0_1_2_2_0 - 1.69143026285912e-05*G0_1_2_2_1 - 6.57778435556326e-05*G0_1_2_2_2 + 5.90121225041959e-05*G0_2_0_0_0 + 2.49955805511403e-05*G0_2_0_0_1 - 6.38984765969003e-06*G0_2_0_0_2 + 2.49955805511403e-05*G0_2_0_1_0 - 6.7657210514365e-06*G0_2_0_1_2 - 6.38984765969003e-06*G0_2_0_2_0 - 6.7657210514365e-06*G0_2_0_2_1 - 1.31555687111266e-05*G0_2_0_2_2 + 2.49955805511403e-05*G0_2_1_0_0 - 6.7657210514365e-06*G0_2_1_0_2 + 4.88635409270407e-06*G0_2_1_1_1 - 1.69143026285912e-05*G0_2_1_1_2 - 6.7657210514365e-06*G0_2_1_2_0 - 1.69143026285912e-05*G0_2_1_2_1 - 6.57778435556326e-05*G0_2_1_2_2 - 6.38984765969003e-06*G0_2_2_0_0 - 6.7657210514365e-06*G0_2_2_0_1 - 1.31555687111266e-05*G0_2_2_0_2 - 6.7657210514365e-06*G0_2_2_1_0 - 1.69143026285912e-05*G0_2_2_1_1 - 6.57778435556326e-05*G0_2_2_1_2 - 1.31555687111266e-05*G0_2_2_2_0 - 6.57778435556326e-05*G0_2_2_2_1 + 9.20889809778831e-05*G0_2_2_2_2; + A[88] = A[185] - 0.000293181245562247*G0_0_0_0_0 - 5.86362491124493e-05*G0_0_0_0_1 - 2.70628842057458e-05*G0_0_0_0_2 - 5.86362491124493e-05*G0_0_0_1_0 + 5.86362491124495e-05*G0_0_0_1_1 - 2.70628842057458e-05*G0_0_0_2_0 - 4.51048070095757e-06*G0_0_0_2_2 - 5.86362491124493e-05*G0_0_1_0_0 + 5.86362491124495e-05*G0_0_1_0_1 + 5.86362491124495e-05*G0_0_1_1_0 + 0.000293181245562247*G0_0_1_1_1 + 2.70628842057459e-05*G0_0_1_1_2 + 2.70628842057459e-05*G0_0_1_2_1 + 4.51048070095771e-06*G0_0_1_2_2 - 2.70628842057458e-05*G0_0_2_0_0 - 4.51048070095758e-06*G0_0_2_0_2 + 2.70628842057459e-05*G0_0_2_1_1 + 4.5104807009577e-06*G0_0_2_1_2 - 4.51048070095757e-06*G0_0_2_2_0 + 4.5104807009577e-06*G0_0_2_2_1 - 5.86362491124493e-05*G0_1_0_0_0 + 5.86362491124495e-05*G0_1_0_0_1 + 5.86362491124495e-05*G0_1_0_1_0 + 0.000293181245562247*G0_1_0_1_1 + 2.70628842057459e-05*G0_1_0_1_2 + 2.70628842057459e-05*G0_1_0_2_1 + 4.51048070095771e-06*G0_1_0_2_2 + 5.86362491124495e-05*G0_1_1_0_0 + 0.000293181245562247*G0_1_1_0_1 + 2.70628842057459e-05*G0_1_1_0_2 + 0.000293181245562247*G0_1_1_1_0 + 0.00146590622781124*G0_1_1_1_1 + 0.00013531442102873*G0_1_1_1_2 + 2.70628842057459e-05*G0_1_1_2_0 + 0.00013531442102873*G0_1_1_2_1 + 2.7062884205746e-05*G0_1_1_2_2 + 2.70628842057459e-05*G0_1_2_0_1 + 4.5104807009577e-06*G0_1_2_0_2 + 2.70628842057459e-05*G0_1_2_1_0 + 0.00013531442102873*G0_1_2_1_1 + 2.7062884205746e-05*G0_1_2_1_2 + 4.5104807009577e-06*G0_1_2_2_0 + 2.7062884205746e-05*G0_1_2_2_1 + 0.000157866824533518*G0_1_2_2_2 - 2.70628842057458e-05*G0_2_0_0_0 - 4.51048070095758e-06*G0_2_0_0_2 + 2.70628842057459e-05*G0_2_0_1_1 + 4.5104807009577e-06*G0_2_0_1_2 - 4.51048070095758e-06*G0_2_0_2_0 + 4.5104807009577e-06*G0_2_0_2_1 + 2.70628842057459e-05*G0_2_1_0_1 + 4.5104807009577e-06*G0_2_1_0_2 + 2.70628842057459e-05*G0_2_1_1_0 + 0.00013531442102873*G0_2_1_1_1 + 2.7062884205746e-05*G0_2_1_1_2 + 4.5104807009577e-06*G0_2_1_2_0 + 2.7062884205746e-05*G0_2_1_2_1 + 0.000157866824533518*G0_2_1_2_2 - 4.51048070095758e-06*G0_2_2_0_0 + 4.5104807009577e-06*G0_2_2_0_1 + 4.51048070095771e-06*G0_2_2_1_0 + 2.7062884205746e-05*G0_2_2_1_1 + 0.000157866824533518*G0_2_2_1_2 + 0.000157866824533518*G0_2_2_2_1 + 0.000473600473600556*G0_2_2_2_2; + A[200] = A[88]; + A[210] = A[14]; + A[203] = A[133]; + A[3] = A[45]; + A[59] = A[213]; + A[17] = A[31]; + A[134] = A[218]; + A[69] = A[139]; + A[48] = -A[49] + 2.76266942933655e-05*G0_0_0_0_0 + 6.43683183365831e-06*G0_0_0_0_1 + 8.0342937485808e-06*G0_0_0_0_2 + 6.43683183365832e-06*G0_0_0_1_0 + 1.71022393244645e-05*G0_0_0_1_1 + 4.74540157079919e-06*G0_0_0_1_2 + 8.0342937485808e-06*G0_0_0_2_0 + 4.74540157079919e-06*G0_0_0_2_1 - 6.20191096381675e-06*G0_0_0_2_2 + 6.43683183365831e-06*G0_0_1_0_0 + 1.71022393244644e-05*G0_0_1_0_1 + 4.74540157079919e-06*G0_0_1_0_2 + 1.71022393244644e-05*G0_0_1_1_0 + 0.000200622422844679*G0_0_1_1_1 + 5.32800532800623e-05*G0_0_1_1_2 + 4.74540157079919e-06*G0_0_1_2_0 + 5.32800532800623e-05*G0_0_1_2_1 + 6.10794261588019e-06*G0_0_1_2_2 + 8.0342937485808e-06*G0_0_2_0_0 + 4.74540157079919e-06*G0_0_2_0_1 - 6.20191096381675e-06*G0_0_2_0_2 + 4.74540157079919e-06*G0_0_2_1_0 + 5.32800532800623e-05*G0_0_2_1_1 + 6.10794261588019e-06*G0_0_2_1_2 - 6.20191096381675e-06*G0_0_2_2_0 + 6.10794261588019e-06*G0_0_2_2_1 - 5.77905339810198e-05*G0_0_2_2_2 + 6.43683183365831e-06*G0_1_0_0_0 + 1.71022393244645e-05*G0_1_0_0_1 + 4.74540157079919e-06*G0_1_0_0_2 + 1.71022393244645e-05*G0_1_0_1_0 + 0.000200622422844679*G0_1_0_1_1 + 5.32800532800623e-05*G0_1_0_1_2 + 4.74540157079919e-06*G0_1_0_2_0 + 5.32800532800623e-05*G0_1_0_2_1 + 6.10794261588019e-06*G0_1_0_2_2 + 1.71022393244644e-05*G0_1_1_0_0 + 0.000200622422844679*G0_1_1_0_1 + 5.32800532800623e-05*G0_1_1_0_2 + 0.000200622422844679*G0_1_1_1_0 + 0.00409795965351591*G0_1_1_1_1 + 0.00107546774213459*G0_1_1_1_2 + 5.32800532800623e-05*G0_1_1_2_0 + 0.00107546774213459*G0_1_1_2_1 + 0.000323626990293712*G0_1_1_2_2 + 4.74540157079919e-06*G0_1_2_0_0 + 5.32800532800623e-05*G0_1_2_0_1 + 6.1079426158802e-06*G0_1_2_0_2 + 5.32800532800623e-05*G0_1_2_1_0 + 0.00107546774213459*G0_1_2_1_1 + 0.000323626990293712*G0_1_2_1_2 + 6.10794261588019e-06*G0_1_2_2_0 + 0.000323626990293712*G0_1_2_2_1 + 1.36254104508099e-05*G0_1_2_2_2 + 8.0342937485808e-06*G0_2_0_0_0 + 4.74540157079919e-06*G0_2_0_0_1 - 6.20191096381675e-06*G0_2_0_0_2 + 4.74540157079919e-06*G0_2_0_1_0 + 5.32800532800623e-05*G0_2_0_1_1 + 6.10794261588019e-06*G0_2_0_1_2 - 6.20191096381675e-06*G0_2_0_2_0 + 6.10794261588019e-06*G0_2_0_2_1 - 5.77905339810198e-05*G0_2_0_2_2 + 4.74540157079919e-06*G0_2_1_0_0 + 5.32800532800623e-05*G0_2_1_0_1 + 6.10794261588019e-06*G0_2_1_0_2 + 5.32800532800623e-05*G0_2_1_1_0 + 0.00107546774213459*G0_2_1_1_1 + 0.000323626990293712*G0_2_1_1_2 + 6.10794261588019e-06*G0_2_1_2_0 + 0.000323626990293712*G0_2_1_2_1 + 1.36254104508099e-05*G0_2_1_2_2 - 6.20191096381675e-06*G0_2_2_0_0 + 6.10794261588019e-06*G0_2_2_0_1 - 5.77905339810198e-05*G0_2_2_0_2 + 6.1079426158802e-06*G0_2_2_1_0 + 0.000323626990293712*G0_2_2_1_1 + 1.36254104508099e-05*G0_2_2_1_2 - 5.77905339810198e-05*G0_2_2_2_0 + 1.36254104508099e-05*G0_2_2_2_1 - 0.000600457743314987*G0_2_2_2_2; + A[39] = A[137]; + A[121] = A[2] + 2.09887114649056e-05*G0_0_0_0_0 - 1.2209278082296e-05*G0_0_0_2_2 - 1.2209278082296e-05*G0_0_2_0_2 - 1.2209278082296e-05*G0_0_2_2_0 - 4.97415576780739e-05*G0_0_2_2_2 + 2.23615302980394e-06*G0_1_1_1_1 - 2.79482422339612e-05*G0_1_2_2_2 - 1.2209278082296e-05*G0_2_0_0_2 - 1.2209278082296e-05*G0_2_0_2_0 - 4.97415576780739e-05*G0_2_0_2_2 - 2.79482422339612e-05*G0_2_1_2_2 - 1.2209278082296e-05*G0_2_2_0_0 - 4.97415576780739e-05*G0_2_2_0_2 - 2.79482422339612e-05*G0_2_2_1_2 - 4.97415576780739e-05*G0_2_2_2_0 - 2.79482422339612e-05*G0_2_2_2_1 - 0.00021722105055442*G0_2_2_2_2; + A[211] = A[121] + 8.04603979207289e-05*G0_0_0_0_0 - 1.86057328914503e-05*G0_0_0_0_2 - 1.86057328914503e-05*G0_0_0_2_0 - 3.08098720797185e-05*G0_0_0_2_2 - 5.89651383302275e-06*G0_0_1_2_2 - 1.86057328914503e-05*G0_0_2_0_0 - 3.08098720797185e-05*G0_0_2_0_2 - 5.89651383302275e-06*G0_0_2_1_2 - 3.08098720797185e-05*G0_0_2_2_0 - 5.89651383302275e-06*G0_0_2_2_1 - 3.52381304762316e-05*G0_0_2_2_2 - 5.89651383302275e-06*G0_1_0_2_2 - 0.000109355664911239*G0_1_1_1_1 - 5.89651383302275e-06*G0_1_2_0_2 - 5.89651383302275e-06*G0_1_2_2_0 - 2.34920869841538e-06*G0_1_2_2_2 - 1.86057328914503e-05*G0_2_0_0_0 - 3.08098720797185e-05*G0_2_0_0_2 - 5.89651383302275e-06*G0_2_0_1_2 - 3.08098720797185e-05*G0_2_0_2_0 - 5.89651383302275e-06*G0_2_0_2_1 - 3.52381304762316e-05*G0_2_0_2_2 - 5.89651383302275e-06*G0_2_1_0_2 - 5.89651383302275e-06*G0_2_1_2_0 - 2.34920869841538e-06*G0_2_1_2_2 - 3.08098720797185e-05*G0_2_2_0_0 - 5.89651383302275e-06*G0_2_2_0_1 - 3.52381304762316e-05*G0_2_2_0_2 - 5.89651383302275e-06*G0_2_2_1_0 - 2.34920869841538e-06*G0_2_2_1_2 - 3.52381304762316e-05*G0_2_2_2_0 - 2.34920869841538e-06*G0_2_2_2_1 - 2.70159000317763e-06*G0_2_2_2_2; + A[157] = A[211] + 0.00144582049343978*G0_0_0_0_0 + 8.57696095791478e-05*G0_0_0_0_1 + 0.000108744870649651*G0_0_0_0_2 + 8.57696095791478e-05*G0_0_0_1_0 - 5.10952891905357e-05*G0_0_0_1_1 + 0.000108744870649651*G0_0_0_2_0 - 5.49714835429218e-06*G0_0_0_2_2 + 8.57696095791479e-05*G0_0_1_0_0 - 5.10952891905357e-05*G0_0_1_0_1 - 5.10952891905357e-05*G0_0_1_1_0 - 7.11105473010354e-05*G0_0_1_1_1 - 1.22276312752524e-05*G0_0_1_1_2 - 1.22276312752524e-05*G0_0_1_2_1 + 1.51523961047793e-06*G0_0_1_2_2 + 0.000108744870649651*G0_0_2_0_0 - 5.49714835429217e-06*G0_0_2_0_2 - 1.22276312752524e-05*G0_0_2_1_1 + 1.51523961047793e-06*G0_0_2_1_2 - 5.49714835429217e-06*G0_0_2_2_0 + 1.51523961047793e-06*G0_0_2_2_1 + 2.54419302038391e-05*G0_0_2_2_2 + 8.57696095791478e-05*G0_1_0_0_0 - 5.10952891905357e-05*G0_1_0_0_1 - 5.10952891905357e-05*G0_1_0_1_0 - 7.11105473010354e-05*G0_1_0_1_1 - 1.22276312752524e-05*G0_1_0_1_2 - 1.22276312752524e-05*G0_1_0_2_1 + 1.51523961047793e-06*G0_1_0_2_2 - 5.10952891905357e-05*G0_1_1_0_0 - 7.11105473010354e-05*G0_1_1_0_1 - 1.22276312752524e-05*G0_1_1_0_2 - 7.11105473010354e-05*G0_1_1_1_0 - 6.69524479048541e-06*G0_1_1_1_1 - 1.22276312752524e-05*G0_1_1_2_0 - 1.22276312752524e-05*G0_1_2_0_1 + 1.51523961047793e-06*G0_1_2_0_2 - 1.22276312752524e-05*G0_1_2_1_0 + 1.51523961047793e-06*G0_1_2_2_0 + 2.50895488990767e-05*G0_1_2_2_2 + 0.000108744870649651*G0_2_0_0_0 - 5.49714835429218e-06*G0_2_0_0_2 - 1.22276312752524e-05*G0_2_0_1_1 + 1.51523961047793e-06*G0_2_0_1_2 - 5.49714835429217e-06*G0_2_0_2_0 + 1.51523961047793e-06*G0_2_0_2_1 + 2.54419302038391e-05*G0_2_0_2_2 - 1.22276312752524e-05*G0_2_1_0_1 + 1.51523961047793e-06*G0_2_1_0_2 - 1.22276312752524e-05*G0_2_1_1_0 + 1.51523961047793e-06*G0_2_1_2_0 + 2.50895488990767e-05*G0_2_1_2_2 - 5.49714835429217e-06*G0_2_2_0_0 + 1.51523961047794e-06*G0_2_2_0_1 + 2.54419302038391e-05*G0_2_2_0_2 + 1.51523961047793e-06*G0_2_2_1_0 + 2.50895488990767e-05*G0_2_2_1_2 + 2.54419302038391e-05*G0_2_2_2_0 + 2.50895488990767e-05*G0_2_2_2_1 + 0.000208962113724053*G0_2_2_2_2; + A[46] = A[121] + 4.31549637898917e-05*G0_0_0_0_0 - 3.92317852635379e-06*G0_0_0_0_2 - 3.92317852635379e-06*G0_0_0_2_0 + 1.13936621873148e-06*G0_0_0_2_2 + 4.91689380578353e-05*G0_0_1_1_1 - 3.9231785263538e-06*G0_0_2_0_0 + 1.13936621873148e-06*G0_0_2_0_2 + 1.13936621873148e-06*G0_0_2_2_0 + 3.10565389930521e-05*G0_0_2_2_2 + 4.91689380578353e-05*G0_1_0_1_1 + 4.91689380578353e-05*G0_1_1_0_1 + 4.91689380578353e-05*G0_1_1_1_0 + 0.00149891261002398*G0_1_1_1_1 + 9.73512084623362e-05*G0_1_1_1_2 + 9.73512084623362e-05*G0_1_1_2_1 + 9.73512084623362e-05*G0_1_2_1_1 + 6.10794261588013e-06*G0_1_2_2_2 - 3.9231785263538e-06*G0_2_0_0_0 + 1.13936621873148e-06*G0_2_0_0_2 + 1.13936621873148e-06*G0_2_0_2_0 + 3.10565389930521e-05*G0_2_0_2_2 + 9.73512084623362e-05*G0_2_1_1_1 + 6.10794261588013e-06*G0_2_1_2_2 + 1.13936621873148e-06*G0_2_2_0_0 + 3.10565389930521e-05*G0_2_2_0_2 + 6.10794261588013e-06*G0_2_2_1_2 + 3.10565389930521e-05*G0_2_2_2_0 + 6.10794261588014e-06*G0_2_2_2_1 + 0.000180066846733543*G0_2_2_2_2; + A[18] = A[46]; + A[29] = A[211]; + A[87] = A[185]; + A[64] = A[160] - 0.00323993466850664*G0_0_0_0_0 - 0.00106845535416982*G0_0_0_0_1 - 0.000313654599368938*G0_0_0_0_2 - 0.00106845535416982*G0_0_0_1_0 - 0.000766640766640896*G0_0_0_1_1 - 8.74258017115308e-05*G0_0_0_1_2 - 0.000313654599368938*G0_0_0_2_0 - 8.74258017115308e-05*G0_0_0_2_1 - 0.00106845535416982*G0_0_1_0_0 - 0.000766640766640896*G0_0_1_0_1 - 8.74258017115308e-05*G0_0_1_0_2 - 0.000766640766640896*G0_0_1_1_0 - 0.000754800754800882*G0_0_1_1_1 - 8.74258017115308e-05*G0_0_1_2_0 + 8.74258017115306e-05*G0_0_1_2_2 - 0.000313654599368938*G0_0_2_0_0 - 8.74258017115308e-05*G0_0_2_0_1 - 8.74258017115308e-05*G0_0_2_1_0 + 8.74258017115306e-05*G0_0_2_1_2 + 8.74258017115306e-05*G0_0_2_2_1 + 0.000313654599368937*G0_0_2_2_2 - 0.00106845535416982*G0_1_0_0_0 - 0.000766640766640896*G0_1_0_0_1 - 8.74258017115308e-05*G0_1_0_0_2 - 0.000766640766640896*G0_1_0_1_0 - 0.000754800754800882*G0_1_0_1_1 - 8.74258017115308e-05*G0_1_0_2_0 + 8.74258017115306e-05*G0_1_0_2_2 - 0.000766640766640896*G0_1_1_0_0 - 0.000754800754800882*G0_1_1_0_1 - 0.000754800754800882*G0_1_1_1_0 + 0.000754800754800882*G0_1_1_1_2 + 0.000754800754800882*G0_1_1_2_1 + 0.000766640766640896*G0_1_1_2_2 - 8.74258017115308e-05*G0_1_2_0_0 + 8.74258017115306e-05*G0_1_2_0_2 + 0.000754800754800882*G0_1_2_1_1 + 0.000766640766640896*G0_1_2_1_2 + 8.74258017115306e-05*G0_1_2_2_0 + 0.000766640766640896*G0_1_2_2_1 + 0.00106845535416982*G0_1_2_2_2 - 0.000313654599368938*G0_2_0_0_0 - 8.74258017115308e-05*G0_2_0_0_1 - 8.74258017115308e-05*G0_2_0_1_0 + 8.74258017115306e-05*G0_2_0_1_2 + 8.74258017115306e-05*G0_2_0_2_1 + 0.000313654599368937*G0_2_0_2_2 - 8.74258017115308e-05*G0_2_1_0_0 + 8.74258017115306e-05*G0_2_1_0_2 + 0.000754800754800882*G0_2_1_1_1 + 0.000766640766640896*G0_2_1_1_2 + 8.74258017115306e-05*G0_2_1_2_0 + 0.000766640766640896*G0_2_1_2_1 + 0.00106845535416982*G0_2_1_2_2 + 8.74258017115306e-05*G0_2_2_0_1 + 0.000313654599368937*G0_2_2_0_2 + 8.74258017115306e-05*G0_2_2_1_0 + 0.000766640766640896*G0_2_2_1_1 + 0.00106845535416982*G0_2_2_1_2 + 0.000313654599368937*G0_2_2_2_0 + 0.00106845535416982*G0_2_2_2_1 + 0.00323993466850664*G0_2_2_2_2; + A[162] = A[214] - 0.00209737352594531*G0_0_0_0_0 + 1.52228723657315e-05*G0_0_0_0_1 - 0.000392411820983316*G0_0_0_0_2 + 1.52228723657316e-05*G0_0_0_1_0 + 0.000243565957851713*G0_0_0_1_1 - 0.000392411820983316*G0_0_0_2_0 + 1.52228723657316e-05*G0_0_1_0_0 + 0.000243565957851713*G0_0_1_0_1 + 0.000243565957851713*G0_0_1_1_0 + 0.000194514480228799*G0_0_1_1_1 - 0.000392411820983316*G0_0_2_0_0 + 0.000392411820983315*G0_0_2_2_2 + 1.52228723657316e-05*G0_1_0_0_0 + 0.000243565957851713*G0_1_0_0_1 + 0.000243565957851713*G0_1_0_1_0 + 0.000194514480228799*G0_1_0_1_1 + 0.000243565957851713*G0_1_1_0_0 + 0.000194514480228799*G0_1_1_0_1 + 0.000194514480228799*G0_1_1_1_0 - 0.000194514480228798*G0_1_1_1_2 - 0.000194514480228798*G0_1_1_2_1 - 0.000243565957851713*G0_1_1_2_2 - 0.000194514480228798*G0_1_2_1_1 - 0.000243565957851713*G0_1_2_1_2 - 0.000243565957851713*G0_1_2_2_1 - 1.52228723657324e-05*G0_1_2_2_2 - 0.000392411820983316*G0_2_0_0_0 + 0.000392411820983315*G0_2_0_2_2 - 0.000194514480228798*G0_2_1_1_1 - 0.000243565957851713*G0_2_1_1_2 - 0.000243565957851713*G0_2_1_2_1 - 1.52228723657324e-05*G0_2_1_2_2 + 0.000392411820983315*G0_2_2_0_2 - 0.000243565957851713*G0_2_2_1_1 - 1.52228723657324e-05*G0_2_2_1_2 + 0.000392411820983315*G0_2_2_2_0 - 1.52228723657323e-05*G0_2_2_2_1 + 0.0020973735259453*G0_2_2_2_2; + A[93] = A[51]; + A[166] = A[26]; + A[115] = A[157]; + A[224] = A[192] - 0.00866012294583869*G0_0_0_0_0 - 0.00243565957851713*G0_0_0_0_1 - 0.00216503073645967*G0_0_0_0_2 - 0.00243565957851713*G0_0_0_1_0 - 0.00086601229458387*G0_0_0_1_1 - 0.000487131915703427*G0_0_0_1_2 - 0.00216503073645967*G0_0_0_2_0 - 0.000487131915703427*G0_0_0_2_1 - 0.00243565957851713*G0_0_1_0_0 - 0.00086601229458387*G0_0_1_0_1 - 0.000487131915703427*G0_0_1_0_2 - 0.000866012294583869*G0_0_1_1_0 - 0.000270628842057459*G0_0_1_1_1 - 0.000487131915703427*G0_0_1_2_0 + 0.000487131915703425*G0_0_1_2_2 - 0.00216503073645967*G0_0_2_0_0 - 0.000487131915703427*G0_0_2_0_1 - 0.000487131915703427*G0_0_2_1_0 + 0.000487131915703425*G0_0_2_1_2 + 0.000487131915703425*G0_0_2_2_1 + 0.00216503073645967*G0_0_2_2_2 - 0.00243565957851713*G0_1_0_0_0 - 0.00086601229458387*G0_1_0_0_1 - 0.000487131915703427*G0_1_0_0_2 - 0.00086601229458387*G0_1_0_1_0 - 0.000270628842057459*G0_1_0_1_1 - 0.000487131915703427*G0_1_0_2_0 + 0.000487131915703425*G0_1_0_2_2 - 0.00086601229458387*G0_1_1_0_0 - 0.000270628842057459*G0_1_1_0_1 - 0.000270628842057459*G0_1_1_1_0 + 0.000270628842057458*G0_1_1_1_2 + 0.000270628842057459*G0_1_1_2_1 + 0.000866012294583867*G0_1_1_2_2 - 0.000487131915703427*G0_1_2_0_0 + 0.000487131915703425*G0_1_2_0_2 + 0.000270628842057459*G0_1_2_1_1 + 0.000866012294583867*G0_1_2_1_2 + 0.000487131915703426*G0_1_2_2_0 + 0.000866012294583867*G0_1_2_2_1 + 0.00243565957851713*G0_1_2_2_2 - 0.00216503073645967*G0_2_0_0_0 - 0.000487131915703427*G0_2_0_0_1 - 0.000487131915703427*G0_2_0_1_0 + 0.000487131915703425*G0_2_0_1_2 + 0.000487131915703425*G0_2_0_2_1 + 0.00216503073645967*G0_2_0_2_2 - 0.000487131915703427*G0_2_1_0_0 + 0.000487131915703425*G0_2_1_0_2 + 0.000270628842057458*G0_2_1_1_1 + 0.000866012294583867*G0_2_1_1_2 + 0.000487131915703425*G0_2_1_2_0 + 0.000866012294583867*G0_2_1_2_1 + 0.00243565957851713*G0_2_1_2_2 + 0.000487131915703426*G0_2_2_0_1 + 0.00216503073645967*G0_2_2_0_2 + 0.000487131915703425*G0_2_2_1_0 + 0.000866012294583867*G0_2_2_1_1 + 0.00243565957851713*G0_2_2_1_2 + 0.00216503073645967*G0_2_2_2_0 + 0.00243565957851713*G0_2_2_2_1 + 0.00866012294583867*G0_2_2_2_2; + A[190] = A[162]; + A[206] = A[178]; + A[0] = 0.00166469333136028*G0_0_0_0_0 + 6.73709007042453e-05*G0_0_0_0_1 + 6.73709007042454e-05*G0_0_0_0_2 + 6.73709007042453e-05*G0_0_0_1_0 + 7.29722951945297e-06*G0_0_0_1_1 + 3.64861475972648e-06*G0_0_0_1_2 + 6.73709007042454e-05*G0_0_0_2_0 + 3.64861475972648e-06*G0_0_0_2_1 + 7.29722951945298e-06*G0_0_0_2_2 + 6.73709007042453e-05*G0_0_1_0_0 + 7.29722951945297e-06*G0_0_1_0_1 + 3.64861475972648e-06*G0_0_1_0_2 + 7.29722951945297e-06*G0_0_1_1_0 + 5.47292213958973e-06*G0_0_1_1_1 + 1.82430737986324e-06*G0_0_1_1_2 + 3.64861475972648e-06*G0_0_1_2_0 + 1.82430737986324e-06*G0_0_1_2_1 + 1.82430737986324e-06*G0_0_1_2_2 + 6.73709007042454e-05*G0_0_2_0_0 + 3.64861475972648e-06*G0_0_2_0_1 + 7.29722951945298e-06*G0_0_2_0_2 + 3.64861475972648e-06*G0_0_2_1_0 + 1.82430737986324e-06*G0_0_2_1_1 + 1.82430737986324e-06*G0_0_2_1_2 + 7.29722951945298e-06*G0_0_2_2_0 + 1.82430737986324e-06*G0_0_2_2_1 + 5.47292213958973e-06*G0_0_2_2_2 + 6.73709007042453e-05*G0_1_0_0_0 + 7.29722951945297e-06*G0_1_0_0_1 + 3.64861475972648e-06*G0_1_0_0_2 + 7.29722951945297e-06*G0_1_0_1_0 + 5.47292213958973e-06*G0_1_0_1_1 + 1.82430737986324e-06*G0_1_0_1_2 + 3.64861475972648e-06*G0_1_0_2_0 + 1.82430737986324e-06*G0_1_0_2_1 + 1.82430737986324e-06*G0_1_0_2_2 + 7.29722951945297e-06*G0_1_1_0_0 + 5.47292213958973e-06*G0_1_1_0_1 + 1.82430737986324e-06*G0_1_1_0_2 + 5.47292213958973e-06*G0_1_1_1_0 + 2.69483602816982e-05*G0_1_1_1_1 + 6.73709007042455e-06*G0_1_1_1_2 + 1.82430737986324e-06*G0_1_1_2_0 + 6.73709007042455e-06*G0_1_1_2_1 + 4.49139338028303e-06*G0_1_1_2_2 + 3.64861475972648e-06*G0_1_2_0_0 + 1.82430737986324e-06*G0_1_2_0_1 + 1.82430737986324e-06*G0_1_2_0_2 + 1.82430737986324e-06*G0_1_2_1_0 + 6.73709007042455e-06*G0_1_2_1_1 + 4.49139338028303e-06*G0_1_2_1_2 + 1.82430737986324e-06*G0_1_2_2_0 + 4.49139338028303e-06*G0_1_2_2_1 + 6.73709007042455e-06*G0_1_2_2_2 + 6.73709007042454e-05*G0_2_0_0_0 + 3.64861475972648e-06*G0_2_0_0_1 + 7.29722951945298e-06*G0_2_0_0_2 + 3.64861475972648e-06*G0_2_0_1_0 + 1.82430737986324e-06*G0_2_0_1_1 + 1.82430737986324e-06*G0_2_0_1_2 + 7.29722951945298e-06*G0_2_0_2_0 + 1.82430737986324e-06*G0_2_0_2_1 + 5.47292213958973e-06*G0_2_0_2_2 + 3.64861475972648e-06*G0_2_1_0_0 + 1.82430737986324e-06*G0_2_1_0_1 + 1.82430737986324e-06*G0_2_1_0_2 + 1.82430737986324e-06*G0_2_1_1_0 + 6.73709007042455e-06*G0_2_1_1_1 + 4.49139338028303e-06*G0_2_1_1_2 + 1.82430737986324e-06*G0_2_1_2_0 + 4.49139338028303e-06*G0_2_1_2_1 + 6.73709007042454e-06*G0_2_1_2_2 + 7.29722951945298e-06*G0_2_2_0_0 + 1.82430737986324e-06*G0_2_2_0_1 + 5.47292213958973e-06*G0_2_2_0_2 + 1.82430737986324e-06*G0_2_2_1_0 + 4.49139338028303e-06*G0_2_2_1_1 + 6.73709007042454e-06*G0_2_2_1_2 + 5.47292213958973e-06*G0_2_2_2_0 + 6.73709007042454e-06*G0_2_2_2_1 + 2.69483602816982e-05*G0_2_2_2_2; + A[58] = A[198]; + A[28] = -A[181] - 0.000184647803695454*G0_0_0_0_0 - 1.04304866209647e-05*G0_0_0_0_1 - 4.17219464838584e-05*G0_0_0_0_2 - 1.04304866209647e-05*G0_0_0_1_0 - 4.22857565714813e-07*G0_0_0_1_2 - 4.17219464838584e-05*G0_0_0_2_0 - 4.22857565714813e-07*G0_0_0_2_1 - 7.18857861715133e-06*G0_0_0_2_2 - 1.04304866209647e-05*G0_0_1_0_0 - 4.22857565714811e-07*G0_0_1_0_2 - 9.86667653334483e-06*G0_0_1_1_1 - 4.22857565714811e-07*G0_0_1_2_0 + 4.36952817905271e-06*G0_0_1_2_2 - 4.17219464838584e-05*G0_0_2_0_0 - 4.22857565714813e-07*G0_0_2_0_1 - 7.18857861715133e-06*G0_0_2_0_2 - 4.22857565714813e-07*G0_0_2_1_0 + 4.36952817905271e-06*G0_0_2_1_2 - 7.18857861715133e-06*G0_0_2_2_0 + 4.36952817905271e-06*G0_0_2_2_1 + 2.25524035047882e-05*G0_0_2_2_2 - 1.04304866209647e-05*G0_1_0_0_0 - 4.22857565714813e-07*G0_1_0_0_2 - 9.86667653334484e-06*G0_1_0_1_1 - 4.22857565714813e-07*G0_1_0_2_0 + 4.36952817905271e-06*G0_1_0_2_2 - 9.86667653334484e-06*G0_1_1_0_1 - 9.86667653334484e-06*G0_1_1_1_0 + 0.000167733501066864*G0_1_1_1_1 - 9.86667653334469e-06*G0_1_1_1_2 - 9.86667653334469e-06*G0_1_1_2_1 - 4.22857565714813e-07*G0_1_2_0_0 + 4.36952817905271e-06*G0_1_2_0_2 - 9.86667653334469e-06*G0_1_2_1_1 + 4.36952817905271e-06*G0_1_2_2_0 + 1.83238278476404e-05*G0_1_2_2_2 - 4.17219464838584e-05*G0_2_0_0_0 - 4.22857565714813e-07*G0_2_0_0_1 - 7.18857861715133e-06*G0_2_0_0_2 - 4.22857565714813e-07*G0_2_0_1_0 + 4.36952817905271e-06*G0_2_0_1_2 - 7.18857861715133e-06*G0_2_0_2_0 + 4.36952817905271e-06*G0_2_0_2_1 + 2.25524035047882e-05*G0_2_0_2_2 - 4.22857565714813e-07*G0_2_1_0_0 + 4.36952817905271e-06*G0_2_1_0_2 - 9.8666765333447e-06*G0_2_1_1_1 + 4.36952817905271e-06*G0_2_1_2_0 + 1.83238278476404e-05*G0_2_1_2_2 - 7.18857861715133e-06*G0_2_2_0_0 + 4.36952817905271e-06*G0_2_2_0_1 + 2.25524035047882e-05*G0_2_2_0_2 + 4.36952817905271e-06*G0_2_2_1_0 + 1.83238278476404e-05*G0_2_2_1_2 + 2.25524035047882e-05*G0_2_2_2_0 + 1.83238278476404e-05*G0_2_2_2_1 + 0.000136723946247779*G0_2_2_2_2; + A[222] = -A[28] - 0.0012960584389158*G0_0_0_0_0 - 0.000552392933345407*G0_0_0_0_1 + 0.000151383008525891*G0_0_0_0_2 - 0.000552392933345408*G0_0_0_1_0 - 0.0003547774976347*G0_0_0_1_1 - 8.95048514096298e-06*G0_0_0_1_2 + 0.000151383008525891*G0_0_0_2_0 - 8.950485140963e-06*G0_0_0_2_1 + 0.000335114620828962*G0_0_0_2_2 - 0.000552392933345408*G0_0_1_0_0 - 0.0003547774976347*G0_0_1_0_1 - 8.95048514096301e-06*G0_0_1_0_2 - 0.0003547774976347*G0_0_1_1_0 - 0.000319257462114659*G0_0_1_1_1 - 0.000103459151078216*G0_0_1_1_2 - 8.950485140963e-06*G0_0_1_2_0 - 0.000103459151078216*G0_0_1_2_1 - 8.95048514096301e-06*G0_0_1_2_2 + 0.000151383008525891*G0_0_2_0_0 - 8.95048514096299e-06*G0_0_2_0_1 + 0.000335114620828962*G0_0_2_0_2 - 8.95048514096299e-06*G0_0_2_1_0 - 0.000103459151078216*G0_0_2_1_1 - 8.95048514096297e-06*G0_0_2_1_2 + 0.000335114620828962*G0_0_2_2_0 - 8.95048514096297e-06*G0_0_2_2_1 + 0.000151383008525891*G0_0_2_2_2 - 0.000552392933345408*G0_1_0_0_0 - 0.0003547774976347*G0_1_0_0_1 - 8.95048514096301e-06*G0_1_0_0_2 - 0.0003547774976347*G0_1_0_1_0 - 0.000319257462114659*G0_1_0_1_1 - 0.000103459151078216*G0_1_0_1_2 - 8.950485140963e-06*G0_1_0_2_0 - 0.000103459151078216*G0_1_0_2_1 - 8.95048514096301e-06*G0_1_0_2_2 - 0.0003547774976347*G0_1_1_0_0 - 0.000319257462114659*G0_1_1_0_1 - 0.000103459151078216*G0_1_1_0_2 - 0.000319257462114659*G0_1_1_1_0 - 7.68191244381831e-05*G0_1_1_1_1 - 0.000319257462114659*G0_1_1_1_2 - 0.000103459151078216*G0_1_1_2_0 - 0.000319257462114659*G0_1_1_2_1 - 0.0003547774976347*G0_1_1_2_2 - 8.950485140963e-06*G0_1_2_0_0 - 0.000103459151078216*G0_1_2_0_1 - 8.95048514096297e-06*G0_1_2_0_2 - 0.000103459151078216*G0_1_2_1_0 - 0.000319257462114659*G0_1_2_1_1 - 0.0003547774976347*G0_1_2_1_2 - 8.95048514096297e-06*G0_1_2_2_0 - 0.0003547774976347*G0_1_2_2_1 - 0.000552392933345408*G0_1_2_2_2 + 0.000151383008525891*G0_2_0_0_0 - 8.95048514096296e-06*G0_2_0_0_1 + 0.000335114620828962*G0_2_0_0_2 - 8.95048514096298e-06*G0_2_0_1_0 - 0.000103459151078216*G0_2_0_1_1 - 8.95048514096297e-06*G0_2_0_1_2 + 0.000335114620828962*G0_2_0_2_0 - 8.95048514096298e-06*G0_2_0_2_1 + 0.000151383008525891*G0_2_0_2_2 - 8.950485140963e-06*G0_2_1_0_0 - 0.000103459151078216*G0_2_1_0_1 - 8.95048514096297e-06*G0_2_1_0_2 - 0.000103459151078216*G0_2_1_1_0 - 0.000319257462114659*G0_2_1_1_1 - 0.0003547774976347*G0_2_1_1_2 - 8.95048514096297e-06*G0_2_1_2_0 - 0.0003547774976347*G0_2_1_2_1 - 0.000552392933345408*G0_2_1_2_2 + 0.000335114620828962*G0_2_2_0_0 - 8.95048514096298e-06*G0_2_2_0_1 + 0.00015138300852589*G0_2_2_0_2 - 8.95048514096298e-06*G0_2_2_1_0 - 0.0003547774976347*G0_2_2_1_1 - 0.000552392933345408*G0_2_2_1_2 + 0.000151383008525891*G0_2_2_2_0 - 0.000552392933345408*G0_2_2_2_1 - 0.0012960584389158*G0_2_2_2_2; + A[194] = A[222]; + A[131] = A[173]; + A[74] = A[214]; + A[40] = A[1] + 0.000207780168097663*G0_0_0_0_0 - 9.74627958755107e-06*G0_0_0_0_1 - 9.74627958755107e-06*G0_0_0_1_0 - 2.66246099579478e-05*G0_0_0_1_1 - 9.74627958755107e-06*G0_0_1_0_0 - 2.66246099579478e-05*G0_0_1_0_1 - 2.66246099579478e-05*G0_0_1_1_0 - 9.74627958755108e-06*G0_0_1_1_1 - 9.74627958755108e-06*G0_1_0_0_0 - 2.66246099579478e-05*G0_1_0_0_1 - 2.66246099579478e-05*G0_1_0_1_0 - 9.74627958755108e-06*G0_1_0_1_1 - 2.66246099579478e-05*G0_1_1_0_0 - 9.74627958755108e-06*G0_1_1_0_1 - 9.74627958755108e-06*G0_1_1_1_0 + 0.000207780168097664*G0_1_1_1_1 - 4.36071864643287e-07*G0_2_2_2_2; + A[145] = A[159]; + A[151] = A[25]; + A[102] = A[186]; + A[177] = A[191]; + A[114] = A[142]; + A[221] = A[179]; + A[196] = A[28]; + A[209] = A[223]; + A[13] = A[195]; + A[53] = A[123]; + A[30] = A[2]; + A[23] = A[121]; + A[128] = -A[113] - 0.000600457743314987*G0_0_0_0_0 - 5.77905339810198e-05*G0_0_0_0_1 + 1.36254104508096e-05*G0_0_0_0_2 - 5.77905339810198e-05*G0_0_0_1_0 - 6.20191096381674e-06*G0_0_0_1_1 + 6.10794261588015e-06*G0_0_0_1_2 + 1.36254104508096e-05*G0_0_0_2_0 + 6.10794261588015e-06*G0_0_0_2_1 + 0.000323626990293711*G0_0_0_2_2 - 5.77905339810198e-05*G0_0_1_0_0 - 6.20191096381674e-06*G0_0_1_0_1 + 6.10794261588015e-06*G0_0_1_0_2 - 6.20191096381674e-06*G0_0_1_1_0 + 8.03429374858084e-06*G0_0_1_1_1 + 4.74540157079921e-06*G0_0_1_1_2 + 6.10794261588016e-06*G0_0_1_2_0 + 4.74540157079921e-06*G0_0_1_2_1 + 5.32800532800623e-05*G0_0_1_2_2 + 1.36254104508096e-05*G0_0_2_0_0 + 6.10794261588015e-06*G0_0_2_0_1 + 0.000323626990293711*G0_0_2_0_2 + 6.10794261588015e-06*G0_0_2_1_0 + 4.74540157079921e-06*G0_0_2_1_1 + 5.32800532800623e-05*G0_0_2_1_2 + 0.000323626990293711*G0_0_2_2_0 + 5.32800532800623e-05*G0_0_2_2_1 + 0.00107546774213459*G0_0_2_2_2 - 5.77905339810198e-05*G0_1_0_0_0 - 6.20191096381674e-06*G0_1_0_0_1 + 6.10794261588015e-06*G0_1_0_0_2 - 6.20191096381674e-06*G0_1_0_1_0 + 8.03429374858084e-06*G0_1_0_1_1 + 4.74540157079921e-06*G0_1_0_1_2 + 6.10794261588016e-06*G0_1_0_2_0 + 4.74540157079921e-06*G0_1_0_2_1 + 5.32800532800623e-05*G0_1_0_2_2 - 6.20191096381674e-06*G0_1_1_0_0 + 8.03429374858084e-06*G0_1_1_0_1 + 4.74540157079921e-06*G0_1_1_0_2 + 8.03429374858084e-06*G0_1_1_1_0 + 2.76266942933657e-05*G0_1_1_1_1 + 6.43683183365833e-06*G0_1_1_1_2 + 4.74540157079921e-06*G0_1_1_2_0 + 6.43683183365833e-06*G0_1_1_2_1 + 1.71022393244645e-05*G0_1_1_2_2 + 6.10794261588015e-06*G0_1_2_0_0 + 4.74540157079921e-06*G0_1_2_0_1 + 5.32800532800623e-05*G0_1_2_0_2 + 4.74540157079921e-06*G0_1_2_1_0 + 6.43683183365832e-06*G0_1_2_1_1 + 1.71022393244645e-05*G0_1_2_1_2 + 5.32800532800623e-05*G0_1_2_2_0 + 1.71022393244645e-05*G0_1_2_2_1 + 0.000200622422844679*G0_1_2_2_2 + 1.36254104508096e-05*G0_2_0_0_0 + 6.10794261588016e-06*G0_2_0_0_1 + 0.000323626990293711*G0_2_0_0_2 + 6.10794261588016e-06*G0_2_0_1_0 + 4.74540157079921e-06*G0_2_0_1_1 + 5.32800532800623e-05*G0_2_0_1_2 + 0.000323626990293711*G0_2_0_2_0 + 5.32800532800623e-05*G0_2_0_2_1 + 0.00107546774213459*G0_2_0_2_2 + 6.10794261588016e-06*G0_2_1_0_0 + 4.74540157079921e-06*G0_2_1_0_1 + 5.32800532800623e-05*G0_2_1_0_2 + 4.74540157079921e-06*G0_2_1_1_0 + 6.43683183365833e-06*G0_2_1_1_1 + 1.71022393244645e-05*G0_2_1_1_2 + 5.32800532800623e-05*G0_2_1_2_0 + 1.71022393244645e-05*G0_2_1_2_1 + 0.000200622422844679*G0_2_1_2_2 + 0.000323626990293711*G0_2_2_0_0 + 5.32800532800623e-05*G0_2_2_0_1 + 0.00107546774213459*G0_2_2_0_2 + 5.32800532800623e-05*G0_2_2_1_0 + 1.71022393244645e-05*G0_2_2_1_1 + 0.000200622422844679*G0_2_2_1_2 + 0.00107546774213459*G0_2_2_2_0 + 0.000200622422844679*G0_2_2_2_1 + 0.0040979596535159*G0_2_2_2_2; + A[63] = A[49]; + A[140] = A[84]; + A[77] = A[35]; + A[171] = A[101]; + A[152] = A[40]; + } + + /// 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 mass_matrix_f4_p1_q4_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f4_p1_q4_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_p1_q4_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 4, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 3), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1))))), 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 4; + } + + /// 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 mass_matrix_f4_p1_q4_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f4_p1_q4_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f4_p1_q4_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f4_p1_q4_tensor_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f4_p1_q4_tensor_finite_element_0(); + break; + } + case 5: + { + return new mass_matrix_f4_p1_q4_tensor_finite_element_0(); + 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 mass_matrix_f4_p1_q4_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f4_p1_q4_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f4_p1_q4_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f4_p1_q4_tensor_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f4_p1_q4_tensor_dofmap_0(); + break; + } + case 5: + { + return new mass_matrix_f4_p1_q4_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f4_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/mass_matrix_2d/mass_matrix_f4_p2_q1_excafe.h b/mass_matrix_2d/mass_matrix_f4_p2_q1_excafe.h new file mode 100644 index 0000000..c32802c --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f4_p2_q1_excafe.h @@ -0,0 +1,569 @@ +#include +#include +#include +#include + +// Common sub-expression elimination pass took 88 minutes and 54.65 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][4]*w[1][1] + w[0][1]*w[1][4]; + const double var_1 = 0.2000000000000000111022302*var_0; + const double var_2 = -1.0000000000000000000000000*x[0][1]; + const double var_3 = var_2 + x[2][1]; + const double var_4 = -1.0000000000000000000000000*x[0][0]; + const double var_5 = var_4 + x[1][0]; + const double var_6 = var_2 + x[1][1]; + const double var_7 = var_4 + x[2][0]; + const double var_8 = var_3*var_5 + -1.0000000000000000000000000*var_6*var_7; + const double var_9 = std::abs(var_8); + const double var_10 = w[2][1]*w[3][2] + w[2][2]*w[3][1]; + const double var_11 = w[0][1]*w[1][2] + w[0][2]*w[1][1]; + const double var_12 = w[2][2]*w[3][0] + w[2][0]*w[3][2]; + const double var_13 = w[2][1]*w[3][0] + w[2][0]*w[3][1]; + const double var_14 = w[0][2]*w[1][0] + w[0][0]*w[1][2]; + const double var_15 = w[0][1]*w[1][0] + w[0][0]*w[1][1]; + const double var_16 = var_13*var_14 + var_12*var_15; + const double var_17 = var_10*w[0][0]*w[1][0] + var_11*w[2][0]*w[3][0] + var_16; + const double var_18 = w[2][3]*w[3][0] + w[2][0]*w[3][3]; + const double var_19 = w[2][3]*w[3][1] + w[2][1]*w[3][3]; + const double var_20 = w[2][2]*w[3][3] + w[2][3]*w[3][2]; + const double var_21 = w[0][0]*w[1][3] + w[0][3]*w[1][0]; + const double var_22 = w[0][0]*w[1][0]*w[2][3]*w[3][3] + var_18*var_21 + w[0][3]*w[1][3]*w[2][0]*w[3][0]; + const double var_23 = -1.0000000000000000000000000*var_21; + const double var_24 = -1.0000000000000000000000000*var_11; + const double var_25 = w[0][4]*w[1][5] + w[0][5]*w[1][4]; + const double var_26 = 2.6666666666666665186369300*var_25; + const double var_27 = var_26 + var_24 + 32.0000000000000000000000000*w[0][3]*w[1][3] + 2.6666666666666665186369300*var_23; + const double var_28 = w[0][1]*w[1][3] + w[0][3]*w[1][1]; + const double var_29 = w[0][3]*w[1][2] + w[0][2]*w[1][3]; + const double var_30 = var_13*var_29 + var_10*var_21 + var_12*var_28; + const double var_31 = var_30 + var_11*var_18; + const double var_32 = -1.0000000000000000000000000*var_28; + const double var_33 = w[0][5]*w[1][2] + w[0][2]*w[1][5]; + const double var_34 = 0.1000000000000000055511151*var_15; + const double var_35 = 0.3333333333333333148296163*var_33 + var_34; + const double var_36 = var_35 + var_32; + const double var_37 = w[0][3]*w[1][3]; + const double var_38 = 0.2000000000000000111022302*var_25; + const double var_39 = var_38 + var_37; + const double var_40 = w[2][0]*w[3][0]; + const double var_41 = var_25*var_40; + const double var_42 = -1.0000000000000000000000000*var_29; + const double var_43 = 0.1000000000000000055511151*var_14; + const double var_44 = var_43 + 0.3333333333333333148296163*var_0; + const double var_45 = var_42 + var_44; + const double var_46 = w[0][5]*w[1][3] + w[0][3]*w[1][5]; + const double var_47 = w[0][3]*w[1][4] + w[0][4]*w[1][3]; + const double var_48 = var_10*var_11; + const double var_49 = w[0][2]*w[1][2]*w[2][1]*w[3][1] + w[0][1]*w[1][1]*w[2][2]*w[3][2] + var_48; + const double var_50 = w[0][0]*w[1][5] + w[0][5]*w[1][0]; + const double var_51 = w[0][0]*w[1][4] + w[0][4]*w[1][0]; + const double var_52 = var_0*var_13 + var_51*w[2][1]*w[3][1] + var_12*var_33 + var_50*w[2][2]*w[3][2]; + const double var_53 = var_46*w[2][2]*w[3][2] + var_47*w[2][1]*w[3][1] + 0.4750000000000000333066907*var_49 + -0.2000000000000000111022302*var_52; + const double var_54 = var_20*var_36 + -1.0000000000000000000000000*var_10*w[0][3]*w[1][3] + 0.3333333333333333148296163*var_53 + var_27*w[2][3]*w[3][3] + 0.1250000000000000000000000*w[0][0]*w[1][0]*w[2][0]*w[3][0] + 0.4000000000000000222044605*var_22 + -2.6666666666666665186369300*var_18*var_39 + var_19*var_45 + 0.1000000000000000055511151*var_31 + 0.2000000000000000111022302*var_41; + const double var_55 = var_18*w[0][0]*w[1][0] + var_21*w[2][0]*w[3][0]; + const double var_56 = -0.0001515151515151515150201*var_55 + -0.0000378787878787878787550*var_17 + 0.0020202020202020202002680*var_54; + const double var_57 = var_10*var_14 + var_11*var_12; + const double var_58 = var_57 + var_13*w[0][2]*w[1][2] + var_15*w[2][2]*w[3][2]; + const double var_59 = w[2][1]*w[3][5] + w[2][5]*w[3][1]; + const double var_60 = w[2][5]*w[3][0] + w[2][0]*w[3][5]; + const double var_61 = w[0][1]*w[1][5] + w[0][5]*w[1][1]; + const double var_62 = -1.0000000000000000000000000*var_15*w[2][5]*w[3][5] + -1.0000000000000000000000000*var_13*w[0][5]*w[1][5] + -1.0000000000000000000000000*var_60*var_61 + -1.0000000000000000000000000*var_50*var_59; + const double var_63 = w[2][2]*w[3][5] + w[2][5]*w[3][2]; + const double var_64 = w[2][2]*w[3][2]; + const double var_65 = 0.2000000000000000111022302*var_64 + 2.6666666666666665186369300*w[2][5]*w[3][5] + -0.5333333333333333259318465*var_63; + const double var_66 = w[0][2]*w[1][2]*w[2][5]*w[3][5] + w[0][5]*w[1][5]*w[2][2]*w[3][2] + var_33*var_63; + const double var_67 = var_13*var_33 + var_12*var_61 + var_10*var_50; + const double var_68 = var_15*var_63 + var_67; + const double var_69 = 0.1000000000000000055511151*var_11; + const double var_70 = var_69 + 0.3333333333333333148296163*var_21; + const double var_71 = w[0][4]*w[1][2] + w[0][2]*w[1][4]; + const double var_72 = -1.0000000000000000000000000*var_0*var_10 + -1.0000000000000000000000000*var_29*w[2][0]*w[3][0] + -1.0000000000000000000000000*var_71*w[2][1]*w[3][1] + -1.0000000000000000000000000*var_12*var_21; + const double var_73 = -0.3333333333333333148296163*var_33 + 4.0000000000000000000000000*w[0][5]*w[1][5]; + const double var_74 = w[0][5]*w[1][5]; + const double var_75 = var_13*var_15; + const double var_76 = var_75 + w[0][1]*w[1][1]*w[2][0]*w[3][0] + w[0][0]*w[1][0]*w[2][1]*w[3][1]; + const double var_77 = 0.4750000000000000333066907*var_76 + -8.0000000000000000000000000*var_63*var_74 + var_25*w[2][1]*w[3][1] + var_46*w[2][0]*w[3][0]; + const double var_78 = var_62 + 0.3333333333333333148296163*var_77 + var_44*var_59 + 0.1000000000000000055511151*var_68 + 0.1250000000000000000000000*w[0][2]*w[1][2]*w[2][2]*w[3][2] + 8.0000000000000000000000000*var_73*w[2][5]*w[3][5] + var_60*var_70 + 0.4000000000000000222044605*var_66 + 0.0666666666666666657414808*var_72 + var_47*var_65; + const double var_79 = var_63*w[0][2]*w[1][2] + var_33*w[2][2]*w[3][2]; + const double var_80 = 0.0020202020202020202002680*var_78 + -0.0000378787878787878787550*var_58 + -0.0001515151515151515150201*var_79; + const double var_81 = w[0][4]*w[1][4]; + const double var_82 = 0.0666666666666666657414808*var_14; + const double var_83 = var_82 + 1.3333333333333332593184650*var_46 + 0.4000000000000000222044605*var_81; + const double var_84 = -0.2500000000000000000000000*w[0][1]*w[1][1]; + const double var_85 = var_50 + var_29; + const double var_86 = -1.0000000000000000000000000*var_61; + const double var_87 = var_32 + var_86; + const double var_88 = var_87 + var_85; + const double var_89 = -0.0181818181818181809350499*var_83 + 0.0060606060606060606008039*var_88 + 0.0303030303030303038713811*var_84; + const double var_90 = w[0][1]*w[1][1]; + const double var_91 = var_47 + var_25; + const double var_92 = 0.1454545454545454474803989*var_91 + 0.0250000000000000013877788*var_14 + 0.0727272727272727237401995*var_81 + 0.3636363636363636464565730*var_46 + 0.1818181818181818232282865*var_90 + 0.0909090909090909116141432*var_1; + const double var_93 = var_13 + var_10; + const double var_94 = var_11 + var_15; + const double var_95 = var_93*w[0][1]*w[1][1] + var_94*w[2][1]*w[3][1]; + const double var_96 = var_63 + var_18; + const double var_97 = var_20 + var_60; + const double var_98 = w[2][1]*w[3][1]; + const double var_99 = -1.0000000000000000000000000*var_51; + const double var_100 = -0.0533333333333333367565210*w[0][4]*w[1][4] + 0.8000000000000000444089210*var_90 + 0.2666666666666666629659233*var_46 + 0.0666666666666666657414808*var_23; + const double var_101 = w[0][2]*w[1][2]; + const double var_102 = -1.0000000000000000000000000*var_33; + const double var_103 = 0.8000000000000000444089210*var_74 + 0.0133333333333333341891302*var_101 + 0.0666666666666666657414808*var_102 + -0.1333333333333333314829616*var_15; + const double var_104 = w[0][0]*w[1][0]; + const double var_105 = var_61 + 0.0400000000000000008326673*var_104; + const double var_106 = 0.3333333333333333148296163*var_28; + const double var_107 = 0.0666666666666666657414808*var_42; + const double var_108 = var_100 + 0.0133333333333333341891302*var_99 + -0.0833333333333333287074041*var_11 + var_107 + 0.6666666666666666296592325*var_105 + var_103 + 0.2666666666666666629659233*var_37 + var_106; + const double var_109 = -1.0000000000000000000000000*var_50; + const double var_110 = var_102 + var_109; + const double var_111 = -1.0000000000000000000000000*var_71; + const double var_112 = 0.0266666666666666683782605*var_101 + 0.2666666666666666629659233*var_74 + -0.0833333333333333287074041*var_15; + const double var_113 = var_100 + -0.1333333333333333314829616*var_11 + 0.3333333333333333148296163*var_105 + 0.0133333333333333341891302*var_111 + 0.8000000000000000444089210*var_37 + 0.0666666666666666657414808*var_110 + var_112 + 2.0000000000000000000000000*var_106; + const double var_114 = var_74 + var_37; + const double var_115 = var_12*var_14; + const double var_116 = w[0][2]*w[1][2]*w[2][0]*w[3][0] + w[0][0]*w[1][0]*w[2][2]*w[3][2] + var_115; + const double var_117 = var_10 + 4.0000000000000000000000000*var_18; + const double var_118 = -1.0000000000000000000000000*var_37; + const double var_119 = 0.2000000000000000111022302*var_21; + const double var_120 = var_119 + var_118; + const double var_121 = -1.0000000000000000000000000*var_74; + const double var_122 = 0.2000000000000000111022302*var_33; + const double var_123 = var_121 + var_122; + const double var_124 = var_13 + 4.0000000000000000000000000*var_63; + const double var_125 = -1.0000000000000000000000000*var_104; + const double var_126 = 0.2000000000000000111022302*var_125 + 0.4000000000000000222044605*var_11 + -8.0000000000000000000000000*var_37 + var_21; + const double var_127 = 4.0000000000000000000000000*var_121; + const double var_128 = var_126 + 0.8000000000000000444089210*var_50 + var_86 + var_127; + const double var_129 = -1.0000000000000000000000000*var_101; + const double var_130 = var_33 + -8.0000000000000000000000000*var_74 + 0.4000000000000000222044605*var_15 + 0.2000000000000000111022302*var_129; + const double var_131 = var_32 + var_130 + 4.0000000000000000000000000*var_118 + 0.8000000000000000444089210*var_29; + const double var_132 = var_10*var_15 + var_11*var_13; + const double var_133 = var_14*w[2][1]*w[3][1] + var_12*w[0][1]*w[1][1] + var_132; + const double var_134 = var_0*var_12 + var_10*var_51 + var_13*var_71; + const double var_135 = var_64 + var_40; + const double var_136 = -1.0000000000000000000000000*var_0*var_135; + const double var_137 = 0.2500000000000000000000000*var_134 + var_61*var_64 + -0.5000000000000000000000000*var_12*var_71 + 0.1250000000000000000000000*var_136 + var_15*var_18 + var_11*var_63 + var_28*var_40 + 1.4375000000000000000000000*var_133; + const double var_138 = 2.0000000000000000000000000*var_12*var_46 + var_10*var_29 + var_13*var_50 + var_61*w[2][0]*w[3][0] + var_28*w[2][2]*w[3][2]; + const double var_139 = var_10*var_32; + const double var_140 = -1.0000000000000000000000000*var_85*var_98 + 0.2000000000000000111022302*var_138 + var_139 + var_13*var_86; + const double var_141 = var_131*var_60 + 0.0625000000000000000000000*var_116 + var_128*var_20 + var_117*var_123 + 0.5000000000000000000000000*var_63*var_71 + 0.2000000000000000111022302*var_137 + var_120*var_124 + 2.0000000000000000000000000*var_140 + -1.0000000000000000000000000*var_46*var_93 + var_114*var_12; + const double var_142 = 1.6000000000000000888178420*var_47; + const double var_143 = 5.3333333333333330372738601*var_74 + -0.0666666666666666657414808*var_15 + 0.8000000000000000444089210*var_102 + var_142 + 0.1666666666666666574148081*w[0][2]*w[1][2]; + const double var_144 = 0.5333333333333333259318465*var_42; + const double var_145 = var_144 + 1.6000000000000000888178420*var_81 + 2.6666666666666665186369300*var_46 + 0.3333333333333333148296163*var_90 + var_43; + const double var_146 = 2.6666666666666665186369300*var_37 + 0.5333333333333333259318465*var_23 + 2.1333333333333333037273860*var_25 + 0.2000000000000000111022302*var_104; + const double var_147 = -1.0000000000000000000000000*var_0; + const double var_148 = var_147 + var_99; + const double var_149 = 0.2666666666666666629659233*var_148; + const double var_150 = 0.5333333333333333259318465*var_109; + const double var_151 = var_149 + var_143 + 0.4000000000000000222044605*var_111 + var_145 + var_146 + var_150; + const double var_152 = 1.6000000000000000888178420*var_25; + const double var_153 = -0.0666666666666666657414808*var_11 + 0.1666666666666666574148081*w[0][0]*w[1][0] + var_152 + 0.8000000000000000444089210*var_23 + 5.3333333333333330372738601*var_37; + const double var_154 = 0.2000000000000000111022302*var_101 + 2.6666666666666665186369300*var_74 + 2.1333333333333333037273860*var_47; + const double var_155 = var_147 + var_111; + const double var_156 = 0.2666666666666666629659233*var_155; + const double var_157 = var_153 + 0.4000000000000000222044605*var_99 + var_156 + var_145 + 0.5333333333333333259318465*var_110 + var_154; + const double var_158 = var_101 + var_104; + const double var_159 = var_46 + var_25; + const double var_160 = var_50 + var_61; + const double var_161 = var_32 + var_99; + const double var_162 = var_42 + var_111; + const double var_163 = var_74 + var_81; + const double var_164 = var_163 + var_37; + const double var_165 = 8.0000000000000000000000000*var_164 + var_162 + -1.0000000000000000000000000*var_160 + var_161; + const double var_166 = 0.6666666666666666296592325*var_90; + const double var_167 = var_147 + 4.0000000000000000000000000*var_47 + var_23; + const double var_168 = var_167 + var_102; + const double var_169 = var_14 + var_15; + const double var_170 = var_11 + var_169; + const double var_171 = 1.3333333333333332593184650*var_165 + 8.0000000000000000000000000*var_159 + 0.1666666666666666574148081*var_170 + var_166 + 2.0000000000000000000000000*var_168 + 0.6666666666666666296592325*var_158; + const double var_172 = -1.0000000000000000000000000*var_90; + const double var_173 = -1.0000000000000000000000000*var_14; + const double var_174 = var_173 + var_0; + const double var_175 = 0.0333333333333333328707404*var_174 + 0.0666666666666666657414808*var_172 + -0.5333333333333333259318465*var_46 + -0.2666666666666666629659233*var_81; + const double var_176 = -0.4000000000000000222044605*var_47; + const double var_177 = -0.5333333333333333259318465*var_74; + const double var_178 = -0.0083333333333333332176851*var_15 + 0.1000000000000000055511151*var_33 + -0.0333333333333333328707404*var_101 + var_177 + var_176; + const double var_179 = 0.0166666666666666664353702*var_11; + const double var_180 = var_179 + -0.8000000000000000444089210*var_37 + 0.1666666666666666574148081*var_21 + -0.2666666666666666629659233*var_25; + const double var_181 = 0.3333333333333333148296163*var_71 + var_29; + const double var_182 = 0.1333333333333333314829616*var_51 + var_175 + 0.2000000000000000111022302*var_50 + var_178 + var_180 + 0.0666666666666666657414808*var_86 + 0.1000000000000000055511151*var_181; + const double var_183 = -0.5333333333333333259318465*var_37; + const double var_184 = -0.0333333333333333328707404*var_104 + -0.4000000000000000222044605*var_25 + -0.0083333333333333332176851*var_11 + var_183 + 0.1000000000000000055511151*var_21; + const double var_185 = 0.0166666666666666664353702*var_15; + const double var_186 = 0.1666666666666666574148081*var_33 + var_185 + -0.8000000000000000444089210*var_74 + -0.2666666666666666629659233*var_47; + const double var_187 = 0.3333333333333333148296163*var_51; + const double var_188 = var_187 + var_50; + const double var_189 = var_186 + 0.1000000000000000055511151*var_188 + 0.2000000000000000111022302*var_29 + var_175 + 0.1333333333333333314829616*var_71 + 0.0666666666666666657414808*var_32 + var_184; + const double var_190 = var_51 + var_71; + const double var_191 = var_61 + var_28; + const double var_192 = -1.0000000000000000000000000*var_94 + var_42 + var_109; + const double var_193 = -1.0000000000000000000000000*var_81; + const double var_194 = 0.0166666666666666664353702*var_14; + const double var_195 = -0.2666666666666666629659233*var_91 + 0.3333333333333333148296163*var_191 + 0.2500000000000000000000000*var_90 + 0.1333333333333333314829616*var_0 + 0.0333333333333333328707404*var_190 + 0.0666666666666666657414808*var_192 + 0.4000000000000000222044605*var_193 + -0.0083333333333333332176851*var_158 + var_194; + const double var_196 = var_182*w[3][0] + var_195*w[3][1] + var_157*w[3][3] + var_189*w[3][2] + var_151*w[3][5] + 0.2000000000000000111022302*var_171*w[3][4]; + const double var_197 = -0.2000000000000000111022302*var_10 + 0.5000000000000000000000000*w[2][0]*w[3][0]; + const double var_198 = 0.3333333333333333148296163*var_197 + -0.8000000000000000444089210*var_18 + 5.3333333333333330372738601*w[2][3]*w[3][3]; + const double var_199 = -0.2000000000000000111022302*var_13 + 0.5000000000000000000000000*w[2][2]*w[3][2]; + const double var_200 = 0.3333333333333333148296163*var_199 + 5.3333333333333330372738601*w[2][5]*w[3][5] + -0.8000000000000000444089210*var_63; + const double var_201 = 0.2500000000000000000000000*var_13 + var_64; + const double var_202 = var_12 + var_201; + const double var_203 = -0.0333333333333333328707404*var_202 + 0.1000000000000000055511151*var_20 + 0.1666666666666666574148081*var_18; + const double var_204 = var_203 + 0.1000000000000000055511151*var_63 + 0.2000000000000000111022302*var_60; + const double var_205 = 0.5000000000000000000000000*var_0*var_98; + const double var_206 = var_20*var_29; + const double var_207 = var_50*var_60 + var_206; + const double var_208 = var_189*w[2][2] + var_195*w[2][1] + var_182*w[2][0]; + const double var_209 = var_208 + var_151*w[2][5]; + const double var_210 = var_157*w[2][3]; + const double var_211 = var_209 + var_210; + const double var_212 = var_13 + var_12; + const double var_213 = var_212 + var_10; + const double var_214 = var_98 + var_40; + const double var_215 = var_64 + var_214; + const double var_216 = 0.6666666666666666296592325*var_215 + 0.1666666666666666574148081*var_213; + const double var_217 = var_12*var_158 + var_135*var_14; + const double var_218 = 0.1250000000000000000000000*var_10 + 0.5000000000000000000000000*var_40; + const double var_219 = -0.3333333333333333148296163*var_218 + 0.5000000000000000000000000*var_18 + -2.6666666666666665186369300*w[2][3]*w[3][3]; + const double var_220 = var_20 + var_219 + 0.5000000000000000000000000*var_60; + const double var_221 = 0.5000000000000000000000000*var_12*var_91 + var_220*var_71 + var_216*w[0][4]*w[1][4] + 0.0312500000000000000000000*var_217; + const double var_222 = var_198*var_47 + 4.0000000000000000000000000*var_191*var_98 + 0.5000000000000000000000000*var_205 + 0.2000000000000000111022302*var_221 + var_196*w[2][4] + 12.8750000000000000000000000*w[0][1]*w[1][1]*w[2][1]*w[3][1] + var_204*var_51 + var_211*w[3][4] + var_200*var_25 + 0.8000000000000000444089210*var_207; + const double var_223 = var_33 + var_21; + const double var_224 = var_13*var_32; + const double var_225 = -1.0000000000000000000000000*var_223*w[2][1]*w[3][1] + -1.0000000000000000000000000*var_10*var_61 + var_224; + const double var_226 = var_42 + var_191 + var_110 + var_23; + const double var_227 = -0.2000000000000000111022302*var_94 + var_90; + const double var_228 = 0.5333333333333333259318465*var_91 + 0.2666666666666666629659233*var_226 + 1.6000000000000000888178420*var_114 + 0.3333333333333333148296163*var_227 + -0.1066666666666666735130420*var_190 + 0.8000000000000000444089210*var_83 + 0.0666666666666666657414808*var_158; + const double var_229 = 1.6000000000000000888178420*var_46; + const double var_230 = var_229 + 0.4266666666666666940521679*w[0][4]*w[1][4] + var_166 + var_82; + const double var_231 = var_24 + 4.0000000000000000000000000*var_23; + const double var_232 = 1.0666666666666666518636930*var_37 + 0.0666666666666666657414808*var_231 + 0.1600000000000000033306691*var_104; + const double var_233 = var_106 + var_61; + const double var_234 = 0.2666666666666666629659233*var_42; + const double var_235 = 0.1066666666666666735130420*var_99 + var_234 + var_232 + 0.1600000000000000033306691*var_111 + 0.8000000000000000444089210*var_233 + var_230 + var_150; + const double var_236 = var_235*w[2][5] + var_228*w[2][3]; + const double var_237 = -1.0000000000000000000000000*var_15; + const double var_238 = 0.1600000000000000033306691*var_101 + 1.0666666666666666518636930*var_74 + 0.0666666666666666657414808*var_237; + const double var_239 = 0.3333333333333333148296163*var_61 + var_28; + const double var_240 = 0.2666666666666666629659233*var_110; + const double var_241 = var_144 + 0.1600000000000000033306691*var_99 + var_238 + 0.8000000000000000444089210*var_239 + var_240 + var_230; + const double var_242 = var_228*w[2][5] + var_241*w[2][3]; + const double var_243 = 0.6666666666666666296592325*var_114*var_98 + 0.0833333333333333287074041*var_225 + var_236*w[3][5] + 0.0666666666666666657414808*var_141 + var_242*w[3][3] + var_113*var_19 + 0.2000000000000000111022302*var_222 + var_108*var_59; + const double var_244 = 0.3333333333333333148296163*var_46*var_98; + const double var_245 = var_243 + var_244; + const double var_246 = 0.0227272727272727279035358*var_10 + 0.0370370370370370349810685*var_18; + const double var_247 = 0.0227272727272727279035358*var_13 + 0.0370370370370370349810685*var_63; + const double var_248 = var_247*w[0][0]*w[1][0] + var_246*w[0][2]*w[1][2] + 0.0370370370370370349810685*var_12*var_85; + const double var_249 = -0.0046296296296296293726336*var_33 + 0.0404040404040404074748061*w[0][5]*w[1][5] + -0.0028409090909090909879420*var_15; + const double var_250 = 0.0404040404040404074748061*w[0][3]*w[1][3] + -0.0028409090909090909879420*var_11 + -0.0046296296296296293726336*var_21; + const double var_251 = var_250*w[2][2]*w[3][2] + var_249*w[2][0]*w[3][0]; + const double var_252 = 0.0400000000000000008326673*var_251 + -0.0050000000000000001040834*var_248 + 0.0101010101010101018687015*var_245 + var_80 + -0.0018939393939393939919613*var_95 + var_56 + -0.0074074074074074076901031*var_92*var_97 + 0.1111111111111111049432054*var_89*var_96; + A[4] = 0.1428571428571428492126927*var_252*var_9; + const double var_253 = var_33 + var_0; + const double var_254 = -1.0000000000000000000000000*var_253*w[2][0]*w[3][0] + -1.0000000000000000000000000*var_12*var_50 + var_13*var_99; + const double var_255 = 0.5000000000000000000000000*var_201; + const double var_256 = var_81 + var_37; + const double var_257 = w[2][2]*w[3][4] + w[2][4]*w[3][2]; + const double var_258 = var_257*var_71; + const double var_259 = var_258 + var_206 + var_256*var_64; + const double var_260 = 0.3333333333333333148296163*var_104 + var_26 + 0.2666666666666666629659233*var_23 + var_69 + 1.6000000000000000888178420*var_37; + const double var_261 = 0.2000000000000000111022302*var_90 + 2.1333333333333333037273860*var_46 + 2.6666666666666665186369300*var_81; + const double var_262 = 0.6666666666666666296592325*var_32 + var_42; + const double var_263 = 0.5333333333333333259318465*var_86; + const double var_264 = var_263 + var_143 + var_261 + var_260 + 0.5333333333333333259318465*var_155 + 0.4000000000000000222044605*var_262; + const double var_265 = var_86 + var_102; + const double var_266 = -0.0666666666666666657414808*var_14 + var_229 + 5.3333333333333330372738601*var_81 + 0.1666666666666666574148081*w[0][1]*w[1][1] + 0.8000000000000000444089210*var_147; + const double var_267 = 0.5333333333333333259318465*var_111; + const double var_268 = var_234 + var_266 + var_260 + 0.4000000000000000222044605*var_32 + var_267 + 0.5333333333333333259318465*var_265 + var_154; + const double var_269 = var_24 + var_21; + const double var_270 = 0.0666666666666666657414808*var_125 + 0.0333333333333333328707404*var_269 + -0.2666666666666666629659233*var_37 + -0.5333333333333333259318465*var_25; + const double var_271 = -0.8000000000000000444089210*var_81 + -0.2666666666666666629659233*var_46 + var_194 + 0.1666666666666666574148081*var_0; + const double var_272 = var_71 + 0.3333333333333333148296163*var_29; + const double var_273 = 0.0666666666666666657414808*var_109 + 0.1333333333333333314829616*var_28 + var_271 + 0.2000000000000000111022302*var_61 + var_178 + var_270 + 0.1000000000000000055511151*var_272; + const double var_274 = -0.4000000000000000222044605*var_46; + const double var_275 = -0.5333333333333333259318465*var_81; + const double var_276 = -0.0083333333333333332176851*var_14 + -0.0333333333333333328707404*var_90 + var_275 + 0.1000000000000000055511151*var_0 + var_274; + const double var_277 = 0.0666666666666666657414808*var_99 + var_276 + var_186 + 0.1333333333333333314829616*var_29 + 0.2000000000000000111022302*var_71 + 0.1000000000000000055511151*var_233 + var_270; + const double var_278 = var_101 + var_90; + const double var_279 = var_47 + var_46; + const double var_280 = var_29 + var_28; + const double var_281 = var_50 + var_51; + const double var_282 = var_86 + var_111 + -1.0000000000000000000000000*var_169; + const double var_283 = 0.2500000000000000000000000*var_104 + 0.0333333333333333328707404*var_280 + 0.1333333333333333314829616*var_21 + 0.3333333333333333148296163*var_281 + var_179 + -0.0083333333333333332176851*var_278 + -0.2666666666666666629659233*var_279 + 0.0666666666666666657414808*var_282 + 0.4000000000000000222044605*var_118; + const double var_284 = 0.2000000000000000111022302*var_171*w[3][3] + var_264*w[3][5] + var_268*w[3][4] + var_283*w[3][0] + var_273*w[3][1] + var_277*w[3][2]; + const double var_285 = -0.0625000000000000000000000*var_14 + 0.2000000000000000111022302*var_46 + 0.3333333333333333148296163*var_81; + const double var_286 = var_285 + 0.2500000000000000000000000*var_71 + 0.5000000000000000000000000*var_29; + const double var_287 = var_61 + var_71; + const double var_288 = -1.0000000000000000000000000*var_287*var_40 + var_109*var_13 + var_12*var_99; + const double var_289 = 1.6000000000000000888178420*var_74 + var_34 + 2.6666666666666665186369300*var_47 + 0.5333333333333333259318465*var_161 + 0.3333333333333333148296163*var_101; + const double var_290 = 0.2500000000000000000000000*var_94 + 32.0000000000000000000000000*w[0][4]*w[1][4]; + const double var_291 = -1.0000000000000000000000000*var_290 + var_190; + const double var_292 = w[2][4]*w[3][1] + w[2][1]*w[3][4]; + const double var_293 = 4.0000000000000000000000000*var_292 + var_12; + const double var_294 = var_86 + var_104; + const double var_295 = var_38 + -0.0625000000000000000000000*var_11 + 0.3333333333333333148296163*var_37; + const double var_296 = var_295 + 0.5000000000000000000000000*var_71 + 0.2500000000000000000000000*var_29; + const double var_297 = var_90 + var_104; + const double var_298 = var_15*var_214 + var_13*var_297; + const double var_299 = -1.0000000000000000000000000*var_28*var_64; + const double var_300 = var_299 + var_10*var_42; + const double var_301 = var_20 + -1.0000000000000000000000000*var_19; + const double var_302 = w[2][0]*w[3][4] + w[2][4]*w[3][0]; + const double var_303 = var_257 + -1.0000000000000000000000000*var_302; + const double var_304 = var_303*var_37 + var_301*var_81; + const double var_305 = -1.0000000000000000000000000*var_51*var_64; + const double var_306 = -1.0000000000000000000000000*var_14*var_257 + var_300 + var_305 + var_20*var_24 + 2.0000000000000000000000000*var_304 + var_111*var_12; + const double var_307 = 2.0000000000000000000000000*var_74 + 0.3333333333333333148296163*var_15; + const double var_308 = var_11*var_40 + var_10*var_104 + var_16; + const double var_309 = var_41 + 0.0500000000000000027755576*var_30 + 0.0312500000000000000000000*var_308 + var_197*var_37; + const double var_310 = 0.3333333333333333148296163*var_309 + 0.8125000000000000000000000*w[0][0]*w[1][0]*w[2][0]*w[3][0] + 0.1000000000000000055511151*var_10*var_25; + const double var_311 = 0.5000000000000000000000000*w[2][1]*w[3][1] + -0.2000000000000000111022302*var_12; + const double var_312 = var_14*var_98 + var_132 + var_12*var_90; + const double var_313 = 0.0104166666666666660884255*var_312 + 0.0166666666666666664353702*var_134 + 0.1000000000000000055511151*var_12*var_46 + 0.8125000000000000000000000*w[0][1]*w[1][1]*w[2][1]*w[3][1] + 0.3333333333333333148296163*var_311*var_81 + var_244; + const double var_314 = var_10 + var_12; + const double var_315 = 0.5000000000000000000000000*var_10 + var_40; + const double var_316 = var_315 + var_255; + const double var_317 = var_64 + var_98; + const double var_318 = 0.1250000000000000000000000*var_317 + var_212; + const double var_319 = var_14 + var_11; + const double var_320 = -32.0000000000000000000000000*var_33 + 8.0000000000000000000000000*var_167 + var_319; + const double var_321 = -0.2500000000000000000000000*w[0][2]*w[1][2]; + const double var_322 = var_33 + var_321 + -4.0000000000000000000000000*var_47; + const double var_323 = var_32 + var_147 + var_322 + -8.0000000000000000000000000*var_46; + const double var_324 = var_98 + 0.5000000000000000000000000*var_12; + const double var_325 = var_255 + var_324; + const double var_326 = var_218 + var_324; + const double var_327 = 0.5000000000000000000000000*var_98 + 0.1250000000000000000000000*var_12; + const double var_328 = var_315 + var_327; + const double var_329 = 32.0000000000000000000000000*w[0][5]*w[1][5] + 0.2500000000000000000000000*var_319; + const double var_330 = var_23 + -8.0000000000000000000000000*var_25; + const double var_331 = var_322 + var_99 + var_330; + const double var_332 = var_32*var_93; + const double var_333 = -0.2500000000000000000000000*w[2][2]*w[3][2] + var_63; + const double var_334 = -0.2500000000000000000000000*var_33 + var_74; + const double var_335 = -1.0000000000000000000000000*var_0*var_316 + -1.0000000000000000000000000*var_328*var_71 + var_160*var_333 + -1.0000000000000000000000000*var_21*var_325 + -0.0625000000000000000000000*var_58 + var_323*var_60 + -1.0000000000000000000000000*var_329*var_63 + 0.9062500000000000000000000*var_76 + var_331*var_59 + 8.0000000000000000000000000*var_62 + -0.1250000000000000000000000*var_135*var_28 + var_332 + -1.0000000000000000000000000*var_318*var_51 + var_314*var_334 + -1.0000000000000000000000000*var_29*var_326 + var_320*w[2][5]*w[3][5]; + const double var_336 = var_319*w[2][2]*w[3][2] + var_314*w[0][2]*w[1][2]; + const double var_337 = -1.0000000000000000000000000*var_50*var_98 + -1.0000000000000000000000000*var_61*var_93; + const double var_338 = -1.0000000000000000000000000*var_214*var_33; + const double var_339 = var_125 + var_71; + const double var_340 = var_172 + var_29; + const double var_341 = var_33*var_64; + const double var_342 = var_0 + var_21; + const double var_343 = 0.5000000000000000000000000*var_101 + var_297; + const double var_344 = var_342 + -1.0000000000000000000000000*var_343; + const double var_345 = -0.0625000000000000000000000*var_336 + var_340*var_60 + -1.0000000000000000000000000*var_212*var_50 + -0.5000000000000000000000000*var_341 + var_344*var_63 + var_10*var_81 + var_339*var_59 + var_338 + -1.0000000000000000000000000*var_40*var_61 + var_337 + var_12*var_37; + const double var_346 = var_273*w[2][1] + var_277*w[2][2] + var_283*w[2][0]; + const double var_347 = var_264*w[2][5] + var_346; + const double var_348 = 0.8000000000000000444089210*var_162 + var_297; + const double var_349 = 0.5000000000000000000000000*var_50 + 0.2500000000000000000000000*var_51 + var_285; + const double var_350 = var_64*w[0][2]*w[1][2] + -1.0000000000000000000000000*var_104*var_12 + -1.0000000000000000000000000*var_10*var_90; + const double var_351 = 0.5000000000000000000000000*var_61 + var_295 + 0.2500000000000000000000000*var_28; + const double var_352 = 0.0416666666666666643537020*var_14 + 0.5000000000000000000000000*var_227 + var_275 + var_1; + const double var_353 = var_233 + var_352; + const double var_354 = -0.2000000000000000111022302*var_169 + var_104; + const double var_355 = var_183 + 0.5000000000000000000000000*var_354 + var_119 + 0.0416666666666666643537020*var_11; + const double var_356 = var_188 + var_355; + const double var_357 = var_71 + var_29; + const double var_358 = var_176 + 0.1666666666666666574148081*var_357; + const double var_359 = var_349*var_40 + var_196*w[2][3] + 0.0416666666666666643537020*var_68 + var_214*var_74 + 0.0625000000000000000000000*var_350 + var_358*var_63 + var_159*var_200 + var_351*var_98 + var_209*w[3][3] + var_256*var_65 + 0.0666666666666666657414808*var_335 + var_347*w[3][4] + var_348*w[2][5]*w[3][5] + var_353*var_59 + 0.2000000000000000111022302*var_216*var_47 + 0.1000000000000000055511151*var_345 + var_310 + var_284*w[2][4] + -0.1250000000000000000000000*var_298 + var_356*var_60 + var_313; + const double var_360 = var_297*w[2][2]*w[3][2] + var_214*w[0][2]*w[1][2] + var_48 + var_115; + const double var_361 = 0.0018181818181818181802412*var_66 + 0.0001388888888888888887684*var_360 + 0.0060606060606060606008039*var_359 + 0.1616161616161616298992243*w[0][5]*w[1][5]*w[2][5]*w[3][5]; + const double var_362 = var_19 + var_219 + 0.5000000000000000000000000*var_302; + const double var_363 = 0.3333333333333333148296163*var_311 + 5.3333333333333330372738601*w[2][4]*w[3][4] + -0.8000000000000000444089210*var_292; + const double var_364 = var_19*var_51; + const double var_365 = -2.6666666666666665186369300*w[2][4]*w[3][4] + 0.5000000000000000000000000*var_292 + -0.3333333333333333148296163*var_327; + const double var_366 = var_365 + 0.5000000000000000000000000*var_19 + var_302; + const double var_367 = var_302*var_51 + var_19*var_28; + const double var_368 = var_216*w[0][5]*w[1][5] + var_362*var_61 + 4.0000000000000000000000000*var_367 + 0.5000000000000000000000000*var_13*var_159 + var_366*var_50; + const double var_369 = 0.2666666666666666629659233*var_265; + const double var_370 = var_153 + 0.4000000000000000222044605*var_109 + var_369 + var_261 + 0.5333333333333333259318465*var_147 + var_289; + const double var_371 = var_266 + var_240 + var_289 + 0.4000000000000000222044605*var_86 + var_146; + const double var_372 = var_33 + var_237; + const double var_373 = -0.2666666666666666629659233*var_74 + -0.5333333333333333259318465*var_47 + 0.0666666666666666657414808*var_129 + 0.0333333333333333328707404*var_372; + const double var_374 = 0.3333333333333333148296163*var_50 + var_51; + const double var_375 = 0.1000000000000000055511151*var_374 + 0.2000000000000000111022302*var_28 + var_271 + var_107 + 0.1333333333333333314829616*var_61 + var_373 + var_184; + const double var_376 = 0.2000000000000000111022302*var_51 + var_276 + 0.0666666666666666657414808*var_111 + 0.1000000000000000055511151*var_239 + 0.1333333333333333314829616*var_50 + var_180 + var_373; + const double var_377 = -0.1250000000000000000000000*var_297 + 2.0000000000000000000000000*var_33 + -4.0000000000000000000000000*var_159 + var_161 + 0.5000000000000000000000000*var_160 + -1.0000000000000000000000000*var_319; + const double var_378 = var_185 + 0.3333333333333333148296163*var_357 + 0.4000000000000000222044605*var_121 + 0.0666666666666666657414808*var_377 + 0.2500000000000000000000000*var_101; + const double var_379 = 0.2000000000000000111022302*var_171*w[3][5] + var_376*w[3][0] + var_375*w[3][1] + var_371*w[3][4] + var_370*w[3][3] + var_378*w[3][2]; + const double var_380 = var_193 + var_1; + const double var_381 = var_20 + var_257; + const double var_382 = var_13*var_47; + const double var_383 = var_28*var_302; + const double var_384 = var_383 + var_364 + var_382 + -1.0000000000000000000000000*var_381*w[0][5]*w[1][5]; + const double var_385 = var_20*var_90; + const double var_386 = var_10*var_28 + var_12*var_51 + 2.0000000000000000000000000*var_384 + var_104*var_257 + var_71*w[2][0]*w[3][0] + var_385 + var_29*w[2][1]*w[3][1]; + const double var_387 = var_90 + var_109; + const double var_388 = var_14*var_18 + var_257*var_387 + 1.4375000000000000000000000*var_58 + var_11*var_292 + 0.1250000000000000000000000*var_338 + -0.5000000000000000000000000*var_13*var_160 + var_71*var_98 + var_29*var_40 + var_20*var_294 + 0.2500000000000000000000000*var_67 + 2.0000000000000000000000000*var_386; + const double var_389 = var_126 + var_111; + const double var_390 = var_18*var_50 + var_292*var_61; + const double var_391 = 0.4000000000000000222044605*var_14 + -8.0000000000000000000000000*var_81 + 0.2000000000000000111022302*var_172 + var_0; + const double var_392 = var_42 + var_391; + const double var_393 = 0.5000000000000000000000000*var_390 + var_120*var_293 + var_20*var_99 + -1.0000000000000000000000000*var_314*var_47 + var_167*var_381 + var_13*var_256 + var_19*var_389 + 2.0000000000000000000000000*var_306 + var_257*var_32 + 0.0625000000000000000000000*var_76 + var_117*var_380 + 0.2000000000000000111022302*var_388 + var_302*var_392; + const double var_394 = var_257*var_81 + var_357*var_64 + var_20*var_37 + var_101*var_381; + const double var_395 = var_378*w[2][2] + var_375*w[2][1] + var_376*w[2][0]; + const double var_396 = var_395 + var_370*w[2][3]; + const double var_397 = var_371*w[2][4] + var_396; + const double var_398 = var_379*w[2][5] + 4.0000000000000000000000000*var_394 + 0.0062500000000000003469447*var_298 + var_397*w[3][5] + 12.8750000000000000000000000*w[0][2]*w[1][2]*w[2][2]*w[3][2] + 0.2500000000000000000000000*var_341 + 0.3333333333333333148296163*var_393 + var_198*var_46 + var_25*var_363; + const double var_399 = var_101 + -0.2000000000000000111022302*var_319; + const double var_400 = var_167 + var_357 + var_161 + 2.0000000000000000000000000*var_159; + const double var_401 = 1.6000000000000000888178420*var_256 + 0.0666666666666666657414808*var_297 + 0.2666666666666666629659233*var_400 + 0.3333333333333333148296163*var_399 + 0.1600000000000000033306691*var_307 + -0.1066666666666666735130420*var_160; + const double var_402 = 0.6666666666666666296592325*var_101 + 0.4266666666666666940521679*w[0][5]*w[1][5] + var_142 + 0.0666666666666666657414808*var_15; + const double var_403 = 0.1600000000000000033306691*var_90 + 1.0666666666666666518636930*var_81 + 0.0666666666666666657414808*var_173; + const double var_404 = 0.1600000000000000033306691*var_109 + var_149 + var_403 + 0.8000000000000000444089210*var_181 + 0.5333333333333333259318465*var_32 + var_402; + const double var_405 = var_404*w[2][3] + var_401*w[2][4]; + const double var_406 = 0.5333333333333333259318465*var_99 + var_232 + 0.1600000000000000033306691*var_86 + 0.2666666666666666629659233*var_32 + var_402 + 0.8000000000000000444089210*var_272; + const double var_407 = var_406*w[2][4] + var_401*w[2][3]; + const double var_408 = var_14*var_20 + var_10*var_71 + var_12*var_29 + var_11*var_257 + var_342*w[2][2]*w[3][2]; + const double var_409 = var_257*var_29 + var_20*var_71 + -0.2500000000000000000000000*var_408; + const double var_410 = var_405*w[3][3] + 0.3333333333333333148296163*var_409 + 0.0400000000000000008326673*var_368 + 0.2000000000000000111022302*var_398 + 0.6666666666666666296592325*var_259 + var_407*w[3][4]; + const double var_411 = 0.3333333333333333148296163*var_47*var_64; + const double var_412 = var_411 + var_410; + const double var_413 = var_292 + var_18; + const double var_414 = var_40*w[0][0]*w[1][0] + -1.0000000000000000000000000*var_101*var_12 + -1.0000000000000000000000000*var_13*var_90; + const double var_415 = var_13*var_61 + var_50*w[2][1]*w[3][1] + var_12*var_71 + var_51*w[2][2]*w[3][2] + 2.0000000000000000000000000*var_10*var_25; + const double var_416 = var_15*var_64 + var_101*var_13 + var_57; + const double var_417 = 0.8125000000000000000000000*w[0][2]*w[1][2]*w[2][2]*w[3][2] + var_411 + 0.0104166666666666660884255*var_416 + 0.1000000000000000055511151*var_382 + 0.3333333333333333148296163*var_199*var_74 + 0.0166666666666666664353702*var_67; + const double var_418 = var_99 + var_109; + const double var_419 = 0.8000000000000000444089210*var_418 + var_278 + 2.6666666666666665186369300*var_163; + const double var_420 = var_11*var_317 + var_10*var_278; + const double var_421 = 0.3333333333333333148296163*var_74 + 0.2000000000000000111022302*var_47 + -0.0625000000000000000000000*var_15; + const double var_422 = 0.2500000000000000000000000*var_61 + var_421 + 0.5000000000000000000000000*var_28; + const double var_423 = 0.5000000000000000000000000*var_13 + var_64; + const double var_424 = 0.1250000000000000000000000*var_214 + var_314; + const double var_425 = var_46 + var_28; + const double var_426 = var_47 + var_29; + const double var_427 = var_231 + 4.0000000000000000000000000*var_25; + const double var_428 = -1.0000000000000000000000000*var_163*var_18 + -1.0000000000000000000000000*var_117*w[0][3]*w[1][3] + var_427*w[2][3]*w[3][3] + -1.0000000000000000000000000*var_20*var_425 + -1.0000000000000000000000000*var_19*var_426; + const double var_429 = var_51 + var_0; + const double var_430 = -0.2500000000000000000000000*w[0][0]*w[1][0]; + const double var_431 = var_430 + -4.0000000000000000000000000*var_25 + var_21; + const double var_432 = var_102 + var_111 + var_431; + const double var_433 = var_147 + var_86 + var_431; + const double var_434 = 0.5000000000000000000000000*var_135*var_61 + var_169*var_18 + var_21*var_212 + var_280*w[2][0]*w[3][0]; + const double var_435 = -1.0000000000000000000000000*var_327*var_51 + -1.0000000000000000000000000*var_324*var_33 + 0.9062500000000000000000000*var_49 + var_18*var_280 + var_20*var_433 + var_212*var_37 + -0.2500000000000000000000000*var_434 + 8.0000000000000000000000000*var_428 + var_19*var_432 + -1.0000000000000000000000000*var_424*var_71 + -0.0625000000000000000000000*var_17 + var_337 + var_169*w[2][3]*w[3][3] + -1.0000000000000000000000000*var_423*var_429; + const double var_436 = var_212*w[0][0]*w[1][0] + var_169*w[2][0]*w[3][0]; + const double var_437 = -1.0000000000000000000000000*var_21*var_317; + const double var_438 = var_278 + 0.5000000000000000000000000*var_104; + const double var_439 = var_98 + var_314; + const double var_440 = 0.5000000000000000000000000*var_21*var_40; + const double var_441 = var_12*var_74 + -1.0000000000000000000000000*var_385 + -1.0000000000000000000000000*var_29*var_439 + -1.0000000000000000000000000*var_18*var_438 + -1.0000000000000000000000000*var_440 + var_437 + var_13*var_81 + var_129*var_19 + var_299 + -0.0625000000000000000000000*var_436 + var_332 + var_364; + const double var_442 = var_216 + -2.0000000000000000000000000*var_18; + const double var_443 = 0.3333333333333333148296163*var_435 + var_163*var_40 + var_219*var_253 + 0.5000000000000000000000000*var_441 + var_25*var_442; + const double var_444 = var_208 + var_210; + const double var_445 = var_352 + var_239; + const double var_446 = var_177 + 0.5000000000000000000000000*var_399 + 0.0416666666666666643537020*var_15 + var_122; + const double var_447 = var_181 + var_446; + const double var_448 = var_419*w[2][3]*w[3][3] + -0.1250000000000000000000000*var_420 + var_20*var_447 + var_444*w[3][5] + 0.1666666666666666574148081*var_18*var_51 + 0.2000000000000000111022302*var_443 + var_198*var_279 + var_317*var_37 + var_422*var_98 + var_203*var_50 + var_286*var_64 + 0.0416666666666666643537020*var_31 + var_417 + var_396*w[3][4] + var_19*var_445 + 0.0625000000000000000000000*var_414 + var_196*w[2][5] + var_379*w[2][4] + var_313; + const double var_449 = -0.0533333333333333367565210*w[0][3]*w[1][3] + 0.2666666666666666629659233*var_25 + 0.8000000000000000444089210*var_104; + const double var_450 = var_50 + 0.0400000000000000008326673*var_90; + const double var_451 = -2.0000000000000000000000000*var_14 + var_147 + var_265; + const double var_452 = 0.8000000000000000444089210*var_81 + 0.2000000000000000111022302*var_107 + var_449 + 0.0666666666666666657414808*var_451 + 0.3333333333333333148296163*var_450 + var_112 + 2.0000000000000000000000000*var_187; + const double var_453 = var_317*w[0][0]*w[1][0] + var_75 + var_278*w[2][0]*w[3][0] + var_115; + const double var_454 = 0.1616161616161616298992243*w[0][3]*w[1][3]*w[2][3]*w[3][3] + 0.0001388888888888888887684*var_453 + 0.0060606060606060606008039*var_448 + 0.0018181818181818181802412*var_22; + const double var_455 = 0.2500000000000000000000000*var_50 + 0.5000000000000000000000000*var_51 + var_421; + const double var_456 = 0.0666666666666666657414808*var_11; + const double var_457 = var_456 + 0.4000000000000000222044605*var_37 + 1.3333333333333332593184650*var_25; + const double var_458 = -4.0000000000000000000000000*var_46 + var_0 + var_84; + const double var_459 = var_42 + var_102 + -8.0000000000000000000000000*var_47 + var_458; + const double var_460 = var_456 + var_152 + 0.4266666666666666940521679*w[0][3]*w[1][3] + 0.6666666666666666296592325*var_104; + const double var_461 = var_263 + var_156 + 0.8000000000000000444089210*var_188 + var_403 + var_460 + 0.1600000000000000033306691*var_262; + const double var_462 = var_272 + var_446; + const double var_463 = -0.0833333333333333287074041*var_14 + 0.2666666666666666629659233*var_81 + var_449 + var_103 + 0.0666666666666666657414808*var_155 + 0.6666666666666666296592325*var_450 + 0.0133333333333333341891302*var_32 + var_187; + const double var_464 = 2.6666666666666665186369300*w[2][4]*w[3][4] + -0.5333333333333333259318465*var_292 + 0.2000000000000000111022302*var_98; + const double var_465 = w[0][1]*w[1][1]*w[2][4]*w[3][4] + var_0*var_292 + w[0][4]*w[1][4]*w[2][1]*w[3][1]; + const double var_466 = -1.0000000000000000000000000*var_14*w[2][4]*w[3][4] + -1.0000000000000000000000000*var_12*w[0][4]*w[1][4] + -1.0000000000000000000000000*var_302*var_71; + const double var_467 = var_14*var_292 + var_134; + const double var_468 = -1.0000000000000000000000000*var_13*var_21 + -1.0000000000000000000000000*var_61*w[2][2]*w[3][2] + -1.0000000000000000000000000*var_10*var_33 + var_32*w[2][0]*w[3][0]; + const double var_469 = 4.0000000000000000000000000*w[0][4]*w[1][4] + -0.3333333333333333148296163*var_0; + const double var_470 = var_35 + var_99; + const double var_471 = -8.0000000000000000000000000*var_292*var_81 + 0.4750000000000000333066907*var_116 + var_25*w[2][2]*w[3][2] + var_47*w[2][0]*w[3][0]; + const double var_472 = 8.0000000000000000000000000*var_469*w[2][4]*w[3][4] + var_46*var_464 + 0.1000000000000000055511151*var_467 + var_466 + var_302*var_70 + 0.1250000000000000000000000*w[0][1]*w[1][1]*w[2][1]*w[3][1] + var_257*var_470 + 0.3333333333333333148296163*var_471 + 0.0666666666666666657414808*var_468 + 0.4000000000000000222044605*var_465; + const double var_473 = var_0*w[2][1]*w[3][1] + var_292*w[0][1]*w[1][1]; + const double var_474 = -0.0000378787878787878787550*var_133 + -0.0001515151515151515150201*var_473 + 0.0020202020202020202002680*var_472; + const double var_475 = var_162 + var_51 + var_28; + const double var_476 = -0.0036363636363636363604823*var_307 + 0.0060606060606060606008039*var_475 + 0.0303030303030303038713811*var_321 + -0.0242424242424242424032155*var_47; + const double var_477 = 0.0727272727272727237401995*var_74 + 0.0250000000000000013877788*var_15 + 0.0909090909090909116141432*var_122 + 0.1454545454545454474803989*var_159 + 0.3636363636363636464565730*var_47 + 0.1818181818181818232282865*var_101; + const double var_478 = var_19 + var_302; + const double var_479 = 0.0370370370370370349810685*var_292 + 0.0227272727272727279035358*var_12; + const double var_480 = var_479*w[0][0]*w[1][0] + var_246*w[0][1]*w[1][1]; + const double var_481 = 0.0404040404040404074748061*w[0][4]*w[1][4] + -0.0028409090909090909879420*var_14 + -0.0046296296296296293726336*var_0; + const double var_482 = 0.0046296296296296293726336*var_13*var_161 + var_481*w[2][0]*w[3][0] + var_250*w[2][1]*w[3][1]; + const double var_483 = -0.0018939393939393939919613*var_336 + -0.0050000000000000001040834*var_480 + 0.0400000000000000008326673*var_482 + 0.1111111111111111049432054*var_413*var_476 + 0.0101010101010101018687015*var_412 + var_56 + var_474 + -0.0074074074074074076901031*var_477*var_478; + const double var_484 = var_158 + 0.5000000000000000000000000*var_90; + const double var_485 = var_257 + var_59; + const double var_486 = 0.8000000000000000444089210*var_61 + var_127 + var_109 + var_391; + const double var_487 = 4.0000000000000000000000000*var_193 + var_130 + var_99 + 0.8000000000000000444089210*var_71; + const double var_488 = var_139 + var_300; + const double var_489 = var_437 + var_224; + const double var_490 = var_51*var_98 + 0.1250000000000000000000000*var_489 + 1.4375000000000000000000000*var_17 + var_50*var_64 + var_14*var_63 + var_15*var_292 + 0.2500000000000000000000000*var_30 + 0.5000000000000000000000000*var_488; + const double var_491 = var_28*var_292 + var_29*var_63; + const double var_492 = var_124*var_380 + var_487*var_59 + 0.0625000000000000000000000*var_49 + 2.0000000000000000000000000*var_288 + 0.5000000000000000000000000*var_491 + var_123*var_293 + 0.4000000000000000222044605*var_415 + -1.0000000000000000000000000*var_212*var_25 + var_257*var_486 + var_10*var_163 + 0.2000000000000000111022302*var_490; + const double var_493 = var_63 + var_257; + const double var_494 = var_365 + var_257 + 0.5000000000000000000000000*var_59; + const double var_495 = var_258 + var_59*var_61; + const double var_496 = var_28*var_59 + var_216*w[0][3]*w[1][3] + 0.5000000000000000000000000*var_10*var_279 + 4.0000000000000000000000000*var_495 + var_29*var_494; + const double var_497 = var_347 + var_268*w[2][4]; + const double var_498 = var_363*var_47 + 0.1000000000000000055511151*var_28*var_493 + 4.0000000000000000000000000*var_281*var_40 + 12.8750000000000000000000000*w[0][0]*w[1][0]*w[2][0]*w[3][0] + var_497*w[3][3] + 0.2000000000000000111022302*var_496 + var_200*var_46 + 0.3333333333333333148296163*var_492 + var_284*w[2][3] + 0.5000000000000000000000000*var_440; + const double var_499 = var_292 + var_63; + const double var_500 = var_75 + var_135*w[0][1]*w[1][1] + var_158*w[2][1]*w[3][1] + var_48; + const double var_501 = var_156 + var_369 + 1.6000000000000000888178420*var_163 + -0.1066666666666666735130420*var_280 + 0.3333333333333333148296163*var_354 + 0.2666666666666666629659233*var_281 + 0.0666666666666666657414808*var_278 + 0.5333333333333333259318465*var_279 + 0.8000000000000000444089210*var_457; + const double var_502 = var_238 + 0.8000000000000000444089210*var_374 + var_369 + var_460 + 0.1600000000000000033306691*var_32 + var_267; + const double var_503 = var_501*w[2][5] + var_502*w[2][4]; + const double var_504 = var_274 + 0.1666666666666666574148081*var_191; + const double var_505 = var_147 + var_46; + const double var_506 = var_94 + 32.0000000000000000000000000*var_505; + const double var_507 = -8.0000000000000000000000000*var_51 + var_330 + var_458 + var_109; + const double var_508 = var_21 + var_28; + const double var_509 = var_0*var_93 + var_190*w[2][1]*w[3][1]; + const double var_510 = -1.0000000000000000000000000*var_423*var_508 + -1.0000000000000000000000000*var_318*var_50 + -1.0000000000000000000000000*var_316*var_61 + -1.0000000000000000000000000*var_315*var_33 + 0.9062500000000000000000000*var_116 + var_302*var_459 + var_291*var_292 + 8.0000000000000000000000000*var_466 + var_506*w[2][4]*w[3][4] + -0.2500000000000000000000000*var_509 + -1.0000000000000000000000000*var_29*var_424 + -0.0625000000000000000000000*var_133 + var_81*var_93 + var_257*var_507 + -1.0000000000000000000000000*var_218*var_28; + A[5] = 0.0476190476190476164042309*var_454*var_9; + const double var_511 = var_501*w[2][4] + var_461*w[2][5]; + const double var_512 = var_249*w[2][1]*w[3][1] + var_481*w[2][2]*w[3][2]; + A[8] = 0.1428571428571428492126927*var_483*var_9; + const double var_513 = var_40 + var_314; + const double var_514 = var_61 + var_125; + const double var_515 = -1.0000000000000000000000000*var_212*var_51 + -0.0625000000000000000000000*var_95 + var_383 + var_129*var_302 + -1.0000000000000000000000000*var_205 + var_13*var_37 + -1.0000000000000000000000000*var_513*var_71 + var_136 + var_305 + -1.0000000000000000000000000*var_292*var_484 + var_257*var_514 + var_10*var_74; + const double var_516 = var_418 + var_287; + const double var_517 = 0.0303030303030303038713811*var_430 + -0.0181818181818181809350499*var_457 + 0.0060606060606060606008039*var_516; + const double var_518 = 0.1818181818181818232282865*var_104 + 0.3636363636363636464565730*var_25 + 0.0250000000000000013877788*var_11 + 0.0909090909090909116141432*var_119 + 0.1454545454545454474803989*var_279 + 0.0727272727272727237401995*var_37; + const double var_519 = 0.0012500000000000000260209*var_420 + var_511*w[3][5] + 0.6666666666666666296592325*var_163*var_40 + var_503*w[3][4] + 0.2000000000000000111022302*var_498 + 0.0833333333333333287074041*var_254 + var_463*var_60 + var_302*var_452; + const double var_520 = var_247*w[0][1]*w[1][1] + var_479*w[0][2]*w[1][2] + 0.0370370370370370349810685*var_10*var_287; + const double var_521 = 0.0101010101010101018687015*var_519 + 0.1111111111111111049432054*var_499*var_517 + 0.0400000000000000008326673*var_512 + -0.0074074074074074076901031*var_485*var_518 + 0.0033670033670033668558863*var_25*var_40 + var_80 + -0.0018939393939393939919613*var_436 + -0.0050000000000000001040834*var_520 + var_474; + const double var_522 = var_374 + var_355; + const double var_523 = var_158 + 0.8000000000000000444089210*var_87; + const double var_524 = var_523*w[3][4] + var_268*w[3][5] + var_371*w[3][3]; + const double var_525 = -1.0000000000000000000000000*var_104*var_13 + var_98*w[0][1]*w[1][1] + -1.0000000000000000000000000*var_10*var_101; + const double var_526 = var_216*var_46 + 0.3333333333333333148296163*var_510 + 0.5000000000000000000000000*var_515 + var_223*var_365; + const double var_527 = 0.0625000000000000000000000*var_525 + 0.0416666666666666643537020*var_467 + var_524*w[2][4] + var_40*var_455 + var_135*var_81 + var_284*w[2][5] + var_292*var_504 + 0.2000000000000000111022302*var_526 + var_395*w[3][3] + var_302*var_522 + var_346*w[3][5] + var_417 + -0.1250000000000000000000000*var_217 + var_310 + var_363*var_91 + var_114*var_464 + var_296*var_64 + var_379*w[2][3] + var_257*var_462; + const double var_528 = 0.0001388888888888888887684*var_500 + 0.0018181818181818181802412*var_465 + 0.1616161616161616298992243*w[0][4]*w[1][4]*w[2][4]*w[3][4] + 0.0060606060606060606008039*var_527; + A[1] = 0.0476190476190476164042309*var_361*var_9; + A[3] = A[1]; + A[7] = A[5]; + A[2] = 0.0476190476190476164042309*var_528*var_9; + A[0] = 0.1428571428571428492126927*var_521*var_9; + A[6] = 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/mass_matrix_2d/mass_matrix_f4_p2_q1_quadrature.h b/mass_matrix_2d/mass_matrix_f4_p2_q1_quadrature.h new file mode 100644 index 0000000..631ea86 --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f4_p2_q1_quadrature.h @@ -0,0 +1,3451 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F4_P2_Q1_QUADRATURE_H +#define __MASS_MATRIX_F4_P2_Q1_QUADRATURE_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f4_p2_q1_quadrature_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f4_p2_q1_quadrature_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f4_p2_q1_quadrature_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f4_p2_q1_quadrature_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f4_p2_q1_quadrature_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_p2_q1_quadrature_finite_element_1() + { + // 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 mass_matrix_f4_p2_q1_quadrature_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f4_p2_q1_quadrature_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f4_p2_q1_quadrature_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f4_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 mass_matrix_f4_p2_q1_quadrature_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f4_p2_q1_quadrature_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f4_p2_q1_quadrature_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f4_p2_q1_quadrature_dofmap_1() + { + // 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 mass_matrix_f4_p2_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 mass_matrix_f4_p2_q1_quadrature_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f4_p2_q1_quadrature_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_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 + + // Set scale factor + const double det = std::abs(detJ); + + // Cell Volume. + + // Compute circumradius, assuming triangle is embedded in 2D. + + + // Array of quadrature weights. + static const double W36[36] = {0.00619426535265906, 0.0116108747669979, 0.0120606064042655, 0.0084515357969434, 0.0037652982126918, 0.000748542561236343, 0.0130433943300833, 0.0244492622580587, 0.0253962715890485, 0.0177965759970269, 0.00792866733379675, 0.00157622175402364, 0.0169175056800133, 0.0317111115907051, 0.0329393989007878, 0.023082463651359, 0.0102836172287667, 0.00204438659154493, 0.0169175056800133, 0.0317111115907051, 0.0329393989007878, 0.023082463651359, 0.0102836172287667, 0.00204438659154493, 0.0130433943300833, 0.0244492622580587, 0.0253962715890485, 0.0177965759970269, 0.00792866733379675, 0.00157622175402364, 0.00619426535265908, 0.0116108747669979, 0.0120606064042655, 0.00845153579694342, 0.00376529821269181, 0.000748542561236345}; + // Quadrature points on the UFC reference element: (0.0327753666144599, 0.0293164271597849), (0.0287653330125591, 0.148078599668484), (0.0223868729780306, 0.336984690281154), (0.0149015633666711, 0.55867151877155), (0.00779187470128645, 0.769233862030055), (0.00246669715267023, 0.926945671319741), (0.164429241594827, 0.0293164271597849), (0.144311486950417, 0.148078599668484), (0.112311681780954, 0.336984690281154), (0.0747589734626491, 0.55867151877155), (0.0390907007328242, 0.769233862030055), (0.01237506041744, 0.926945671319741), (0.369529924372377, 0.0293164271597849), (0.324318304588776, 0.148078599668484), (0.252403568076518, 0.336984690281154), (0.168009519121192, 0.55867151877155), (0.0878504549759972, 0.769233862030055), (0.0278110821153606, 0.926945671319741), (0.601153648467838, 0.0293164271597849), (0.52760309574274, 0.148078599668484), (0.410611741642328, 0.336984690281154), (0.273318962107258, 0.55867151877155), (0.142915682993948, 0.769233862030055), (0.0452432465648983, 0.926945671319741), (0.806254331245388, 0.0293164271597849), (0.707609913381099, 0.148078599668484), (0.550703627937892, 0.336984690281154), (0.366569507765801, 0.55867151877155), (0.191675437237121, 0.769233862030055), (0.0606792682628189, 0.926945671319741), (0.937908206225755, 0.0293164271597849), (0.823156067318956, 0.148078599668484), (0.640628436740815, 0.336984690281154), (0.426426917861779, 0.55867151877155), (0.222974263268659, 0.769233862030055), (0.0705876315275886, 0.926945671319741) + + // Value of basis functions at quadrature points. + static const double FE0[36][3] = \ + {{0.937908206225755, 0.03277536661446, 0.0293164271597848}, + {0.823156067318957, 0.0287653330125592, 0.148078599668484}, + {0.640628436740815, 0.0223868729780305, 0.336984690281154}, + {0.426426917861779, 0.0149015633666711, 0.55867151877155}, + {0.222974263268659, 0.00779187470128651, 0.769233862030055}, + {0.0705876315275887, 0.00246669715267028, 0.926945671319741}, + {0.806254331245388, 0.164429241594827, 0.0293164271597848}, + {0.707609913381099, 0.144311486950417, 0.148078599668484}, + {0.550703627937892, 0.112311681780954, 0.336984690281154}, + {0.366569507765801, 0.0747589734626491, 0.55867151877155}, + {0.191675437237121, 0.0390907007328243, 0.769233862030055}, + {0.0606792682628189, 0.0123750604174401, 0.926945671319741}, + {0.601153648467838, 0.369529924372377, 0.0293164271597848}, + {0.52760309574274, 0.324318304588776, 0.148078599668484}, + {0.410611741642328, 0.252403568076518, 0.336984690281154}, + {0.273318962107258, 0.168009519121192, 0.55867151877155}, + {0.142915682993948, 0.0878504549759972, 0.769233862030055}, + {0.0452432465648984, 0.0278110821153607, 0.926945671319741}, + {0.369529924372377, 0.601153648467839, 0.0293164271597848}, + {0.324318304588776, 0.52760309574274, 0.148078599668484}, + {0.252403568076518, 0.410611741642328, 0.336984690281154}, + {0.168009519121192, 0.273318962107258, 0.55867151877155}, + {0.0878504549759972, 0.142915682993948, 0.769233862030055}, + {0.0278110821153607, 0.0452432465648984, 0.926945671319741}, + {0.164429241594827, 0.806254331245388, 0.0293164271597848}, + {0.144311486950417, 0.707609913381099, 0.148078599668484}, + {0.112311681780954, 0.550703627937892, 0.336984690281154}, + {0.0747589734626489, 0.366569507765801, 0.55867151877155}, + {0.0390907007328242, 0.191675437237121, 0.769233862030055}, + {0.0123750604174401, 0.0606792682628189, 0.926945671319741}, + {0.03277536661446, 0.937908206225755, 0.0293164271597848}, + {0.0287653330125592, 0.823156067318957, 0.148078599668484}, + {0.0223868729780305, 0.640628436740815, 0.336984690281154}, + {0.0149015633666711, 0.426426917861779, 0.55867151877155}, + {0.00779187470128645, 0.222974263268659, 0.769233862030055}, + {0.00246669715267034, 0.0705876315275887, 0.926945671319741}}; + + static const double FE1[36][6] = \ + {{0.821435400385472, -0.0306269173010354, -0.027597521356955, 0.00384342659195225, 0.109984470441528, 0.122961141239038}, + {0.532015755009065, -0.0271104442459123, -0.104224056308926, 0.0170381209259896, 0.487567191028831, 0.0947134335909535}, + {0.180181151181146, -0.0213845288145617, -0.109867327313383, 0.0301761338274608, 0.863527901361615, 0.0573666697577237}, + {-0.0627470853075864, -0.0144574501851293, 0.0655562130014708, 0.0333003161525148, 0.952930295387644, 0.0254177109510863}, + {-0.123539219108257, -0.00767044807856534, 0.414207606957291, 0.0239750954756995, 0.686077414669827, 0.00694955008400423}, + {-0.0606224040782395, -0.0024545279629842, 0.79151088383707, 0.00914597699249764, 0.261723597972845, 0.00069647323881139}, + {0.493837762058507, -0.110355290611927, -0.027597521356955, 0.0192819115366138, 0.0945459854968659, 0.530287152876896}, + {0.293813665649314, -0.102659876418736, -0.104224056308926, 0.0854777716147778, 0.419127540340042, 0.408464955123528}, + {0.0558453437100203, -0.0870838540520213, -0.109867327313383, 0.151389269199641, 0.742314765989434, 0.247401802466309}, + {-0.0978230997184779, -0.0635811652362709, 0.0655562130014709, 0.167062836984721, 0.819167774555438, 0.109617440413119}, + {-0.118196490757038, -0.0360345349652578, 0.414207606957291, 0.120279562776686, 0.58977294736884, 0.0299709086194782}, + {-0.0533153210689967, -0.0120687761767694, 0.79151088383707, 0.0458840347450652, 0.224985540220277, 0.00300363844335377}, + {0.121617769664549, -0.0964251943590678, -0.027597521356955, 0.0433331884448944, 0.0704947085885853, 0.888577049017995}, + {0.0291269575319054, -0.1139535792061, -0.104224056308926, 0.192098401561452, 0.312506910393369, 0.6844453660283}, + {-0.0734077368932363, -0.124988445721003, -0.109867327313383, 0.340224552856495, 0.553479482332581, 0.414559474738547}, + {-0.123912452012481, -0.111555122090524, 0.0655562130014709, 0.375448532862056, 0.610782078678102, 0.183680749561375}, + {-0.102065898102695, -0.0724150500970178, 0.414207606957291, 0.270310179049135, 0.439742331096391, 0.050220831096895}, + {-0.041149343845434, -0.0262641695385059, 0.79151088383707, 0.103117448726206, 0.167752126239137, 0.00503305458152761}, + {-0.0964251943590678, 0.121617769664549, -0.027597521356955, 0.0704947085885853, 0.0433331884448943, 0.888577049017995}, + {-0.1139535792061, 0.0291269575319054, -0.104224056308926, 0.312506910393369, 0.192098401561452, 0.6844453660283}, + {-0.124988445721003, -0.0734077368932363, -0.109867327313383, 0.553479482332581, 0.340224552856495, 0.414559474738547}, + {-0.111555122090524, -0.123912452012481, 0.0655562130014709, 0.610782078678102, 0.375448532862056, 0.183680749561375}, + {-0.0724150500970178, -0.102065898102695, 0.414207606957291, 0.439742331096391, 0.270310179049135, 0.050220831096895}, + {-0.026264169538506, -0.0411493438454339, 0.79151088383707, 0.167752126239137, 0.103117448726206, 0.00503305458152761}, + {-0.110355290611927, 0.493837762058507, -0.027597521356955, 0.094545985496866, 0.0192819115366137, 0.530287152876895}, + {-0.102659876418736, 0.293813665649314, -0.104224056308926, 0.419127540340043, 0.0854777716147777, 0.408464955123527}, + {-0.0870838540520213, 0.0558453437100204, -0.109867327313383, 0.742314765989434, 0.151389269199641, 0.247401802466309}, + {-0.0635811652362708, -0.0978230997184778, 0.0655562130014709, 0.819167774555438, 0.16706283698472, 0.109617440413119}, + {-0.0360345349652578, -0.118196490757038, 0.414207606957291, 0.58977294736884, 0.120279562776686, 0.0299709086194782}, + {-0.0120687761767695, -0.0533153210689966, 0.79151088383707, 0.224985540220277, 0.0458840347450654, 0.00300363844335377}, + {-0.0306269173010354, 0.821435400385472, -0.027597521356955, 0.109984470441527, 0.00384342659195216, 0.122961141239039}, + {-0.0271104442459124, 0.532015755009064, -0.104224056308926, 0.487567191028831, 0.0170381209259896, 0.0947134335909537}, + {-0.0213845288145617, 0.180181151181146, -0.109867327313383, 0.863527901361614, 0.0301761338274608, 0.0573666697577238}, + {-0.0144574501851293, -0.0627470853075864, 0.0655562130014709, 0.952930295387644, 0.0333003161525146, 0.0254177109510863}, + {-0.00767044807856535, -0.123539219108256, 0.414207606957291, 0.686077414669827, 0.0239750954756995, 0.00694955008400424}, + {-0.00245452796298434, -0.0606224040782394, 0.79151088383707, 0.261723597972845, 0.00914597699249803, 0.000696473238811418}}; + + // Reset values in the element tensor. + for (unsigned int r = 0; r < 9; r++) + { + A[r] = 0.0; + }// end loop over 'r' + + // 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 = 2880 + for (unsigned int ip = 0; ip < 36; 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 = 48 + for (unsigned int r = 0; r < 6; r++) + { + F0 += FE1[ip][r]*w[3][r]; + F1 += FE1[ip][r]*w[2][r]; + F2 += FE1[ip][r]*w[0][r]; + F3 += FE1[ip][r]*w[1][r]; + }// end loop over 'r' + + // Number of operations to compute ip constants: 5 + double I[1]; + // Number of operations: 5 + I[0] = F0*F1*F2*F3*W36[ip]*det; + + + // Number of operations for primary indices: 27 + for (unsigned int j = 0; j < 3; j++) + { + for (unsigned int k = 0; k < 3; k++) + { + // Number of operations to compute entry: 3 + A[j*3 + k] += FE0[ip][j]*FE0[ip][k]*I[0]; + }// 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 mass_matrix_f4_p2_q1_quadrature_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f4_p2_q1_quadrature_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_p2_q1_quadrature_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 3), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1))))), 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 4; + } + + /// 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 mass_matrix_f4_p2_q1_quadrature_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f4_p2_q1_quadrature_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f4_p2_q1_quadrature_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f4_p2_q1_quadrature_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f4_p2_q1_quadrature_finite_element_0(); + break; + } + case 5: + { + return new mass_matrix_f4_p2_q1_quadrature_finite_element_0(); + 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 mass_matrix_f4_p2_q1_quadrature_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f4_p2_q1_quadrature_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f4_p2_q1_quadrature_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f4_p2_q1_quadrature_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f4_p2_q1_quadrature_dofmap_0(); + break; + } + case 5: + { + return new mass_matrix_f4_p2_q1_quadrature_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f4_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/mass_matrix_2d/mass_matrix_f4_p2_q1_tensor.h b/mass_matrix_2d/mass_matrix_f4_p2_q1_tensor.h new file mode 100644 index 0000000..29b98dc --- /dev/null +++ b/mass_matrix_2d/mass_matrix_f4_p2_q1_tensor.h @@ -0,0 +1,4633 @@ +// This code conforms with the UFC specification version 2.0.3 +// and was automatically generated by FFC version 1.0-beta2. +// +// 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 __MASS_MATRIX_F4_P2_Q1_TENSOR_H +#define __MASS_MATRIX_F4_P2_Q1_TENSOR_H + +#include +#include +#include +#include + +/// This class defines the interface for a finite element. + +class mass_matrix_f4_p2_q1_tensor_finite_element_0: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f4_p2_q1_tensor_finite_element_0() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end loop 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.0, 7.07106781186548, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + + static const double dmats1[6][6] = \ + {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.44948974278318, 0.0, 0.0, 0.0, 0.0, 0.0}, + {4.24264068711928, 0.0, 0.0, 0.0, 0.0, 0.0}, + {2.58198889747161, 4.74341649025257, -0.912870929175278, 0.0, 0.0, 0.0}, + {2, 6.12372435695794, 3.53553390593274, 0.0, 0.0, 0.0}, + {-2.3094010767585, 0.0, 8.16496580927726, 0.0, 0.0, 0.0}}; + + // Compute reference derivatives. + // Declare pointer to array of derivatives on FIAT element. + double *derivatives = new double[num_derivatives]; + for (unsigned int r = 0; r < num_derivatives; r++) + { + derivatives[r] = 0.0; + }// end loop over 'r' + + // Declare derivative matrix (of polynomial basis). + double dmats[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Declare (auxiliary) derivative matrix (of polynomial basis). + double dmats_old[6][6] = \ + {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + // Loop possible derivatives. + for (unsigned int r = 0; r < num_derivatives; r++) + { + // Resetting dmats values to compute next derivative. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats[t][u] = 0.0; + if (t == u) + { + dmats[t][u] = 1.0; + } + + }// end loop over 'u' + }// end loop over 't' + + // Looping derivative order to generate dmats. + for (unsigned int s = 0; s < n; s++) + { + // Updating dmats_old with new values and resetting dmats. + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + dmats_old[t][u] = dmats[t][u]; + dmats[t][u] = 0.0; + }// end loop over 'u' + }// end loop over 't' + + // Update dmats using an inner product. + if (combinations[r][s] == 0) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + if (combinations[r][s] == 1) + { + for (unsigned int t = 0; t < 6; t++) + { + for (unsigned int u = 0; u < 6; u++) + { + for (unsigned int tu = 0; tu < 6; tu++) + { + dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u]; + }// end loop over 'tu' + }// end loop over 'u' + }// end loop over 't' + } + + }// end loop over 's' + for (unsigned int s = 0; s < 6; s++) + { + for (unsigned int t = 0; t < 6; t++) + { + derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t]; + }// end loop over 't' + }// end loop over 's' + }// end loop over 'r' + + // Transform derivatives back to physical element + for (unsigned int r = 0; r < num_derivatives; r++) + { + for (unsigned int s = 0; s < num_derivatives; s++) + { + values[r] += transform[r][s]*derivatives[s]; + }// end loop over 's' + }// end loop over 'r' + + // Delete pointer to array of derivatives on FIAT element + delete [] derivatives; + + // Delete pointer to array of combinations of derivatives and transform + for (unsigned int r = 0; r < num_derivatives; r++) + { + delete [] combinations[r]; + }// end 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 mass_matrix_f4_p2_q1_tensor_finite_element_0(); + } + +}; + +/// This class defines the interface for a finite element. + +class mass_matrix_f4_p2_q1_tensor_finite_element_1: public ufc::finite_element +{ +public: + + /// Constructor + mass_matrix_f4_p2_q1_tensor_finite_element_1() : ufc::finite_element() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_p2_q1_tensor_finite_element_1() + { + // 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 mass_matrix_f4_p2_q1_tensor_finite_element_1(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f4_p2_q1_tensor_dofmap_0: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f4_p2_q1_tensor_dofmap_0() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f4_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 mass_matrix_f4_p2_q1_tensor_dofmap_0(); + } + +}; + +/// This class defines the interface for a local-to-global mapping of +/// degrees of freedom (dofs). + +class mass_matrix_f4_p2_q1_tensor_dofmap_1: public ufc::dofmap +{ +private: + + unsigned int _global_dimension; +public: + + /// Constructor + mass_matrix_f4_p2_q1_tensor_dofmap_1() : ufc::dofmap() + { + _global_dimension = 0; + } + + /// Destructor + virtual ~mass_matrix_f4_p2_q1_tensor_dofmap_1() + { + // 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 mass_matrix_f4_p2_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 mass_matrix_f4_p2_q1_tensor_cell_integral_0_0: public ufc::cell_integral +{ +public: + + /// Constructor + mass_matrix_f4_p2_q1_tensor_cell_integral_0_0() : ufc::cell_integral() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_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: 9 + // Number of operations (multiply-add pairs) for geometry tensor: 3240 + // Number of operations (multiply-add pairs) for tensor contraction: 6590 + // Total number of operations (multiply-add pairs): 9839 + + // Extract vertex coordinates + const double * const * x = c.coordinates; + + // Compute Jacobian of affine map from reference cell + const double J_00 = x[1][0] - x[0][0]; + const double J_01 = x[2][0] - x[0][0]; + const double J_10 = x[1][1] - x[0][1]; + const double J_11 = x[2][1] - x[0][1]; + + // Compute determinant of Jacobian + double detJ = J_00*J_11 - J_01*J_10; + + // Compute inverse of Jacobian + + // Set scale factor + const double det = std::abs(detJ); + + // Compute geometry tensor + const double G0_0_0_0_0 = det*w[3][0]*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_0_0_0_1 = det*w[3][0]*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_0_0_0_2 = det*w[3][0]*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_0_0_0_3 = det*w[3][0]*w[2][0]*w[0][0]*w[1][3]*(1.0); + const double G0_0_0_0_4 = det*w[3][0]*w[2][0]*w[0][0]*w[1][4]*(1.0); + const double G0_0_0_0_5 = det*w[3][0]*w[2][0]*w[0][0]*w[1][5]*(1.0); + const double G0_0_0_1_0 = det*w[3][0]*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_0_0_1_1 = det*w[3][0]*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_0_0_1_2 = det*w[3][0]*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_0_0_1_3 = det*w[3][0]*w[2][0]*w[0][1]*w[1][3]*(1.0); + const double G0_0_0_1_4 = det*w[3][0]*w[2][0]*w[0][1]*w[1][4]*(1.0); + const double G0_0_0_1_5 = det*w[3][0]*w[2][0]*w[0][1]*w[1][5]*(1.0); + const double G0_0_0_2_0 = det*w[3][0]*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_0_0_2_1 = det*w[3][0]*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_0_0_2_2 = det*w[3][0]*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_0_0_2_3 = det*w[3][0]*w[2][0]*w[0][2]*w[1][3]*(1.0); + const double G0_0_0_2_4 = det*w[3][0]*w[2][0]*w[0][2]*w[1][4]*(1.0); + const double G0_0_0_2_5 = det*w[3][0]*w[2][0]*w[0][2]*w[1][5]*(1.0); + const double G0_0_0_3_0 = det*w[3][0]*w[2][0]*w[0][3]*w[1][0]*(1.0); + const double G0_0_0_3_1 = det*w[3][0]*w[2][0]*w[0][3]*w[1][1]*(1.0); + const double G0_0_0_3_2 = det*w[3][0]*w[2][0]*w[0][3]*w[1][2]*(1.0); + const double G0_0_0_3_3 = det*w[3][0]*w[2][0]*w[0][3]*w[1][3]*(1.0); + const double G0_0_0_3_4 = det*w[3][0]*w[2][0]*w[0][3]*w[1][4]*(1.0); + const double G0_0_0_3_5 = det*w[3][0]*w[2][0]*w[0][3]*w[1][5]*(1.0); + const double G0_0_0_4_0 = det*w[3][0]*w[2][0]*w[0][4]*w[1][0]*(1.0); + const double G0_0_0_4_1 = det*w[3][0]*w[2][0]*w[0][4]*w[1][1]*(1.0); + const double G0_0_0_4_2 = det*w[3][0]*w[2][0]*w[0][4]*w[1][2]*(1.0); + const double G0_0_0_4_3 = det*w[3][0]*w[2][0]*w[0][4]*w[1][3]*(1.0); + const double G0_0_0_4_4 = det*w[3][0]*w[2][0]*w[0][4]*w[1][4]*(1.0); + const double G0_0_0_4_5 = det*w[3][0]*w[2][0]*w[0][4]*w[1][5]*(1.0); + const double G0_0_0_5_0 = det*w[3][0]*w[2][0]*w[0][5]*w[1][0]*(1.0); + const double G0_0_0_5_1 = det*w[3][0]*w[2][0]*w[0][5]*w[1][1]*(1.0); + const double G0_0_0_5_2 = det*w[3][0]*w[2][0]*w[0][5]*w[1][2]*(1.0); + const double G0_0_0_5_3 = det*w[3][0]*w[2][0]*w[0][5]*w[1][3]*(1.0); + const double G0_0_0_5_4 = det*w[3][0]*w[2][0]*w[0][5]*w[1][4]*(1.0); + const double G0_0_0_5_5 = det*w[3][0]*w[2][0]*w[0][5]*w[1][5]*(1.0); + const double G0_0_1_0_0 = det*w[3][0]*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_0_1_0_1 = det*w[3][0]*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_0_1_0_2 = det*w[3][0]*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_0_1_0_3 = det*w[3][0]*w[2][1]*w[0][0]*w[1][3]*(1.0); + const double G0_0_1_0_4 = det*w[3][0]*w[2][1]*w[0][0]*w[1][4]*(1.0); + const double G0_0_1_0_5 = det*w[3][0]*w[2][1]*w[0][0]*w[1][5]*(1.0); + const double G0_0_1_1_0 = det*w[3][0]*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_0_1_1_1 = det*w[3][0]*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_0_1_1_2 = det*w[3][0]*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_0_1_1_3 = det*w[3][0]*w[2][1]*w[0][1]*w[1][3]*(1.0); + const double G0_0_1_1_4 = det*w[3][0]*w[2][1]*w[0][1]*w[1][4]*(1.0); + const double G0_0_1_1_5 = det*w[3][0]*w[2][1]*w[0][1]*w[1][5]*(1.0); + const double G0_0_1_2_0 = det*w[3][0]*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_0_1_2_1 = det*w[3][0]*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_0_1_2_2 = det*w[3][0]*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_0_1_2_3 = det*w[3][0]*w[2][1]*w[0][2]*w[1][3]*(1.0); + const double G0_0_1_2_4 = det*w[3][0]*w[2][1]*w[0][2]*w[1][4]*(1.0); + const double G0_0_1_2_5 = det*w[3][0]*w[2][1]*w[0][2]*w[1][5]*(1.0); + const double G0_0_1_3_0 = det*w[3][0]*w[2][1]*w[0][3]*w[1][0]*(1.0); + const double G0_0_1_3_1 = det*w[3][0]*w[2][1]*w[0][3]*w[1][1]*(1.0); + const double G0_0_1_3_2 = det*w[3][0]*w[2][1]*w[0][3]*w[1][2]*(1.0); + const double G0_0_1_3_3 = det*w[3][0]*w[2][1]*w[0][3]*w[1][3]*(1.0); + const double G0_0_1_3_4 = det*w[3][0]*w[2][1]*w[0][3]*w[1][4]*(1.0); + const double G0_0_1_3_5 = det*w[3][0]*w[2][1]*w[0][3]*w[1][5]*(1.0); + const double G0_0_1_4_0 = det*w[3][0]*w[2][1]*w[0][4]*w[1][0]*(1.0); + const double G0_0_1_4_1 = det*w[3][0]*w[2][1]*w[0][4]*w[1][1]*(1.0); + const double G0_0_1_4_2 = det*w[3][0]*w[2][1]*w[0][4]*w[1][2]*(1.0); + const double G0_0_1_4_3 = det*w[3][0]*w[2][1]*w[0][4]*w[1][3]*(1.0); + const double G0_0_1_4_4 = det*w[3][0]*w[2][1]*w[0][4]*w[1][4]*(1.0); + const double G0_0_1_4_5 = det*w[3][0]*w[2][1]*w[0][4]*w[1][5]*(1.0); + const double G0_0_1_5_0 = det*w[3][0]*w[2][1]*w[0][5]*w[1][0]*(1.0); + const double G0_0_1_5_1 = det*w[3][0]*w[2][1]*w[0][5]*w[1][1]*(1.0); + const double G0_0_1_5_2 = det*w[3][0]*w[2][1]*w[0][5]*w[1][2]*(1.0); + const double G0_0_1_5_3 = det*w[3][0]*w[2][1]*w[0][5]*w[1][3]*(1.0); + const double G0_0_1_5_4 = det*w[3][0]*w[2][1]*w[0][5]*w[1][4]*(1.0); + const double G0_0_1_5_5 = det*w[3][0]*w[2][1]*w[0][5]*w[1][5]*(1.0); + const double G0_0_2_0_0 = det*w[3][0]*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_0_2_0_1 = det*w[3][0]*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_0_2_0_2 = det*w[3][0]*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_0_2_0_3 = det*w[3][0]*w[2][2]*w[0][0]*w[1][3]*(1.0); + const double G0_0_2_0_4 = det*w[3][0]*w[2][2]*w[0][0]*w[1][4]*(1.0); + const double G0_0_2_0_5 = det*w[3][0]*w[2][2]*w[0][0]*w[1][5]*(1.0); + const double G0_0_2_1_0 = det*w[3][0]*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_0_2_1_1 = det*w[3][0]*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_0_2_1_2 = det*w[3][0]*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_0_2_1_3 = det*w[3][0]*w[2][2]*w[0][1]*w[1][3]*(1.0); + const double G0_0_2_1_4 = det*w[3][0]*w[2][2]*w[0][1]*w[1][4]*(1.0); + const double G0_0_2_1_5 = det*w[3][0]*w[2][2]*w[0][1]*w[1][5]*(1.0); + const double G0_0_2_2_0 = det*w[3][0]*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_0_2_2_1 = det*w[3][0]*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_0_2_2_2 = det*w[3][0]*w[2][2]*w[0][2]*w[1][2]*(1.0); + const double G0_0_2_2_3 = det*w[3][0]*w[2][2]*w[0][2]*w[1][3]*(1.0); + const double G0_0_2_2_4 = det*w[3][0]*w[2][2]*w[0][2]*w[1][4]*(1.0); + const double G0_0_2_2_5 = det*w[3][0]*w[2][2]*w[0][2]*w[1][5]*(1.0); + const double G0_0_2_3_0 = det*w[3][0]*w[2][2]*w[0][3]*w[1][0]*(1.0); + const double G0_0_2_3_1 = det*w[3][0]*w[2][2]*w[0][3]*w[1][1]*(1.0); + const double G0_0_2_3_2 = det*w[3][0]*w[2][2]*w[0][3]*w[1][2]*(1.0); + const double G0_0_2_3_3 = det*w[3][0]*w[2][2]*w[0][3]*w[1][3]*(1.0); + const double G0_0_2_3_4 = det*w[3][0]*w[2][2]*w[0][3]*w[1][4]*(1.0); + const double G0_0_2_3_5 = det*w[3][0]*w[2][2]*w[0][3]*w[1][5]*(1.0); + const double G0_0_2_4_0 = det*w[3][0]*w[2][2]*w[0][4]*w[1][0]*(1.0); + const double G0_0_2_4_1 = det*w[3][0]*w[2][2]*w[0][4]*w[1][1]*(1.0); + const double G0_0_2_4_2 = det*w[3][0]*w[2][2]*w[0][4]*w[1][2]*(1.0); + const double G0_0_2_4_3 = det*w[3][0]*w[2][2]*w[0][4]*w[1][3]*(1.0); + const double G0_0_2_4_4 = det*w[3][0]*w[2][2]*w[0][4]*w[1][4]*(1.0); + const double G0_0_2_4_5 = det*w[3][0]*w[2][2]*w[0][4]*w[1][5]*(1.0); + const double G0_0_2_5_0 = det*w[3][0]*w[2][2]*w[0][5]*w[1][0]*(1.0); + const double G0_0_2_5_1 = det*w[3][0]*w[2][2]*w[0][5]*w[1][1]*(1.0); + const double G0_0_2_5_2 = det*w[3][0]*w[2][2]*w[0][5]*w[1][2]*(1.0); + const double G0_0_2_5_3 = det*w[3][0]*w[2][2]*w[0][5]*w[1][3]*(1.0); + const double G0_0_2_5_4 = det*w[3][0]*w[2][2]*w[0][5]*w[1][4]*(1.0); + const double G0_0_2_5_5 = det*w[3][0]*w[2][2]*w[0][5]*w[1][5]*(1.0); + const double G0_0_3_0_0 = det*w[3][0]*w[2][3]*w[0][0]*w[1][0]*(1.0); + const double G0_0_3_0_1 = det*w[3][0]*w[2][3]*w[0][0]*w[1][1]*(1.0); + const double G0_0_3_0_2 = det*w[3][0]*w[2][3]*w[0][0]*w[1][2]*(1.0); + const double G0_0_3_0_3 = det*w[3][0]*w[2][3]*w[0][0]*w[1][3]*(1.0); + const double G0_0_3_0_4 = det*w[3][0]*w[2][3]*w[0][0]*w[1][4]*(1.0); + const double G0_0_3_0_5 = det*w[3][0]*w[2][3]*w[0][0]*w[1][5]*(1.0); + const double G0_0_3_1_0 = det*w[3][0]*w[2][3]*w[0][1]*w[1][0]*(1.0); + const double G0_0_3_1_1 = det*w[3][0]*w[2][3]*w[0][1]*w[1][1]*(1.0); + const double G0_0_3_1_2 = det*w[3][0]*w[2][3]*w[0][1]*w[1][2]*(1.0); + const double G0_0_3_1_3 = det*w[3][0]*w[2][3]*w[0][1]*w[1][3]*(1.0); + const double G0_0_3_1_4 = det*w[3][0]*w[2][3]*w[0][1]*w[1][4]*(1.0); + const double G0_0_3_1_5 = det*w[3][0]*w[2][3]*w[0][1]*w[1][5]*(1.0); + const double G0_0_3_2_0 = det*w[3][0]*w[2][3]*w[0][2]*w[1][0]*(1.0); + const double G0_0_3_2_1 = det*w[3][0]*w[2][3]*w[0][2]*w[1][1]*(1.0); + const double G0_0_3_2_2 = det*w[3][0]*w[2][3]*w[0][2]*w[1][2]*(1.0); + const double G0_0_3_2_3 = det*w[3][0]*w[2][3]*w[0][2]*w[1][3]*(1.0); + const double G0_0_3_2_4 = det*w[3][0]*w[2][3]*w[0][2]*w[1][4]*(1.0); + const double G0_0_3_2_5 = det*w[3][0]*w[2][3]*w[0][2]*w[1][5]*(1.0); + const double G0_0_3_3_0 = det*w[3][0]*w[2][3]*w[0][3]*w[1][0]*(1.0); + const double G0_0_3_3_1 = det*w[3][0]*w[2][3]*w[0][3]*w[1][1]*(1.0); + const double G0_0_3_3_2 = det*w[3][0]*w[2][3]*w[0][3]*w[1][2]*(1.0); + const double G0_0_3_3_3 = det*w[3][0]*w[2][3]*w[0][3]*w[1][3]*(1.0); + const double G0_0_3_3_4 = det*w[3][0]*w[2][3]*w[0][3]*w[1][4]*(1.0); + const double G0_0_3_3_5 = det*w[3][0]*w[2][3]*w[0][3]*w[1][5]*(1.0); + const double G0_0_3_4_0 = det*w[3][0]*w[2][3]*w[0][4]*w[1][0]*(1.0); + const double G0_0_3_4_1 = det*w[3][0]*w[2][3]*w[0][4]*w[1][1]*(1.0); + const double G0_0_3_4_2 = det*w[3][0]*w[2][3]*w[0][4]*w[1][2]*(1.0); + const double G0_0_3_4_3 = det*w[3][0]*w[2][3]*w[0][4]*w[1][3]*(1.0); + const double G0_0_3_4_4 = det*w[3][0]*w[2][3]*w[0][4]*w[1][4]*(1.0); + const double G0_0_3_4_5 = det*w[3][0]*w[2][3]*w[0][4]*w[1][5]*(1.0); + const double G0_0_3_5_0 = det*w[3][0]*w[2][3]*w[0][5]*w[1][0]*(1.0); + const double G0_0_3_5_1 = det*w[3][0]*w[2][3]*w[0][5]*w[1][1]*(1.0); + const double G0_0_3_5_2 = det*w[3][0]*w[2][3]*w[0][5]*w[1][2]*(1.0); + const double G0_0_3_5_3 = det*w[3][0]*w[2][3]*w[0][5]*w[1][3]*(1.0); + const double G0_0_3_5_4 = det*w[3][0]*w[2][3]*w[0][5]*w[1][4]*(1.0); + const double G0_0_3_5_5 = det*w[3][0]*w[2][3]*w[0][5]*w[1][5]*(1.0); + const double G0_0_4_0_0 = det*w[3][0]*w[2][4]*w[0][0]*w[1][0]*(1.0); + const double G0_0_4_0_1 = det*w[3][0]*w[2][4]*w[0][0]*w[1][1]*(1.0); + const double G0_0_4_0_2 = det*w[3][0]*w[2][4]*w[0][0]*w[1][2]*(1.0); + const double G0_0_4_0_3 = det*w[3][0]*w[2][4]*w[0][0]*w[1][3]*(1.0); + const double G0_0_4_0_4 = det*w[3][0]*w[2][4]*w[0][0]*w[1][4]*(1.0); + const double G0_0_4_0_5 = det*w[3][0]*w[2][4]*w[0][0]*w[1][5]*(1.0); + const double G0_0_4_1_0 = det*w[3][0]*w[2][4]*w[0][1]*w[1][0]*(1.0); + const double G0_0_4_1_1 = det*w[3][0]*w[2][4]*w[0][1]*w[1][1]*(1.0); + const double G0_0_4_1_2 = det*w[3][0]*w[2][4]*w[0][1]*w[1][2]*(1.0); + const double G0_0_4_1_3 = det*w[3][0]*w[2][4]*w[0][1]*w[1][3]*(1.0); + const double G0_0_4_1_4 = det*w[3][0]*w[2][4]*w[0][1]*w[1][4]*(1.0); + const double G0_0_4_1_5 = det*w[3][0]*w[2][4]*w[0][1]*w[1][5]*(1.0); + const double G0_0_4_2_0 = det*w[3][0]*w[2][4]*w[0][2]*w[1][0]*(1.0); + const double G0_0_4_2_1 = det*w[3][0]*w[2][4]*w[0][2]*w[1][1]*(1.0); + const double G0_0_4_2_2 = det*w[3][0]*w[2][4]*w[0][2]*w[1][2]*(1.0); + const double G0_0_4_2_3 = det*w[3][0]*w[2][4]*w[0][2]*w[1][3]*(1.0); + const double G0_0_4_2_4 = det*w[3][0]*w[2][4]*w[0][2]*w[1][4]*(1.0); + const double G0_0_4_2_5 = det*w[3][0]*w[2][4]*w[0][2]*w[1][5]*(1.0); + const double G0_0_4_3_0 = det*w[3][0]*w[2][4]*w[0][3]*w[1][0]*(1.0); + const double G0_0_4_3_1 = det*w[3][0]*w[2][4]*w[0][3]*w[1][1]*(1.0); + const double G0_0_4_3_2 = det*w[3][0]*w[2][4]*w[0][3]*w[1][2]*(1.0); + const double G0_0_4_3_3 = det*w[3][0]*w[2][4]*w[0][3]*w[1][3]*(1.0); + const double G0_0_4_3_4 = det*w[3][0]*w[2][4]*w[0][3]*w[1][4]*(1.0); + const double G0_0_4_3_5 = det*w[3][0]*w[2][4]*w[0][3]*w[1][5]*(1.0); + const double G0_0_4_4_0 = det*w[3][0]*w[2][4]*w[0][4]*w[1][0]*(1.0); + const double G0_0_4_4_1 = det*w[3][0]*w[2][4]*w[0][4]*w[1][1]*(1.0); + const double G0_0_4_4_2 = det*w[3][0]*w[2][4]*w[0][4]*w[1][2]*(1.0); + const double G0_0_4_4_3 = det*w[3][0]*w[2][4]*w[0][4]*w[1][3]*(1.0); + const double G0_0_4_4_4 = det*w[3][0]*w[2][4]*w[0][4]*w[1][4]*(1.0); + const double G0_0_4_4_5 = det*w[3][0]*w[2][4]*w[0][4]*w[1][5]*(1.0); + const double G0_0_4_5_0 = det*w[3][0]*w[2][4]*w[0][5]*w[1][0]*(1.0); + const double G0_0_4_5_1 = det*w[3][0]*w[2][4]*w[0][5]*w[1][1]*(1.0); + const double G0_0_4_5_2 = det*w[3][0]*w[2][4]*w[0][5]*w[1][2]*(1.0); + const double G0_0_4_5_3 = det*w[3][0]*w[2][4]*w[0][5]*w[1][3]*(1.0); + const double G0_0_4_5_4 = det*w[3][0]*w[2][4]*w[0][5]*w[1][4]*(1.0); + const double G0_0_4_5_5 = det*w[3][0]*w[2][4]*w[0][5]*w[1][5]*(1.0); + const double G0_0_5_0_0 = det*w[3][0]*w[2][5]*w[0][0]*w[1][0]*(1.0); + const double G0_0_5_0_1 = det*w[3][0]*w[2][5]*w[0][0]*w[1][1]*(1.0); + const double G0_0_5_0_2 = det*w[3][0]*w[2][5]*w[0][0]*w[1][2]*(1.0); + const double G0_0_5_0_3 = det*w[3][0]*w[2][5]*w[0][0]*w[1][3]*(1.0); + const double G0_0_5_0_4 = det*w[3][0]*w[2][5]*w[0][0]*w[1][4]*(1.0); + const double G0_0_5_0_5 = det*w[3][0]*w[2][5]*w[0][0]*w[1][5]*(1.0); + const double G0_0_5_1_0 = det*w[3][0]*w[2][5]*w[0][1]*w[1][0]*(1.0); + const double G0_0_5_1_1 = det*w[3][0]*w[2][5]*w[0][1]*w[1][1]*(1.0); + const double G0_0_5_1_2 = det*w[3][0]*w[2][5]*w[0][1]*w[1][2]*(1.0); + const double G0_0_5_1_3 = det*w[3][0]*w[2][5]*w[0][1]*w[1][3]*(1.0); + const double G0_0_5_1_4 = det*w[3][0]*w[2][5]*w[0][1]*w[1][4]*(1.0); + const double G0_0_5_1_5 = det*w[3][0]*w[2][5]*w[0][1]*w[1][5]*(1.0); + const double G0_0_5_2_0 = det*w[3][0]*w[2][5]*w[0][2]*w[1][0]*(1.0); + const double G0_0_5_2_1 = det*w[3][0]*w[2][5]*w[0][2]*w[1][1]*(1.0); + const double G0_0_5_2_2 = det*w[3][0]*w[2][5]*w[0][2]*w[1][2]*(1.0); + const double G0_0_5_2_3 = det*w[3][0]*w[2][5]*w[0][2]*w[1][3]*(1.0); + const double G0_0_5_2_4 = det*w[3][0]*w[2][5]*w[0][2]*w[1][4]*(1.0); + const double G0_0_5_2_5 = det*w[3][0]*w[2][5]*w[0][2]*w[1][5]*(1.0); + const double G0_0_5_3_0 = det*w[3][0]*w[2][5]*w[0][3]*w[1][0]*(1.0); + const double G0_0_5_3_1 = det*w[3][0]*w[2][5]*w[0][3]*w[1][1]*(1.0); + const double G0_0_5_3_2 = det*w[3][0]*w[2][5]*w[0][3]*w[1][2]*(1.0); + const double G0_0_5_3_3 = det*w[3][0]*w[2][5]*w[0][3]*w[1][3]*(1.0); + const double G0_0_5_3_4 = det*w[3][0]*w[2][5]*w[0][3]*w[1][4]*(1.0); + const double G0_0_5_3_5 = det*w[3][0]*w[2][5]*w[0][3]*w[1][5]*(1.0); + const double G0_0_5_4_0 = det*w[3][0]*w[2][5]*w[0][4]*w[1][0]*(1.0); + const double G0_0_5_4_1 = det*w[3][0]*w[2][5]*w[0][4]*w[1][1]*(1.0); + const double G0_0_5_4_2 = det*w[3][0]*w[2][5]*w[0][4]*w[1][2]*(1.0); + const double G0_0_5_4_3 = det*w[3][0]*w[2][5]*w[0][4]*w[1][3]*(1.0); + const double G0_0_5_4_4 = det*w[3][0]*w[2][5]*w[0][4]*w[1][4]*(1.0); + const double G0_0_5_4_5 = det*w[3][0]*w[2][5]*w[0][4]*w[1][5]*(1.0); + const double G0_0_5_5_0 = det*w[3][0]*w[2][5]*w[0][5]*w[1][0]*(1.0); + const double G0_0_5_5_1 = det*w[3][0]*w[2][5]*w[0][5]*w[1][1]*(1.0); + const double G0_0_5_5_2 = det*w[3][0]*w[2][5]*w[0][5]*w[1][2]*(1.0); + const double G0_0_5_5_3 = det*w[3][0]*w[2][5]*w[0][5]*w[1][3]*(1.0); + const double G0_0_5_5_4 = det*w[3][0]*w[2][5]*w[0][5]*w[1][4]*(1.0); + const double G0_0_5_5_5 = det*w[3][0]*w[2][5]*w[0][5]*w[1][5]*(1.0); + const double G0_1_0_0_0 = det*w[3][1]*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_1_0_0_1 = det*w[3][1]*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_1_0_0_2 = det*w[3][1]*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_1_0_0_3 = det*w[3][1]*w[2][0]*w[0][0]*w[1][3]*(1.0); + const double G0_1_0_0_4 = det*w[3][1]*w[2][0]*w[0][0]*w[1][4]*(1.0); + const double G0_1_0_0_5 = det*w[3][1]*w[2][0]*w[0][0]*w[1][5]*(1.0); + const double G0_1_0_1_0 = det*w[3][1]*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_1_0_1_1 = det*w[3][1]*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_1_0_1_2 = det*w[3][1]*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_1_0_1_3 = det*w[3][1]*w[2][0]*w[0][1]*w[1][3]*(1.0); + const double G0_1_0_1_4 = det*w[3][1]*w[2][0]*w[0][1]*w[1][4]*(1.0); + const double G0_1_0_1_5 = det*w[3][1]*w[2][0]*w[0][1]*w[1][5]*(1.0); + const double G0_1_0_2_0 = det*w[3][1]*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_1_0_2_1 = det*w[3][1]*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_1_0_2_2 = det*w[3][1]*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_1_0_2_3 = det*w[3][1]*w[2][0]*w[0][2]*w[1][3]*(1.0); + const double G0_1_0_2_4 = det*w[3][1]*w[2][0]*w[0][2]*w[1][4]*(1.0); + const double G0_1_0_2_5 = det*w[3][1]*w[2][0]*w[0][2]*w[1][5]*(1.0); + const double G0_1_0_3_0 = det*w[3][1]*w[2][0]*w[0][3]*w[1][0]*(1.0); + const double G0_1_0_3_1 = det*w[3][1]*w[2][0]*w[0][3]*w[1][1]*(1.0); + const double G0_1_0_3_2 = det*w[3][1]*w[2][0]*w[0][3]*w[1][2]*(1.0); + const double G0_1_0_3_3 = det*w[3][1]*w[2][0]*w[0][3]*w[1][3]*(1.0); + const double G0_1_0_3_4 = det*w[3][1]*w[2][0]*w[0][3]*w[1][4]*(1.0); + const double G0_1_0_3_5 = det*w[3][1]*w[2][0]*w[0][3]*w[1][5]*(1.0); + const double G0_1_0_4_0 = det*w[3][1]*w[2][0]*w[0][4]*w[1][0]*(1.0); + const double G0_1_0_4_1 = det*w[3][1]*w[2][0]*w[0][4]*w[1][1]*(1.0); + const double G0_1_0_4_2 = det*w[3][1]*w[2][0]*w[0][4]*w[1][2]*(1.0); + const double G0_1_0_4_3 = det*w[3][1]*w[2][0]*w[0][4]*w[1][3]*(1.0); + const double G0_1_0_4_4 = det*w[3][1]*w[2][0]*w[0][4]*w[1][4]*(1.0); + const double G0_1_0_4_5 = det*w[3][1]*w[2][0]*w[0][4]*w[1][5]*(1.0); + const double G0_1_0_5_0 = det*w[3][1]*w[2][0]*w[0][5]*w[1][0]*(1.0); + const double G0_1_0_5_1 = det*w[3][1]*w[2][0]*w[0][5]*w[1][1]*(1.0); + const double G0_1_0_5_2 = det*w[3][1]*w[2][0]*w[0][5]*w[1][2]*(1.0); + const double G0_1_0_5_3 = det*w[3][1]*w[2][0]*w[0][5]*w[1][3]*(1.0); + const double G0_1_0_5_4 = det*w[3][1]*w[2][0]*w[0][5]*w[1][4]*(1.0); + const double G0_1_0_5_5 = det*w[3][1]*w[2][0]*w[0][5]*w[1][5]*(1.0); + const double G0_1_1_0_0 = det*w[3][1]*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_1_1_0_1 = det*w[3][1]*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_1_1_0_2 = det*w[3][1]*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_1_1_0_3 = det*w[3][1]*w[2][1]*w[0][0]*w[1][3]*(1.0); + const double G0_1_1_0_4 = det*w[3][1]*w[2][1]*w[0][0]*w[1][4]*(1.0); + const double G0_1_1_0_5 = det*w[3][1]*w[2][1]*w[0][0]*w[1][5]*(1.0); + const double G0_1_1_1_0 = det*w[3][1]*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_1_1_1_1 = det*w[3][1]*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_1_1_1_2 = det*w[3][1]*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_1_1_1_3 = det*w[3][1]*w[2][1]*w[0][1]*w[1][3]*(1.0); + const double G0_1_1_1_4 = det*w[3][1]*w[2][1]*w[0][1]*w[1][4]*(1.0); + const double G0_1_1_1_5 = det*w[3][1]*w[2][1]*w[0][1]*w[1][5]*(1.0); + const double G0_1_1_2_0 = det*w[3][1]*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_1_1_2_1 = det*w[3][1]*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_1_1_2_2 = det*w[3][1]*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_1_1_2_3 = det*w[3][1]*w[2][1]*w[0][2]*w[1][3]*(1.0); + const double G0_1_1_2_4 = det*w[3][1]*w[2][1]*w[0][2]*w[1][4]*(1.0); + const double G0_1_1_2_5 = det*w[3][1]*w[2][1]*w[0][2]*w[1][5]*(1.0); + const double G0_1_1_3_0 = det*w[3][1]*w[2][1]*w[0][3]*w[1][0]*(1.0); + const double G0_1_1_3_1 = det*w[3][1]*w[2][1]*w[0][3]*w[1][1]*(1.0); + const double G0_1_1_3_2 = det*w[3][1]*w[2][1]*w[0][3]*w[1][2]*(1.0); + const double G0_1_1_3_3 = det*w[3][1]*w[2][1]*w[0][3]*w[1][3]*(1.0); + const double G0_1_1_3_4 = det*w[3][1]*w[2][1]*w[0][3]*w[1][4]*(1.0); + const double G0_1_1_3_5 = det*w[3][1]*w[2][1]*w[0][3]*w[1][5]*(1.0); + const double G0_1_1_4_0 = det*w[3][1]*w[2][1]*w[0][4]*w[1][0]*(1.0); + const double G0_1_1_4_1 = det*w[3][1]*w[2][1]*w[0][4]*w[1][1]*(1.0); + const double G0_1_1_4_2 = det*w[3][1]*w[2][1]*w[0][4]*w[1][2]*(1.0); + const double G0_1_1_4_3 = det*w[3][1]*w[2][1]*w[0][4]*w[1][3]*(1.0); + const double G0_1_1_4_4 = det*w[3][1]*w[2][1]*w[0][4]*w[1][4]*(1.0); + const double G0_1_1_4_5 = det*w[3][1]*w[2][1]*w[0][4]*w[1][5]*(1.0); + const double G0_1_1_5_0 = det*w[3][1]*w[2][1]*w[0][5]*w[1][0]*(1.0); + const double G0_1_1_5_1 = det*w[3][1]*w[2][1]*w[0][5]*w[1][1]*(1.0); + const double G0_1_1_5_2 = det*w[3][1]*w[2][1]*w[0][5]*w[1][2]*(1.0); + const double G0_1_1_5_3 = det*w[3][1]*w[2][1]*w[0][5]*w[1][3]*(1.0); + const double G0_1_1_5_4 = det*w[3][1]*w[2][1]*w[0][5]*w[1][4]*(1.0); + const double G0_1_1_5_5 = det*w[3][1]*w[2][1]*w[0][5]*w[1][5]*(1.0); + const double G0_1_2_0_0 = det*w[3][1]*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_1_2_0_1 = det*w[3][1]*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_1_2_0_2 = det*w[3][1]*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_1_2_0_3 = det*w[3][1]*w[2][2]*w[0][0]*w[1][3]*(1.0); + const double G0_1_2_0_4 = det*w[3][1]*w[2][2]*w[0][0]*w[1][4]*(1.0); + const double G0_1_2_0_5 = det*w[3][1]*w[2][2]*w[0][0]*w[1][5]*(1.0); + const double G0_1_2_1_0 = det*w[3][1]*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_1_2_1_1 = det*w[3][1]*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_1_2_1_2 = det*w[3][1]*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_1_2_1_3 = det*w[3][1]*w[2][2]*w[0][1]*w[1][3]*(1.0); + const double G0_1_2_1_4 = det*w[3][1]*w[2][2]*w[0][1]*w[1][4]*(1.0); + const double G0_1_2_1_5 = det*w[3][1]*w[2][2]*w[0][1]*w[1][5]*(1.0); + const double G0_1_2_2_0 = det*w[3][1]*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_1_2_2_1 = det*w[3][1]*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_1_2_2_2 = det*w[3][1]*w[2][2]*w[0][2]*w[1][2]*(1.0); + const double G0_1_2_2_3 = det*w[3][1]*w[2][2]*w[0][2]*w[1][3]*(1.0); + const double G0_1_2_2_4 = det*w[3][1]*w[2][2]*w[0][2]*w[1][4]*(1.0); + const double G0_1_2_2_5 = det*w[3][1]*w[2][2]*w[0][2]*w[1][5]*(1.0); + const double G0_1_2_3_0 = det*w[3][1]*w[2][2]*w[0][3]*w[1][0]*(1.0); + const double G0_1_2_3_1 = det*w[3][1]*w[2][2]*w[0][3]*w[1][1]*(1.0); + const double G0_1_2_3_2 = det*w[3][1]*w[2][2]*w[0][3]*w[1][2]*(1.0); + const double G0_1_2_3_3 = det*w[3][1]*w[2][2]*w[0][3]*w[1][3]*(1.0); + const double G0_1_2_3_4 = det*w[3][1]*w[2][2]*w[0][3]*w[1][4]*(1.0); + const double G0_1_2_3_5 = det*w[3][1]*w[2][2]*w[0][3]*w[1][5]*(1.0); + const double G0_1_2_4_0 = det*w[3][1]*w[2][2]*w[0][4]*w[1][0]*(1.0); + const double G0_1_2_4_1 = det*w[3][1]*w[2][2]*w[0][4]*w[1][1]*(1.0); + const double G0_1_2_4_2 = det*w[3][1]*w[2][2]*w[0][4]*w[1][2]*(1.0); + const double G0_1_2_4_3 = det*w[3][1]*w[2][2]*w[0][4]*w[1][3]*(1.0); + const double G0_1_2_4_4 = det*w[3][1]*w[2][2]*w[0][4]*w[1][4]*(1.0); + const double G0_1_2_4_5 = det*w[3][1]*w[2][2]*w[0][4]*w[1][5]*(1.0); + const double G0_1_2_5_0 = det*w[3][1]*w[2][2]*w[0][5]*w[1][0]*(1.0); + const double G0_1_2_5_1 = det*w[3][1]*w[2][2]*w[0][5]*w[1][1]*(1.0); + const double G0_1_2_5_2 = det*w[3][1]*w[2][2]*w[0][5]*w[1][2]*(1.0); + const double G0_1_2_5_3 = det*w[3][1]*w[2][2]*w[0][5]*w[1][3]*(1.0); + const double G0_1_2_5_4 = det*w[3][1]*w[2][2]*w[0][5]*w[1][4]*(1.0); + const double G0_1_2_5_5 = det*w[3][1]*w[2][2]*w[0][5]*w[1][5]*(1.0); + const double G0_1_3_0_0 = det*w[3][1]*w[2][3]*w[0][0]*w[1][0]*(1.0); + const double G0_1_3_0_1 = det*w[3][1]*w[2][3]*w[0][0]*w[1][1]*(1.0); + const double G0_1_3_0_2 = det*w[3][1]*w[2][3]*w[0][0]*w[1][2]*(1.0); + const double G0_1_3_0_3 = det*w[3][1]*w[2][3]*w[0][0]*w[1][3]*(1.0); + const double G0_1_3_0_4 = det*w[3][1]*w[2][3]*w[0][0]*w[1][4]*(1.0); + const double G0_1_3_0_5 = det*w[3][1]*w[2][3]*w[0][0]*w[1][5]*(1.0); + const double G0_1_3_1_0 = det*w[3][1]*w[2][3]*w[0][1]*w[1][0]*(1.0); + const double G0_1_3_1_1 = det*w[3][1]*w[2][3]*w[0][1]*w[1][1]*(1.0); + const double G0_1_3_1_2 = det*w[3][1]*w[2][3]*w[0][1]*w[1][2]*(1.0); + const double G0_1_3_1_3 = det*w[3][1]*w[2][3]*w[0][1]*w[1][3]*(1.0); + const double G0_1_3_1_4 = det*w[3][1]*w[2][3]*w[0][1]*w[1][4]*(1.0); + const double G0_1_3_1_5 = det*w[3][1]*w[2][3]*w[0][1]*w[1][5]*(1.0); + const double G0_1_3_2_0 = det*w[3][1]*w[2][3]*w[0][2]*w[1][0]*(1.0); + const double G0_1_3_2_1 = det*w[3][1]*w[2][3]*w[0][2]*w[1][1]*(1.0); + const double G0_1_3_2_2 = det*w[3][1]*w[2][3]*w[0][2]*w[1][2]*(1.0); + const double G0_1_3_2_3 = det*w[3][1]*w[2][3]*w[0][2]*w[1][3]*(1.0); + const double G0_1_3_2_4 = det*w[3][1]*w[2][3]*w[0][2]*w[1][4]*(1.0); + const double G0_1_3_2_5 = det*w[3][1]*w[2][3]*w[0][2]*w[1][5]*(1.0); + const double G0_1_3_3_0 = det*w[3][1]*w[2][3]*w[0][3]*w[1][0]*(1.0); + const double G0_1_3_3_1 = det*w[3][1]*w[2][3]*w[0][3]*w[1][1]*(1.0); + const double G0_1_3_3_2 = det*w[3][1]*w[2][3]*w[0][3]*w[1][2]*(1.0); + const double G0_1_3_3_3 = det*w[3][1]*w[2][3]*w[0][3]*w[1][3]*(1.0); + const double G0_1_3_3_4 = det*w[3][1]*w[2][3]*w[0][3]*w[1][4]*(1.0); + const double G0_1_3_3_5 = det*w[3][1]*w[2][3]*w[0][3]*w[1][5]*(1.0); + const double G0_1_3_4_0 = det*w[3][1]*w[2][3]*w[0][4]*w[1][0]*(1.0); + const double G0_1_3_4_1 = det*w[3][1]*w[2][3]*w[0][4]*w[1][1]*(1.0); + const double G0_1_3_4_2 = det*w[3][1]*w[2][3]*w[0][4]*w[1][2]*(1.0); + const double G0_1_3_4_3 = det*w[3][1]*w[2][3]*w[0][4]*w[1][3]*(1.0); + const double G0_1_3_4_4 = det*w[3][1]*w[2][3]*w[0][4]*w[1][4]*(1.0); + const double G0_1_3_4_5 = det*w[3][1]*w[2][3]*w[0][4]*w[1][5]*(1.0); + const double G0_1_3_5_0 = det*w[3][1]*w[2][3]*w[0][5]*w[1][0]*(1.0); + const double G0_1_3_5_1 = det*w[3][1]*w[2][3]*w[0][5]*w[1][1]*(1.0); + const double G0_1_3_5_2 = det*w[3][1]*w[2][3]*w[0][5]*w[1][2]*(1.0); + const double G0_1_3_5_3 = det*w[3][1]*w[2][3]*w[0][5]*w[1][3]*(1.0); + const double G0_1_3_5_4 = det*w[3][1]*w[2][3]*w[0][5]*w[1][4]*(1.0); + const double G0_1_3_5_5 = det*w[3][1]*w[2][3]*w[0][5]*w[1][5]*(1.0); + const double G0_1_4_0_0 = det*w[3][1]*w[2][4]*w[0][0]*w[1][0]*(1.0); + const double G0_1_4_0_1 = det*w[3][1]*w[2][4]*w[0][0]*w[1][1]*(1.0); + const double G0_1_4_0_2 = det*w[3][1]*w[2][4]*w[0][0]*w[1][2]*(1.0); + const double G0_1_4_0_3 = det*w[3][1]*w[2][4]*w[0][0]*w[1][3]*(1.0); + const double G0_1_4_0_4 = det*w[3][1]*w[2][4]*w[0][0]*w[1][4]*(1.0); + const double G0_1_4_0_5 = det*w[3][1]*w[2][4]*w[0][0]*w[1][5]*(1.0); + const double G0_1_4_1_0 = det*w[3][1]*w[2][4]*w[0][1]*w[1][0]*(1.0); + const double G0_1_4_1_1 = det*w[3][1]*w[2][4]*w[0][1]*w[1][1]*(1.0); + const double G0_1_4_1_2 = det*w[3][1]*w[2][4]*w[0][1]*w[1][2]*(1.0); + const double G0_1_4_1_3 = det*w[3][1]*w[2][4]*w[0][1]*w[1][3]*(1.0); + const double G0_1_4_1_4 = det*w[3][1]*w[2][4]*w[0][1]*w[1][4]*(1.0); + const double G0_1_4_1_5 = det*w[3][1]*w[2][4]*w[0][1]*w[1][5]*(1.0); + const double G0_1_4_2_0 = det*w[3][1]*w[2][4]*w[0][2]*w[1][0]*(1.0); + const double G0_1_4_2_1 = det*w[3][1]*w[2][4]*w[0][2]*w[1][1]*(1.0); + const double G0_1_4_2_2 = det*w[3][1]*w[2][4]*w[0][2]*w[1][2]*(1.0); + const double G0_1_4_2_3 = det*w[3][1]*w[2][4]*w[0][2]*w[1][3]*(1.0); + const double G0_1_4_2_4 = det*w[3][1]*w[2][4]*w[0][2]*w[1][4]*(1.0); + const double G0_1_4_2_5 = det*w[3][1]*w[2][4]*w[0][2]*w[1][5]*(1.0); + const double G0_1_4_3_0 = det*w[3][1]*w[2][4]*w[0][3]*w[1][0]*(1.0); + const double G0_1_4_3_1 = det*w[3][1]*w[2][4]*w[0][3]*w[1][1]*(1.0); + const double G0_1_4_3_2 = det*w[3][1]*w[2][4]*w[0][3]*w[1][2]*(1.0); + const double G0_1_4_3_3 = det*w[3][1]*w[2][4]*w[0][3]*w[1][3]*(1.0); + const double G0_1_4_3_4 = det*w[3][1]*w[2][4]*w[0][3]*w[1][4]*(1.0); + const double G0_1_4_3_5 = det*w[3][1]*w[2][4]*w[0][3]*w[1][5]*(1.0); + const double G0_1_4_4_0 = det*w[3][1]*w[2][4]*w[0][4]*w[1][0]*(1.0); + const double G0_1_4_4_1 = det*w[3][1]*w[2][4]*w[0][4]*w[1][1]*(1.0); + const double G0_1_4_4_2 = det*w[3][1]*w[2][4]*w[0][4]*w[1][2]*(1.0); + const double G0_1_4_4_3 = det*w[3][1]*w[2][4]*w[0][4]*w[1][3]*(1.0); + const double G0_1_4_4_4 = det*w[3][1]*w[2][4]*w[0][4]*w[1][4]*(1.0); + const double G0_1_4_4_5 = det*w[3][1]*w[2][4]*w[0][4]*w[1][5]*(1.0); + const double G0_1_4_5_0 = det*w[3][1]*w[2][4]*w[0][5]*w[1][0]*(1.0); + const double G0_1_4_5_1 = det*w[3][1]*w[2][4]*w[0][5]*w[1][1]*(1.0); + const double G0_1_4_5_2 = det*w[3][1]*w[2][4]*w[0][5]*w[1][2]*(1.0); + const double G0_1_4_5_3 = det*w[3][1]*w[2][4]*w[0][5]*w[1][3]*(1.0); + const double G0_1_4_5_4 = det*w[3][1]*w[2][4]*w[0][5]*w[1][4]*(1.0); + const double G0_1_4_5_5 = det*w[3][1]*w[2][4]*w[0][5]*w[1][5]*(1.0); + const double G0_1_5_0_0 = det*w[3][1]*w[2][5]*w[0][0]*w[1][0]*(1.0); + const double G0_1_5_0_1 = det*w[3][1]*w[2][5]*w[0][0]*w[1][1]*(1.0); + const double G0_1_5_0_2 = det*w[3][1]*w[2][5]*w[0][0]*w[1][2]*(1.0); + const double G0_1_5_0_3 = det*w[3][1]*w[2][5]*w[0][0]*w[1][3]*(1.0); + const double G0_1_5_0_4 = det*w[3][1]*w[2][5]*w[0][0]*w[1][4]*(1.0); + const double G0_1_5_0_5 = det*w[3][1]*w[2][5]*w[0][0]*w[1][5]*(1.0); + const double G0_1_5_1_0 = det*w[3][1]*w[2][5]*w[0][1]*w[1][0]*(1.0); + const double G0_1_5_1_1 = det*w[3][1]*w[2][5]*w[0][1]*w[1][1]*(1.0); + const double G0_1_5_1_2 = det*w[3][1]*w[2][5]*w[0][1]*w[1][2]*(1.0); + const double G0_1_5_1_3 = det*w[3][1]*w[2][5]*w[0][1]*w[1][3]*(1.0); + const double G0_1_5_1_4 = det*w[3][1]*w[2][5]*w[0][1]*w[1][4]*(1.0); + const double G0_1_5_1_5 = det*w[3][1]*w[2][5]*w[0][1]*w[1][5]*(1.0); + const double G0_1_5_2_0 = det*w[3][1]*w[2][5]*w[0][2]*w[1][0]*(1.0); + const double G0_1_5_2_1 = det*w[3][1]*w[2][5]*w[0][2]*w[1][1]*(1.0); + const double G0_1_5_2_2 = det*w[3][1]*w[2][5]*w[0][2]*w[1][2]*(1.0); + const double G0_1_5_2_3 = det*w[3][1]*w[2][5]*w[0][2]*w[1][3]*(1.0); + const double G0_1_5_2_4 = det*w[3][1]*w[2][5]*w[0][2]*w[1][4]*(1.0); + const double G0_1_5_2_5 = det*w[3][1]*w[2][5]*w[0][2]*w[1][5]*(1.0); + const double G0_1_5_3_0 = det*w[3][1]*w[2][5]*w[0][3]*w[1][0]*(1.0); + const double G0_1_5_3_1 = det*w[3][1]*w[2][5]*w[0][3]*w[1][1]*(1.0); + const double G0_1_5_3_2 = det*w[3][1]*w[2][5]*w[0][3]*w[1][2]*(1.0); + const double G0_1_5_3_3 = det*w[3][1]*w[2][5]*w[0][3]*w[1][3]*(1.0); + const double G0_1_5_3_4 = det*w[3][1]*w[2][5]*w[0][3]*w[1][4]*(1.0); + const double G0_1_5_3_5 = det*w[3][1]*w[2][5]*w[0][3]*w[1][5]*(1.0); + const double G0_1_5_4_0 = det*w[3][1]*w[2][5]*w[0][4]*w[1][0]*(1.0); + const double G0_1_5_4_1 = det*w[3][1]*w[2][5]*w[0][4]*w[1][1]*(1.0); + const double G0_1_5_4_2 = det*w[3][1]*w[2][5]*w[0][4]*w[1][2]*(1.0); + const double G0_1_5_4_3 = det*w[3][1]*w[2][5]*w[0][4]*w[1][3]*(1.0); + const double G0_1_5_4_4 = det*w[3][1]*w[2][5]*w[0][4]*w[1][4]*(1.0); + const double G0_1_5_4_5 = det*w[3][1]*w[2][5]*w[0][4]*w[1][5]*(1.0); + const double G0_1_5_5_0 = det*w[3][1]*w[2][5]*w[0][5]*w[1][0]*(1.0); + const double G0_1_5_5_1 = det*w[3][1]*w[2][5]*w[0][5]*w[1][1]*(1.0); + const double G0_1_5_5_2 = det*w[3][1]*w[2][5]*w[0][5]*w[1][2]*(1.0); + const double G0_1_5_5_3 = det*w[3][1]*w[2][5]*w[0][5]*w[1][3]*(1.0); + const double G0_1_5_5_4 = det*w[3][1]*w[2][5]*w[0][5]*w[1][4]*(1.0); + const double G0_1_5_5_5 = det*w[3][1]*w[2][5]*w[0][5]*w[1][5]*(1.0); + const double G0_2_0_0_0 = det*w[3][2]*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_2_0_0_1 = det*w[3][2]*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_2_0_0_2 = det*w[3][2]*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_2_0_0_3 = det*w[3][2]*w[2][0]*w[0][0]*w[1][3]*(1.0); + const double G0_2_0_0_4 = det*w[3][2]*w[2][0]*w[0][0]*w[1][4]*(1.0); + const double G0_2_0_0_5 = det*w[3][2]*w[2][0]*w[0][0]*w[1][5]*(1.0); + const double G0_2_0_1_0 = det*w[3][2]*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_2_0_1_1 = det*w[3][2]*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_2_0_1_2 = det*w[3][2]*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_2_0_1_3 = det*w[3][2]*w[2][0]*w[0][1]*w[1][3]*(1.0); + const double G0_2_0_1_4 = det*w[3][2]*w[2][0]*w[0][1]*w[1][4]*(1.0); + const double G0_2_0_1_5 = det*w[3][2]*w[2][0]*w[0][1]*w[1][5]*(1.0); + const double G0_2_0_2_0 = det*w[3][2]*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_2_0_2_1 = det*w[3][2]*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_2_0_2_2 = det*w[3][2]*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_2_0_2_3 = det*w[3][2]*w[2][0]*w[0][2]*w[1][3]*(1.0); + const double G0_2_0_2_4 = det*w[3][2]*w[2][0]*w[0][2]*w[1][4]*(1.0); + const double G0_2_0_2_5 = det*w[3][2]*w[2][0]*w[0][2]*w[1][5]*(1.0); + const double G0_2_0_3_0 = det*w[3][2]*w[2][0]*w[0][3]*w[1][0]*(1.0); + const double G0_2_0_3_1 = det*w[3][2]*w[2][0]*w[0][3]*w[1][1]*(1.0); + const double G0_2_0_3_2 = det*w[3][2]*w[2][0]*w[0][3]*w[1][2]*(1.0); + const double G0_2_0_3_3 = det*w[3][2]*w[2][0]*w[0][3]*w[1][3]*(1.0); + const double G0_2_0_3_4 = det*w[3][2]*w[2][0]*w[0][3]*w[1][4]*(1.0); + const double G0_2_0_3_5 = det*w[3][2]*w[2][0]*w[0][3]*w[1][5]*(1.0); + const double G0_2_0_4_0 = det*w[3][2]*w[2][0]*w[0][4]*w[1][0]*(1.0); + const double G0_2_0_4_1 = det*w[3][2]*w[2][0]*w[0][4]*w[1][1]*(1.0); + const double G0_2_0_4_2 = det*w[3][2]*w[2][0]*w[0][4]*w[1][2]*(1.0); + const double G0_2_0_4_3 = det*w[3][2]*w[2][0]*w[0][4]*w[1][3]*(1.0); + const double G0_2_0_4_4 = det*w[3][2]*w[2][0]*w[0][4]*w[1][4]*(1.0); + const double G0_2_0_4_5 = det*w[3][2]*w[2][0]*w[0][4]*w[1][5]*(1.0); + const double G0_2_0_5_0 = det*w[3][2]*w[2][0]*w[0][5]*w[1][0]*(1.0); + const double G0_2_0_5_1 = det*w[3][2]*w[2][0]*w[0][5]*w[1][1]*(1.0); + const double G0_2_0_5_2 = det*w[3][2]*w[2][0]*w[0][5]*w[1][2]*(1.0); + const double G0_2_0_5_3 = det*w[3][2]*w[2][0]*w[0][5]*w[1][3]*(1.0); + const double G0_2_0_5_4 = det*w[3][2]*w[2][0]*w[0][5]*w[1][4]*(1.0); + const double G0_2_0_5_5 = det*w[3][2]*w[2][0]*w[0][5]*w[1][5]*(1.0); + const double G0_2_1_0_0 = det*w[3][2]*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_2_1_0_1 = det*w[3][2]*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_2_1_0_2 = det*w[3][2]*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_2_1_0_3 = det*w[3][2]*w[2][1]*w[0][0]*w[1][3]*(1.0); + const double G0_2_1_0_4 = det*w[3][2]*w[2][1]*w[0][0]*w[1][4]*(1.0); + const double G0_2_1_0_5 = det*w[3][2]*w[2][1]*w[0][0]*w[1][5]*(1.0); + const double G0_2_1_1_0 = det*w[3][2]*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_2_1_1_1 = det*w[3][2]*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_2_1_1_2 = det*w[3][2]*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_2_1_1_3 = det*w[3][2]*w[2][1]*w[0][1]*w[1][3]*(1.0); + const double G0_2_1_1_4 = det*w[3][2]*w[2][1]*w[0][1]*w[1][4]*(1.0); + const double G0_2_1_1_5 = det*w[3][2]*w[2][1]*w[0][1]*w[1][5]*(1.0); + const double G0_2_1_2_0 = det*w[3][2]*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_2_1_2_1 = det*w[3][2]*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_2_1_2_2 = det*w[3][2]*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_2_1_2_3 = det*w[3][2]*w[2][1]*w[0][2]*w[1][3]*(1.0); + const double G0_2_1_2_4 = det*w[3][2]*w[2][1]*w[0][2]*w[1][4]*(1.0); + const double G0_2_1_2_5 = det*w[3][2]*w[2][1]*w[0][2]*w[1][5]*(1.0); + const double G0_2_1_3_0 = det*w[3][2]*w[2][1]*w[0][3]*w[1][0]*(1.0); + const double G0_2_1_3_1 = det*w[3][2]*w[2][1]*w[0][3]*w[1][1]*(1.0); + const double G0_2_1_3_2 = det*w[3][2]*w[2][1]*w[0][3]*w[1][2]*(1.0); + const double G0_2_1_3_3 = det*w[3][2]*w[2][1]*w[0][3]*w[1][3]*(1.0); + const double G0_2_1_3_4 = det*w[3][2]*w[2][1]*w[0][3]*w[1][4]*(1.0); + const double G0_2_1_3_5 = det*w[3][2]*w[2][1]*w[0][3]*w[1][5]*(1.0); + const double G0_2_1_4_0 = det*w[3][2]*w[2][1]*w[0][4]*w[1][0]*(1.0); + const double G0_2_1_4_1 = det*w[3][2]*w[2][1]*w[0][4]*w[1][1]*(1.0); + const double G0_2_1_4_2 = det*w[3][2]*w[2][1]*w[0][4]*w[1][2]*(1.0); + const double G0_2_1_4_3 = det*w[3][2]*w[2][1]*w[0][4]*w[1][3]*(1.0); + const double G0_2_1_4_4 = det*w[3][2]*w[2][1]*w[0][4]*w[1][4]*(1.0); + const double G0_2_1_4_5 = det*w[3][2]*w[2][1]*w[0][4]*w[1][5]*(1.0); + const double G0_2_1_5_0 = det*w[3][2]*w[2][1]*w[0][5]*w[1][0]*(1.0); + const double G0_2_1_5_1 = det*w[3][2]*w[2][1]*w[0][5]*w[1][1]*(1.0); + const double G0_2_1_5_2 = det*w[3][2]*w[2][1]*w[0][5]*w[1][2]*(1.0); + const double G0_2_1_5_3 = det*w[3][2]*w[2][1]*w[0][5]*w[1][3]*(1.0); + const double G0_2_1_5_4 = det*w[3][2]*w[2][1]*w[0][5]*w[1][4]*(1.0); + const double G0_2_1_5_5 = det*w[3][2]*w[2][1]*w[0][5]*w[1][5]*(1.0); + const double G0_2_2_0_0 = det*w[3][2]*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_2_2_0_1 = det*w[3][2]*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_2_2_0_2 = det*w[3][2]*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_2_2_0_3 = det*w[3][2]*w[2][2]*w[0][0]*w[1][3]*(1.0); + const double G0_2_2_0_4 = det*w[3][2]*w[2][2]*w[0][0]*w[1][4]*(1.0); + const double G0_2_2_0_5 = det*w[3][2]*w[2][2]*w[0][0]*w[1][5]*(1.0); + const double G0_2_2_1_0 = det*w[3][2]*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_2_2_1_1 = det*w[3][2]*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_2_2_1_2 = det*w[3][2]*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_2_2_1_3 = det*w[3][2]*w[2][2]*w[0][1]*w[1][3]*(1.0); + const double G0_2_2_1_4 = det*w[3][2]*w[2][2]*w[0][1]*w[1][4]*(1.0); + const double G0_2_2_1_5 = det*w[3][2]*w[2][2]*w[0][1]*w[1][5]*(1.0); + const double G0_2_2_2_0 = det*w[3][2]*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_2_2_2_1 = det*w[3][2]*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_2_2_2_2 = det*w[3][2]*w[2][2]*w[0][2]*w[1][2]*(1.0); + const double G0_2_2_2_3 = det*w[3][2]*w[2][2]*w[0][2]*w[1][3]*(1.0); + const double G0_2_2_2_4 = det*w[3][2]*w[2][2]*w[0][2]*w[1][4]*(1.0); + const double G0_2_2_2_5 = det*w[3][2]*w[2][2]*w[0][2]*w[1][5]*(1.0); + const double G0_2_2_3_0 = det*w[3][2]*w[2][2]*w[0][3]*w[1][0]*(1.0); + const double G0_2_2_3_1 = det*w[3][2]*w[2][2]*w[0][3]*w[1][1]*(1.0); + const double G0_2_2_3_2 = det*w[3][2]*w[2][2]*w[0][3]*w[1][2]*(1.0); + const double G0_2_2_3_3 = det*w[3][2]*w[2][2]*w[0][3]*w[1][3]*(1.0); + const double G0_2_2_3_4 = det*w[3][2]*w[2][2]*w[0][3]*w[1][4]*(1.0); + const double G0_2_2_3_5 = det*w[3][2]*w[2][2]*w[0][3]*w[1][5]*(1.0); + const double G0_2_2_4_0 = det*w[3][2]*w[2][2]*w[0][4]*w[1][0]*(1.0); + const double G0_2_2_4_1 = det*w[3][2]*w[2][2]*w[0][4]*w[1][1]*(1.0); + const double G0_2_2_4_2 = det*w[3][2]*w[2][2]*w[0][4]*w[1][2]*(1.0); + const double G0_2_2_4_3 = det*w[3][2]*w[2][2]*w[0][4]*w[1][3]*(1.0); + const double G0_2_2_4_4 = det*w[3][2]*w[2][2]*w[0][4]*w[1][4]*(1.0); + const double G0_2_2_4_5 = det*w[3][2]*w[2][2]*w[0][4]*w[1][5]*(1.0); + const double G0_2_2_5_0 = det*w[3][2]*w[2][2]*w[0][5]*w[1][0]*(1.0); + const double G0_2_2_5_1 = det*w[3][2]*w[2][2]*w[0][5]*w[1][1]*(1.0); + const double G0_2_2_5_2 = det*w[3][2]*w[2][2]*w[0][5]*w[1][2]*(1.0); + const double G0_2_2_5_3 = det*w[3][2]*w[2][2]*w[0][5]*w[1][3]*(1.0); + const double G0_2_2_5_4 = det*w[3][2]*w[2][2]*w[0][5]*w[1][4]*(1.0); + const double G0_2_2_5_5 = det*w[3][2]*w[2][2]*w[0][5]*w[1][5]*(1.0); + const double G0_2_3_0_0 = det*w[3][2]*w[2][3]*w[0][0]*w[1][0]*(1.0); + const double G0_2_3_0_1 = det*w[3][2]*w[2][3]*w[0][0]*w[1][1]*(1.0); + const double G0_2_3_0_2 = det*w[3][2]*w[2][3]*w[0][0]*w[1][2]*(1.0); + const double G0_2_3_0_3 = det*w[3][2]*w[2][3]*w[0][0]*w[1][3]*(1.0); + const double G0_2_3_0_4 = det*w[3][2]*w[2][3]*w[0][0]*w[1][4]*(1.0); + const double G0_2_3_0_5 = det*w[3][2]*w[2][3]*w[0][0]*w[1][5]*(1.0); + const double G0_2_3_1_0 = det*w[3][2]*w[2][3]*w[0][1]*w[1][0]*(1.0); + const double G0_2_3_1_1 = det*w[3][2]*w[2][3]*w[0][1]*w[1][1]*(1.0); + const double G0_2_3_1_2 = det*w[3][2]*w[2][3]*w[0][1]*w[1][2]*(1.0); + const double G0_2_3_1_3 = det*w[3][2]*w[2][3]*w[0][1]*w[1][3]*(1.0); + const double G0_2_3_1_4 = det*w[3][2]*w[2][3]*w[0][1]*w[1][4]*(1.0); + const double G0_2_3_1_5 = det*w[3][2]*w[2][3]*w[0][1]*w[1][5]*(1.0); + const double G0_2_3_2_0 = det*w[3][2]*w[2][3]*w[0][2]*w[1][0]*(1.0); + const double G0_2_3_2_1 = det*w[3][2]*w[2][3]*w[0][2]*w[1][1]*(1.0); + const double G0_2_3_2_2 = det*w[3][2]*w[2][3]*w[0][2]*w[1][2]*(1.0); + const double G0_2_3_2_3 = det*w[3][2]*w[2][3]*w[0][2]*w[1][3]*(1.0); + const double G0_2_3_2_4 = det*w[3][2]*w[2][3]*w[0][2]*w[1][4]*(1.0); + const double G0_2_3_2_5 = det*w[3][2]*w[2][3]*w[0][2]*w[1][5]*(1.0); + const double G0_2_3_3_0 = det*w[3][2]*w[2][3]*w[0][3]*w[1][0]*(1.0); + const double G0_2_3_3_1 = det*w[3][2]*w[2][3]*w[0][3]*w[1][1]*(1.0); + const double G0_2_3_3_2 = det*w[3][2]*w[2][3]*w[0][3]*w[1][2]*(1.0); + const double G0_2_3_3_3 = det*w[3][2]*w[2][3]*w[0][3]*w[1][3]*(1.0); + const double G0_2_3_3_4 = det*w[3][2]*w[2][3]*w[0][3]*w[1][4]*(1.0); + const double G0_2_3_3_5 = det*w[3][2]*w[2][3]*w[0][3]*w[1][5]*(1.0); + const double G0_2_3_4_0 = det*w[3][2]*w[2][3]*w[0][4]*w[1][0]*(1.0); + const double G0_2_3_4_1 = det*w[3][2]*w[2][3]*w[0][4]*w[1][1]*(1.0); + const double G0_2_3_4_2 = det*w[3][2]*w[2][3]*w[0][4]*w[1][2]*(1.0); + const double G0_2_3_4_3 = det*w[3][2]*w[2][3]*w[0][4]*w[1][3]*(1.0); + const double G0_2_3_4_4 = det*w[3][2]*w[2][3]*w[0][4]*w[1][4]*(1.0); + const double G0_2_3_4_5 = det*w[3][2]*w[2][3]*w[0][4]*w[1][5]*(1.0); + const double G0_2_3_5_0 = det*w[3][2]*w[2][3]*w[0][5]*w[1][0]*(1.0); + const double G0_2_3_5_1 = det*w[3][2]*w[2][3]*w[0][5]*w[1][1]*(1.0); + const double G0_2_3_5_2 = det*w[3][2]*w[2][3]*w[0][5]*w[1][2]*(1.0); + const double G0_2_3_5_3 = det*w[3][2]*w[2][3]*w[0][5]*w[1][3]*(1.0); + const double G0_2_3_5_4 = det*w[3][2]*w[2][3]*w[0][5]*w[1][4]*(1.0); + const double G0_2_3_5_5 = det*w[3][2]*w[2][3]*w[0][5]*w[1][5]*(1.0); + const double G0_2_4_0_0 = det*w[3][2]*w[2][4]*w[0][0]*w[1][0]*(1.0); + const double G0_2_4_0_1 = det*w[3][2]*w[2][4]*w[0][0]*w[1][1]*(1.0); + const double G0_2_4_0_2 = det*w[3][2]*w[2][4]*w[0][0]*w[1][2]*(1.0); + const double G0_2_4_0_3 = det*w[3][2]*w[2][4]*w[0][0]*w[1][3]*(1.0); + const double G0_2_4_0_4 = det*w[3][2]*w[2][4]*w[0][0]*w[1][4]*(1.0); + const double G0_2_4_0_5 = det*w[3][2]*w[2][4]*w[0][0]*w[1][5]*(1.0); + const double G0_2_4_1_0 = det*w[3][2]*w[2][4]*w[0][1]*w[1][0]*(1.0); + const double G0_2_4_1_1 = det*w[3][2]*w[2][4]*w[0][1]*w[1][1]*(1.0); + const double G0_2_4_1_2 = det*w[3][2]*w[2][4]*w[0][1]*w[1][2]*(1.0); + const double G0_2_4_1_3 = det*w[3][2]*w[2][4]*w[0][1]*w[1][3]*(1.0); + const double G0_2_4_1_4 = det*w[3][2]*w[2][4]*w[0][1]*w[1][4]*(1.0); + const double G0_2_4_1_5 = det*w[3][2]*w[2][4]*w[0][1]*w[1][5]*(1.0); + const double G0_2_4_2_0 = det*w[3][2]*w[2][4]*w[0][2]*w[1][0]*(1.0); + const double G0_2_4_2_1 = det*w[3][2]*w[2][4]*w[0][2]*w[1][1]*(1.0); + const double G0_2_4_2_2 = det*w[3][2]*w[2][4]*w[0][2]*w[1][2]*(1.0); + const double G0_2_4_2_3 = det*w[3][2]*w[2][4]*w[0][2]*w[1][3]*(1.0); + const double G0_2_4_2_4 = det*w[3][2]*w[2][4]*w[0][2]*w[1][4]*(1.0); + const double G0_2_4_2_5 = det*w[3][2]*w[2][4]*w[0][2]*w[1][5]*(1.0); + const double G0_2_4_3_0 = det*w[3][2]*w[2][4]*w[0][3]*w[1][0]*(1.0); + const double G0_2_4_3_1 = det*w[3][2]*w[2][4]*w[0][3]*w[1][1]*(1.0); + const double G0_2_4_3_2 = det*w[3][2]*w[2][4]*w[0][3]*w[1][2]*(1.0); + const double G0_2_4_3_3 = det*w[3][2]*w[2][4]*w[0][3]*w[1][3]*(1.0); + const double G0_2_4_3_4 = det*w[3][2]*w[2][4]*w[0][3]*w[1][4]*(1.0); + const double G0_2_4_3_5 = det*w[3][2]*w[2][4]*w[0][3]*w[1][5]*(1.0); + const double G0_2_4_4_0 = det*w[3][2]*w[2][4]*w[0][4]*w[1][0]*(1.0); + const double G0_2_4_4_1 = det*w[3][2]*w[2][4]*w[0][4]*w[1][1]*(1.0); + const double G0_2_4_4_2 = det*w[3][2]*w[2][4]*w[0][4]*w[1][2]*(1.0); + const double G0_2_4_4_3 = det*w[3][2]*w[2][4]*w[0][4]*w[1][3]*(1.0); + const double G0_2_4_4_4 = det*w[3][2]*w[2][4]*w[0][4]*w[1][4]*(1.0); + const double G0_2_4_4_5 = det*w[3][2]*w[2][4]*w[0][4]*w[1][5]*(1.0); + const double G0_2_4_5_0 = det*w[3][2]*w[2][4]*w[0][5]*w[1][0]*(1.0); + const double G0_2_4_5_1 = det*w[3][2]*w[2][4]*w[0][5]*w[1][1]*(1.0); + const double G0_2_4_5_2 = det*w[3][2]*w[2][4]*w[0][5]*w[1][2]*(1.0); + const double G0_2_4_5_3 = det*w[3][2]*w[2][4]*w[0][5]*w[1][3]*(1.0); + const double G0_2_4_5_4 = det*w[3][2]*w[2][4]*w[0][5]*w[1][4]*(1.0); + const double G0_2_4_5_5 = det*w[3][2]*w[2][4]*w[0][5]*w[1][5]*(1.0); + const double G0_2_5_0_0 = det*w[3][2]*w[2][5]*w[0][0]*w[1][0]*(1.0); + const double G0_2_5_0_1 = det*w[3][2]*w[2][5]*w[0][0]*w[1][1]*(1.0); + const double G0_2_5_0_2 = det*w[3][2]*w[2][5]*w[0][0]*w[1][2]*(1.0); + const double G0_2_5_0_3 = det*w[3][2]*w[2][5]*w[0][0]*w[1][3]*(1.0); + const double G0_2_5_0_4 = det*w[3][2]*w[2][5]*w[0][0]*w[1][4]*(1.0); + const double G0_2_5_0_5 = det*w[3][2]*w[2][5]*w[0][0]*w[1][5]*(1.0); + const double G0_2_5_1_0 = det*w[3][2]*w[2][5]*w[0][1]*w[1][0]*(1.0); + const double G0_2_5_1_1 = det*w[3][2]*w[2][5]*w[0][1]*w[1][1]*(1.0); + const double G0_2_5_1_2 = det*w[3][2]*w[2][5]*w[0][1]*w[1][2]*(1.0); + const double G0_2_5_1_3 = det*w[3][2]*w[2][5]*w[0][1]*w[1][3]*(1.0); + const double G0_2_5_1_4 = det*w[3][2]*w[2][5]*w[0][1]*w[1][4]*(1.0); + const double G0_2_5_1_5 = det*w[3][2]*w[2][5]*w[0][1]*w[1][5]*(1.0); + const double G0_2_5_2_0 = det*w[3][2]*w[2][5]*w[0][2]*w[1][0]*(1.0); + const double G0_2_5_2_1 = det*w[3][2]*w[2][5]*w[0][2]*w[1][1]*(1.0); + const double G0_2_5_2_2 = det*w[3][2]*w[2][5]*w[0][2]*w[1][2]*(1.0); + const double G0_2_5_2_3 = det*w[3][2]*w[2][5]*w[0][2]*w[1][3]*(1.0); + const double G0_2_5_2_4 = det*w[3][2]*w[2][5]*w[0][2]*w[1][4]*(1.0); + const double G0_2_5_2_5 = det*w[3][2]*w[2][5]*w[0][2]*w[1][5]*(1.0); + const double G0_2_5_3_0 = det*w[3][2]*w[2][5]*w[0][3]*w[1][0]*(1.0); + const double G0_2_5_3_1 = det*w[3][2]*w[2][5]*w[0][3]*w[1][1]*(1.0); + const double G0_2_5_3_2 = det*w[3][2]*w[2][5]*w[0][3]*w[1][2]*(1.0); + const double G0_2_5_3_3 = det*w[3][2]*w[2][5]*w[0][3]*w[1][3]*(1.0); + const double G0_2_5_3_4 = det*w[3][2]*w[2][5]*w[0][3]*w[1][4]*(1.0); + const double G0_2_5_3_5 = det*w[3][2]*w[2][5]*w[0][3]*w[1][5]*(1.0); + const double G0_2_5_4_0 = det*w[3][2]*w[2][5]*w[0][4]*w[1][0]*(1.0); + const double G0_2_5_4_1 = det*w[3][2]*w[2][5]*w[0][4]*w[1][1]*(1.0); + const double G0_2_5_4_2 = det*w[3][2]*w[2][5]*w[0][4]*w[1][2]*(1.0); + const double G0_2_5_4_3 = det*w[3][2]*w[2][5]*w[0][4]*w[1][3]*(1.0); + const double G0_2_5_4_4 = det*w[3][2]*w[2][5]*w[0][4]*w[1][4]*(1.0); + const double G0_2_5_4_5 = det*w[3][2]*w[2][5]*w[0][4]*w[1][5]*(1.0); + const double G0_2_5_5_0 = det*w[3][2]*w[2][5]*w[0][5]*w[1][0]*(1.0); + const double G0_2_5_5_1 = det*w[3][2]*w[2][5]*w[0][5]*w[1][1]*(1.0); + const double G0_2_5_5_2 = det*w[3][2]*w[2][5]*w[0][5]*w[1][2]*(1.0); + const double G0_2_5_5_3 = det*w[3][2]*w[2][5]*w[0][5]*w[1][3]*(1.0); + const double G0_2_5_5_4 = det*w[3][2]*w[2][5]*w[0][5]*w[1][4]*(1.0); + const double G0_2_5_5_5 = det*w[3][2]*w[2][5]*w[0][5]*w[1][5]*(1.0); + const double G0_3_0_0_0 = det*w[3][3]*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_3_0_0_1 = det*w[3][3]*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_3_0_0_2 = det*w[3][3]*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_3_0_0_3 = det*w[3][3]*w[2][0]*w[0][0]*w[1][3]*(1.0); + const double G0_3_0_0_4 = det*w[3][3]*w[2][0]*w[0][0]*w[1][4]*(1.0); + const double G0_3_0_0_5 = det*w[3][3]*w[2][0]*w[0][0]*w[1][5]*(1.0); + const double G0_3_0_1_0 = det*w[3][3]*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_3_0_1_1 = det*w[3][3]*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_3_0_1_2 = det*w[3][3]*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_3_0_1_3 = det*w[3][3]*w[2][0]*w[0][1]*w[1][3]*(1.0); + const double G0_3_0_1_4 = det*w[3][3]*w[2][0]*w[0][1]*w[1][4]*(1.0); + const double G0_3_0_1_5 = det*w[3][3]*w[2][0]*w[0][1]*w[1][5]*(1.0); + const double G0_3_0_2_0 = det*w[3][3]*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_3_0_2_1 = det*w[3][3]*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_3_0_2_2 = det*w[3][3]*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_3_0_2_3 = det*w[3][3]*w[2][0]*w[0][2]*w[1][3]*(1.0); + const double G0_3_0_2_4 = det*w[3][3]*w[2][0]*w[0][2]*w[1][4]*(1.0); + const double G0_3_0_2_5 = det*w[3][3]*w[2][0]*w[0][2]*w[1][5]*(1.0); + const double G0_3_0_3_0 = det*w[3][3]*w[2][0]*w[0][3]*w[1][0]*(1.0); + const double G0_3_0_3_1 = det*w[3][3]*w[2][0]*w[0][3]*w[1][1]*(1.0); + const double G0_3_0_3_2 = det*w[3][3]*w[2][0]*w[0][3]*w[1][2]*(1.0); + const double G0_3_0_3_3 = det*w[3][3]*w[2][0]*w[0][3]*w[1][3]*(1.0); + const double G0_3_0_3_4 = det*w[3][3]*w[2][0]*w[0][3]*w[1][4]*(1.0); + const double G0_3_0_3_5 = det*w[3][3]*w[2][0]*w[0][3]*w[1][5]*(1.0); + const double G0_3_0_4_0 = det*w[3][3]*w[2][0]*w[0][4]*w[1][0]*(1.0); + const double G0_3_0_4_1 = det*w[3][3]*w[2][0]*w[0][4]*w[1][1]*(1.0); + const double G0_3_0_4_2 = det*w[3][3]*w[2][0]*w[0][4]*w[1][2]*(1.0); + const double G0_3_0_4_3 = det*w[3][3]*w[2][0]*w[0][4]*w[1][3]*(1.0); + const double G0_3_0_4_4 = det*w[3][3]*w[2][0]*w[0][4]*w[1][4]*(1.0); + const double G0_3_0_4_5 = det*w[3][3]*w[2][0]*w[0][4]*w[1][5]*(1.0); + const double G0_3_0_5_0 = det*w[3][3]*w[2][0]*w[0][5]*w[1][0]*(1.0); + const double G0_3_0_5_1 = det*w[3][3]*w[2][0]*w[0][5]*w[1][1]*(1.0); + const double G0_3_0_5_2 = det*w[3][3]*w[2][0]*w[0][5]*w[1][2]*(1.0); + const double G0_3_0_5_3 = det*w[3][3]*w[2][0]*w[0][5]*w[1][3]*(1.0); + const double G0_3_0_5_4 = det*w[3][3]*w[2][0]*w[0][5]*w[1][4]*(1.0); + const double G0_3_0_5_5 = det*w[3][3]*w[2][0]*w[0][5]*w[1][5]*(1.0); + const double G0_3_1_0_0 = det*w[3][3]*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_3_1_0_1 = det*w[3][3]*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_3_1_0_2 = det*w[3][3]*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_3_1_0_3 = det*w[3][3]*w[2][1]*w[0][0]*w[1][3]*(1.0); + const double G0_3_1_0_4 = det*w[3][3]*w[2][1]*w[0][0]*w[1][4]*(1.0); + const double G0_3_1_0_5 = det*w[3][3]*w[2][1]*w[0][0]*w[1][5]*(1.0); + const double G0_3_1_1_0 = det*w[3][3]*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_3_1_1_1 = det*w[3][3]*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_3_1_1_2 = det*w[3][3]*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_3_1_1_3 = det*w[3][3]*w[2][1]*w[0][1]*w[1][3]*(1.0); + const double G0_3_1_1_4 = det*w[3][3]*w[2][1]*w[0][1]*w[1][4]*(1.0); + const double G0_3_1_1_5 = det*w[3][3]*w[2][1]*w[0][1]*w[1][5]*(1.0); + const double G0_3_1_2_0 = det*w[3][3]*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_3_1_2_1 = det*w[3][3]*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_3_1_2_2 = det*w[3][3]*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_3_1_2_3 = det*w[3][3]*w[2][1]*w[0][2]*w[1][3]*(1.0); + const double G0_3_1_2_4 = det*w[3][3]*w[2][1]*w[0][2]*w[1][4]*(1.0); + const double G0_3_1_2_5 = det*w[3][3]*w[2][1]*w[0][2]*w[1][5]*(1.0); + const double G0_3_1_3_0 = det*w[3][3]*w[2][1]*w[0][3]*w[1][0]*(1.0); + const double G0_3_1_3_1 = det*w[3][3]*w[2][1]*w[0][3]*w[1][1]*(1.0); + const double G0_3_1_3_2 = det*w[3][3]*w[2][1]*w[0][3]*w[1][2]*(1.0); + const double G0_3_1_3_3 = det*w[3][3]*w[2][1]*w[0][3]*w[1][3]*(1.0); + const double G0_3_1_3_4 = det*w[3][3]*w[2][1]*w[0][3]*w[1][4]*(1.0); + const double G0_3_1_3_5 = det*w[3][3]*w[2][1]*w[0][3]*w[1][5]*(1.0); + const double G0_3_1_4_0 = det*w[3][3]*w[2][1]*w[0][4]*w[1][0]*(1.0); + const double G0_3_1_4_1 = det*w[3][3]*w[2][1]*w[0][4]*w[1][1]*(1.0); + const double G0_3_1_4_2 = det*w[3][3]*w[2][1]*w[0][4]*w[1][2]*(1.0); + const double G0_3_1_4_3 = det*w[3][3]*w[2][1]*w[0][4]*w[1][3]*(1.0); + const double G0_3_1_4_4 = det*w[3][3]*w[2][1]*w[0][4]*w[1][4]*(1.0); + const double G0_3_1_4_5 = det*w[3][3]*w[2][1]*w[0][4]*w[1][5]*(1.0); + const double G0_3_1_5_0 = det*w[3][3]*w[2][1]*w[0][5]*w[1][0]*(1.0); + const double G0_3_1_5_1 = det*w[3][3]*w[2][1]*w[0][5]*w[1][1]*(1.0); + const double G0_3_1_5_2 = det*w[3][3]*w[2][1]*w[0][5]*w[1][2]*(1.0); + const double G0_3_1_5_3 = det*w[3][3]*w[2][1]*w[0][5]*w[1][3]*(1.0); + const double G0_3_1_5_4 = det*w[3][3]*w[2][1]*w[0][5]*w[1][4]*(1.0); + const double G0_3_1_5_5 = det*w[3][3]*w[2][1]*w[0][5]*w[1][5]*(1.0); + const double G0_3_2_0_0 = det*w[3][3]*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_3_2_0_1 = det*w[3][3]*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_3_2_0_2 = det*w[3][3]*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_3_2_0_3 = det*w[3][3]*w[2][2]*w[0][0]*w[1][3]*(1.0); + const double G0_3_2_0_4 = det*w[3][3]*w[2][2]*w[0][0]*w[1][4]*(1.0); + const double G0_3_2_0_5 = det*w[3][3]*w[2][2]*w[0][0]*w[1][5]*(1.0); + const double G0_3_2_1_0 = det*w[3][3]*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_3_2_1_1 = det*w[3][3]*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_3_2_1_2 = det*w[3][3]*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_3_2_1_3 = det*w[3][3]*w[2][2]*w[0][1]*w[1][3]*(1.0); + const double G0_3_2_1_4 = det*w[3][3]*w[2][2]*w[0][1]*w[1][4]*(1.0); + const double G0_3_2_1_5 = det*w[3][3]*w[2][2]*w[0][1]*w[1][5]*(1.0); + const double G0_3_2_2_0 = det*w[3][3]*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_3_2_2_1 = det*w[3][3]*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_3_2_2_2 = det*w[3][3]*w[2][2]*w[0][2]*w[1][2]*(1.0); + const double G0_3_2_2_3 = det*w[3][3]*w[2][2]*w[0][2]*w[1][3]*(1.0); + const double G0_3_2_2_4 = det*w[3][3]*w[2][2]*w[0][2]*w[1][4]*(1.0); + const double G0_3_2_2_5 = det*w[3][3]*w[2][2]*w[0][2]*w[1][5]*(1.0); + const double G0_3_2_3_0 = det*w[3][3]*w[2][2]*w[0][3]*w[1][0]*(1.0); + const double G0_3_2_3_1 = det*w[3][3]*w[2][2]*w[0][3]*w[1][1]*(1.0); + const double G0_3_2_3_2 = det*w[3][3]*w[2][2]*w[0][3]*w[1][2]*(1.0); + const double G0_3_2_3_3 = det*w[3][3]*w[2][2]*w[0][3]*w[1][3]*(1.0); + const double G0_3_2_3_4 = det*w[3][3]*w[2][2]*w[0][3]*w[1][4]*(1.0); + const double G0_3_2_3_5 = det*w[3][3]*w[2][2]*w[0][3]*w[1][5]*(1.0); + const double G0_3_2_4_0 = det*w[3][3]*w[2][2]*w[0][4]*w[1][0]*(1.0); + const double G0_3_2_4_1 = det*w[3][3]*w[2][2]*w[0][4]*w[1][1]*(1.0); + const double G0_3_2_4_2 = det*w[3][3]*w[2][2]*w[0][4]*w[1][2]*(1.0); + const double G0_3_2_4_3 = det*w[3][3]*w[2][2]*w[0][4]*w[1][3]*(1.0); + const double G0_3_2_4_4 = det*w[3][3]*w[2][2]*w[0][4]*w[1][4]*(1.0); + const double G0_3_2_4_5 = det*w[3][3]*w[2][2]*w[0][4]*w[1][5]*(1.0); + const double G0_3_2_5_0 = det*w[3][3]*w[2][2]*w[0][5]*w[1][0]*(1.0); + const double G0_3_2_5_1 = det*w[3][3]*w[2][2]*w[0][5]*w[1][1]*(1.0); + const double G0_3_2_5_2 = det*w[3][3]*w[2][2]*w[0][5]*w[1][2]*(1.0); + const double G0_3_2_5_3 = det*w[3][3]*w[2][2]*w[0][5]*w[1][3]*(1.0); + const double G0_3_2_5_4 = det*w[3][3]*w[2][2]*w[0][5]*w[1][4]*(1.0); + const double G0_3_2_5_5 = det*w[3][3]*w[2][2]*w[0][5]*w[1][5]*(1.0); + const double G0_3_3_0_0 = det*w[3][3]*w[2][3]*w[0][0]*w[1][0]*(1.0); + const double G0_3_3_0_1 = det*w[3][3]*w[2][3]*w[0][0]*w[1][1]*(1.0); + const double G0_3_3_0_2 = det*w[3][3]*w[2][3]*w[0][0]*w[1][2]*(1.0); + const double G0_3_3_0_3 = det*w[3][3]*w[2][3]*w[0][0]*w[1][3]*(1.0); + const double G0_3_3_0_4 = det*w[3][3]*w[2][3]*w[0][0]*w[1][4]*(1.0); + const double G0_3_3_0_5 = det*w[3][3]*w[2][3]*w[0][0]*w[1][5]*(1.0); + const double G0_3_3_1_0 = det*w[3][3]*w[2][3]*w[0][1]*w[1][0]*(1.0); + const double G0_3_3_1_1 = det*w[3][3]*w[2][3]*w[0][1]*w[1][1]*(1.0); + const double G0_3_3_1_2 = det*w[3][3]*w[2][3]*w[0][1]*w[1][2]*(1.0); + const double G0_3_3_1_3 = det*w[3][3]*w[2][3]*w[0][1]*w[1][3]*(1.0); + const double G0_3_3_1_4 = det*w[3][3]*w[2][3]*w[0][1]*w[1][4]*(1.0); + const double G0_3_3_1_5 = det*w[3][3]*w[2][3]*w[0][1]*w[1][5]*(1.0); + const double G0_3_3_2_0 = det*w[3][3]*w[2][3]*w[0][2]*w[1][0]*(1.0); + const double G0_3_3_2_1 = det*w[3][3]*w[2][3]*w[0][2]*w[1][1]*(1.0); + const double G0_3_3_2_2 = det*w[3][3]*w[2][3]*w[0][2]*w[1][2]*(1.0); + const double G0_3_3_2_3 = det*w[3][3]*w[2][3]*w[0][2]*w[1][3]*(1.0); + const double G0_3_3_2_4 = det*w[3][3]*w[2][3]*w[0][2]*w[1][4]*(1.0); + const double G0_3_3_2_5 = det*w[3][3]*w[2][3]*w[0][2]*w[1][5]*(1.0); + const double G0_3_3_3_0 = det*w[3][3]*w[2][3]*w[0][3]*w[1][0]*(1.0); + const double G0_3_3_3_1 = det*w[3][3]*w[2][3]*w[0][3]*w[1][1]*(1.0); + const double G0_3_3_3_2 = det*w[3][3]*w[2][3]*w[0][3]*w[1][2]*(1.0); + const double G0_3_3_3_3 = det*w[3][3]*w[2][3]*w[0][3]*w[1][3]*(1.0); + const double G0_3_3_3_4 = det*w[3][3]*w[2][3]*w[0][3]*w[1][4]*(1.0); + const double G0_3_3_3_5 = det*w[3][3]*w[2][3]*w[0][3]*w[1][5]*(1.0); + const double G0_3_3_4_0 = det*w[3][3]*w[2][3]*w[0][4]*w[1][0]*(1.0); + const double G0_3_3_4_1 = det*w[3][3]*w[2][3]*w[0][4]*w[1][1]*(1.0); + const double G0_3_3_4_2 = det*w[3][3]*w[2][3]*w[0][4]*w[1][2]*(1.0); + const double G0_3_3_4_3 = det*w[3][3]*w[2][3]*w[0][4]*w[1][3]*(1.0); + const double G0_3_3_4_4 = det*w[3][3]*w[2][3]*w[0][4]*w[1][4]*(1.0); + const double G0_3_3_4_5 = det*w[3][3]*w[2][3]*w[0][4]*w[1][5]*(1.0); + const double G0_3_3_5_0 = det*w[3][3]*w[2][3]*w[0][5]*w[1][0]*(1.0); + const double G0_3_3_5_1 = det*w[3][3]*w[2][3]*w[0][5]*w[1][1]*(1.0); + const double G0_3_3_5_2 = det*w[3][3]*w[2][3]*w[0][5]*w[1][2]*(1.0); + const double G0_3_3_5_3 = det*w[3][3]*w[2][3]*w[0][5]*w[1][3]*(1.0); + const double G0_3_3_5_4 = det*w[3][3]*w[2][3]*w[0][5]*w[1][4]*(1.0); + const double G0_3_3_5_5 = det*w[3][3]*w[2][3]*w[0][5]*w[1][5]*(1.0); + const double G0_3_4_0_0 = det*w[3][3]*w[2][4]*w[0][0]*w[1][0]*(1.0); + const double G0_3_4_0_1 = det*w[3][3]*w[2][4]*w[0][0]*w[1][1]*(1.0); + const double G0_3_4_0_2 = det*w[3][3]*w[2][4]*w[0][0]*w[1][2]*(1.0); + const double G0_3_4_0_3 = det*w[3][3]*w[2][4]*w[0][0]*w[1][3]*(1.0); + const double G0_3_4_0_4 = det*w[3][3]*w[2][4]*w[0][0]*w[1][4]*(1.0); + const double G0_3_4_0_5 = det*w[3][3]*w[2][4]*w[0][0]*w[1][5]*(1.0); + const double G0_3_4_1_0 = det*w[3][3]*w[2][4]*w[0][1]*w[1][0]*(1.0); + const double G0_3_4_1_1 = det*w[3][3]*w[2][4]*w[0][1]*w[1][1]*(1.0); + const double G0_3_4_1_2 = det*w[3][3]*w[2][4]*w[0][1]*w[1][2]*(1.0); + const double G0_3_4_1_3 = det*w[3][3]*w[2][4]*w[0][1]*w[1][3]*(1.0); + const double G0_3_4_1_4 = det*w[3][3]*w[2][4]*w[0][1]*w[1][4]*(1.0); + const double G0_3_4_1_5 = det*w[3][3]*w[2][4]*w[0][1]*w[1][5]*(1.0); + const double G0_3_4_2_0 = det*w[3][3]*w[2][4]*w[0][2]*w[1][0]*(1.0); + const double G0_3_4_2_1 = det*w[3][3]*w[2][4]*w[0][2]*w[1][1]*(1.0); + const double G0_3_4_2_2 = det*w[3][3]*w[2][4]*w[0][2]*w[1][2]*(1.0); + const double G0_3_4_2_3 = det*w[3][3]*w[2][4]*w[0][2]*w[1][3]*(1.0); + const double G0_3_4_2_4 = det*w[3][3]*w[2][4]*w[0][2]*w[1][4]*(1.0); + const double G0_3_4_2_5 = det*w[3][3]*w[2][4]*w[0][2]*w[1][5]*(1.0); + const double G0_3_4_3_0 = det*w[3][3]*w[2][4]*w[0][3]*w[1][0]*(1.0); + const double G0_3_4_3_1 = det*w[3][3]*w[2][4]*w[0][3]*w[1][1]*(1.0); + const double G0_3_4_3_2 = det*w[3][3]*w[2][4]*w[0][3]*w[1][2]*(1.0); + const double G0_3_4_3_3 = det*w[3][3]*w[2][4]*w[0][3]*w[1][3]*(1.0); + const double G0_3_4_3_4 = det*w[3][3]*w[2][4]*w[0][3]*w[1][4]*(1.0); + const double G0_3_4_3_5 = det*w[3][3]*w[2][4]*w[0][3]*w[1][5]*(1.0); + const double G0_3_4_4_0 = det*w[3][3]*w[2][4]*w[0][4]*w[1][0]*(1.0); + const double G0_3_4_4_1 = det*w[3][3]*w[2][4]*w[0][4]*w[1][1]*(1.0); + const double G0_3_4_4_2 = det*w[3][3]*w[2][4]*w[0][4]*w[1][2]*(1.0); + const double G0_3_4_4_3 = det*w[3][3]*w[2][4]*w[0][4]*w[1][3]*(1.0); + const double G0_3_4_4_4 = det*w[3][3]*w[2][4]*w[0][4]*w[1][4]*(1.0); + const double G0_3_4_4_5 = det*w[3][3]*w[2][4]*w[0][4]*w[1][5]*(1.0); + const double G0_3_4_5_0 = det*w[3][3]*w[2][4]*w[0][5]*w[1][0]*(1.0); + const double G0_3_4_5_1 = det*w[3][3]*w[2][4]*w[0][5]*w[1][1]*(1.0); + const double G0_3_4_5_2 = det*w[3][3]*w[2][4]*w[0][5]*w[1][2]*(1.0); + const double G0_3_4_5_3 = det*w[3][3]*w[2][4]*w[0][5]*w[1][3]*(1.0); + const double G0_3_4_5_4 = det*w[3][3]*w[2][4]*w[0][5]*w[1][4]*(1.0); + const double G0_3_4_5_5 = det*w[3][3]*w[2][4]*w[0][5]*w[1][5]*(1.0); + const double G0_3_5_0_0 = det*w[3][3]*w[2][5]*w[0][0]*w[1][0]*(1.0); + const double G0_3_5_0_1 = det*w[3][3]*w[2][5]*w[0][0]*w[1][1]*(1.0); + const double G0_3_5_0_2 = det*w[3][3]*w[2][5]*w[0][0]*w[1][2]*(1.0); + const double G0_3_5_0_3 = det*w[3][3]*w[2][5]*w[0][0]*w[1][3]*(1.0); + const double G0_3_5_0_4 = det*w[3][3]*w[2][5]*w[0][0]*w[1][4]*(1.0); + const double G0_3_5_0_5 = det*w[3][3]*w[2][5]*w[0][0]*w[1][5]*(1.0); + const double G0_3_5_1_0 = det*w[3][3]*w[2][5]*w[0][1]*w[1][0]*(1.0); + const double G0_3_5_1_1 = det*w[3][3]*w[2][5]*w[0][1]*w[1][1]*(1.0); + const double G0_3_5_1_2 = det*w[3][3]*w[2][5]*w[0][1]*w[1][2]*(1.0); + const double G0_3_5_1_3 = det*w[3][3]*w[2][5]*w[0][1]*w[1][3]*(1.0); + const double G0_3_5_1_4 = det*w[3][3]*w[2][5]*w[0][1]*w[1][4]*(1.0); + const double G0_3_5_1_5 = det*w[3][3]*w[2][5]*w[0][1]*w[1][5]*(1.0); + const double G0_3_5_2_0 = det*w[3][3]*w[2][5]*w[0][2]*w[1][0]*(1.0); + const double G0_3_5_2_1 = det*w[3][3]*w[2][5]*w[0][2]*w[1][1]*(1.0); + const double G0_3_5_2_2 = det*w[3][3]*w[2][5]*w[0][2]*w[1][2]*(1.0); + const double G0_3_5_2_3 = det*w[3][3]*w[2][5]*w[0][2]*w[1][3]*(1.0); + const double G0_3_5_2_4 = det*w[3][3]*w[2][5]*w[0][2]*w[1][4]*(1.0); + const double G0_3_5_2_5 = det*w[3][3]*w[2][5]*w[0][2]*w[1][5]*(1.0); + const double G0_3_5_3_0 = det*w[3][3]*w[2][5]*w[0][3]*w[1][0]*(1.0); + const double G0_3_5_3_1 = det*w[3][3]*w[2][5]*w[0][3]*w[1][1]*(1.0); + const double G0_3_5_3_2 = det*w[3][3]*w[2][5]*w[0][3]*w[1][2]*(1.0); + const double G0_3_5_3_3 = det*w[3][3]*w[2][5]*w[0][3]*w[1][3]*(1.0); + const double G0_3_5_3_4 = det*w[3][3]*w[2][5]*w[0][3]*w[1][4]*(1.0); + const double G0_3_5_3_5 = det*w[3][3]*w[2][5]*w[0][3]*w[1][5]*(1.0); + const double G0_3_5_4_0 = det*w[3][3]*w[2][5]*w[0][4]*w[1][0]*(1.0); + const double G0_3_5_4_1 = det*w[3][3]*w[2][5]*w[0][4]*w[1][1]*(1.0); + const double G0_3_5_4_2 = det*w[3][3]*w[2][5]*w[0][4]*w[1][2]*(1.0); + const double G0_3_5_4_3 = det*w[3][3]*w[2][5]*w[0][4]*w[1][3]*(1.0); + const double G0_3_5_4_4 = det*w[3][3]*w[2][5]*w[0][4]*w[1][4]*(1.0); + const double G0_3_5_4_5 = det*w[3][3]*w[2][5]*w[0][4]*w[1][5]*(1.0); + const double G0_3_5_5_0 = det*w[3][3]*w[2][5]*w[0][5]*w[1][0]*(1.0); + const double G0_3_5_5_1 = det*w[3][3]*w[2][5]*w[0][5]*w[1][1]*(1.0); + const double G0_3_5_5_2 = det*w[3][3]*w[2][5]*w[0][5]*w[1][2]*(1.0); + const double G0_3_5_5_3 = det*w[3][3]*w[2][5]*w[0][5]*w[1][3]*(1.0); + const double G0_3_5_5_4 = det*w[3][3]*w[2][5]*w[0][5]*w[1][4]*(1.0); + const double G0_3_5_5_5 = det*w[3][3]*w[2][5]*w[0][5]*w[1][5]*(1.0); + const double G0_4_0_0_0 = det*w[3][4]*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_4_0_0_1 = det*w[3][4]*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_4_0_0_2 = det*w[3][4]*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_4_0_0_3 = det*w[3][4]*w[2][0]*w[0][0]*w[1][3]*(1.0); + const double G0_4_0_0_4 = det*w[3][4]*w[2][0]*w[0][0]*w[1][4]*(1.0); + const double G0_4_0_0_5 = det*w[3][4]*w[2][0]*w[0][0]*w[1][5]*(1.0); + const double G0_4_0_1_0 = det*w[3][4]*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_4_0_1_1 = det*w[3][4]*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_4_0_1_2 = det*w[3][4]*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_4_0_1_3 = det*w[3][4]*w[2][0]*w[0][1]*w[1][3]*(1.0); + const double G0_4_0_1_4 = det*w[3][4]*w[2][0]*w[0][1]*w[1][4]*(1.0); + const double G0_4_0_1_5 = det*w[3][4]*w[2][0]*w[0][1]*w[1][5]*(1.0); + const double G0_4_0_2_0 = det*w[3][4]*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_4_0_2_1 = det*w[3][4]*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_4_0_2_2 = det*w[3][4]*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_4_0_2_3 = det*w[3][4]*w[2][0]*w[0][2]*w[1][3]*(1.0); + const double G0_4_0_2_4 = det*w[3][4]*w[2][0]*w[0][2]*w[1][4]*(1.0); + const double G0_4_0_2_5 = det*w[3][4]*w[2][0]*w[0][2]*w[1][5]*(1.0); + const double G0_4_0_3_0 = det*w[3][4]*w[2][0]*w[0][3]*w[1][0]*(1.0); + const double G0_4_0_3_1 = det*w[3][4]*w[2][0]*w[0][3]*w[1][1]*(1.0); + const double G0_4_0_3_2 = det*w[3][4]*w[2][0]*w[0][3]*w[1][2]*(1.0); + const double G0_4_0_3_3 = det*w[3][4]*w[2][0]*w[0][3]*w[1][3]*(1.0); + const double G0_4_0_3_4 = det*w[3][4]*w[2][0]*w[0][3]*w[1][4]*(1.0); + const double G0_4_0_3_5 = det*w[3][4]*w[2][0]*w[0][3]*w[1][5]*(1.0); + const double G0_4_0_4_0 = det*w[3][4]*w[2][0]*w[0][4]*w[1][0]*(1.0); + const double G0_4_0_4_1 = det*w[3][4]*w[2][0]*w[0][4]*w[1][1]*(1.0); + const double G0_4_0_4_2 = det*w[3][4]*w[2][0]*w[0][4]*w[1][2]*(1.0); + const double G0_4_0_4_3 = det*w[3][4]*w[2][0]*w[0][4]*w[1][3]*(1.0); + const double G0_4_0_4_4 = det*w[3][4]*w[2][0]*w[0][4]*w[1][4]*(1.0); + const double G0_4_0_4_5 = det*w[3][4]*w[2][0]*w[0][4]*w[1][5]*(1.0); + const double G0_4_0_5_0 = det*w[3][4]*w[2][0]*w[0][5]*w[1][0]*(1.0); + const double G0_4_0_5_1 = det*w[3][4]*w[2][0]*w[0][5]*w[1][1]*(1.0); + const double G0_4_0_5_2 = det*w[3][4]*w[2][0]*w[0][5]*w[1][2]*(1.0); + const double G0_4_0_5_3 = det*w[3][4]*w[2][0]*w[0][5]*w[1][3]*(1.0); + const double G0_4_0_5_4 = det*w[3][4]*w[2][0]*w[0][5]*w[1][4]*(1.0); + const double G0_4_0_5_5 = det*w[3][4]*w[2][0]*w[0][5]*w[1][5]*(1.0); + const double G0_4_1_0_0 = det*w[3][4]*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_4_1_0_1 = det*w[3][4]*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_4_1_0_2 = det*w[3][4]*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_4_1_0_3 = det*w[3][4]*w[2][1]*w[0][0]*w[1][3]*(1.0); + const double G0_4_1_0_4 = det*w[3][4]*w[2][1]*w[0][0]*w[1][4]*(1.0); + const double G0_4_1_0_5 = det*w[3][4]*w[2][1]*w[0][0]*w[1][5]*(1.0); + const double G0_4_1_1_0 = det*w[3][4]*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_4_1_1_1 = det*w[3][4]*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_4_1_1_2 = det*w[3][4]*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_4_1_1_3 = det*w[3][4]*w[2][1]*w[0][1]*w[1][3]*(1.0); + const double G0_4_1_1_4 = det*w[3][4]*w[2][1]*w[0][1]*w[1][4]*(1.0); + const double G0_4_1_1_5 = det*w[3][4]*w[2][1]*w[0][1]*w[1][5]*(1.0); + const double G0_4_1_2_0 = det*w[3][4]*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_4_1_2_1 = det*w[3][4]*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_4_1_2_2 = det*w[3][4]*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_4_1_2_3 = det*w[3][4]*w[2][1]*w[0][2]*w[1][3]*(1.0); + const double G0_4_1_2_4 = det*w[3][4]*w[2][1]*w[0][2]*w[1][4]*(1.0); + const double G0_4_1_2_5 = det*w[3][4]*w[2][1]*w[0][2]*w[1][5]*(1.0); + const double G0_4_1_3_0 = det*w[3][4]*w[2][1]*w[0][3]*w[1][0]*(1.0); + const double G0_4_1_3_1 = det*w[3][4]*w[2][1]*w[0][3]*w[1][1]*(1.0); + const double G0_4_1_3_2 = det*w[3][4]*w[2][1]*w[0][3]*w[1][2]*(1.0); + const double G0_4_1_3_3 = det*w[3][4]*w[2][1]*w[0][3]*w[1][3]*(1.0); + const double G0_4_1_3_4 = det*w[3][4]*w[2][1]*w[0][3]*w[1][4]*(1.0); + const double G0_4_1_3_5 = det*w[3][4]*w[2][1]*w[0][3]*w[1][5]*(1.0); + const double G0_4_1_4_0 = det*w[3][4]*w[2][1]*w[0][4]*w[1][0]*(1.0); + const double G0_4_1_4_1 = det*w[3][4]*w[2][1]*w[0][4]*w[1][1]*(1.0); + const double G0_4_1_4_2 = det*w[3][4]*w[2][1]*w[0][4]*w[1][2]*(1.0); + const double G0_4_1_4_3 = det*w[3][4]*w[2][1]*w[0][4]*w[1][3]*(1.0); + const double G0_4_1_4_4 = det*w[3][4]*w[2][1]*w[0][4]*w[1][4]*(1.0); + const double G0_4_1_4_5 = det*w[3][4]*w[2][1]*w[0][4]*w[1][5]*(1.0); + const double G0_4_1_5_0 = det*w[3][4]*w[2][1]*w[0][5]*w[1][0]*(1.0); + const double G0_4_1_5_1 = det*w[3][4]*w[2][1]*w[0][5]*w[1][1]*(1.0); + const double G0_4_1_5_2 = det*w[3][4]*w[2][1]*w[0][5]*w[1][2]*(1.0); + const double G0_4_1_5_3 = det*w[3][4]*w[2][1]*w[0][5]*w[1][3]*(1.0); + const double G0_4_1_5_4 = det*w[3][4]*w[2][1]*w[0][5]*w[1][4]*(1.0); + const double G0_4_1_5_5 = det*w[3][4]*w[2][1]*w[0][5]*w[1][5]*(1.0); + const double G0_4_2_0_0 = det*w[3][4]*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_4_2_0_1 = det*w[3][4]*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_4_2_0_2 = det*w[3][4]*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_4_2_0_3 = det*w[3][4]*w[2][2]*w[0][0]*w[1][3]*(1.0); + const double G0_4_2_0_4 = det*w[3][4]*w[2][2]*w[0][0]*w[1][4]*(1.0); + const double G0_4_2_0_5 = det*w[3][4]*w[2][2]*w[0][0]*w[1][5]*(1.0); + const double G0_4_2_1_0 = det*w[3][4]*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_4_2_1_1 = det*w[3][4]*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_4_2_1_2 = det*w[3][4]*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_4_2_1_3 = det*w[3][4]*w[2][2]*w[0][1]*w[1][3]*(1.0); + const double G0_4_2_1_4 = det*w[3][4]*w[2][2]*w[0][1]*w[1][4]*(1.0); + const double G0_4_2_1_5 = det*w[3][4]*w[2][2]*w[0][1]*w[1][5]*(1.0); + const double G0_4_2_2_0 = det*w[3][4]*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_4_2_2_1 = det*w[3][4]*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_4_2_2_2 = det*w[3][4]*w[2][2]*w[0][2]*w[1][2]*(1.0); + const double G0_4_2_2_3 = det*w[3][4]*w[2][2]*w[0][2]*w[1][3]*(1.0); + const double G0_4_2_2_4 = det*w[3][4]*w[2][2]*w[0][2]*w[1][4]*(1.0); + const double G0_4_2_2_5 = det*w[3][4]*w[2][2]*w[0][2]*w[1][5]*(1.0); + const double G0_4_2_3_0 = det*w[3][4]*w[2][2]*w[0][3]*w[1][0]*(1.0); + const double G0_4_2_3_1 = det*w[3][4]*w[2][2]*w[0][3]*w[1][1]*(1.0); + const double G0_4_2_3_2 = det*w[3][4]*w[2][2]*w[0][3]*w[1][2]*(1.0); + const double G0_4_2_3_3 = det*w[3][4]*w[2][2]*w[0][3]*w[1][3]*(1.0); + const double G0_4_2_3_4 = det*w[3][4]*w[2][2]*w[0][3]*w[1][4]*(1.0); + const double G0_4_2_3_5 = det*w[3][4]*w[2][2]*w[0][3]*w[1][5]*(1.0); + const double G0_4_2_4_0 = det*w[3][4]*w[2][2]*w[0][4]*w[1][0]*(1.0); + const double G0_4_2_4_1 = det*w[3][4]*w[2][2]*w[0][4]*w[1][1]*(1.0); + const double G0_4_2_4_2 = det*w[3][4]*w[2][2]*w[0][4]*w[1][2]*(1.0); + const double G0_4_2_4_3 = det*w[3][4]*w[2][2]*w[0][4]*w[1][3]*(1.0); + const double G0_4_2_4_4 = det*w[3][4]*w[2][2]*w[0][4]*w[1][4]*(1.0); + const double G0_4_2_4_5 = det*w[3][4]*w[2][2]*w[0][4]*w[1][5]*(1.0); + const double G0_4_2_5_0 = det*w[3][4]*w[2][2]*w[0][5]*w[1][0]*(1.0); + const double G0_4_2_5_1 = det*w[3][4]*w[2][2]*w[0][5]*w[1][1]*(1.0); + const double G0_4_2_5_2 = det*w[3][4]*w[2][2]*w[0][5]*w[1][2]*(1.0); + const double G0_4_2_5_3 = det*w[3][4]*w[2][2]*w[0][5]*w[1][3]*(1.0); + const double G0_4_2_5_4 = det*w[3][4]*w[2][2]*w[0][5]*w[1][4]*(1.0); + const double G0_4_2_5_5 = det*w[3][4]*w[2][2]*w[0][5]*w[1][5]*(1.0); + const double G0_4_3_0_0 = det*w[3][4]*w[2][3]*w[0][0]*w[1][0]*(1.0); + const double G0_4_3_0_1 = det*w[3][4]*w[2][3]*w[0][0]*w[1][1]*(1.0); + const double G0_4_3_0_2 = det*w[3][4]*w[2][3]*w[0][0]*w[1][2]*(1.0); + const double G0_4_3_0_3 = det*w[3][4]*w[2][3]*w[0][0]*w[1][3]*(1.0); + const double G0_4_3_0_4 = det*w[3][4]*w[2][3]*w[0][0]*w[1][4]*(1.0); + const double G0_4_3_0_5 = det*w[3][4]*w[2][3]*w[0][0]*w[1][5]*(1.0); + const double G0_4_3_1_0 = det*w[3][4]*w[2][3]*w[0][1]*w[1][0]*(1.0); + const double G0_4_3_1_1 = det*w[3][4]*w[2][3]*w[0][1]*w[1][1]*(1.0); + const double G0_4_3_1_2 = det*w[3][4]*w[2][3]*w[0][1]*w[1][2]*(1.0); + const double G0_4_3_1_3 = det*w[3][4]*w[2][3]*w[0][1]*w[1][3]*(1.0); + const double G0_4_3_1_4 = det*w[3][4]*w[2][3]*w[0][1]*w[1][4]*(1.0); + const double G0_4_3_1_5 = det*w[3][4]*w[2][3]*w[0][1]*w[1][5]*(1.0); + const double G0_4_3_2_0 = det*w[3][4]*w[2][3]*w[0][2]*w[1][0]*(1.0); + const double G0_4_3_2_1 = det*w[3][4]*w[2][3]*w[0][2]*w[1][1]*(1.0); + const double G0_4_3_2_2 = det*w[3][4]*w[2][3]*w[0][2]*w[1][2]*(1.0); + const double G0_4_3_2_3 = det*w[3][4]*w[2][3]*w[0][2]*w[1][3]*(1.0); + const double G0_4_3_2_4 = det*w[3][4]*w[2][3]*w[0][2]*w[1][4]*(1.0); + const double G0_4_3_2_5 = det*w[3][4]*w[2][3]*w[0][2]*w[1][5]*(1.0); + const double G0_4_3_3_0 = det*w[3][4]*w[2][3]*w[0][3]*w[1][0]*(1.0); + const double G0_4_3_3_1 = det*w[3][4]*w[2][3]*w[0][3]*w[1][1]*(1.0); + const double G0_4_3_3_2 = det*w[3][4]*w[2][3]*w[0][3]*w[1][2]*(1.0); + const double G0_4_3_3_3 = det*w[3][4]*w[2][3]*w[0][3]*w[1][3]*(1.0); + const double G0_4_3_3_4 = det*w[3][4]*w[2][3]*w[0][3]*w[1][4]*(1.0); + const double G0_4_3_3_5 = det*w[3][4]*w[2][3]*w[0][3]*w[1][5]*(1.0); + const double G0_4_3_4_0 = det*w[3][4]*w[2][3]*w[0][4]*w[1][0]*(1.0); + const double G0_4_3_4_1 = det*w[3][4]*w[2][3]*w[0][4]*w[1][1]*(1.0); + const double G0_4_3_4_2 = det*w[3][4]*w[2][3]*w[0][4]*w[1][2]*(1.0); + const double G0_4_3_4_3 = det*w[3][4]*w[2][3]*w[0][4]*w[1][3]*(1.0); + const double G0_4_3_4_4 = det*w[3][4]*w[2][3]*w[0][4]*w[1][4]*(1.0); + const double G0_4_3_4_5 = det*w[3][4]*w[2][3]*w[0][4]*w[1][5]*(1.0); + const double G0_4_3_5_0 = det*w[3][4]*w[2][3]*w[0][5]*w[1][0]*(1.0); + const double G0_4_3_5_1 = det*w[3][4]*w[2][3]*w[0][5]*w[1][1]*(1.0); + const double G0_4_3_5_2 = det*w[3][4]*w[2][3]*w[0][5]*w[1][2]*(1.0); + const double G0_4_3_5_3 = det*w[3][4]*w[2][3]*w[0][5]*w[1][3]*(1.0); + const double G0_4_3_5_4 = det*w[3][4]*w[2][3]*w[0][5]*w[1][4]*(1.0); + const double G0_4_3_5_5 = det*w[3][4]*w[2][3]*w[0][5]*w[1][5]*(1.0); + const double G0_4_4_0_0 = det*w[3][4]*w[2][4]*w[0][0]*w[1][0]*(1.0); + const double G0_4_4_0_1 = det*w[3][4]*w[2][4]*w[0][0]*w[1][1]*(1.0); + const double G0_4_4_0_2 = det*w[3][4]*w[2][4]*w[0][0]*w[1][2]*(1.0); + const double G0_4_4_0_3 = det*w[3][4]*w[2][4]*w[0][0]*w[1][3]*(1.0); + const double G0_4_4_0_4 = det*w[3][4]*w[2][4]*w[0][0]*w[1][4]*(1.0); + const double G0_4_4_0_5 = det*w[3][4]*w[2][4]*w[0][0]*w[1][5]*(1.0); + const double G0_4_4_1_0 = det*w[3][4]*w[2][4]*w[0][1]*w[1][0]*(1.0); + const double G0_4_4_1_1 = det*w[3][4]*w[2][4]*w[0][1]*w[1][1]*(1.0); + const double G0_4_4_1_2 = det*w[3][4]*w[2][4]*w[0][1]*w[1][2]*(1.0); + const double G0_4_4_1_3 = det*w[3][4]*w[2][4]*w[0][1]*w[1][3]*(1.0); + const double G0_4_4_1_4 = det*w[3][4]*w[2][4]*w[0][1]*w[1][4]*(1.0); + const double G0_4_4_1_5 = det*w[3][4]*w[2][4]*w[0][1]*w[1][5]*(1.0); + const double G0_4_4_2_0 = det*w[3][4]*w[2][4]*w[0][2]*w[1][0]*(1.0); + const double G0_4_4_2_1 = det*w[3][4]*w[2][4]*w[0][2]*w[1][1]*(1.0); + const double G0_4_4_2_2 = det*w[3][4]*w[2][4]*w[0][2]*w[1][2]*(1.0); + const double G0_4_4_2_3 = det*w[3][4]*w[2][4]*w[0][2]*w[1][3]*(1.0); + const double G0_4_4_2_4 = det*w[3][4]*w[2][4]*w[0][2]*w[1][4]*(1.0); + const double G0_4_4_2_5 = det*w[3][4]*w[2][4]*w[0][2]*w[1][5]*(1.0); + const double G0_4_4_3_0 = det*w[3][4]*w[2][4]*w[0][3]*w[1][0]*(1.0); + const double G0_4_4_3_1 = det*w[3][4]*w[2][4]*w[0][3]*w[1][1]*(1.0); + const double G0_4_4_3_2 = det*w[3][4]*w[2][4]*w[0][3]*w[1][2]*(1.0); + const double G0_4_4_3_3 = det*w[3][4]*w[2][4]*w[0][3]*w[1][3]*(1.0); + const double G0_4_4_3_4 = det*w[3][4]*w[2][4]*w[0][3]*w[1][4]*(1.0); + const double G0_4_4_3_5 = det*w[3][4]*w[2][4]*w[0][3]*w[1][5]*(1.0); + const double G0_4_4_4_0 = det*w[3][4]*w[2][4]*w[0][4]*w[1][0]*(1.0); + const double G0_4_4_4_1 = det*w[3][4]*w[2][4]*w[0][4]*w[1][1]*(1.0); + const double G0_4_4_4_2 = det*w[3][4]*w[2][4]*w[0][4]*w[1][2]*(1.0); + const double G0_4_4_4_3 = det*w[3][4]*w[2][4]*w[0][4]*w[1][3]*(1.0); + const double G0_4_4_4_4 = det*w[3][4]*w[2][4]*w[0][4]*w[1][4]*(1.0); + const double G0_4_4_4_5 = det*w[3][4]*w[2][4]*w[0][4]*w[1][5]*(1.0); + const double G0_4_4_5_0 = det*w[3][4]*w[2][4]*w[0][5]*w[1][0]*(1.0); + const double G0_4_4_5_1 = det*w[3][4]*w[2][4]*w[0][5]*w[1][1]*(1.0); + const double G0_4_4_5_2 = det*w[3][4]*w[2][4]*w[0][5]*w[1][2]*(1.0); + const double G0_4_4_5_3 = det*w[3][4]*w[2][4]*w[0][5]*w[1][3]*(1.0); + const double G0_4_4_5_4 = det*w[3][4]*w[2][4]*w[0][5]*w[1][4]*(1.0); + const double G0_4_4_5_5 = det*w[3][4]*w[2][4]*w[0][5]*w[1][5]*(1.0); + const double G0_4_5_0_0 = det*w[3][4]*w[2][5]*w[0][0]*w[1][0]*(1.0); + const double G0_4_5_0_1 = det*w[3][4]*w[2][5]*w[0][0]*w[1][1]*(1.0); + const double G0_4_5_0_2 = det*w[3][4]*w[2][5]*w[0][0]*w[1][2]*(1.0); + const double G0_4_5_0_3 = det*w[3][4]*w[2][5]*w[0][0]*w[1][3]*(1.0); + const double G0_4_5_0_4 = det*w[3][4]*w[2][5]*w[0][0]*w[1][4]*(1.0); + const double G0_4_5_0_5 = det*w[3][4]*w[2][5]*w[0][0]*w[1][5]*(1.0); + const double G0_4_5_1_0 = det*w[3][4]*w[2][5]*w[0][1]*w[1][0]*(1.0); + const double G0_4_5_1_1 = det*w[3][4]*w[2][5]*w[0][1]*w[1][1]*(1.0); + const double G0_4_5_1_2 = det*w[3][4]*w[2][5]*w[0][1]*w[1][2]*(1.0); + const double G0_4_5_1_3 = det*w[3][4]*w[2][5]*w[0][1]*w[1][3]*(1.0); + const double G0_4_5_1_4 = det*w[3][4]*w[2][5]*w[0][1]*w[1][4]*(1.0); + const double G0_4_5_1_5 = det*w[3][4]*w[2][5]*w[0][1]*w[1][5]*(1.0); + const double G0_4_5_2_0 = det*w[3][4]*w[2][5]*w[0][2]*w[1][0]*(1.0); + const double G0_4_5_2_1 = det*w[3][4]*w[2][5]*w[0][2]*w[1][1]*(1.0); + const double G0_4_5_2_2 = det*w[3][4]*w[2][5]*w[0][2]*w[1][2]*(1.0); + const double G0_4_5_2_3 = det*w[3][4]*w[2][5]*w[0][2]*w[1][3]*(1.0); + const double G0_4_5_2_4 = det*w[3][4]*w[2][5]*w[0][2]*w[1][4]*(1.0); + const double G0_4_5_2_5 = det*w[3][4]*w[2][5]*w[0][2]*w[1][5]*(1.0); + const double G0_4_5_3_0 = det*w[3][4]*w[2][5]*w[0][3]*w[1][0]*(1.0); + const double G0_4_5_3_1 = det*w[3][4]*w[2][5]*w[0][3]*w[1][1]*(1.0); + const double G0_4_5_3_2 = det*w[3][4]*w[2][5]*w[0][3]*w[1][2]*(1.0); + const double G0_4_5_3_3 = det*w[3][4]*w[2][5]*w[0][3]*w[1][3]*(1.0); + const double G0_4_5_3_4 = det*w[3][4]*w[2][5]*w[0][3]*w[1][4]*(1.0); + const double G0_4_5_3_5 = det*w[3][4]*w[2][5]*w[0][3]*w[1][5]*(1.0); + const double G0_4_5_4_0 = det*w[3][4]*w[2][5]*w[0][4]*w[1][0]*(1.0); + const double G0_4_5_4_1 = det*w[3][4]*w[2][5]*w[0][4]*w[1][1]*(1.0); + const double G0_4_5_4_2 = det*w[3][4]*w[2][5]*w[0][4]*w[1][2]*(1.0); + const double G0_4_5_4_3 = det*w[3][4]*w[2][5]*w[0][4]*w[1][3]*(1.0); + const double G0_4_5_4_4 = det*w[3][4]*w[2][5]*w[0][4]*w[1][4]*(1.0); + const double G0_4_5_4_5 = det*w[3][4]*w[2][5]*w[0][4]*w[1][5]*(1.0); + const double G0_4_5_5_0 = det*w[3][4]*w[2][5]*w[0][5]*w[1][0]*(1.0); + const double G0_4_5_5_1 = det*w[3][4]*w[2][5]*w[0][5]*w[1][1]*(1.0); + const double G0_4_5_5_2 = det*w[3][4]*w[2][5]*w[0][5]*w[1][2]*(1.0); + const double G0_4_5_5_3 = det*w[3][4]*w[2][5]*w[0][5]*w[1][3]*(1.0); + const double G0_4_5_5_4 = det*w[3][4]*w[2][5]*w[0][5]*w[1][4]*(1.0); + const double G0_4_5_5_5 = det*w[3][4]*w[2][5]*w[0][5]*w[1][5]*(1.0); + const double G0_5_0_0_0 = det*w[3][5]*w[2][0]*w[0][0]*w[1][0]*(1.0); + const double G0_5_0_0_1 = det*w[3][5]*w[2][0]*w[0][0]*w[1][1]*(1.0); + const double G0_5_0_0_2 = det*w[3][5]*w[2][0]*w[0][0]*w[1][2]*(1.0); + const double G0_5_0_0_3 = det*w[3][5]*w[2][0]*w[0][0]*w[1][3]*(1.0); + const double G0_5_0_0_4 = det*w[3][5]*w[2][0]*w[0][0]*w[1][4]*(1.0); + const double G0_5_0_0_5 = det*w[3][5]*w[2][0]*w[0][0]*w[1][5]*(1.0); + const double G0_5_0_1_0 = det*w[3][5]*w[2][0]*w[0][1]*w[1][0]*(1.0); + const double G0_5_0_1_1 = det*w[3][5]*w[2][0]*w[0][1]*w[1][1]*(1.0); + const double G0_5_0_1_2 = det*w[3][5]*w[2][0]*w[0][1]*w[1][2]*(1.0); + const double G0_5_0_1_3 = det*w[3][5]*w[2][0]*w[0][1]*w[1][3]*(1.0); + const double G0_5_0_1_4 = det*w[3][5]*w[2][0]*w[0][1]*w[1][4]*(1.0); + const double G0_5_0_1_5 = det*w[3][5]*w[2][0]*w[0][1]*w[1][5]*(1.0); + const double G0_5_0_2_0 = det*w[3][5]*w[2][0]*w[0][2]*w[1][0]*(1.0); + const double G0_5_0_2_1 = det*w[3][5]*w[2][0]*w[0][2]*w[1][1]*(1.0); + const double G0_5_0_2_2 = det*w[3][5]*w[2][0]*w[0][2]*w[1][2]*(1.0); + const double G0_5_0_2_3 = det*w[3][5]*w[2][0]*w[0][2]*w[1][3]*(1.0); + const double G0_5_0_2_4 = det*w[3][5]*w[2][0]*w[0][2]*w[1][4]*(1.0); + const double G0_5_0_2_5 = det*w[3][5]*w[2][0]*w[0][2]*w[1][5]*(1.0); + const double G0_5_0_3_0 = det*w[3][5]*w[2][0]*w[0][3]*w[1][0]*(1.0); + const double G0_5_0_3_1 = det*w[3][5]*w[2][0]*w[0][3]*w[1][1]*(1.0); + const double G0_5_0_3_2 = det*w[3][5]*w[2][0]*w[0][3]*w[1][2]*(1.0); + const double G0_5_0_3_3 = det*w[3][5]*w[2][0]*w[0][3]*w[1][3]*(1.0); + const double G0_5_0_3_4 = det*w[3][5]*w[2][0]*w[0][3]*w[1][4]*(1.0); + const double G0_5_0_3_5 = det*w[3][5]*w[2][0]*w[0][3]*w[1][5]*(1.0); + const double G0_5_0_4_0 = det*w[3][5]*w[2][0]*w[0][4]*w[1][0]*(1.0); + const double G0_5_0_4_1 = det*w[3][5]*w[2][0]*w[0][4]*w[1][1]*(1.0); + const double G0_5_0_4_2 = det*w[3][5]*w[2][0]*w[0][4]*w[1][2]*(1.0); + const double G0_5_0_4_3 = det*w[3][5]*w[2][0]*w[0][4]*w[1][3]*(1.0); + const double G0_5_0_4_4 = det*w[3][5]*w[2][0]*w[0][4]*w[1][4]*(1.0); + const double G0_5_0_4_5 = det*w[3][5]*w[2][0]*w[0][4]*w[1][5]*(1.0); + const double G0_5_0_5_0 = det*w[3][5]*w[2][0]*w[0][5]*w[1][0]*(1.0); + const double G0_5_0_5_1 = det*w[3][5]*w[2][0]*w[0][5]*w[1][1]*(1.0); + const double G0_5_0_5_2 = det*w[3][5]*w[2][0]*w[0][5]*w[1][2]*(1.0); + const double G0_5_0_5_3 = det*w[3][5]*w[2][0]*w[0][5]*w[1][3]*(1.0); + const double G0_5_0_5_4 = det*w[3][5]*w[2][0]*w[0][5]*w[1][4]*(1.0); + const double G0_5_0_5_5 = det*w[3][5]*w[2][0]*w[0][5]*w[1][5]*(1.0); + const double G0_5_1_0_0 = det*w[3][5]*w[2][1]*w[0][0]*w[1][0]*(1.0); + const double G0_5_1_0_1 = det*w[3][5]*w[2][1]*w[0][0]*w[1][1]*(1.0); + const double G0_5_1_0_2 = det*w[3][5]*w[2][1]*w[0][0]*w[1][2]*(1.0); + const double G0_5_1_0_3 = det*w[3][5]*w[2][1]*w[0][0]*w[1][3]*(1.0); + const double G0_5_1_0_4 = det*w[3][5]*w[2][1]*w[0][0]*w[1][4]*(1.0); + const double G0_5_1_0_5 = det*w[3][5]*w[2][1]*w[0][0]*w[1][5]*(1.0); + const double G0_5_1_1_0 = det*w[3][5]*w[2][1]*w[0][1]*w[1][0]*(1.0); + const double G0_5_1_1_1 = det*w[3][5]*w[2][1]*w[0][1]*w[1][1]*(1.0); + const double G0_5_1_1_2 = det*w[3][5]*w[2][1]*w[0][1]*w[1][2]*(1.0); + const double G0_5_1_1_3 = det*w[3][5]*w[2][1]*w[0][1]*w[1][3]*(1.0); + const double G0_5_1_1_4 = det*w[3][5]*w[2][1]*w[0][1]*w[1][4]*(1.0); + const double G0_5_1_1_5 = det*w[3][5]*w[2][1]*w[0][1]*w[1][5]*(1.0); + const double G0_5_1_2_0 = det*w[3][5]*w[2][1]*w[0][2]*w[1][0]*(1.0); + const double G0_5_1_2_1 = det*w[3][5]*w[2][1]*w[0][2]*w[1][1]*(1.0); + const double G0_5_1_2_2 = det*w[3][5]*w[2][1]*w[0][2]*w[1][2]*(1.0); + const double G0_5_1_2_3 = det*w[3][5]*w[2][1]*w[0][2]*w[1][3]*(1.0); + const double G0_5_1_2_4 = det*w[3][5]*w[2][1]*w[0][2]*w[1][4]*(1.0); + const double G0_5_1_2_5 = det*w[3][5]*w[2][1]*w[0][2]*w[1][5]*(1.0); + const double G0_5_1_3_0 = det*w[3][5]*w[2][1]*w[0][3]*w[1][0]*(1.0); + const double G0_5_1_3_1 = det*w[3][5]*w[2][1]*w[0][3]*w[1][1]*(1.0); + const double G0_5_1_3_2 = det*w[3][5]*w[2][1]*w[0][3]*w[1][2]*(1.0); + const double G0_5_1_3_3 = det*w[3][5]*w[2][1]*w[0][3]*w[1][3]*(1.0); + const double G0_5_1_3_4 = det*w[3][5]*w[2][1]*w[0][3]*w[1][4]*(1.0); + const double G0_5_1_3_5 = det*w[3][5]*w[2][1]*w[0][3]*w[1][5]*(1.0); + const double G0_5_1_4_0 = det*w[3][5]*w[2][1]*w[0][4]*w[1][0]*(1.0); + const double G0_5_1_4_1 = det*w[3][5]*w[2][1]*w[0][4]*w[1][1]*(1.0); + const double G0_5_1_4_2 = det*w[3][5]*w[2][1]*w[0][4]*w[1][2]*(1.0); + const double G0_5_1_4_3 = det*w[3][5]*w[2][1]*w[0][4]*w[1][3]*(1.0); + const double G0_5_1_4_4 = det*w[3][5]*w[2][1]*w[0][4]*w[1][4]*(1.0); + const double G0_5_1_4_5 = det*w[3][5]*w[2][1]*w[0][4]*w[1][5]*(1.0); + const double G0_5_1_5_0 = det*w[3][5]*w[2][1]*w[0][5]*w[1][0]*(1.0); + const double G0_5_1_5_1 = det*w[3][5]*w[2][1]*w[0][5]*w[1][1]*(1.0); + const double G0_5_1_5_2 = det*w[3][5]*w[2][1]*w[0][5]*w[1][2]*(1.0); + const double G0_5_1_5_3 = det*w[3][5]*w[2][1]*w[0][5]*w[1][3]*(1.0); + const double G0_5_1_5_4 = det*w[3][5]*w[2][1]*w[0][5]*w[1][4]*(1.0); + const double G0_5_1_5_5 = det*w[3][5]*w[2][1]*w[0][5]*w[1][5]*(1.0); + const double G0_5_2_0_0 = det*w[3][5]*w[2][2]*w[0][0]*w[1][0]*(1.0); + const double G0_5_2_0_1 = det*w[3][5]*w[2][2]*w[0][0]*w[1][1]*(1.0); + const double G0_5_2_0_2 = det*w[3][5]*w[2][2]*w[0][0]*w[1][2]*(1.0); + const double G0_5_2_0_3 = det*w[3][5]*w[2][2]*w[0][0]*w[1][3]*(1.0); + const double G0_5_2_0_4 = det*w[3][5]*w[2][2]*w[0][0]*w[1][4]*(1.0); + const double G0_5_2_0_5 = det*w[3][5]*w[2][2]*w[0][0]*w[1][5]*(1.0); + const double G0_5_2_1_0 = det*w[3][5]*w[2][2]*w[0][1]*w[1][0]*(1.0); + const double G0_5_2_1_1 = det*w[3][5]*w[2][2]*w[0][1]*w[1][1]*(1.0); + const double G0_5_2_1_2 = det*w[3][5]*w[2][2]*w[0][1]*w[1][2]*(1.0); + const double G0_5_2_1_3 = det*w[3][5]*w[2][2]*w[0][1]*w[1][3]*(1.0); + const double G0_5_2_1_4 = det*w[3][5]*w[2][2]*w[0][1]*w[1][4]*(1.0); + const double G0_5_2_1_5 = det*w[3][5]*w[2][2]*w[0][1]*w[1][5]*(1.0); + const double G0_5_2_2_0 = det*w[3][5]*w[2][2]*w[0][2]*w[1][0]*(1.0); + const double G0_5_2_2_1 = det*w[3][5]*w[2][2]*w[0][2]*w[1][1]*(1.0); + const double G0_5_2_2_2 = det*w[3][5]*w[2][2]*w[0][2]*w[1][2]*(1.0); + const double G0_5_2_2_3 = det*w[3][5]*w[2][2]*w[0][2]*w[1][3]*(1.0); + const double G0_5_2_2_4 = det*w[3][5]*w[2][2]*w[0][2]*w[1][4]*(1.0); + const double G0_5_2_2_5 = det*w[3][5]*w[2][2]*w[0][2]*w[1][5]*(1.0); + const double G0_5_2_3_0 = det*w[3][5]*w[2][2]*w[0][3]*w[1][0]*(1.0); + const double G0_5_2_3_1 = det*w[3][5]*w[2][2]*w[0][3]*w[1][1]*(1.0); + const double G0_5_2_3_2 = det*w[3][5]*w[2][2]*w[0][3]*w[1][2]*(1.0); + const double G0_5_2_3_3 = det*w[3][5]*w[2][2]*w[0][3]*w[1][3]*(1.0); + const double G0_5_2_3_4 = det*w[3][5]*w[2][2]*w[0][3]*w[1][4]*(1.0); + const double G0_5_2_3_5 = det*w[3][5]*w[2][2]*w[0][3]*w[1][5]*(1.0); + const double G0_5_2_4_0 = det*w[3][5]*w[2][2]*w[0][4]*w[1][0]*(1.0); + const double G0_5_2_4_1 = det*w[3][5]*w[2][2]*w[0][4]*w[1][1]*(1.0); + const double G0_5_2_4_2 = det*w[3][5]*w[2][2]*w[0][4]*w[1][2]*(1.0); + const double G0_5_2_4_3 = det*w[3][5]*w[2][2]*w[0][4]*w[1][3]*(1.0); + const double G0_5_2_4_4 = det*w[3][5]*w[2][2]*w[0][4]*w[1][4]*(1.0); + const double G0_5_2_4_5 = det*w[3][5]*w[2][2]*w[0][4]*w[1][5]*(1.0); + const double G0_5_2_5_0 = det*w[3][5]*w[2][2]*w[0][5]*w[1][0]*(1.0); + const double G0_5_2_5_1 = det*w[3][5]*w[2][2]*w[0][5]*w[1][1]*(1.0); + const double G0_5_2_5_2 = det*w[3][5]*w[2][2]*w[0][5]*w[1][2]*(1.0); + const double G0_5_2_5_3 = det*w[3][5]*w[2][2]*w[0][5]*w[1][3]*(1.0); + const double G0_5_2_5_4 = det*w[3][5]*w[2][2]*w[0][5]*w[1][4]*(1.0); + const double G0_5_2_5_5 = det*w[3][5]*w[2][2]*w[0][5]*w[1][5]*(1.0); + const double G0_5_3_0_0 = det*w[3][5]*w[2][3]*w[0][0]*w[1][0]*(1.0); + const double G0_5_3_0_1 = det*w[3][5]*w[2][3]*w[0][0]*w[1][1]*(1.0); + const double G0_5_3_0_2 = det*w[3][5]*w[2][3]*w[0][0]*w[1][2]*(1.0); + const double G0_5_3_0_3 = det*w[3][5]*w[2][3]*w[0][0]*w[1][3]*(1.0); + const double G0_5_3_0_4 = det*w[3][5]*w[2][3]*w[0][0]*w[1][4]*(1.0); + const double G0_5_3_0_5 = det*w[3][5]*w[2][3]*w[0][0]*w[1][5]*(1.0); + const double G0_5_3_1_0 = det*w[3][5]*w[2][3]*w[0][1]*w[1][0]*(1.0); + const double G0_5_3_1_1 = det*w[3][5]*w[2][3]*w[0][1]*w[1][1]*(1.0); + const double G0_5_3_1_2 = det*w[3][5]*w[2][3]*w[0][1]*w[1][2]*(1.0); + const double G0_5_3_1_3 = det*w[3][5]*w[2][3]*w[0][1]*w[1][3]*(1.0); + const double G0_5_3_1_4 = det*w[3][5]*w[2][3]*w[0][1]*w[1][4]*(1.0); + const double G0_5_3_1_5 = det*w[3][5]*w[2][3]*w[0][1]*w[1][5]*(1.0); + const double G0_5_3_2_0 = det*w[3][5]*w[2][3]*w[0][2]*w[1][0]*(1.0); + const double G0_5_3_2_1 = det*w[3][5]*w[2][3]*w[0][2]*w[1][1]*(1.0); + const double G0_5_3_2_2 = det*w[3][5]*w[2][3]*w[0][2]*w[1][2]*(1.0); + const double G0_5_3_2_3 = det*w[3][5]*w[2][3]*w[0][2]*w[1][3]*(1.0); + const double G0_5_3_2_4 = det*w[3][5]*w[2][3]*w[0][2]*w[1][4]*(1.0); + const double G0_5_3_2_5 = det*w[3][5]*w[2][3]*w[0][2]*w[1][5]*(1.0); + const double G0_5_3_3_0 = det*w[3][5]*w[2][3]*w[0][3]*w[1][0]*(1.0); + const double G0_5_3_3_1 = det*w[3][5]*w[2][3]*w[0][3]*w[1][1]*(1.0); + const double G0_5_3_3_2 = det*w[3][5]*w[2][3]*w[0][3]*w[1][2]*(1.0); + const double G0_5_3_3_3 = det*w[3][5]*w[2][3]*w[0][3]*w[1][3]*(1.0); + const double G0_5_3_3_4 = det*w[3][5]*w[2][3]*w[0][3]*w[1][4]*(1.0); + const double G0_5_3_3_5 = det*w[3][5]*w[2][3]*w[0][3]*w[1][5]*(1.0); + const double G0_5_3_4_0 = det*w[3][5]*w[2][3]*w[0][4]*w[1][0]*(1.0); + const double G0_5_3_4_1 = det*w[3][5]*w[2][3]*w[0][4]*w[1][1]*(1.0); + const double G0_5_3_4_2 = det*w[3][5]*w[2][3]*w[0][4]*w[1][2]*(1.0); + const double G0_5_3_4_3 = det*w[3][5]*w[2][3]*w[0][4]*w[1][3]*(1.0); + const double G0_5_3_4_4 = det*w[3][5]*w[2][3]*w[0][4]*w[1][4]*(1.0); + const double G0_5_3_4_5 = det*w[3][5]*w[2][3]*w[0][4]*w[1][5]*(1.0); + const double G0_5_3_5_0 = det*w[3][5]*w[2][3]*w[0][5]*w[1][0]*(1.0); + const double G0_5_3_5_1 = det*w[3][5]*w[2][3]*w[0][5]*w[1][1]*(1.0); + const double G0_5_3_5_2 = det*w[3][5]*w[2][3]*w[0][5]*w[1][2]*(1.0); + const double G0_5_3_5_3 = det*w[3][5]*w[2][3]*w[0][5]*w[1][3]*(1.0); + const double G0_5_3_5_4 = det*w[3][5]*w[2][3]*w[0][5]*w[1][4]*(1.0); + const double G0_5_3_5_5 = det*w[3][5]*w[2][3]*w[0][5]*w[1][5]*(1.0); + const double G0_5_4_0_0 = det*w[3][5]*w[2][4]*w[0][0]*w[1][0]*(1.0); + const double G0_5_4_0_1 = det*w[3][5]*w[2][4]*w[0][0]*w[1][1]*(1.0); + const double G0_5_4_0_2 = det*w[3][5]*w[2][4]*w[0][0]*w[1][2]*(1.0); + const double G0_5_4_0_3 = det*w[3][5]*w[2][4]*w[0][0]*w[1][3]*(1.0); + const double G0_5_4_0_4 = det*w[3][5]*w[2][4]*w[0][0]*w[1][4]*(1.0); + const double G0_5_4_0_5 = det*w[3][5]*w[2][4]*w[0][0]*w[1][5]*(1.0); + const double G0_5_4_1_0 = det*w[3][5]*w[2][4]*w[0][1]*w[1][0]*(1.0); + const double G0_5_4_1_1 = det*w[3][5]*w[2][4]*w[0][1]*w[1][1]*(1.0); + const double G0_5_4_1_2 = det*w[3][5]*w[2][4]*w[0][1]*w[1][2]*(1.0); + const double G0_5_4_1_3 = det*w[3][5]*w[2][4]*w[0][1]*w[1][3]*(1.0); + const double G0_5_4_1_4 = det*w[3][5]*w[2][4]*w[0][1]*w[1][4]*(1.0); + const double G0_5_4_1_5 = det*w[3][5]*w[2][4]*w[0][1]*w[1][5]*(1.0); + const double G0_5_4_2_0 = det*w[3][5]*w[2][4]*w[0][2]*w[1][0]*(1.0); + const double G0_5_4_2_1 = det*w[3][5]*w[2][4]*w[0][2]*w[1][1]*(1.0); + const double G0_5_4_2_2 = det*w[3][5]*w[2][4]*w[0][2]*w[1][2]*(1.0); + const double G0_5_4_2_3 = det*w[3][5]*w[2][4]*w[0][2]*w[1][3]*(1.0); + const double G0_5_4_2_4 = det*w[3][5]*w[2][4]*w[0][2]*w[1][4]*(1.0); + const double G0_5_4_2_5 = det*w[3][5]*w[2][4]*w[0][2]*w[1][5]*(1.0); + const double G0_5_4_3_0 = det*w[3][5]*w[2][4]*w[0][3]*w[1][0]*(1.0); + const double G0_5_4_3_1 = det*w[3][5]*w[2][4]*w[0][3]*w[1][1]*(1.0); + const double G0_5_4_3_2 = det*w[3][5]*w[2][4]*w[0][3]*w[1][2]*(1.0); + const double G0_5_4_3_3 = det*w[3][5]*w[2][4]*w[0][3]*w[1][3]*(1.0); + const double G0_5_4_3_4 = det*w[3][5]*w[2][4]*w[0][3]*w[1][4]*(1.0); + const double G0_5_4_3_5 = det*w[3][5]*w[2][4]*w[0][3]*w[1][5]*(1.0); + const double G0_5_4_4_0 = det*w[3][5]*w[2][4]*w[0][4]*w[1][0]*(1.0); + const double G0_5_4_4_1 = det*w[3][5]*w[2][4]*w[0][4]*w[1][1]*(1.0); + const double G0_5_4_4_2 = det*w[3][5]*w[2][4]*w[0][4]*w[1][2]*(1.0); + const double G0_5_4_4_3 = det*w[3][5]*w[2][4]*w[0][4]*w[1][3]*(1.0); + const double G0_5_4_4_4 = det*w[3][5]*w[2][4]*w[0][4]*w[1][4]*(1.0); + const double G0_5_4_4_5 = det*w[3][5]*w[2][4]*w[0][4]*w[1][5]*(1.0); + const double G0_5_4_5_0 = det*w[3][5]*w[2][4]*w[0][5]*w[1][0]*(1.0); + const double G0_5_4_5_1 = det*w[3][5]*w[2][4]*w[0][5]*w[1][1]*(1.0); + const double G0_5_4_5_2 = det*w[3][5]*w[2][4]*w[0][5]*w[1][2]*(1.0); + const double G0_5_4_5_3 = det*w[3][5]*w[2][4]*w[0][5]*w[1][3]*(1.0); + const double G0_5_4_5_4 = det*w[3][5]*w[2][4]*w[0][5]*w[1][4]*(1.0); + const double G0_5_4_5_5 = det*w[3][5]*w[2][4]*w[0][5]*w[1][5]*(1.0); + const double G0_5_5_0_0 = det*w[3][5]*w[2][5]*w[0][0]*w[1][0]*(1.0); + const double G0_5_5_0_1 = det*w[3][5]*w[2][5]*w[0][0]*w[1][1]*(1.0); + const double G0_5_5_0_2 = det*w[3][5]*w[2][5]*w[0][0]*w[1][2]*(1.0); + const double G0_5_5_0_3 = det*w[3][5]*w[2][5]*w[0][0]*w[1][3]*(1.0); + const double G0_5_5_0_4 = det*w[3][5]*w[2][5]*w[0][0]*w[1][4]*(1.0); + const double G0_5_5_0_5 = det*w[3][5]*w[2][5]*w[0][0]*w[1][5]*(1.0); + const double G0_5_5_1_0 = det*w[3][5]*w[2][5]*w[0][1]*w[1][0]*(1.0); + const double G0_5_5_1_1 = det*w[3][5]*w[2][5]*w[0][1]*w[1][1]*(1.0); + const double G0_5_5_1_2 = det*w[3][5]*w[2][5]*w[0][1]*w[1][2]*(1.0); + const double G0_5_5_1_3 = det*w[3][5]*w[2][5]*w[0][1]*w[1][3]*(1.0); + const double G0_5_5_1_4 = det*w[3][5]*w[2][5]*w[0][1]*w[1][4]*(1.0); + const double G0_5_5_1_5 = det*w[3][5]*w[2][5]*w[0][1]*w[1][5]*(1.0); + const double G0_5_5_2_0 = det*w[3][5]*w[2][5]*w[0][2]*w[1][0]*(1.0); + const double G0_5_5_2_1 = det*w[3][5]*w[2][5]*w[0][2]*w[1][1]*(1.0); + const double G0_5_5_2_2 = det*w[3][5]*w[2][5]*w[0][2]*w[1][2]*(1.0); + const double G0_5_5_2_3 = det*w[3][5]*w[2][5]*w[0][2]*w[1][3]*(1.0); + const double G0_5_5_2_4 = det*w[3][5]*w[2][5]*w[0][2]*w[1][4]*(1.0); + const double G0_5_5_2_5 = det*w[3][5]*w[2][5]*w[0][2]*w[1][5]*(1.0); + const double G0_5_5_3_0 = det*w[3][5]*w[2][5]*w[0][3]*w[1][0]*(1.0); + const double G0_5_5_3_1 = det*w[3][5]*w[2][5]*w[0][3]*w[1][1]*(1.0); + const double G0_5_5_3_2 = det*w[3][5]*w[2][5]*w[0][3]*w[1][2]*(1.0); + const double G0_5_5_3_3 = det*w[3][5]*w[2][5]*w[0][3]*w[1][3]*(1.0); + const double G0_5_5_3_4 = det*w[3][5]*w[2][5]*w[0][3]*w[1][4]*(1.0); + const double G0_5_5_3_5 = det*w[3][5]*w[2][5]*w[0][3]*w[1][5]*(1.0); + const double G0_5_5_4_0 = det*w[3][5]*w[2][5]*w[0][4]*w[1][0]*(1.0); + const double G0_5_5_4_1 = det*w[3][5]*w[2][5]*w[0][4]*w[1][1]*(1.0); + const double G0_5_5_4_2 = det*w[3][5]*w[2][5]*w[0][4]*w[1][2]*(1.0); + const double G0_5_5_4_3 = det*w[3][5]*w[2][5]*w[0][4]*w[1][3]*(1.0); + const double G0_5_5_4_4 = det*w[3][5]*w[2][5]*w[0][4]*w[1][4]*(1.0); + const double G0_5_5_4_5 = det*w[3][5]*w[2][5]*w[0][4]*w[1][5]*(1.0); + const double G0_5_5_5_0 = det*w[3][5]*w[2][5]*w[0][5]*w[1][0]*(1.0); + const double G0_5_5_5_1 = det*w[3][5]*w[2][5]*w[0][5]*w[1][1]*(1.0); + const double G0_5_5_5_2 = det*w[3][5]*w[2][5]*w[0][5]*w[1][2]*(1.0); + const double G0_5_5_5_3 = det*w[3][5]*w[2][5]*w[0][5]*w[1][3]*(1.0); + const double G0_5_5_5_4 = det*w[3][5]*w[2][5]*w[0][5]*w[1][4]*(1.0); + const double G0_5_5_5_5 = det*w[3][5]*w[2][5]*w[0][5]*w[1][5]*(1.0); + + // Compute element tensor + A[1] = 0.000234487734487743*G0_0_0_0_0 - 3.60750360750373e-05*G0_0_0_0_1 - 1.80375180375187e-05*G0_0_0_0_2 + 7.21500721500747e-05*G0_0_0_0_4 + 0.000144300144300149*G0_0_0_0_5 - 3.60750360750374e-05*G0_0_0_1_0 + 1.7436267436268e-05*G0_0_0_1_1 + 3.00625300625311e-06*G0_0_0_1_2 - 2.40500240500249e-06*G0_0_0_1_3 - 1.92400192400199e-05*G0_0_0_1_4 - 2.88600288600299e-05*G0_0_0_1_5 - 1.80375180375187e-05*G0_0_0_2_0 + 3.00625300625311e-06*G0_0_0_2_1 + 6.61375661375684e-06*G0_0_0_2_2 - 9.62000962000995e-06*G0_0_0_2_3 - 1.92400192400199e-05*G0_0_0_2_4 - 2.88600288600299e-05*G0_0_0_2_5 - 2.40500240500249e-06*G0_0_0_3_1 - 9.62000962000995e-06*G0_0_0_3_2 + 4.81000481000497e-05*G0_0_0_3_3 + 3.84800384800398e-05*G0_0_0_3_4 + 5.77200577200597e-05*G0_0_0_3_5 + 7.21500721500747e-05*G0_0_0_4_0 - 1.92400192400199e-05*G0_0_0_4_1 - 1.92400192400199e-05*G0_0_0_4_2 + 3.84800384800398e-05*G0_0_0_4_3 + 9.62000962000995e-05*G0_0_0_4_4 + 9.62000962000995e-05*G0_0_0_4_5 + 0.000144300144300149*G0_0_0_5_0 - 2.88600288600299e-05*G0_0_0_5_1 - 2.88600288600299e-05*G0_0_0_5_2 + 5.77200577200597e-05*G0_0_0_5_3 + 9.62000962000995e-05*G0_0_0_5_4 + 0.000288600288600299*G0_0_0_5_5 - 3.60750360750373e-05*G0_0_1_0_0 + 1.7436267436268e-05*G0_0_1_0_1 + 3.00625300625311e-06*G0_0_1_0_2 - 2.40500240500249e-06*G0_0_1_0_3 - 1.92400192400199e-05*G0_0_1_0_4 - 2.88600288600299e-05*G0_0_1_0_5 + 1.7436267436268e-05*G0_0_1_1_0 - 3.60750360750374e-05*G0_0_1_1_1 + 3.00625300625311e-06*G0_0_1_1_2 - 1.92400192400199e-05*G0_0_1_1_3 - 2.40500240500248e-06*G0_0_1_1_4 - 2.88600288600299e-05*G0_0_1_1_5 + 3.00625300625311e-06*G0_0_1_2_0 + 3.00625300625311e-06*G0_0_1_2_1 - 1.20250120250125e-06*G0_0_1_2_2 + 4.81000481000498e-06*G0_0_1_2_3 + 4.81000481000498e-06*G0_0_1_2_4 + 1.20250120250124e-05*G0_0_1_2_5 - 2.40500240500249e-06*G0_0_1_3_0 - 1.92400192400199e-05*G0_0_1_3_1 + 4.81000481000498e-06*G0_0_1_3_2 + 9.62000962000993e-06*G0_0_1_3_4 - 1.92400192400199e-05*G0_0_1_3_5 - 1.92400192400199e-05*G0_0_1_4_0 - 2.40500240500248e-06*G0_0_1_4_1 + 4.81000481000498e-06*G0_0_1_4_2 + 9.62000962000993e-06*G0_0_1_4_3 - 1.92400192400199e-05*G0_0_1_4_5 - 2.88600288600299e-05*G0_0_1_5_0 - 2.88600288600299e-05*G0_0_1_5_1 + 1.20250120250124e-05*G0_0_1_5_2 - 1.92400192400199e-05*G0_0_1_5_3 - 1.92400192400199e-05*G0_0_1_5_4 - 0.000153920153920159*G0_0_1_5_5 - 1.80375180375187e-05*G0_0_2_0_0 + 3.00625300625311e-06*G0_0_2_0_1 + 6.61375661375684e-06*G0_0_2_0_2 - 9.62000962000995e-06*G0_0_2_0_3 - 1.92400192400199e-05*G0_0_2_0_4 - 2.88600288600299e-05*G0_0_2_0_5 + 3.00625300625311e-06*G0_0_2_1_0 + 3.00625300625311e-06*G0_0_2_1_1 - 1.20250120250125e-06*G0_0_2_1_2 + 4.81000481000498e-06*G0_0_2_1_3 + 4.81000481000498e-06*G0_0_2_1_4 + 1.20250120250124e-05*G0_0_2_1_5 + 6.61375661375684e-06*G0_0_2_2_0 - 1.20250120250125e-06*G0_0_2_2_1 - 1.80375180375187e-06*G0_0_2_2_2 - 9.62000962000995e-06*G0_0_2_2_3 - 2.40500240500249e-06*G0_0_2_2_4 - 4.81000481000497e-06*G0_0_2_2_5 - 9.62000962000995e-06*G0_0_2_3_0 + 4.81000481000498e-06*G0_0_2_3_1 - 9.62000962000995e-06*G0_0_2_3_2 + 2.88600288600298e-05*G0_0_2_3_3 + 9.62000962000994e-06*G0_0_2_3_4 + 2.88600288600298e-05*G0_0_2_3_5 - 1.92400192400199e-05*G0_0_2_4_0 + 4.81000481000498e-06*G0_0_2_4_1 - 2.40500240500249e-06*G0_0_2_4_2 + 9.62000962000994e-06*G0_0_2_4_3 - 1.92400192400199e-05*G0_0_2_4_4 - 2.88600288600299e-05*G0_0_2_5_0 + 1.20250120250124e-05*G0_0_2_5_1 - 4.81000481000497e-06*G0_0_2_5_2 + 2.88600288600298e-05*G0_0_2_5_3 + 1.92400192400198e-05*G0_0_2_5_5 - 2.40500240500249e-06*G0_0_3_0_1 - 9.62000962000995e-06*G0_0_3_0_2 + 4.81000481000497e-05*G0_0_3_0_3 + 3.84800384800398e-05*G0_0_3_0_4 + 5.77200577200597e-05*G0_0_3_0_5 - 2.40500240500249e-06*G0_0_3_1_0 - 1.92400192400199e-05*G0_0_3_1_1 + 4.81000481000498e-06*G0_0_3_1_2 + 9.62000962000993e-06*G0_0_3_1_4 - 1.92400192400199e-05*G0_0_3_1_5 - 9.62000962000995e-06*G0_0_3_2_0 + 4.81000481000498e-06*G0_0_3_2_1 - 9.62000962000995e-06*G0_0_3_2_2 + 2.88600288600298e-05*G0_0_3_2_3 + 9.62000962000994e-06*G0_0_3_2_4 + 2.88600288600298e-05*G0_0_3_2_5 + 4.81000481000497e-05*G0_0_3_3_0 + 2.88600288600298e-05*G0_0_3_3_2 - 0.000230880230880239*G0_0_3_3_3 - 0.000115440115440119*G0_0_3_3_4 - 0.000153920153920159*G0_0_3_3_5 + 3.84800384800398e-05*G0_0_3_4_0 + 9.62000962000993e-06*G0_0_3_4_1 + 9.62000962000994e-06*G0_0_3_4_2 - 0.000115440115440119*G0_0_3_4_3 - 7.69600769600795e-05*G0_0_3_4_4 - 7.69600769600795e-05*G0_0_3_4_5 + 5.77200577200597e-05*G0_0_3_5_0 - 1.92400192400199e-05*G0_0_3_5_1 + 2.88600288600298e-05*G0_0_3_5_2 - 0.000153920153920159*G0_0_3_5_3 - 7.69600769600795e-05*G0_0_3_5_4 - 0.000153920153920159*G0_0_3_5_5 + 7.21500721500747e-05*G0_0_4_0_0 - 1.92400192400199e-05*G0_0_4_0_1 - 1.92400192400199e-05*G0_0_4_0_2 + 3.84800384800398e-05*G0_0_4_0_3 + 9.62000962000995e-05*G0_0_4_0_4 + 9.62000962000995e-05*G0_0_4_0_5 - 1.92400192400199e-05*G0_0_4_1_0 - 2.40500240500248e-06*G0_0_4_1_1 + 4.81000481000498e-06*G0_0_4_1_2 + 9.62000962000993e-06*G0_0_4_1_3 - 1.92400192400199e-05*G0_0_4_1_5 - 1.92400192400199e-05*G0_0_4_2_0 + 4.81000481000498e-06*G0_0_4_2_1 - 2.40500240500249e-06*G0_0_4_2_2 + 9.62000962000994e-06*G0_0_4_2_3 - 1.92400192400199e-05*G0_0_4_2_4 + 3.84800384800398e-05*G0_0_4_3_0 + 9.62000962000993e-06*G0_0_4_3_1 + 9.62000962000994e-06*G0_0_4_3_2 - 0.000115440115440119*G0_0_4_3_3 - 7.69600769600795e-05*G0_0_4_3_4 - 7.69600769600795e-05*G0_0_4_3_5 + 9.62000962000995e-05*G0_0_4_4_0 - 1.92400192400199e-05*G0_0_4_4_2 - 7.69600769600795e-05*G0_0_4_4_3 + 9.62000962000995e-05*G0_0_4_5_0 - 1.92400192400199e-05*G0_0_4_5_1 - 7.69600769600795e-05*G0_0_4_5_3 + 0.000144300144300149*G0_0_5_0_0 - 2.88600288600299e-05*G0_0_5_0_1 - 2.88600288600299e-05*G0_0_5_0_2 + 5.77200577200597e-05*G0_0_5_0_3 + 9.62000962000995e-05*G0_0_5_0_4 + 0.000288600288600299*G0_0_5_0_5 - 2.88600288600299e-05*G0_0_5_1_0 - 2.88600288600299e-05*G0_0_5_1_1 + 1.20250120250124e-05*G0_0_5_1_2 - 1.92400192400199e-05*G0_0_5_1_3 - 1.92400192400199e-05*G0_0_5_1_4 - 0.000153920153920159*G0_0_5_1_5 - 2.88600288600299e-05*G0_0_5_2_0 + 1.20250120250124e-05*G0_0_5_2_1 - 4.81000481000497e-06*G0_0_5_2_2 + 2.88600288600298e-05*G0_0_5_2_3 + 1.92400192400198e-05*G0_0_5_2_5 + 5.77200577200597e-05*G0_0_5_3_0 - 1.92400192400199e-05*G0_0_5_3_1 + 2.88600288600298e-05*G0_0_5_3_2 - 0.000153920153920159*G0_0_5_3_3 - 7.69600769600795e-05*G0_0_5_3_4 - 0.000153920153920159*G0_0_5_3_5 + 9.62000962000995e-05*G0_0_5_4_0 - 1.92400192400199e-05*G0_0_5_4_1 - 7.69600769600795e-05*G0_0_5_4_3 + 0.000288600288600299*G0_0_5_5_0 - 0.000153920153920159*G0_0_5_5_1 + 1.92400192400198e-05*G0_0_5_5_2 - 0.000153920153920159*G0_0_5_5_3 - 3.60750360750373e-05*G0_1_0_0_0 + 1.7436267436268e-05*G0_1_0_0_1 + 3.00625300625311e-06*G0_1_0_0_2 - 2.40500240500249e-06*G0_1_0_0_3 - 1.92400192400199e-05*G0_1_0_0_4 - 2.88600288600299e-05*G0_1_0_0_5 + 1.74362674362681e-05*G0_1_0_1_0 - 3.60750360750374e-05*G0_1_0_1_1 + 3.00625300625311e-06*G0_1_0_1_2 - 1.92400192400199e-05*G0_1_0_1_3 - 2.40500240500248e-06*G0_1_0_1_4 - 2.88600288600299e-05*G0_1_0_1_5 + 3.00625300625311e-06*G0_1_0_2_0 + 3.00625300625311e-06*G0_1_0_2_1 - 1.20250120250125e-06*G0_1_0_2_2 + 4.81000481000498e-06*G0_1_0_2_3 + 4.81000481000498e-06*G0_1_0_2_4 + 1.20250120250124e-05*G0_1_0_2_5 - 2.40500240500249e-06*G0_1_0_3_0 - 1.92400192400199e-05*G0_1_0_3_1 + 4.81000481000498e-06*G0_1_0_3_2 + 9.62000962000993e-06*G0_1_0_3_4 - 1.92400192400199e-05*G0_1_0_3_5 - 1.92400192400199e-05*G0_1_0_4_0 - 2.40500240500248e-06*G0_1_0_4_1 + 4.81000481000498e-06*G0_1_0_4_2 + 9.62000962000993e-06*G0_1_0_4_3 - 1.92400192400199e-05*G0_1_0_4_5 - 2.88600288600299e-05*G0_1_0_5_0 - 2.88600288600299e-05*G0_1_0_5_1 + 1.20250120250124e-05*G0_1_0_5_2 - 1.92400192400199e-05*G0_1_0_5_3 - 1.92400192400199e-05*G0_1_0_5_4 - 0.000153920153920159*G0_1_0_5_5 + 1.74362674362681e-05*G0_1_1_0_0 - 3.60750360750374e-05*G0_1_1_0_1 + 3.00625300625311e-06*G0_1_1_0_2 - 1.92400192400199e-05*G0_1_1_0_3 - 2.40500240500248e-06*G0_1_1_0_4 - 2.88600288600299e-05*G0_1_1_0_5 - 3.60750360750374e-05*G0_1_1_1_0 + 0.000234487734487743*G0_1_1_1_1 - 1.80375180375187e-05*G0_1_1_1_2 + 7.21500721500748e-05*G0_1_1_1_3 + 0.00014430014430015*G0_1_1_1_5 + 3.00625300625311e-06*G0_1_1_2_0 - 1.80375180375187e-05*G0_1_1_2_1 + 6.61375661375685e-06*G0_1_1_2_2 - 1.92400192400199e-05*G0_1_1_2_3 - 9.62000962000995e-06*G0_1_1_2_4 - 2.88600288600299e-05*G0_1_1_2_5 - 1.92400192400199e-05*G0_1_1_3_0 + 7.21500721500748e-05*G0_1_1_3_1 - 1.92400192400199e-05*G0_1_1_3_2 + 9.62000962000996e-05*G0_1_1_3_3 + 3.84800384800398e-05*G0_1_1_3_4 + 9.62000962000996e-05*G0_1_1_3_5 - 2.40500240500248e-06*G0_1_1_4_0 - 9.62000962000995e-06*G0_1_1_4_2 + 3.84800384800398e-05*G0_1_1_4_3 + 4.81000481000497e-05*G0_1_1_4_4 + 5.77200577200597e-05*G0_1_1_4_5 - 2.88600288600299e-05*G0_1_1_5_0 + 0.00014430014430015*G0_1_1_5_1 - 2.88600288600299e-05*G0_1_1_5_2 + 9.62000962000996e-05*G0_1_1_5_3 + 5.77200577200597e-05*G0_1_1_5_4 + 0.000288600288600299*G0_1_1_5_5 + 3.00625300625311e-06*G0_1_2_0_0 + 3.00625300625311e-06*G0_1_2_0_1 - 1.20250120250125e-06*G0_1_2_0_2 + 4.81000481000498e-06*G0_1_2_0_3 + 4.81000481000498e-06*G0_1_2_0_4 + 1.20250120250124e-05*G0_1_2_0_5 + 3.00625300625311e-06*G0_1_2_1_0 - 1.80375180375187e-05*G0_1_2_1_1 + 6.61375661375685e-06*G0_1_2_1_2 - 1.92400192400199e-05*G0_1_2_1_3 - 9.62000962000995e-06*G0_1_2_1_4 - 2.88600288600299e-05*G0_1_2_1_5 - 1.20250120250125e-06*G0_1_2_2_0 + 6.61375661375685e-06*G0_1_2_2_1 - 1.80375180375187e-06*G0_1_2_2_2 - 2.40500240500248e-06*G0_1_2_2_3 - 9.62000962000995e-06*G0_1_2_2_4 - 4.81000481000497e-06*G0_1_2_2_5 + 4.81000481000498e-06*G0_1_2_3_0 - 1.92400192400199e-05*G0_1_2_3_1 - 2.40500240500248e-06*G0_1_2_3_2 - 1.92400192400199e-05*G0_1_2_3_3 + 9.62000962000996e-06*G0_1_2_3_4 + 4.81000481000498e-06*G0_1_2_4_0 - 9.62000962000995e-06*G0_1_2_4_1 - 9.62000962000995e-06*G0_1_2_4_2 + 9.62000962000996e-06*G0_1_2_4_3 + 2.88600288600299e-05*G0_1_2_4_4 + 2.88600288600299e-05*G0_1_2_4_5 + 1.20250120250124e-05*G0_1_2_5_0 - 2.88600288600299e-05*G0_1_2_5_1 - 4.81000481000497e-06*G0_1_2_5_2 + 2.88600288600299e-05*G0_1_2_5_4 + 1.92400192400199e-05*G0_1_2_5_5 - 2.40500240500249e-06*G0_1_3_0_0 - 1.92400192400199e-05*G0_1_3_0_1 + 4.81000481000498e-06*G0_1_3_0_2 + 9.62000962000993e-06*G0_1_3_0_4 - 1.92400192400199e-05*G0_1_3_0_5 - 1.92400192400199e-05*G0_1_3_1_0 + 7.21500721500748e-05*G0_1_3_1_1 - 1.92400192400199e-05*G0_1_3_1_2 + 9.62000962000996e-05*G0_1_3_1_3 + 3.84800384800398e-05*G0_1_3_1_4 + 9.62000962000996e-05*G0_1_3_1_5 + 4.81000481000498e-06*G0_1_3_2_0 - 1.92400192400199e-05*G0_1_3_2_1 - 2.40500240500248e-06*G0_1_3_2_2 - 1.92400192400199e-05*G0_1_3_2_3 + 9.62000962000995e-06*G0_1_3_2_4 + 9.62000962000996e-05*G0_1_3_3_1 - 1.92400192400199e-05*G0_1_3_3_2 - 7.69600769600795e-05*G0_1_3_3_4 + 9.62000962000993e-06*G0_1_3_4_0 + 3.84800384800398e-05*G0_1_3_4_1 + 9.62000962000996e-06*G0_1_3_4_2 - 7.69600769600795e-05*G0_1_3_4_3 - 0.000115440115440119*G0_1_3_4_4 - 7.69600769600796e-05*G0_1_3_4_5 - 1.92400192400199e-05*G0_1_3_5_0 + 9.62000962000996e-05*G0_1_3_5_1 - 7.69600769600796e-05*G0_1_3_5_4 - 1.92400192400199e-05*G0_1_4_0_0 - 2.40500240500248e-06*G0_1_4_0_1 + 4.81000481000498e-06*G0_1_4_0_2 + 9.62000962000993e-06*G0_1_4_0_3 - 1.92400192400199e-05*G0_1_4_0_5 - 2.40500240500248e-06*G0_1_4_1_0 - 9.62000962000995e-06*G0_1_4_1_2 + 3.84800384800398e-05*G0_1_4_1_3 + 4.81000481000497e-05*G0_1_4_1_4 + 5.77200577200597e-05*G0_1_4_1_5 + 4.81000481000498e-06*G0_1_4_2_0 - 9.62000962000995e-06*G0_1_4_2_1 - 9.62000962000995e-06*G0_1_4_2_2 + 9.62000962000996e-06*G0_1_4_2_3 + 2.88600288600299e-05*G0_1_4_2_4 + 2.88600288600299e-05*G0_1_4_2_5 + 9.62000962000993e-06*G0_1_4_3_0 + 3.84800384800398e-05*G0_1_4_3_1 + 9.62000962000996e-06*G0_1_4_3_2 - 7.69600769600795e-05*G0_1_4_3_3 - 0.000115440115440119*G0_1_4_3_4 - 7.69600769600796e-05*G0_1_4_3_5 + 4.81000481000497e-05*G0_1_4_4_1 + 2.88600288600299e-05*G0_1_4_4_2 - 0.000115440115440119*G0_1_4_4_3 - 0.000230880230880239*G0_1_4_4_4 - 0.000153920153920159*G0_1_4_4_5 - 1.92400192400199e-05*G0_1_4_5_0 + 5.77200577200597e-05*G0_1_4_5_1 + 2.88600288600299e-05*G0_1_4_5_2 - 7.69600769600796e-05*G0_1_4_5_3 - 0.000153920153920159*G0_1_4_5_4 - 0.000153920153920159*G0_1_4_5_5 - 2.88600288600299e-05*G0_1_5_0_0 - 2.88600288600299e-05*G0_1_5_0_1 + 1.20250120250124e-05*G0_1_5_0_2 - 1.92400192400199e-05*G0_1_5_0_3 - 1.92400192400199e-05*G0_1_5_0_4 - 0.000153920153920159*G0_1_5_0_5 - 2.88600288600299e-05*G0_1_5_1_0 + 0.00014430014430015*G0_1_5_1_1 - 2.88600288600299e-05*G0_1_5_1_2 + 9.62000962000996e-05*G0_1_5_1_3 + 5.77200577200597e-05*G0_1_5_1_4 + 0.000288600288600299*G0_1_5_1_5 + 1.20250120250124e-05*G0_1_5_2_0 - 2.88600288600299e-05*G0_1_5_2_1 - 4.81000481000497e-06*G0_1_5_2_2 + 2.88600288600299e-05*G0_1_5_2_4 + 1.92400192400199e-05*G0_1_5_2_5 - 1.92400192400199e-05*G0_1_5_3_0 + 9.62000962000996e-05*G0_1_5_3_1 - 7.69600769600796e-05*G0_1_5_3_4 - 1.92400192400199e-05*G0_1_5_4_0 + 5.77200577200597e-05*G0_1_5_4_1 + 2.88600288600299e-05*G0_1_5_4_2 - 7.69600769600796e-05*G0_1_5_4_3 - 0.000153920153920159*G0_1_5_4_4 - 0.000153920153920159*G0_1_5_4_5 - 0.000153920153920159*G0_1_5_5_0 + 0.000288600288600299*G0_1_5_5_1 + 1.92400192400199e-05*G0_1_5_5_2 - 0.000153920153920159*G0_1_5_5_4 - 1.80375180375187e-05*G0_2_0_0_0 + 3.00625300625311e-06*G0_2_0_0_1 + 6.61375661375684e-06*G0_2_0_0_2 - 9.62000962000995e-06*G0_2_0_0_3 - 1.92400192400199e-05*G0_2_0_0_4 - 2.88600288600299e-05*G0_2_0_0_5 + 3.00625300625311e-06*G0_2_0_1_0 + 3.00625300625311e-06*G0_2_0_1_1 - 1.20250120250125e-06*G0_2_0_1_2 + 4.81000481000498e-06*G0_2_0_1_3 + 4.81000481000498e-06*G0_2_0_1_4 + 1.20250120250124e-05*G0_2_0_1_5 + 6.61375661375684e-06*G0_2_0_2_0 - 1.20250120250125e-06*G0_2_0_2_1 - 1.80375180375187e-06*G0_2_0_2_2 - 9.62000962000995e-06*G0_2_0_2_3 - 2.40500240500249e-06*G0_2_0_2_4 - 4.81000481000497e-06*G0_2_0_2_5 - 9.62000962000995e-06*G0_2_0_3_0 + 4.81000481000498e-06*G0_2_0_3_1 - 9.62000962000995e-06*G0_2_0_3_2 + 2.88600288600298e-05*G0_2_0_3_3 + 9.62000962000994e-06*G0_2_0_3_4 + 2.88600288600298e-05*G0_2_0_3_5 - 1.92400192400199e-05*G0_2_0_4_0 + 4.81000481000498e-06*G0_2_0_4_1 - 2.40500240500249e-06*G0_2_0_4_2 + 9.62000962000994e-06*G0_2_0_4_3 - 1.92400192400199e-05*G0_2_0_4_4 - 2.88600288600299e-05*G0_2_0_5_0 + 1.20250120250124e-05*G0_2_0_5_1 - 4.81000481000497e-06*G0_2_0_5_2 + 2.88600288600298e-05*G0_2_0_5_3 + 1.92400192400198e-05*G0_2_0_5_5 + 3.00625300625311e-06*G0_2_1_0_0 + 3.00625300625311e-06*G0_2_1_0_1 - 1.20250120250125e-06*G0_2_1_0_2 + 4.81000481000498e-06*G0_2_1_0_3 + 4.81000481000498e-06*G0_2_1_0_4 + 1.20250120250124e-05*G0_2_1_0_5 + 3.00625300625311e-06*G0_2_1_1_0 - 1.80375180375187e-05*G0_2_1_1_1 + 6.61375661375685e-06*G0_2_1_1_2 - 1.92400192400199e-05*G0_2_1_1_3 - 9.62000962000995e-06*G0_2_1_1_4 - 2.88600288600299e-05*G0_2_1_1_5 - 1.20250120250125e-06*G0_2_1_2_0 + 6.61375661375685e-06*G0_2_1_2_1 - 1.80375180375187e-06*G0_2_1_2_2 - 2.40500240500248e-06*G0_2_1_2_3 - 9.62000962000995e-06*G0_2_1_2_4 - 4.81000481000497e-06*G0_2_1_2_5 + 4.81000481000498e-06*G0_2_1_3_0 - 1.92400192400199e-05*G0_2_1_3_1 - 2.40500240500248e-06*G0_2_1_3_2 - 1.92400192400199e-05*G0_2_1_3_3 + 9.62000962000996e-06*G0_2_1_3_4 + 4.81000481000498e-06*G0_2_1_4_0 - 9.62000962000995e-06*G0_2_1_4_1 - 9.62000962000995e-06*G0_2_1_4_2 + 9.62000962000996e-06*G0_2_1_4_3 + 2.88600288600299e-05*G0_2_1_4_4 + 2.88600288600299e-05*G0_2_1_4_5 + 1.20250120250124e-05*G0_2_1_5_0 - 2.88600288600299e-05*G0_2_1_5_1 - 4.81000481000497e-06*G0_2_1_5_2 + 2.88600288600299e-05*G0_2_1_5_4 + 1.92400192400199e-05*G0_2_1_5_5 + 6.61375661375684e-06*G0_2_2_0_0 - 1.20250120250125e-06*G0_2_2_0_1 - 1.80375180375187e-06*G0_2_2_0_2 - 9.62000962000995e-06*G0_2_2_0_3 - 2.40500240500249e-06*G0_2_2_0_4 - 4.81000481000496e-06*G0_2_2_0_5 - 1.20250120250125e-06*G0_2_2_1_0 + 6.61375661375685e-06*G0_2_2_1_1 - 1.80375180375187e-06*G0_2_2_1_2 - 2.40500240500248e-06*G0_2_2_1_3 - 9.62000962000995e-06*G0_2_2_1_4 - 4.81000481000497e-06*G0_2_2_1_5 - 1.80375180375187e-06*G0_2_2_2_0 - 1.80375180375187e-06*G0_2_2_2_1 + 1.80375180375187e-05*G0_2_2_2_2 - 1.44300144300149e-05*G0_2_2_2_5 - 9.62000962000995e-06*G0_2_2_3_0 - 2.40500240500248e-06*G0_2_2_3_1 + 5.77200577200597e-05*G0_2_2_3_3 + 3.84800384800398e-05*G0_2_2_3_4 + 4.81000481000498e-05*G0_2_2_3_5 - 2.40500240500249e-06*G0_2_2_4_0 - 9.62000962000995e-06*G0_2_2_4_1 + 3.84800384800398e-05*G0_2_2_4_3 + 5.77200577200597e-05*G0_2_2_4_4 + 4.81000481000498e-05*G0_2_2_4_5 - 4.81000481000497e-06*G0_2_2_5_0 - 4.81000481000497e-06*G0_2_2_5_1 - 1.44300144300149e-05*G0_2_2_5_2 + 4.81000481000498e-05*G0_2_2_5_3 + 4.81000481000498e-05*G0_2_2_5_4 + 8.65800865800896e-05*G0_2_2_5_5 - 9.62000962000995e-06*G0_2_3_0_0 + 4.81000481000498e-06*G0_2_3_0_1 - 9.62000962000995e-06*G0_2_3_0_2 + 2.88600288600298e-05*G0_2_3_0_3 + 9.62000962000994e-06*G0_2_3_0_4 + 2.88600288600298e-05*G0_2_3_0_5 + 4.81000481000498e-06*G0_2_3_1_0 - 1.92400192400199e-05*G0_2_3_1_1 - 2.40500240500248e-06*G0_2_3_1_2 - 1.92400192400199e-05*G0_2_3_1_3 + 9.62000962000996e-06*G0_2_3_1_4 - 9.62000962000995e-06*G0_2_3_2_0 - 2.40500240500248e-06*G0_2_3_2_1 + 5.77200577200597e-05*G0_2_3_2_3 + 3.84800384800398e-05*G0_2_3_2_4 + 4.81000481000498e-05*G0_2_3_2_5 + 2.88600288600298e-05*G0_2_3_3_0 - 1.92400192400199e-05*G0_2_3_3_1 + 5.77200577200597e-05*G0_2_3_3_2 - 0.000153920153920159*G0_2_3_3_3 - 7.69600769600796e-05*G0_2_3_3_4 - 0.000153920153920159*G0_2_3_3_5 + 9.62000962000994e-06*G0_2_3_4_0 + 9.62000962000996e-06*G0_2_3_4_1 + 3.84800384800398e-05*G0_2_3_4_2 - 7.69600769600796e-05*G0_2_3_4_3 - 7.69600769600796e-05*G0_2_3_4_4 - 0.000115440115440119*G0_2_3_4_5 + 2.88600288600298e-05*G0_2_3_5_0 + 4.81000481000497e-05*G0_2_3_5_2 - 0.000153920153920159*G0_2_3_5_3 - 0.000115440115440119*G0_2_3_5_4 - 0.000230880230880239*G0_2_3_5_5 - 1.92400192400199e-05*G0_2_4_0_0 + 4.81000481000498e-06*G0_2_4_0_1 - 2.40500240500249e-06*G0_2_4_0_2 + 9.62000962000994e-06*G0_2_4_0_3 - 1.92400192400199e-05*G0_2_4_0_4 + 4.81000481000498e-06*G0_2_4_1_0 - 9.62000962000995e-06*G0_2_4_1_1 - 9.62000962000995e-06*G0_2_4_1_2 + 9.62000962000995e-06*G0_2_4_1_3 + 2.88600288600299e-05*G0_2_4_1_4 + 2.88600288600299e-05*G0_2_4_1_5 - 2.40500240500249e-06*G0_2_4_2_0 - 9.62000962000995e-06*G0_2_4_2_1 + 3.84800384800398e-05*G0_2_4_2_3 + 5.77200577200597e-05*G0_2_4_2_4 + 4.81000481000498e-05*G0_2_4_2_5 + 9.62000962000994e-06*G0_2_4_3_0 + 9.62000962000996e-06*G0_2_4_3_1 + 3.84800384800398e-05*G0_2_4_3_2 - 7.69600769600796e-05*G0_2_4_3_3 - 7.69600769600796e-05*G0_2_4_3_4 - 0.000115440115440119*G0_2_4_3_5 - 1.92400192400199e-05*G0_2_4_4_0 + 2.88600288600299e-05*G0_2_4_4_1 + 5.77200577200597e-05*G0_2_4_4_2 - 7.69600769600796e-05*G0_2_4_4_3 - 0.000153920153920159*G0_2_4_4_4 - 0.000153920153920159*G0_2_4_4_5 + 2.88600288600299e-05*G0_2_4_5_1 + 4.81000481000498e-05*G0_2_4_5_2 - 0.000115440115440119*G0_2_4_5_3 - 0.000153920153920159*G0_2_4_5_4 - 0.000230880230880239*G0_2_4_5_5 - 2.88600288600299e-05*G0_2_5_0_0 + 1.20250120250125e-05*G0_2_5_0_1 - 4.81000481000496e-06*G0_2_5_0_2 + 2.88600288600298e-05*G0_2_5_0_3 + 1.92400192400198e-05*G0_2_5_0_5 + 1.20250120250124e-05*G0_2_5_1_0 - 2.88600288600299e-05*G0_2_5_1_1 - 4.81000481000497e-06*G0_2_5_1_2 + 2.88600288600299e-05*G0_2_5_1_4 + 1.92400192400199e-05*G0_2_5_1_5 - 4.81000481000496e-06*G0_2_5_2_0 - 4.81000481000497e-06*G0_2_5_2_1 - 1.44300144300149e-05*G0_2_5_2_2 + 4.81000481000497e-05*G0_2_5_2_3 + 4.81000481000498e-05*G0_2_5_2_4 + 8.65800865800896e-05*G0_2_5_2_5 + 2.88600288600298e-05*G0_2_5_3_0 + 4.81000481000497e-05*G0_2_5_3_2 - 0.000153920153920159*G0_2_5_3_3 - 0.000115440115440119*G0_2_5_3_4 - 0.000230880230880239*G0_2_5_3_5 + 2.88600288600299e-05*G0_2_5_4_1 + 4.81000481000498e-05*G0_2_5_4_2 - 0.000115440115440119*G0_2_5_4_3 - 0.000153920153920159*G0_2_5_4_4 - 0.000230880230880239*G0_2_5_4_5 + 1.92400192400198e-05*G0_2_5_5_0 + 1.92400192400199e-05*G0_2_5_5_1 + 8.65800865800896e-05*G0_2_5_5_2 - 0.000230880230880239*G0_2_5_5_3 - 0.000230880230880239*G0_2_5_5_4 - 0.000615680615680637*G0_2_5_5_5 - 2.40500240500249e-06*G0_3_0_0_1 - 9.62000962000995e-06*G0_3_0_0_2 + 4.81000481000497e-05*G0_3_0_0_3 + 3.84800384800398e-05*G0_3_0_0_4 + 5.77200577200597e-05*G0_3_0_0_5 - 2.40500240500249e-06*G0_3_0_1_0 - 1.92400192400199e-05*G0_3_0_1_1 + 4.81000481000498e-06*G0_3_0_1_2 + 9.62000962000993e-06*G0_3_0_1_4 - 1.92400192400199e-05*G0_3_0_1_5 - 9.62000962000995e-06*G0_3_0_2_0 + 4.81000481000498e-06*G0_3_0_2_1 - 9.62000962000995e-06*G0_3_0_2_2 + 2.88600288600298e-05*G0_3_0_2_3 + 9.62000962000994e-06*G0_3_0_2_4 + 2.88600288600298e-05*G0_3_0_2_5 + 4.81000481000497e-05*G0_3_0_3_0 + 2.88600288600298e-05*G0_3_0_3_2 - 0.000230880230880239*G0_3_0_3_3 - 0.000115440115440119*G0_3_0_3_4 - 0.000153920153920159*G0_3_0_3_5 + 3.84800384800398e-05*G0_3_0_4_0 + 9.62000962000993e-06*G0_3_0_4_1 + 9.62000962000994e-06*G0_3_0_4_2 - 0.000115440115440119*G0_3_0_4_3 - 7.69600769600795e-05*G0_3_0_4_4 - 7.69600769600795e-05*G0_3_0_4_5 + 5.77200577200597e-05*G0_3_0_5_0 - 1.92400192400199e-05*G0_3_0_5_1 + 2.88600288600298e-05*G0_3_0_5_2 - 0.000153920153920159*G0_3_0_5_3 - 7.69600769600795e-05*G0_3_0_5_4 - 0.000153920153920159*G0_3_0_5_5 - 2.40500240500249e-06*G0_3_1_0_0 - 1.92400192400199e-05*G0_3_1_0_1 + 4.81000481000498e-06*G0_3_1_0_2 + 9.62000962000993e-06*G0_3_1_0_4 - 1.92400192400199e-05*G0_3_1_0_5 - 1.92400192400199e-05*G0_3_1_1_0 + 7.21500721500748e-05*G0_3_1_1_1 - 1.92400192400199e-05*G0_3_1_1_2 + 9.62000962000996e-05*G0_3_1_1_3 + 3.84800384800398e-05*G0_3_1_1_4 + 9.62000962000996e-05*G0_3_1_1_5 + 4.81000481000498e-06*G0_3_1_2_0 - 1.92400192400199e-05*G0_3_1_2_1 - 2.40500240500248e-06*G0_3_1_2_2 - 1.92400192400199e-05*G0_3_1_2_3 + 9.62000962000995e-06*G0_3_1_2_4 + 9.62000962000996e-05*G0_3_1_3_1 - 1.92400192400199e-05*G0_3_1_3_2 - 7.69600769600795e-05*G0_3_1_3_4 + 9.62000962000993e-06*G0_3_1_4_0 + 3.84800384800398e-05*G0_3_1_4_1 + 9.62000962000996e-06*G0_3_1_4_2 - 7.69600769600795e-05*G0_3_1_4_3 - 0.000115440115440119*G0_3_1_4_4 - 7.69600769600796e-05*G0_3_1_4_5 - 1.92400192400199e-05*G0_3_1_5_0 + 9.62000962000996e-05*G0_3_1_5_1 - 7.69600769600796e-05*G0_3_1_5_4 - 9.62000962000995e-06*G0_3_2_0_0 + 4.81000481000498e-06*G0_3_2_0_1 - 9.62000962000995e-06*G0_3_2_0_2 + 2.88600288600298e-05*G0_3_2_0_3 + 9.62000962000994e-06*G0_3_2_0_4 + 2.88600288600298e-05*G0_3_2_0_5 + 4.81000481000498e-06*G0_3_2_1_0 - 1.92400192400199e-05*G0_3_2_1_1 - 2.40500240500248e-06*G0_3_2_1_2 - 1.92400192400199e-05*G0_3_2_1_3 + 9.62000962000996e-06*G0_3_2_1_4 - 9.62000962000995e-06*G0_3_2_2_0 - 2.40500240500248e-06*G0_3_2_2_1 + 5.77200577200597e-05*G0_3_2_2_3 + 3.84800384800398e-05*G0_3_2_2_4 + 4.81000481000498e-05*G0_3_2_2_5 + 2.88600288600298e-05*G0_3_2_3_0 - 1.92400192400199e-05*G0_3_2_3_1 + 5.77200577200597e-05*G0_3_2_3_2 - 0.000153920153920159*G0_3_2_3_3 - 7.69600769600796e-05*G0_3_2_3_4 - 0.000153920153920159*G0_3_2_3_5 + 9.62000962000994e-06*G0_3_2_4_0 + 9.62000962000996e-06*G0_3_2_4_1 + 3.84800384800398e-05*G0_3_2_4_2 - 7.69600769600796e-05*G0_3_2_4_3 - 7.69600769600796e-05*G0_3_2_4_4 - 0.000115440115440119*G0_3_2_4_5 + 2.88600288600298e-05*G0_3_2_5_0 + 4.81000481000497e-05*G0_3_2_5_2 - 0.000153920153920159*G0_3_2_5_3 - 0.000115440115440119*G0_3_2_5_4 - 0.000230880230880239*G0_3_2_5_5 + 4.81000481000497e-05*G0_3_3_0_0 + 2.88600288600298e-05*G0_3_3_0_2 - 0.000230880230880239*G0_3_3_0_3 - 0.000115440115440119*G0_3_3_0_4 - 0.000153920153920159*G0_3_3_0_5 + 9.62000962000996e-05*G0_3_3_1_1 - 1.92400192400199e-05*G0_3_3_1_2 - 7.69600769600795e-05*G0_3_3_1_4 + 2.88600288600298e-05*G0_3_3_2_0 - 1.92400192400199e-05*G0_3_3_2_1 + 5.77200577200597e-05*G0_3_3_2_2 - 0.000153920153920159*G0_3_3_2_3 - 7.69600769600796e-05*G0_3_3_2_4 - 0.000153920153920159*G0_3_3_2_5 - 0.000230880230880239*G0_3_3_3_0 - 0.000153920153920159*G0_3_3_3_2 + 0.00153920153920159*G0_3_3_3_3 + 0.000615680615680636*G0_3_3_3_4 + 0.000769600769600796*G0_3_3_3_5 - 0.000115440115440119*G0_3_3_4_0 - 7.69600769600795e-05*G0_3_3_4_1 - 7.69600769600796e-05*G0_3_3_4_2 + 0.000615680615680636*G0_3_3_4_3 + 0.000461760461760477*G0_3_3_4_4 + 0.000461760461760477*G0_3_3_4_5 - 0.000153920153920159*G0_3_3_5_0 - 0.000153920153920159*G0_3_3_5_2 + 0.000769600769600796*G0_3_3_5_3 + 0.000461760461760477*G0_3_3_5_4 + 0.000769600769600796*G0_3_3_5_5 + 3.84800384800398e-05*G0_3_4_0_0 + 9.62000962000993e-06*G0_3_4_0_1 + 9.62000962000994e-06*G0_3_4_0_2 - 0.000115440115440119*G0_3_4_0_3 - 7.69600769600795e-05*G0_3_4_0_4 - 7.69600769600795e-05*G0_3_4_0_5 + 9.62000962000993e-06*G0_3_4_1_0 + 3.84800384800398e-05*G0_3_4_1_1 + 9.62000962000996e-06*G0_3_4_1_2 - 7.69600769600795e-05*G0_3_4_1_3 - 0.000115440115440119*G0_3_4_1_4 - 7.69600769600796e-05*G0_3_4_1_5 + 9.62000962000994e-06*G0_3_4_2_0 + 9.62000962000996e-06*G0_3_4_2_1 + 3.84800384800398e-05*G0_3_4_2_2 - 7.69600769600796e-05*G0_3_4_2_3 - 7.69600769600796e-05*G0_3_4_2_4 - 0.000115440115440119*G0_3_4_2_5 - 0.000115440115440119*G0_3_4_3_0 - 7.69600769600795e-05*G0_3_4_3_1 - 7.69600769600796e-05*G0_3_4_3_2 + 0.000615680615680636*G0_3_4_3_3 + 0.000461760461760477*G0_3_4_3_4 + 0.000461760461760477*G0_3_4_3_5 - 7.69600769600795e-05*G0_3_4_4_0 - 0.000115440115440119*G0_3_4_4_1 - 7.69600769600796e-05*G0_3_4_4_2 + 0.000461760461760477*G0_3_4_4_3 + 0.000615680615680637*G0_3_4_4_4 + 0.000461760461760477*G0_3_4_4_5 - 7.69600769600795e-05*G0_3_4_5_0 - 7.69600769600796e-05*G0_3_4_5_1 - 0.000115440115440119*G0_3_4_5_2 + 0.000461760461760477*G0_3_4_5_3 + 0.000461760461760478*G0_3_4_5_4 + 0.000615680615680636*G0_3_4_5_5 + 5.77200577200597e-05*G0_3_5_0_0 - 1.92400192400199e-05*G0_3_5_0_1 + 2.88600288600298e-05*G0_3_5_0_2 - 0.000153920153920159*G0_3_5_0_3 - 7.69600769600795e-05*G0_3_5_0_4 - 0.000153920153920159*G0_3_5_0_5 - 1.92400192400199e-05*G0_3_5_1_0 + 9.62000962000996e-05*G0_3_5_1_1 - 7.69600769600796e-05*G0_3_5_1_4 + 2.88600288600298e-05*G0_3_5_2_0 + 4.81000481000497e-05*G0_3_5_2_2 - 0.000153920153920159*G0_3_5_2_3 - 0.000115440115440119*G0_3_5_2_4 - 0.000230880230880239*G0_3_5_2_5 - 0.000153920153920159*G0_3_5_3_0 - 0.000153920153920159*G0_3_5_3_2 + 0.000769600769600796*G0_3_5_3_3 + 0.000461760461760477*G0_3_5_3_4 + 0.000769600769600796*G0_3_5_3_5 - 7.69600769600795e-05*G0_3_5_4_0 - 7.69600769600796e-05*G0_3_5_4_1 - 0.000115440115440119*G0_3_5_4_2 + 0.000461760461760477*G0_3_5_4_3 + 0.000461760461760477*G0_3_5_4_4 + 0.000615680615680636*G0_3_5_4_5 - 0.000153920153920159*G0_3_5_5_0 - 0.000230880230880239*G0_3_5_5_2 + 0.000769600769600796*G0_3_5_5_3 + 0.000615680615680636*G0_3_5_5_4 + 0.00153920153920159*G0_3_5_5_5 + 7.21500721500747e-05*G0_4_0_0_0 - 1.92400192400199e-05*G0_4_0_0_1 - 1.92400192400199e-05*G0_4_0_0_2 + 3.84800384800398e-05*G0_4_0_0_3 + 9.62000962000995e-05*G0_4_0_0_4 + 9.62000962000995e-05*G0_4_0_0_5 - 1.92400192400199e-05*G0_4_0_1_0 - 2.40500240500248e-06*G0_4_0_1_1 + 4.81000481000498e-06*G0_4_0_1_2 + 9.62000962000993e-06*G0_4_0_1_3 - 1.92400192400199e-05*G0_4_0_1_5 - 1.92400192400199e-05*G0_4_0_2_0 + 4.81000481000498e-06*G0_4_0_2_1 - 2.40500240500249e-06*G0_4_0_2_2 + 9.62000962000994e-06*G0_4_0_2_3 - 1.92400192400199e-05*G0_4_0_2_4 + 3.84800384800398e-05*G0_4_0_3_0 + 9.62000962000993e-06*G0_4_0_3_1 + 9.62000962000994e-06*G0_4_0_3_2 - 0.000115440115440119*G0_4_0_3_3 - 7.69600769600795e-05*G0_4_0_3_4 - 7.69600769600795e-05*G0_4_0_3_5 + 9.62000962000995e-05*G0_4_0_4_0 - 1.92400192400199e-05*G0_4_0_4_2 - 7.69600769600795e-05*G0_4_0_4_3 + 9.62000962000995e-05*G0_4_0_5_0 - 1.92400192400199e-05*G0_4_0_5_1 - 7.69600769600795e-05*G0_4_0_5_3 - 1.92400192400199e-05*G0_4_1_0_0 - 2.40500240500248e-06*G0_4_1_0_1 + 4.81000481000498e-06*G0_4_1_0_2 + 9.62000962000993e-06*G0_4_1_0_3 - 1.92400192400199e-05*G0_4_1_0_5 - 2.40500240500248e-06*G0_4_1_1_0 - 9.62000962000995e-06*G0_4_1_1_2 + 3.84800384800398e-05*G0_4_1_1_3 + 4.81000481000497e-05*G0_4_1_1_4 + 5.77200577200597e-05*G0_4_1_1_5 + 4.81000481000498e-06*G0_4_1_2_0 - 9.62000962000995e-06*G0_4_1_2_1 - 9.62000962000995e-06*G0_4_1_2_2 + 9.62000962000995e-06*G0_4_1_2_3 + 2.88600288600299e-05*G0_4_1_2_4 + 2.88600288600299e-05*G0_4_1_2_5 + 9.62000962000993e-06*G0_4_1_3_0 + 3.84800384800398e-05*G0_4_1_3_1 + 9.62000962000996e-06*G0_4_1_3_2 - 7.69600769600795e-05*G0_4_1_3_3 - 0.000115440115440119*G0_4_1_3_4 - 7.69600769600796e-05*G0_4_1_3_5 + 4.81000481000497e-05*G0_4_1_4_1 + 2.88600288600299e-05*G0_4_1_4_2 - 0.000115440115440119*G0_4_1_4_3 - 0.000230880230880239*G0_4_1_4_4 - 0.000153920153920159*G0_4_1_4_5 - 1.92400192400199e-05*G0_4_1_5_0 + 5.77200577200597e-05*G0_4_1_5_1 + 2.88600288600299e-05*G0_4_1_5_2 - 7.69600769600796e-05*G0_4_1_5_3 - 0.000153920153920159*G0_4_1_5_4 - 0.000153920153920159*G0_4_1_5_5 - 1.92400192400199e-05*G0_4_2_0_0 + 4.81000481000498e-06*G0_4_2_0_1 - 2.40500240500249e-06*G0_4_2_0_2 + 9.62000962000994e-06*G0_4_2_0_3 - 1.92400192400199e-05*G0_4_2_0_4 + 4.81000481000498e-06*G0_4_2_1_0 - 9.62000962000995e-06*G0_4_2_1_1 - 9.62000962000995e-06*G0_4_2_1_2 + 9.62000962000996e-06*G0_4_2_1_3 + 2.88600288600299e-05*G0_4_2_1_4 + 2.88600288600299e-05*G0_4_2_1_5 - 2.40500240500249e-06*G0_4_2_2_0 - 9.62000962000995e-06*G0_4_2_2_1 + 3.84800384800398e-05*G0_4_2_2_3 + 5.77200577200597e-05*G0_4_2_2_4 + 4.81000481000498e-05*G0_4_2_2_5 + 9.62000962000994e-06*G0_4_2_3_0 + 9.62000962000996e-06*G0_4_2_3_1 + 3.84800384800398e-05*G0_4_2_3_2 - 7.69600769600796e-05*G0_4_2_3_3 - 7.69600769600796e-05*G0_4_2_3_4 - 0.000115440115440119*G0_4_2_3_5 - 1.92400192400199e-05*G0_4_2_4_0 + 2.88600288600299e-05*G0_4_2_4_1 + 5.77200577200597e-05*G0_4_2_4_2 - 7.69600769600796e-05*G0_4_2_4_3 - 0.000153920153920159*G0_4_2_4_4 - 0.000153920153920159*G0_4_2_4_5 + 2.88600288600299e-05*G0_4_2_5_1 + 4.81000481000498e-05*G0_4_2_5_2 - 0.000115440115440119*G0_4_2_5_3 - 0.000153920153920159*G0_4_2_5_4 - 0.000230880230880239*G0_4_2_5_5 + 3.84800384800398e-05*G0_4_3_0_0 + 9.62000962000993e-06*G0_4_3_0_1 + 9.62000962000994e-06*G0_4_3_0_2 - 0.000115440115440119*G0_4_3_0_3 - 7.69600769600795e-05*G0_4_3_0_4 - 7.69600769600795e-05*G0_4_3_0_5 + 9.62000962000993e-06*G0_4_3_1_0 + 3.84800384800398e-05*G0_4_3_1_1 + 9.62000962000996e-06*G0_4_3_1_2 - 7.69600769600795e-05*G0_4_3_1_3 - 0.000115440115440119*G0_4_3_1_4 - 7.69600769600796e-05*G0_4_3_1_5 + 9.62000962000994e-06*G0_4_3_2_0 + 9.62000962000996e-06*G0_4_3_2_1 + 3.84800384800398e-05*G0_4_3_2_2 - 7.69600769600796e-05*G0_4_3_2_3 - 7.69600769600796e-05*G0_4_3_2_4 - 0.000115440115440119*G0_4_3_2_5 - 0.000115440115440119*G0_4_3_3_0 - 7.69600769600795e-05*G0_4_3_3_1 - 7.69600769600796e-05*G0_4_3_3_2 + 0.000615680615680636*G0_4_3_3_3 + 0.000461760461760477*G0_4_3_3_4 + 0.000461760461760477*G0_4_3_3_5 - 7.69600769600795e-05*G0_4_3_4_0 - 0.000115440115440119*G0_4_3_4_1 - 7.69600769600796e-05*G0_4_3_4_2 + 0.000461760461760477*G0_4_3_4_3 + 0.000615680615680637*G0_4_3_4_4 + 0.000461760461760477*G0_4_3_4_5 - 7.69600769600795e-05*G0_4_3_5_0 - 7.69600769600796e-05*G0_4_3_5_1 - 0.000115440115440119*G0_4_3_5_2 + 0.000461760461760477*G0_4_3_5_3 + 0.000461760461760477*G0_4_3_5_4 + 0.000615680615680636*G0_4_3_5_5 + 9.62000962000995e-05*G0_4_4_0_0 - 1.92400192400199e-05*G0_4_4_0_2 - 7.69600769600795e-05*G0_4_4_0_3 + 4.81000481000497e-05*G0_4_4_1_1 + 2.88600288600299e-05*G0_4_4_1_2 - 0.000115440115440119*G0_4_4_1_3 - 0.000230880230880239*G0_4_4_1_4 - 0.000153920153920159*G0_4_4_1_5 - 1.92400192400199e-05*G0_4_4_2_0 + 2.88600288600299e-05*G0_4_4_2_1 + 5.77200577200597e-05*G0_4_4_2_2 - 7.69600769600796e-05*G0_4_4_2_3 - 0.000153920153920159*G0_4_4_2_4 - 0.000153920153920159*G0_4_4_2_5 - 7.69600769600795e-05*G0_4_4_3_0 - 0.000115440115440119*G0_4_4_3_1 - 7.69600769600796e-05*G0_4_4_3_2 + 0.000461760461760477*G0_4_4_3_3 + 0.000615680615680637*G0_4_4_3_4 + 0.000461760461760478*G0_4_4_3_5 - 0.000230880230880239*G0_4_4_4_1 - 0.000153920153920159*G0_4_4_4_2 + 0.000615680615680637*G0_4_4_4_3 + 0.00153920153920159*G0_4_4_4_4 + 0.000769600769600796*G0_4_4_4_5 - 0.000153920153920159*G0_4_4_5_1 - 0.000153920153920159*G0_4_4_5_2 + 0.000461760461760477*G0_4_4_5_3 + 0.000769600769600796*G0_4_4_5_4 + 0.000769600769600796*G0_4_4_5_5 + 9.62000962000995e-05*G0_4_5_0_0 - 1.92400192400199e-05*G0_4_5_0_1 - 7.69600769600795e-05*G0_4_5_0_3 - 1.92400192400199e-05*G0_4_5_1_0 + 5.77200577200597e-05*G0_4_5_1_1 + 2.88600288600299e-05*G0_4_5_1_2 - 7.69600769600796e-05*G0_4_5_1_3 - 0.000153920153920159*G0_4_5_1_4 - 0.000153920153920159*G0_4_5_1_5 + 2.88600288600299e-05*G0_4_5_2_1 + 4.81000481000498e-05*G0_4_5_2_2 - 0.000115440115440119*G0_4_5_2_3 - 0.000153920153920159*G0_4_5_2_4 - 0.000230880230880239*G0_4_5_2_5 - 7.69600769600795e-05*G0_4_5_3_0 - 7.69600769600796e-05*G0_4_5_3_1 - 0.000115440115440119*G0_4_5_3_2 + 0.000461760461760477*G0_4_5_3_3 + 0.000461760461760477*G0_4_5_3_4 + 0.000615680615680636*G0_4_5_3_5 - 0.000153920153920159*G0_4_5_4_1 - 0.000153920153920159*G0_4_5_4_2 + 0.000461760461760477*G0_4_5_4_3 + 0.000769600769600796*G0_4_5_4_4 + 0.000769600769600796*G0_4_5_4_5 - 0.000153920153920159*G0_4_5_5_1 - 0.000230880230880239*G0_4_5_5_2 + 0.000615680615680636*G0_4_5_5_3 + 0.000769600769600796*G0_4_5_5_4 + 0.00153920153920159*G0_4_5_5_5 + 0.00014430014430015*G0_5_0_0_0 - 2.88600288600299e-05*G0_5_0_0_1 - 2.88600288600299e-05*G0_5_0_0_2 + 5.77200577200597e-05*G0_5_0_0_3 + 9.62000962000995e-05*G0_5_0_0_4 + 0.000288600288600299*G0_5_0_0_5 - 2.88600288600299e-05*G0_5_0_1_0 - 2.88600288600299e-05*G0_5_0_1_1 + 1.20250120250124e-05*G0_5_0_1_2 - 1.92400192400199e-05*G0_5_0_1_3 - 1.92400192400199e-05*G0_5_0_1_4 - 0.000153920153920159*G0_5_0_1_5 - 2.88600288600299e-05*G0_5_0_2_0 + 1.20250120250124e-05*G0_5_0_2_1 - 4.81000481000497e-06*G0_5_0_2_2 + 2.88600288600298e-05*G0_5_0_2_3 + 1.92400192400198e-05*G0_5_0_2_5 + 5.77200577200597e-05*G0_5_0_3_0 - 1.92400192400199e-05*G0_5_0_3_1 + 2.88600288600298e-05*G0_5_0_3_2 - 0.000153920153920159*G0_5_0_3_3 - 7.69600769600795e-05*G0_5_0_3_4 - 0.000153920153920159*G0_5_0_3_5 + 9.62000962000995e-05*G0_5_0_4_0 - 1.92400192400199e-05*G0_5_0_4_1 - 7.69600769600795e-05*G0_5_0_4_3 + 0.000288600288600299*G0_5_0_5_0 - 0.000153920153920159*G0_5_0_5_1 + 1.92400192400198e-05*G0_5_0_5_2 - 0.000153920153920159*G0_5_0_5_3 - 2.88600288600299e-05*G0_5_1_0_0 - 2.88600288600299e-05*G0_5_1_0_1 + 1.20250120250124e-05*G0_5_1_0_2 - 1.92400192400199e-05*G0_5_1_0_3 - 1.92400192400199e-05*G0_5_1_0_4 - 0.000153920153920159*G0_5_1_0_5 - 2.88600288600299e-05*G0_5_1_1_0 + 0.00014430014430015*G0_5_1_1_1 - 2.88600288600299e-05*G0_5_1_1_2 + 9.62000962000996e-05*G0_5_1_1_3 + 5.77200577200597e-05*G0_5_1_1_4 + 0.000288600288600299*G0_5_1_1_5 + 1.20250120250124e-05*G0_5_1_2_0 - 2.88600288600299e-05*G0_5_1_2_1 - 4.81000481000497e-06*G0_5_1_2_2 + 2.88600288600299e-05*G0_5_1_2_4 + 1.92400192400199e-05*G0_5_1_2_5 - 1.92400192400199e-05*G0_5_1_3_0 + 9.62000962000996e-05*G0_5_1_3_1 - 7.69600769600796e-05*G0_5_1_3_4 - 1.92400192400199e-05*G0_5_1_4_0 + 5.77200577200597e-05*G0_5_1_4_1 + 2.88600288600299e-05*G0_5_1_4_2 - 7.69600769600796e-05*G0_5_1_4_3 - 0.000153920153920159*G0_5_1_4_4 - 0.000153920153920159*G0_5_1_4_5 - 0.000153920153920159*G0_5_1_5_0 + 0.000288600288600299*G0_5_1_5_1 + 1.92400192400199e-05*G0_5_1_5_2 - 0.000153920153920159*G0_5_1_5_4 - 2.88600288600299e-05*G0_5_2_0_0 + 1.20250120250124e-05*G0_5_2_0_1 - 4.81000481000497e-06*G0_5_2_0_2 + 2.88600288600298e-05*G0_5_2_0_3 + 1.92400192400198e-05*G0_5_2_0_5 + 1.20250120250124e-05*G0_5_2_1_0 - 2.88600288600299e-05*G0_5_2_1_1 - 4.81000481000497e-06*G0_5_2_1_2 + 2.88600288600299e-05*G0_5_2_1_4 + 1.92400192400199e-05*G0_5_2_1_5 - 4.81000481000497e-06*G0_5_2_2_0 - 4.81000481000497e-06*G0_5_2_2_1 - 1.44300144300149e-05*G0_5_2_2_2 + 4.81000481000498e-05*G0_5_2_2_3 + 4.81000481000498e-05*G0_5_2_2_4 + 8.65800865800896e-05*G0_5_2_2_5 + 2.88600288600298e-05*G0_5_2_3_0 + 4.81000481000498e-05*G0_5_2_3_2 - 0.000153920153920159*G0_5_2_3_3 - 0.000115440115440119*G0_5_2_3_4 - 0.000230880230880239*G0_5_2_3_5 + 2.88600288600299e-05*G0_5_2_4_1 + 4.81000481000498e-05*G0_5_2_4_2 - 0.000115440115440119*G0_5_2_4_3 - 0.000153920153920159*G0_5_2_4_4 - 0.000230880230880239*G0_5_2_4_5 + 1.92400192400198e-05*G0_5_2_5_0 + 1.92400192400199e-05*G0_5_2_5_1 + 8.65800865800896e-05*G0_5_2_5_2 - 0.000230880230880239*G0_5_2_5_3 - 0.000230880230880239*G0_5_2_5_4 - 0.000615680615680637*G0_5_2_5_5 + 5.77200577200597e-05*G0_5_3_0_0 - 1.92400192400199e-05*G0_5_3_0_1 + 2.88600288600298e-05*G0_5_3_0_2 - 0.000153920153920159*G0_5_3_0_3 - 7.69600769600795e-05*G0_5_3_0_4 - 0.000153920153920159*G0_5_3_0_5 - 1.92400192400199e-05*G0_5_3_1_0 + 9.62000962000996e-05*G0_5_3_1_1 - 7.69600769600796e-05*G0_5_3_1_4 + 2.88600288600298e-05*G0_5_3_2_0 + 4.81000481000497e-05*G0_5_3_2_2 - 0.000153920153920159*G0_5_3_2_3 - 0.000115440115440119*G0_5_3_2_4 - 0.000230880230880239*G0_5_3_2_5 - 0.000153920153920159*G0_5_3_3_0 - 0.000153920153920159*G0_5_3_3_2 + 0.000769600769600796*G0_5_3_3_3 + 0.000461760461760477*G0_5_3_3_4 + 0.000769600769600796*G0_5_3_3_5 - 7.69600769600795e-05*G0_5_3_4_0 - 7.69600769600796e-05*G0_5_3_4_1 - 0.000115440115440119*G0_5_3_4_2 + 0.000461760461760477*G0_5_3_4_3 + 0.000461760461760477*G0_5_3_4_4 + 0.000615680615680636*G0_5_3_4_5 - 0.000153920153920159*G0_5_3_5_0 - 0.000230880230880239*G0_5_3_5_2 + 0.000769600769600796*G0_5_3_5_3 + 0.000615680615680636*G0_5_3_5_4 + 0.00153920153920159*G0_5_3_5_5 + 9.62000962000995e-05*G0_5_4_0_0 - 1.92400192400199e-05*G0_5_4_0_1 - 7.69600769600795e-05*G0_5_4_0_3 - 1.92400192400199e-05*G0_5_4_1_0 + 5.77200577200597e-05*G0_5_4_1_1 + 2.88600288600299e-05*G0_5_4_1_2 - 7.69600769600796e-05*G0_5_4_1_3 - 0.000153920153920159*G0_5_4_1_4 - 0.000153920153920159*G0_5_4_1_5 + 2.88600288600299e-05*G0_5_4_2_1 + 4.81000481000498e-05*G0_5_4_2_2 - 0.000115440115440119*G0_5_4_2_3 - 0.000153920153920159*G0_5_4_2_4 - 0.000230880230880239*G0_5_4_2_5 - 7.69600769600795e-05*G0_5_4_3_0 - 7.69600769600796e-05*G0_5_4_3_1 - 0.000115440115440119*G0_5_4_3_2 + 0.000461760461760477*G0_5_4_3_3 + 0.000461760461760477*G0_5_4_3_4 + 0.000615680615680636*G0_5_4_3_5 - 0.000153920153920159*G0_5_4_4_1 - 0.000153920153920159*G0_5_4_4_2 + 0.000461760461760477*G0_5_4_4_3 + 0.000769600769600796*G0_5_4_4_4 + 0.000769600769600796*G0_5_4_4_5 - 0.000153920153920159*G0_5_4_5_1 - 0.000230880230880239*G0_5_4_5_2 + 0.000615680615680636*G0_5_4_5_3 + 0.000769600769600796*G0_5_4_5_4 + 0.00153920153920159*G0_5_4_5_5 + 0.000288600288600299*G0_5_5_0_0 - 0.000153920153920159*G0_5_5_0_1 + 1.92400192400198e-05*G0_5_5_0_2 - 0.000153920153920159*G0_5_5_0_3 - 0.000153920153920159*G0_5_5_1_0 + 0.000288600288600299*G0_5_5_1_1 + 1.92400192400199e-05*G0_5_5_1_2 - 0.000153920153920159*G0_5_5_1_4 + 1.92400192400198e-05*G0_5_5_2_0 + 1.92400192400199e-05*G0_5_5_2_1 + 8.65800865800896e-05*G0_5_5_2_2 - 0.000230880230880239*G0_5_5_2_3 - 0.000230880230880239*G0_5_5_2_4 - 0.000615680615680637*G0_5_5_2_5 - 0.000153920153920159*G0_5_5_3_0 - 0.000230880230880239*G0_5_5_3_2 + 0.000769600769600796*G0_5_5_3_3 + 0.000615680615680636*G0_5_5_3_4 + 0.00153920153920159*G0_5_5_3_5 - 0.000153920153920159*G0_5_5_4_1 - 0.000230880230880239*G0_5_5_4_2 + 0.000615680615680636*G0_5_5_4_3 + 0.000769600769600796*G0_5_5_4_4 + 0.00153920153920159*G0_5_5_4_5 - 0.000615680615680637*G0_5_5_5_2 + 0.00153920153920159*G0_5_5_5_3 + 0.00153920153920159*G0_5_5_5_4 + 0.00769600769600797*G0_5_5_5_5; + A[5] = A[1] - 0.000216450216450224*G0_0_0_0_0 + 3.42712842712855e-05*G0_0_0_0_1 + 1.62337662337668e-05*G0_0_0_0_2 - 1.44300144300149e-05*G0_0_0_0_3 - 7.21500721500747e-05*G0_0_0_0_4 - 0.000144300144300149*G0_0_0_0_5 + 3.42712842712855e-05*G0_0_0_1_0 - 1.08225108225112e-05*G0_0_0_1_1 + 9.62000962000996e-06*G0_0_0_1_4 + 2.64550264550274e-05*G0_0_0_1_5 + 1.62337662337668e-05*G0_0_0_2_0 + 1.68350168350174e-05*G0_0_0_2_4 + 1.92400192400199e-05*G0_0_0_2_5 - 1.44300144300149e-05*G0_0_0_3_0 + 3.84800384800397e-05*G0_0_0_3_3 + 9.62000962000993e-06*G0_0_0_3_4 - 9.62000962000999e-06*G0_0_0_3_5 - 7.21500721500747e-05*G0_0_0_4_0 + 9.62000962000996e-06*G0_0_0_4_1 + 1.68350168350174e-05*G0_0_0_4_2 + 9.62000962000993e-06*G0_0_0_4_3 - 3.84800384800398e-05*G0_0_0_4_4 - 5.77200577200597e-05*G0_0_0_4_5 - 0.000144300144300149*G0_0_0_5_0 + 2.64550264550274e-05*G0_0_0_5_1 + 1.92400192400199e-05*G0_0_0_5_2 - 9.62000962000999e-06*G0_0_0_5_3 - 5.77200577200597e-05*G0_0_0_5_4 - 0.000230880230880239*G0_0_0_5_5 + 3.42712842712855e-05*G0_0_1_0_0 - 1.08225108225112e-05*G0_0_1_0_1 + 9.62000962000996e-06*G0_0_1_0_4 + 2.64550264550274e-05*G0_0_1_0_5 - 1.08225108225112e-05*G0_0_1_1_0 + 1.80375180375187e-05*G0_0_1_1_1 - 9.62000962000997e-06*G0_0_1_1_3 + 9.62000962000995e-06*G0_0_1_1_5 + 7.21500721500747e-06*G0_0_1_2_3 - 7.21500721500747e-06*G0_0_1_2_5 - 9.62000962000997e-06*G0_0_1_3_1 + 7.21500721500747e-06*G0_0_1_3_2 + 1.92400192400198e-05*G0_0_1_3_3 + 1.92400192400199e-05*G0_0_1_3_4 + 1.92400192400199e-05*G0_0_1_3_5 + 9.62000962000996e-06*G0_0_1_4_0 + 1.92400192400199e-05*G0_0_1_4_3 + 2.88600288600298e-05*G0_0_1_4_4 + 2.88600288600298e-05*G0_0_1_4_5 + 2.64550264550274e-05*G0_0_1_5_0 + 9.62000962000995e-06*G0_0_1_5_1 - 7.21500721500747e-06*G0_0_1_5_2 + 1.92400192400199e-05*G0_0_1_5_3 + 2.88600288600298e-05*G0_0_1_5_4 + 0.00013468013468014*G0_0_1_5_5 + 1.62337662337668e-05*G0_0_2_0_0 + 1.68350168350174e-05*G0_0_2_0_4 + 1.92400192400199e-05*G0_0_2_0_5 + 7.21500721500747e-06*G0_0_2_1_3 - 7.21500721500747e-06*G0_0_2_1_5 - 1.62337662337668e-05*G0_0_2_2_2 - 1.92400192400199e-05*G0_0_2_2_3 - 1.68350168350174e-05*G0_0_2_2_4 + 7.21500721500747e-06*G0_0_2_3_1 - 1.92400192400199e-05*G0_0_2_3_2 - 9.62000962000993e-06*G0_0_2_3_3 + 1.68350168350174e-05*G0_0_2_4_0 - 1.68350168350174e-05*G0_0_2_4_2 + 1.92400192400199e-05*G0_0_2_5_0 - 7.21500721500747e-06*G0_0_2_5_1 + 9.62000962001001e-06*G0_0_2_5_5 - 1.44300144300149e-05*G0_0_3_0_0 + 3.84800384800397e-05*G0_0_3_0_3 + 9.62000962000992e-06*G0_0_3_0_4 - 9.62000962000999e-06*G0_0_3_0_5 - 9.62000962000997e-06*G0_0_3_1_1 + 7.21500721500747e-06*G0_0_3_1_2 + 1.92400192400198e-05*G0_0_3_1_3 + 1.92400192400199e-05*G0_0_3_1_4 + 1.92400192400199e-05*G0_0_3_1_5 + 7.21500721500747e-06*G0_0_3_2_1 - 1.92400192400199e-05*G0_0_3_2_2 - 9.62000962000993e-06*G0_0_3_2_3 + 3.84800384800397e-05*G0_0_3_3_0 + 1.92400192400198e-05*G0_0_3_3_1 - 9.62000962000993e-06*G0_0_3_3_2 - 0.000384800384800398*G0_0_3_3_3 - 0.000115440115440119*G0_0_3_3_4 - 7.69600769600796e-05*G0_0_3_3_5 + 9.62000962000992e-06*G0_0_3_4_0 + 1.92400192400199e-05*G0_0_3_4_1 - 0.000115440115440119*G0_0_3_4_3 - 7.69600769600796e-05*G0_0_3_4_4 - 3.84800384800398e-05*G0_0_3_4_5 - 9.62000962000999e-06*G0_0_3_5_0 + 1.92400192400199e-05*G0_0_3_5_1 - 7.69600769600796e-05*G0_0_3_5_3 - 3.84800384800398e-05*G0_0_3_5_4 - 7.21500721500747e-05*G0_0_4_0_0 + 9.62000962000996e-06*G0_0_4_0_1 + 1.68350168350174e-05*G0_0_4_0_2 + 9.62000962000993e-06*G0_0_4_0_3 - 3.84800384800398e-05*G0_0_4_0_4 - 5.77200577200597e-05*G0_0_4_0_5 + 9.62000962000996e-06*G0_0_4_1_0 + 1.92400192400199e-05*G0_0_4_1_3 + 2.88600288600298e-05*G0_0_4_1_4 + 2.88600288600298e-05*G0_0_4_1_5 + 1.68350168350174e-05*G0_0_4_2_0 - 1.68350168350174e-05*G0_0_4_2_2 + 9.62000962000992e-06*G0_0_4_3_0 + 1.92400192400199e-05*G0_0_4_3_1 - 0.000115440115440119*G0_0_4_3_3 - 7.69600769600796e-05*G0_0_4_3_4 - 3.84800384800398e-05*G0_0_4_3_5 - 3.84800384800398e-05*G0_0_4_4_0 + 2.88600288600298e-05*G0_0_4_4_1 - 7.69600769600796e-05*G0_0_4_4_3 - 0.000153920153920159*G0_0_4_4_4 - 7.69600769600796e-05*G0_0_4_4_5 - 5.77200577200597e-05*G0_0_4_5_0 + 2.88600288600298e-05*G0_0_4_5_1 - 3.84800384800398e-05*G0_0_4_5_3 - 7.69600769600796e-05*G0_0_4_5_4 - 7.69600769600797e-05*G0_0_4_5_5 - 0.000144300144300149*G0_0_5_0_0 + 2.64550264550274e-05*G0_0_5_0_1 + 1.92400192400199e-05*G0_0_5_0_2 - 9.62000962000999e-06*G0_0_5_0_3 - 5.77200577200597e-05*G0_0_5_0_4 - 0.000230880230880239*G0_0_5_0_5 + 2.64550264550274e-05*G0_0_5_1_0 + 9.62000962000996e-06*G0_0_5_1_1 - 7.21500721500747e-06*G0_0_5_1_2 + 1.92400192400199e-05*G0_0_5_1_3 + 2.88600288600298e-05*G0_0_5_1_4 + 0.00013468013468014*G0_0_5_1_5 + 1.92400192400199e-05*G0_0_5_2_0 - 7.21500721500747e-06*G0_0_5_2_1 + 9.62000962001001e-06*G0_0_5_2_5 - 9.62000962000998e-06*G0_0_5_3_0 + 1.92400192400199e-05*G0_0_5_3_1 - 7.69600769600796e-05*G0_0_5_3_3 - 3.84800384800398e-05*G0_0_5_3_4 - 5.77200577200597e-05*G0_0_5_4_0 + 2.88600288600299e-05*G0_0_5_4_1 - 3.84800384800398e-05*G0_0_5_4_3 - 7.69600769600796e-05*G0_0_5_4_4 - 7.69600769600797e-05*G0_0_5_4_5 - 0.000230880230880239*G0_0_5_5_0 + 0.00013468013468014*G0_0_5_5_1 + 9.62000962001002e-06*G0_0_5_5_2 - 7.69600769600797e-05*G0_0_5_5_4 - 0.00015392015392016*G0_0_5_5_5 + 3.42712842712855e-05*G0_1_0_0_0 - 1.08225108225112e-05*G0_1_0_0_1 + 9.62000962000996e-06*G0_1_0_0_4 + 2.64550264550274e-05*G0_1_0_0_5 - 1.08225108225112e-05*G0_1_0_1_0 + 1.80375180375187e-05*G0_1_0_1_1 - 9.62000962000997e-06*G0_1_0_1_3 + 9.62000962000996e-06*G0_1_0_1_5 + 7.21500721500747e-06*G0_1_0_2_3 - 7.21500721500747e-06*G0_1_0_2_5 - 9.62000962000997e-06*G0_1_0_3_1 + 7.21500721500747e-06*G0_1_0_3_2 + 1.92400192400198e-05*G0_1_0_3_3 + 1.92400192400199e-05*G0_1_0_3_4 + 1.92400192400199e-05*G0_1_0_3_5 + 9.62000962000996e-06*G0_1_0_4_0 + 1.92400192400199e-05*G0_1_0_4_3 + 2.88600288600298e-05*G0_1_0_4_4 + 2.88600288600298e-05*G0_1_0_4_5 + 2.64550264550274e-05*G0_1_0_5_0 + 9.62000962000996e-06*G0_1_0_5_1 - 7.21500721500747e-06*G0_1_0_5_2 + 1.92400192400199e-05*G0_1_0_5_3 + 2.88600288600298e-05*G0_1_0_5_4 + 0.00013468013468014*G0_1_0_5_5 - 1.08225108225112e-05*G0_1_1_0_0 + 1.80375180375187e-05*G0_1_1_0_1 - 9.62000962000996e-06*G0_1_1_0_3 + 9.62000962000996e-06*G0_1_1_0_5 + 1.80375180375187e-05*G0_1_1_1_0 - 1.80375180375186e-05*G0_1_1_1_2 + 7.21500721500745e-05*G0_1_1_1_3 - 7.21500721500748e-05*G0_1_1_1_5 - 1.80375180375186e-05*G0_1_1_2_1 + 1.08225108225112e-05*G0_1_1_2_2 - 9.62000962000996e-06*G0_1_1_2_3 + 9.62000962000994e-06*G0_1_1_2_5 - 9.62000962000997e-06*G0_1_1_3_0 + 7.21500721500745e-05*G0_1_1_3_1 - 9.62000962000997e-06*G0_1_1_3_2 + 0.000192400192400199*G0_1_1_3_3 + 1.92400192400199e-05*G0_1_1_3_4 + 1.92400192400199e-05*G0_1_1_4_3 - 1.92400192400199e-05*G0_1_1_4_5 + 9.62000962000996e-06*G0_1_1_5_0 - 7.21500721500748e-05*G0_1_1_5_1 + 9.62000962000994e-06*G0_1_1_5_2 - 1.92400192400199e-05*G0_1_1_5_4 - 0.000192400192400199*G0_1_1_5_5 + 7.21500721500746e-06*G0_1_2_0_3 - 7.21500721500747e-06*G0_1_2_0_5 - 1.80375180375186e-05*G0_1_2_1_1 + 1.08225108225112e-05*G0_1_2_1_2 - 9.62000962000997e-06*G0_1_2_1_3 + 9.62000962000994e-06*G0_1_2_1_5 + 1.08225108225112e-05*G0_1_2_2_1 - 3.42712842712855e-05*G0_1_2_2_2 - 2.64550264550274e-05*G0_1_2_2_3 - 9.62000962000995e-06*G0_1_2_2_4 + 7.21500721500747e-06*G0_1_2_3_0 - 9.62000962000997e-06*G0_1_2_3_1 - 2.64550264550274e-05*G0_1_2_3_2 - 0.000134680134680139*G0_1_2_3_3 - 2.88600288600299e-05*G0_1_2_3_4 - 1.92400192400199e-05*G0_1_2_3_5 - 9.62000962000995e-06*G0_1_2_4_2 - 2.88600288600299e-05*G0_1_2_4_3 - 2.88600288600299e-05*G0_1_2_4_4 - 1.92400192400199e-05*G0_1_2_4_5 - 7.21500721500747e-06*G0_1_2_5_0 + 9.62000962000994e-06*G0_1_2_5_1 - 1.92400192400199e-05*G0_1_2_5_3 - 1.92400192400199e-05*G0_1_2_5_4 - 1.92400192400199e-05*G0_1_2_5_5 - 9.62000962000997e-06*G0_1_3_0_1 + 7.21500721500747e-06*G0_1_3_0_2 + 1.92400192400198e-05*G0_1_3_0_3 + 1.92400192400199e-05*G0_1_3_0_4 + 1.92400192400199e-05*G0_1_3_0_5 - 9.62000962000997e-06*G0_1_3_1_0 + 7.21500721500745e-05*G0_1_3_1_1 - 9.62000962000997e-06*G0_1_3_1_2 + 0.000192400192400199*G0_1_3_1_3 + 1.92400192400199e-05*G0_1_3_1_4 + 7.21500721500747e-06*G0_1_3_2_0 - 9.62000962000996e-06*G0_1_3_2_1 - 2.64550264550274e-05*G0_1_3_2_2 - 0.000134680134680139*G0_1_3_2_3 - 2.88600288600299e-05*G0_1_3_2_4 - 1.92400192400199e-05*G0_1_3_2_5 + 1.92400192400198e-05*G0_1_3_3_0 + 0.000192400192400199*G0_1_3_3_1 - 0.000134680134680139*G0_1_3_3_2 - 7.69600769600795e-05*G0_1_3_3_4 + 1.92400192400199e-05*G0_1_3_4_0 + 1.92400192400199e-05*G0_1_3_4_1 - 2.88600288600299e-05*G0_1_3_4_2 - 7.69600769600795e-05*G0_1_3_4_3 - 3.84800384800398e-05*G0_1_3_4_4 + 1.92400192400199e-05*G0_1_3_5_0 - 1.92400192400199e-05*G0_1_3_5_2 + 9.62000962000996e-06*G0_1_4_0_0 + 1.92400192400199e-05*G0_1_4_0_3 + 2.88600288600298e-05*G0_1_4_0_4 + 2.88600288600298e-05*G0_1_4_0_5 + 1.92400192400199e-05*G0_1_4_1_3 - 1.92400192400199e-05*G0_1_4_1_5 - 9.62000962000995e-06*G0_1_4_2_2 - 2.88600288600299e-05*G0_1_4_2_3 - 2.88600288600299e-05*G0_1_4_2_4 - 1.92400192400199e-05*G0_1_4_2_5 + 1.92400192400199e-05*G0_1_4_3_0 + 1.92400192400199e-05*G0_1_4_3_1 - 2.88600288600299e-05*G0_1_4_3_2 - 7.69600769600795e-05*G0_1_4_3_3 - 3.84800384800398e-05*G0_1_4_3_4 + 2.88600288600298e-05*G0_1_4_4_0 - 2.88600288600299e-05*G0_1_4_4_2 - 3.84800384800398e-05*G0_1_4_4_3 + 3.84800384800399e-05*G0_1_4_4_5 + 2.88600288600299e-05*G0_1_4_5_0 - 1.92400192400199e-05*G0_1_4_5_1 - 1.92400192400199e-05*G0_1_4_5_2 + 3.84800384800399e-05*G0_1_4_5_4 + 7.69600769600796e-05*G0_1_4_5_5 + 2.64550264550274e-05*G0_1_5_0_0 + 9.62000962000996e-06*G0_1_5_0_1 - 7.21500721500747e-06*G0_1_5_0_2 + 1.92400192400199e-05*G0_1_5_0_3 + 2.88600288600298e-05*G0_1_5_0_4 + 0.00013468013468014*G0_1_5_0_5 + 9.62000962000995e-06*G0_1_5_1_0 - 7.21500721500748e-05*G0_1_5_1_1 + 9.62000962000994e-06*G0_1_5_1_2 - 1.92400192400199e-05*G0_1_5_1_4 - 0.000192400192400199*G0_1_5_1_5 - 7.21500721500747e-06*G0_1_5_2_0 + 9.62000962000995e-06*G0_1_5_2_1 - 1.92400192400199e-05*G0_1_5_2_3 - 1.92400192400199e-05*G0_1_5_2_4 - 1.92400192400199e-05*G0_1_5_2_5 + 1.92400192400199e-05*G0_1_5_3_0 - 1.92400192400199e-05*G0_1_5_3_2 + 2.88600288600299e-05*G0_1_5_4_0 - 1.92400192400199e-05*G0_1_5_4_1 - 1.92400192400199e-05*G0_1_5_4_2 + 3.84800384800399e-05*G0_1_5_4_4 + 7.69600769600796e-05*G0_1_5_4_5 + 0.00013468013468014*G0_1_5_5_0 - 0.000192400192400199*G0_1_5_5_1 - 1.92400192400199e-05*G0_1_5_5_2 + 7.69600769600796e-05*G0_1_5_5_4 + 1.62337662337668e-05*G0_2_0_0_0 + 1.68350168350174e-05*G0_2_0_0_4 + 1.92400192400199e-05*G0_2_0_0_5 + 7.21500721500747e-06*G0_2_0_1_3 - 7.21500721500747e-06*G0_2_0_1_5 - 1.62337662337668e-05*G0_2_0_2_2 - 1.92400192400199e-05*G0_2_0_2_3 - 1.68350168350174e-05*G0_2_0_2_4 + 7.21500721500747e-06*G0_2_0_3_1 - 1.92400192400199e-05*G0_2_0_3_2 - 9.62000962000993e-06*G0_2_0_3_3 + 1.68350168350174e-05*G0_2_0_4_0 - 1.68350168350174e-05*G0_2_0_4_2 + 1.92400192400199e-05*G0_2_0_5_0 - 7.21500721500747e-06*G0_2_0_5_1 + 9.62000962001001e-06*G0_2_0_5_5 + 7.21500721500747e-06*G0_2_1_0_3 - 7.21500721500747e-06*G0_2_1_0_5 - 1.80375180375186e-05*G0_2_1_1_1 + 1.08225108225112e-05*G0_2_1_1_2 - 9.62000962000996e-06*G0_2_1_1_3 + 9.62000962000994e-06*G0_2_1_1_5 + 1.08225108225112e-05*G0_2_1_2_1 - 3.42712842712855e-05*G0_2_1_2_2 - 2.64550264550273e-05*G0_2_1_2_3 - 9.62000962000995e-06*G0_2_1_2_4 + 7.21500721500747e-06*G0_2_1_3_0 - 9.62000962000996e-06*G0_2_1_3_1 - 2.64550264550274e-05*G0_2_1_3_2 - 0.000134680134680139*G0_2_1_3_3 - 2.88600288600299e-05*G0_2_1_3_4 - 1.92400192400199e-05*G0_2_1_3_5 - 9.62000962000995e-06*G0_2_1_4_2 - 2.88600288600299e-05*G0_2_1_4_3 - 2.88600288600299e-05*G0_2_1_4_4 - 1.92400192400199e-05*G0_2_1_4_5 - 7.21500721500747e-06*G0_2_1_5_0 + 9.62000962000994e-06*G0_2_1_5_1 - 1.92400192400199e-05*G0_2_1_5_3 - 1.92400192400199e-05*G0_2_1_5_4 - 1.92400192400199e-05*G0_2_1_5_5 - 1.62337662337668e-05*G0_2_2_0_2 - 1.92400192400199e-05*G0_2_2_0_3 - 1.68350168350174e-05*G0_2_2_0_4 + 1.08225108225112e-05*G0_2_2_1_1 - 3.42712842712855e-05*G0_2_2_1_2 - 2.64550264550274e-05*G0_2_2_1_3 - 9.62000962000995e-06*G0_2_2_1_4 - 1.62337662337668e-05*G0_2_2_2_0 - 3.42712842712855e-05*G0_2_2_2_1 + 0.000216450216450224*G0_2_2_2_2 + 0.000144300144300149*G0_2_2_2_3 + 7.21500721500747e-05*G0_2_2_2_4 + 1.44300144300149e-05*G0_2_2_2_5 - 1.92400192400199e-05*G0_2_2_3_0 - 2.64550264550274e-05*G0_2_2_3_1 + 0.000144300144300149*G0_2_2_3_2 + 0.000230880230880239*G0_2_2_3_3 + 5.77200577200597e-05*G0_2_2_3_4 + 9.62000962000997e-06*G0_2_2_3_5 - 1.68350168350174e-05*G0_2_2_4_0 - 9.62000962000995e-06*G0_2_2_4_1 + 7.21500721500747e-05*G0_2_2_4_2 + 5.77200577200597e-05*G0_2_2_4_3 + 3.84800384800399e-05*G0_2_2_4_4 - 9.62000962000995e-06*G0_2_2_4_5 + 1.44300144300149e-05*G0_2_2_5_2 + 9.62000962000997e-06*G0_2_2_5_3 - 9.62000962000995e-06*G0_2_2_5_4 - 3.84800384800398e-05*G0_2_2_5_5 + 7.21500721500747e-06*G0_2_3_0_1 - 1.92400192400199e-05*G0_2_3_0_2 - 9.62000962000993e-06*G0_2_3_0_3 + 7.21500721500747e-06*G0_2_3_1_0 - 9.62000962000996e-06*G0_2_3_1_1 - 2.64550264550274e-05*G0_2_3_1_2 - 0.000134680134680139*G0_2_3_1_3 - 2.88600288600299e-05*G0_2_3_1_4 - 1.92400192400199e-05*G0_2_3_1_5 - 1.92400192400199e-05*G0_2_3_2_0 - 2.64550264550274e-05*G0_2_3_2_1 + 0.000144300144300149*G0_2_3_2_2 + 0.000230880230880239*G0_2_3_2_3 + 5.77200577200597e-05*G0_2_3_2_4 + 9.62000962000997e-06*G0_2_3_2_5 - 9.62000962000993e-06*G0_2_3_3_0 - 0.000134680134680139*G0_2_3_3_1 + 0.000230880230880239*G0_2_3_3_2 + 0.000153920153920159*G0_2_3_3_3 + 7.69600769600797e-05*G0_2_3_3_4 - 2.88600288600299e-05*G0_2_3_4_1 + 5.77200577200597e-05*G0_2_3_4_2 + 7.69600769600797e-05*G0_2_3_4_3 + 7.69600769600797e-05*G0_2_3_4_4 + 3.84800384800398e-05*G0_2_3_4_5 - 1.92400192400199e-05*G0_2_3_5_1 + 9.62000962000998e-06*G0_2_3_5_2 + 3.84800384800398e-05*G0_2_3_5_4 + 7.69600769600796e-05*G0_2_3_5_5 + 1.68350168350174e-05*G0_2_4_0_0 - 1.68350168350174e-05*G0_2_4_0_2 - 9.62000962000995e-06*G0_2_4_1_2 - 2.88600288600299e-05*G0_2_4_1_3 - 2.88600288600299e-05*G0_2_4_1_4 - 1.92400192400199e-05*G0_2_4_1_5 - 1.68350168350174e-05*G0_2_4_2_0 - 9.62000962000995e-06*G0_2_4_2_1 + 7.21500721500747e-05*G0_2_4_2_2 + 5.77200577200597e-05*G0_2_4_2_3 + 3.84800384800399e-05*G0_2_4_2_4 - 9.62000962000995e-06*G0_2_4_2_5 - 2.88600288600299e-05*G0_2_4_3_1 + 5.77200577200597e-05*G0_2_4_3_2 + 7.69600769600797e-05*G0_2_4_3_3 + 7.69600769600797e-05*G0_2_4_3_4 + 3.84800384800398e-05*G0_2_4_3_5 - 2.88600288600299e-05*G0_2_4_4_1 + 3.84800384800399e-05*G0_2_4_4_2 + 7.69600769600797e-05*G0_2_4_4_3 + 0.000153920153920159*G0_2_4_4_4 + 7.69600769600796e-05*G0_2_4_4_5 - 1.92400192400199e-05*G0_2_4_5_1 - 9.62000962000995e-06*G0_2_4_5_2 + 3.84800384800398e-05*G0_2_4_5_3 + 7.69600769600796e-05*G0_2_4_5_4 + 0.000115440115440119*G0_2_4_5_5 + 1.92400192400199e-05*G0_2_5_0_0 - 7.21500721500747e-06*G0_2_5_0_1 + 9.62000962001001e-06*G0_2_5_0_5 - 7.21500721500747e-06*G0_2_5_1_0 + 9.62000962000994e-06*G0_2_5_1_1 - 1.92400192400199e-05*G0_2_5_1_3 - 1.92400192400199e-05*G0_2_5_1_4 - 1.92400192400199e-05*G0_2_5_1_5 + 1.44300144300149e-05*G0_2_5_2_2 + 9.62000962000998e-06*G0_2_5_2_3 - 9.62000962000995e-06*G0_2_5_2_4 - 3.84800384800398e-05*G0_2_5_2_5 - 1.92400192400199e-05*G0_2_5_3_1 + 9.62000962000998e-06*G0_2_5_3_2 + 3.84800384800398e-05*G0_2_5_3_4 + 7.69600769600796e-05*G0_2_5_3_5 - 1.92400192400199e-05*G0_2_5_4_1 - 9.62000962000995e-06*G0_2_5_4_2 + 3.84800384800398e-05*G0_2_5_4_3 + 7.69600769600795e-05*G0_2_5_4_4 + 0.000115440115440119*G0_2_5_4_5 + 9.62000962001002e-06*G0_2_5_5_0 - 1.92400192400199e-05*G0_2_5_5_1 - 3.84800384800398e-05*G0_2_5_5_2 + 7.69600769600796e-05*G0_2_5_5_3 + 0.000115440115440119*G0_2_5_5_4 + 0.000384800384800398*G0_2_5_5_5 - 1.44300144300149e-05*G0_3_0_0_0 + 3.84800384800397e-05*G0_3_0_0_3 + 9.62000962000992e-06*G0_3_0_0_4 - 9.62000962000998e-06*G0_3_0_0_5 - 9.62000962000997e-06*G0_3_0_1_1 + 7.21500721500747e-06*G0_3_0_1_2 + 1.92400192400198e-05*G0_3_0_1_3 + 1.92400192400199e-05*G0_3_0_1_4 + 1.92400192400199e-05*G0_3_0_1_5 + 7.21500721500747e-06*G0_3_0_2_1 - 1.92400192400199e-05*G0_3_0_2_2 - 9.62000962000993e-06*G0_3_0_2_3 + 3.84800384800397e-05*G0_3_0_3_0 + 1.92400192400198e-05*G0_3_0_3_1 - 9.62000962000992e-06*G0_3_0_3_2 - 0.000384800384800398*G0_3_0_3_3 - 0.000115440115440119*G0_3_0_3_4 - 7.69600769600796e-05*G0_3_0_3_5 + 9.62000962000991e-06*G0_3_0_4_0 + 1.92400192400199e-05*G0_3_0_4_1 - 0.000115440115440119*G0_3_0_4_3 - 7.69600769600796e-05*G0_3_0_4_4 - 3.84800384800398e-05*G0_3_0_4_5 - 9.62000962000998e-06*G0_3_0_5_0 + 1.92400192400199e-05*G0_3_0_5_1 - 7.69600769600796e-05*G0_3_0_5_3 - 3.84800384800398e-05*G0_3_0_5_4 - 9.62000962000997e-06*G0_3_1_0_1 + 7.21500721500747e-06*G0_3_1_0_2 + 1.92400192400198e-05*G0_3_1_0_3 + 1.92400192400199e-05*G0_3_1_0_4 + 1.92400192400199e-05*G0_3_1_0_5 - 9.62000962000997e-06*G0_3_1_1_0 + 7.21500721500745e-05*G0_3_1_1_1 - 9.62000962000997e-06*G0_3_1_1_2 + 0.000192400192400199*G0_3_1_1_3 + 1.92400192400199e-05*G0_3_1_1_4 + 7.21500721500746e-06*G0_3_1_2_0 - 9.62000962000996e-06*G0_3_1_2_1 - 2.64550264550274e-05*G0_3_1_2_2 - 0.000134680134680139*G0_3_1_2_3 - 2.88600288600299e-05*G0_3_1_2_4 - 1.92400192400199e-05*G0_3_1_2_5 + 1.92400192400198e-05*G0_3_1_3_0 + 0.000192400192400199*G0_3_1_3_1 - 0.000134680134680139*G0_3_1_3_2 - 7.69600769600795e-05*G0_3_1_3_4 + 1.92400192400199e-05*G0_3_1_4_0 + 1.92400192400199e-05*G0_3_1_4_1 - 2.88600288600299e-05*G0_3_1_4_2 - 7.69600769600795e-05*G0_3_1_4_3 - 3.84800384800398e-05*G0_3_1_4_4 + 1.92400192400199e-05*G0_3_1_5_0 - 1.92400192400199e-05*G0_3_1_5_2 + 7.21500721500747e-06*G0_3_2_0_1 - 1.92400192400199e-05*G0_3_2_0_2 - 9.62000962000992e-06*G0_3_2_0_3 + 7.21500721500747e-06*G0_3_2_1_0 - 9.62000962000996e-06*G0_3_2_1_1 - 2.64550264550274e-05*G0_3_2_1_2 - 0.000134680134680139*G0_3_2_1_3 - 2.88600288600299e-05*G0_3_2_1_4 - 1.92400192400199e-05*G0_3_2_1_5 - 1.92400192400199e-05*G0_3_2_2_0 - 2.64550264550274e-05*G0_3_2_2_1 + 0.000144300144300149*G0_3_2_2_2 + 0.000230880230880239*G0_3_2_2_3 + 5.77200577200597e-05*G0_3_2_2_4 + 9.62000962000997e-06*G0_3_2_2_5 - 9.62000962000993e-06*G0_3_2_3_0 - 0.000134680134680139*G0_3_2_3_1 + 0.000230880230880239*G0_3_2_3_2 + 0.000153920153920159*G0_3_2_3_3 + 7.69600769600797e-05*G0_3_2_3_4 - 2.88600288600299e-05*G0_3_2_4_1 + 5.77200577200597e-05*G0_3_2_4_2 + 7.69600769600796e-05*G0_3_2_4_3 + 7.69600769600797e-05*G0_3_2_4_4 + 3.84800384800398e-05*G0_3_2_4_5 - 1.92400192400199e-05*G0_3_2_5_1 + 9.62000962000998e-06*G0_3_2_5_2 + 3.84800384800398e-05*G0_3_2_5_4 + 7.69600769600796e-05*G0_3_2_5_5 + 3.84800384800397e-05*G0_3_3_0_0 + 1.92400192400198e-05*G0_3_3_0_1 - 9.62000962000993e-06*G0_3_3_0_2 - 0.000384800384800398*G0_3_3_0_3 - 0.000115440115440119*G0_3_3_0_4 - 7.69600769600796e-05*G0_3_3_0_5 + 1.92400192400198e-05*G0_3_3_1_0 + 0.000192400192400199*G0_3_3_1_1 - 0.000134680134680139*G0_3_3_1_2 - 7.69600769600795e-05*G0_3_3_1_4 - 9.62000962000993e-06*G0_3_3_2_0 - 0.000134680134680139*G0_3_3_2_1 + 0.000230880230880239*G0_3_3_2_2 + 0.000153920153920159*G0_3_3_2_3 + 7.69600769600796e-05*G0_3_3_2_4 - 0.000384800384800398*G0_3_3_3_0 + 0.000153920153920159*G0_3_3_3_2 + 0.00615680615680637*G0_3_3_3_3 + 0.000923520923520955*G0_3_3_3_4 + 0.000769600769600796*G0_3_3_3_5 - 0.000115440115440119*G0_3_3_4_0 - 7.69600769600795e-05*G0_3_3_4_1 + 7.69600769600796e-05*G0_3_3_4_2 + 0.000923520923520955*G0_3_3_4_3 + 0.000307840307840318*G0_3_3_4_4 + 0.000153920153920159*G0_3_3_4_5 - 7.69600769600796e-05*G0_3_3_5_0 + 0.000769600769600796*G0_3_3_5_3 + 0.000153920153920159*G0_3_3_5_4 + 9.62000962000992e-06*G0_3_4_0_0 + 1.92400192400199e-05*G0_3_4_0_1 - 0.000115440115440119*G0_3_4_0_3 - 7.69600769600796e-05*G0_3_4_0_4 - 3.84800384800398e-05*G0_3_4_0_5 + 1.92400192400199e-05*G0_3_4_1_0 + 1.92400192400199e-05*G0_3_4_1_1 - 2.88600288600299e-05*G0_3_4_1_2 - 7.69600769600795e-05*G0_3_4_1_3 - 3.84800384800398e-05*G0_3_4_1_4 - 2.88600288600299e-05*G0_3_4_2_1 + 5.77200577200597e-05*G0_3_4_2_2 + 7.69600769600797e-05*G0_3_4_2_3 + 7.69600769600797e-05*G0_3_4_2_4 + 3.84800384800398e-05*G0_3_4_2_5 - 0.000115440115440119*G0_3_4_3_0 - 7.69600769600795e-05*G0_3_4_3_1 + 7.69600769600797e-05*G0_3_4_3_2 + 0.000923520923520955*G0_3_4_3_3 + 0.000307840307840318*G0_3_4_3_4 + 0.000153920153920159*G0_3_4_3_5 - 7.69600769600796e-05*G0_3_4_4_0 - 3.84800384800398e-05*G0_3_4_4_1 + 7.69600769600796e-05*G0_3_4_4_2 + 0.000307840307840318*G0_3_4_4_3 + 0.000153920153920159*G0_3_4_4_4 - 3.84800384800398e-05*G0_3_4_5_0 + 3.84800384800398e-05*G0_3_4_5_2 + 0.000153920153920159*G0_3_4_5_3 - 0.000153920153920159*G0_3_4_5_5 - 9.62000962000997e-06*G0_3_5_0_0 + 1.92400192400199e-05*G0_3_5_0_1 - 7.69600769600796e-05*G0_3_5_0_3 - 3.84800384800398e-05*G0_3_5_0_4 + 1.92400192400199e-05*G0_3_5_1_0 - 1.92400192400199e-05*G0_3_5_1_2 - 1.92400192400199e-05*G0_3_5_2_1 + 9.62000962000998e-06*G0_3_5_2_2 + 3.84800384800398e-05*G0_3_5_2_4 + 7.69600769600796e-05*G0_3_5_2_5 - 7.69600769600796e-05*G0_3_5_3_0 + 0.000769600769600796*G0_3_5_3_3 + 0.000153920153920159*G0_3_5_3_4 - 3.84800384800398e-05*G0_3_5_4_0 + 3.84800384800398e-05*G0_3_5_4_2 + 0.000153920153920159*G0_3_5_4_3 - 0.000153920153920159*G0_3_5_4_5 + 7.69600769600796e-05*G0_3_5_5_2 - 0.000153920153920159*G0_3_5_5_4 - 0.000769600769600796*G0_3_5_5_5 - 7.21500721500747e-05*G0_4_0_0_0 + 9.62000962000996e-06*G0_4_0_0_1 + 1.68350168350174e-05*G0_4_0_0_2 + 9.62000962000993e-06*G0_4_0_0_3 - 3.84800384800398e-05*G0_4_0_0_4 - 5.77200577200597e-05*G0_4_0_0_5 + 9.62000962000996e-06*G0_4_0_1_0 + 1.92400192400199e-05*G0_4_0_1_3 + 2.88600288600298e-05*G0_4_0_1_4 + 2.88600288600298e-05*G0_4_0_1_5 + 1.68350168350174e-05*G0_4_0_2_0 - 1.68350168350174e-05*G0_4_0_2_2 + 9.62000962000992e-06*G0_4_0_3_0 + 1.92400192400199e-05*G0_4_0_3_1 - 0.000115440115440119*G0_4_0_3_3 - 7.69600769600796e-05*G0_4_0_3_4 - 3.84800384800398e-05*G0_4_0_3_5 - 3.84800384800398e-05*G0_4_0_4_0 + 2.88600288600298e-05*G0_4_0_4_1 - 7.69600769600796e-05*G0_4_0_4_3 - 0.000153920153920159*G0_4_0_4_4 - 7.69600769600796e-05*G0_4_0_4_5 - 5.77200577200597e-05*G0_4_0_5_0 + 2.88600288600299e-05*G0_4_0_5_1 - 3.84800384800398e-05*G0_4_0_5_3 - 7.69600769600796e-05*G0_4_0_5_4 - 7.69600769600797e-05*G0_4_0_5_5 + 9.62000962000996e-06*G0_4_1_0_0 + 1.92400192400199e-05*G0_4_1_0_3 + 2.88600288600298e-05*G0_4_1_0_4 + 2.88600288600298e-05*G0_4_1_0_5 + 1.92400192400199e-05*G0_4_1_1_3 - 1.92400192400199e-05*G0_4_1_1_5 - 9.62000962000995e-06*G0_4_1_2_2 - 2.88600288600299e-05*G0_4_1_2_3 - 2.88600288600299e-05*G0_4_1_2_4 - 1.92400192400199e-05*G0_4_1_2_5 + 1.92400192400199e-05*G0_4_1_3_0 + 1.92400192400199e-05*G0_4_1_3_1 - 2.88600288600299e-05*G0_4_1_3_2 - 7.69600769600795e-05*G0_4_1_3_3 - 3.84800384800398e-05*G0_4_1_3_4 + 2.88600288600298e-05*G0_4_1_4_0 - 2.88600288600299e-05*G0_4_1_4_2 - 3.84800384800398e-05*G0_4_1_4_3 + 3.84800384800399e-05*G0_4_1_4_5 + 2.88600288600299e-05*G0_4_1_5_0 - 1.92400192400199e-05*G0_4_1_5_1 - 1.92400192400199e-05*G0_4_1_5_2 + 3.84800384800399e-05*G0_4_1_5_4 + 7.69600769600796e-05*G0_4_1_5_5 + 1.68350168350174e-05*G0_4_2_0_0 - 1.68350168350174e-05*G0_4_2_0_2 - 9.62000962000995e-06*G0_4_2_1_2 - 2.88600288600299e-05*G0_4_2_1_3 - 2.88600288600299e-05*G0_4_2_1_4 - 1.92400192400199e-05*G0_4_2_1_5 - 1.68350168350174e-05*G0_4_2_2_0 - 9.62000962000995e-06*G0_4_2_2_1 + 7.21500721500747e-05*G0_4_2_2_2 + 5.77200577200597e-05*G0_4_2_2_3 + 3.84800384800399e-05*G0_4_2_2_4 - 9.62000962000995e-06*G0_4_2_2_5 - 2.88600288600299e-05*G0_4_2_3_1 + 5.77200577200597e-05*G0_4_2_3_2 + 7.69600769600796e-05*G0_4_2_3_3 + 7.69600769600797e-05*G0_4_2_3_4 + 3.84800384800398e-05*G0_4_2_3_5 - 2.88600288600299e-05*G0_4_2_4_1 + 3.84800384800399e-05*G0_4_2_4_2 + 7.69600769600796e-05*G0_4_2_4_3 + 0.000153920153920159*G0_4_2_4_4 + 7.69600769600796e-05*G0_4_2_4_5 - 1.92400192400199e-05*G0_4_2_5_1 - 9.62000962000995e-06*G0_4_2_5_2 + 3.84800384800398e-05*G0_4_2_5_3 + 7.69600769600795e-05*G0_4_2_5_4 + 0.000115440115440119*G0_4_2_5_5 + 9.62000962000992e-06*G0_4_3_0_0 + 1.92400192400199e-05*G0_4_3_0_1 - 0.000115440115440119*G0_4_3_0_3 - 7.69600769600796e-05*G0_4_3_0_4 - 3.84800384800398e-05*G0_4_3_0_5 + 1.92400192400199e-05*G0_4_3_1_0 + 1.92400192400199e-05*G0_4_3_1_1 - 2.88600288600299e-05*G0_4_3_1_2 - 7.69600769600795e-05*G0_4_3_1_3 - 3.84800384800398e-05*G0_4_3_1_4 - 2.88600288600299e-05*G0_4_3_2_1 + 5.77200577200597e-05*G0_4_3_2_2 + 7.69600769600797e-05*G0_4_3_2_3 + 7.69600769600797e-05*G0_4_3_2_4 + 3.84800384800398e-05*G0_4_3_2_5 - 0.000115440115440119*G0_4_3_3_0 - 7.69600769600795e-05*G0_4_3_3_1 + 7.69600769600797e-05*G0_4_3_3_2 + 0.000923520923520955*G0_4_3_3_3 + 0.000307840307840318*G0_4_3_3_4 + 0.000153920153920159*G0_4_3_3_5 - 7.69600769600796e-05*G0_4_3_4_0 - 3.84800384800398e-05*G0_4_3_4_1 + 7.69600769600797e-05*G0_4_3_4_2 + 0.000307840307840318*G0_4_3_4_3 + 0.000153920153920159*G0_4_3_4_4 - 3.84800384800398e-05*G0_4_3_5_0 + 3.84800384800398e-05*G0_4_3_5_2 + 0.000153920153920159*G0_4_3_5_3 - 0.000153920153920159*G0_4_3_5_5 - 3.84800384800398e-05*G0_4_4_0_0 + 2.88600288600298e-05*G0_4_4_0_1 - 7.69600769600796e-05*G0_4_4_0_3 - 0.000153920153920159*G0_4_4_0_4 - 7.69600769600796e-05*G0_4_4_0_5 + 2.88600288600298e-05*G0_4_4_1_0 - 2.88600288600299e-05*G0_4_4_1_2 - 3.84800384800398e-05*G0_4_4_1_3 + 3.84800384800399e-05*G0_4_4_1_5 - 2.88600288600299e-05*G0_4_4_2_1 + 3.84800384800399e-05*G0_4_4_2_2 + 7.69600769600797e-05*G0_4_4_2_3 + 0.000153920153920159*G0_4_4_2_4 + 7.69600769600796e-05*G0_4_4_2_5 - 7.69600769600796e-05*G0_4_4_3_0 - 3.84800384800398e-05*G0_4_4_3_1 + 7.69600769600796e-05*G0_4_4_3_2 + 0.000307840307840318*G0_4_4_3_3 + 0.000153920153920159*G0_4_4_3_4 - 0.000153920153920159*G0_4_4_4_0 + 0.000153920153920159*G0_4_4_4_2 + 0.000153920153920159*G0_4_4_4_3 - 0.000153920153920159*G0_4_4_4_5 - 7.69600769600796e-05*G0_4_4_5_0 + 3.84800384800399e-05*G0_4_4_5_1 + 7.69600769600796e-05*G0_4_4_5_2 - 0.000153920153920159*G0_4_4_5_4 - 0.000307840307840319*G0_4_4_5_5 - 5.77200577200597e-05*G0_4_5_0_0 + 2.88600288600299e-05*G0_4_5_0_1 - 3.84800384800398e-05*G0_4_5_0_3 - 7.69600769600796e-05*G0_4_5_0_4 - 7.69600769600797e-05*G0_4_5_0_5 + 2.88600288600299e-05*G0_4_5_1_0 - 1.92400192400199e-05*G0_4_5_1_1 - 1.92400192400199e-05*G0_4_5_1_2 + 3.84800384800399e-05*G0_4_5_1_4 + 7.69600769600796e-05*G0_4_5_1_5 - 1.92400192400199e-05*G0_4_5_2_1 - 9.62000962000995e-06*G0_4_5_2_2 + 3.84800384800398e-05*G0_4_5_2_3 + 7.69600769600795e-05*G0_4_5_2_4 + 0.000115440115440119*G0_4_5_2_5 - 3.84800384800398e-05*G0_4_5_3_0 + 3.84800384800398e-05*G0_4_5_3_2 + 0.000153920153920159*G0_4_5_3_3 - 0.000153920153920159*G0_4_5_3_5 - 7.69600769600796e-05*G0_4_5_4_0 + 3.84800384800399e-05*G0_4_5_4_1 + 7.69600769600796e-05*G0_4_5_4_2 - 0.000153920153920159*G0_4_5_4_4 - 0.000307840307840319*G0_4_5_4_5 - 7.69600769600797e-05*G0_4_5_5_0 + 7.69600769600796e-05*G0_4_5_5_1 + 0.000115440115440119*G0_4_5_5_2 - 0.000153920153920159*G0_4_5_5_3 - 0.000307840307840319*G0_4_5_5_4 - 0.000923520923520956*G0_4_5_5_5 - 0.00014430014430015*G0_5_0_0_0 + 2.64550264550274e-05*G0_5_0_0_1 + 1.92400192400199e-05*G0_5_0_0_2 - 9.62000962000999e-06*G0_5_0_0_3 - 5.77200577200597e-05*G0_5_0_0_4 - 0.000230880230880239*G0_5_0_0_5 + 2.64550264550274e-05*G0_5_0_1_0 + 9.62000962000996e-06*G0_5_0_1_1 - 7.21500721500747e-06*G0_5_0_1_2 + 1.92400192400199e-05*G0_5_0_1_3 + 2.88600288600299e-05*G0_5_0_1_4 + 0.00013468013468014*G0_5_0_1_5 + 1.92400192400199e-05*G0_5_0_2_0 - 7.21500721500747e-06*G0_5_0_2_1 + 9.62000962001001e-06*G0_5_0_2_5 - 9.62000962000999e-06*G0_5_0_3_0 + 1.92400192400199e-05*G0_5_0_3_1 - 7.69600769600796e-05*G0_5_0_3_3 - 3.84800384800398e-05*G0_5_0_3_4 - 5.77200577200597e-05*G0_5_0_4_0 + 2.88600288600299e-05*G0_5_0_4_1 - 3.84800384800398e-05*G0_5_0_4_3 - 7.69600769600796e-05*G0_5_0_4_4 - 7.69600769600797e-05*G0_5_0_4_5 - 0.000230880230880239*G0_5_0_5_0 + 0.00013468013468014*G0_5_0_5_1 + 9.62000962001002e-06*G0_5_0_5_2 - 7.69600769600797e-05*G0_5_0_5_4 - 0.00015392015392016*G0_5_0_5_5 + 2.64550264550274e-05*G0_5_1_0_0 + 9.62000962000996e-06*G0_5_1_0_1 - 7.21500721500747e-06*G0_5_1_0_2 + 1.92400192400199e-05*G0_5_1_0_3 + 2.88600288600298e-05*G0_5_1_0_4 + 0.00013468013468014*G0_5_1_0_5 + 9.62000962000996e-06*G0_5_1_1_0 - 7.21500721500748e-05*G0_5_1_1_1 + 9.62000962000995e-06*G0_5_1_1_2 - 1.92400192400199e-05*G0_5_1_1_4 - 0.000192400192400199*G0_5_1_1_5 - 7.21500721500747e-06*G0_5_1_2_0 + 9.62000962000995e-06*G0_5_1_2_1 - 1.92400192400199e-05*G0_5_1_2_3 - 1.92400192400199e-05*G0_5_1_2_4 - 1.92400192400199e-05*G0_5_1_2_5 + 1.92400192400199e-05*G0_5_1_3_0 - 1.92400192400199e-05*G0_5_1_3_2 + 2.88600288600299e-05*G0_5_1_4_0 - 1.92400192400199e-05*G0_5_1_4_1 - 1.92400192400199e-05*G0_5_1_4_2 + 3.84800384800399e-05*G0_5_1_4_4 + 7.69600769600796e-05*G0_5_1_4_5 + 0.00013468013468014*G0_5_1_5_0 - 0.000192400192400199*G0_5_1_5_1 - 1.92400192400199e-05*G0_5_1_5_2 + 7.69600769600796e-05*G0_5_1_5_4 + 1.92400192400199e-05*G0_5_2_0_0 - 7.21500721500747e-06*G0_5_2_0_1 + 9.62000962001001e-06*G0_5_2_0_5 - 7.21500721500747e-06*G0_5_2_1_0 + 9.62000962000995e-06*G0_5_2_1_1 - 1.92400192400199e-05*G0_5_2_1_3 - 1.92400192400199e-05*G0_5_2_1_4 - 1.92400192400199e-05*G0_5_2_1_5 + 1.44300144300149e-05*G0_5_2_2_2 + 9.62000962000996e-06*G0_5_2_2_3 - 9.62000962000995e-06*G0_5_2_2_4 - 3.84800384800398e-05*G0_5_2_2_5 - 1.92400192400199e-05*G0_5_2_3_1 + 9.62000962000997e-06*G0_5_2_3_2 + 3.84800384800398e-05*G0_5_2_3_4 + 7.69600769600796e-05*G0_5_2_3_5 - 1.92400192400199e-05*G0_5_2_4_1 - 9.62000962000995e-06*G0_5_2_4_2 + 3.84800384800398e-05*G0_5_2_4_3 + 7.69600769600796e-05*G0_5_2_4_4 + 0.000115440115440119*G0_5_2_4_5 + 9.62000962001001e-06*G0_5_2_5_0 - 1.92400192400199e-05*G0_5_2_5_1 - 3.84800384800398e-05*G0_5_2_5_2 + 7.69600769600796e-05*G0_5_2_5_3 + 0.000115440115440119*G0_5_2_5_4 + 0.000384800384800398*G0_5_2_5_5 - 9.62000962000999e-06*G0_5_3_0_0 + 1.92400192400199e-05*G0_5_3_0_1 - 7.69600769600796e-05*G0_5_3_0_3 - 3.84800384800398e-05*G0_5_3_0_4 + 1.92400192400199e-05*G0_5_3_1_0 - 1.92400192400199e-05*G0_5_3_1_2 - 1.92400192400199e-05*G0_5_3_2_1 + 9.62000962000998e-06*G0_5_3_2_2 + 3.84800384800398e-05*G0_5_3_2_4 + 7.69600769600796e-05*G0_5_3_2_5 - 7.69600769600796e-05*G0_5_3_3_0 + 0.000769600769600796*G0_5_3_3_3 + 0.000153920153920159*G0_5_3_3_4 - 3.84800384800398e-05*G0_5_3_4_0 + 3.84800384800398e-05*G0_5_3_4_2 + 0.000153920153920159*G0_5_3_4_3 - 0.000153920153920159*G0_5_3_4_5 + 7.69600769600796e-05*G0_5_3_5_2 - 0.000153920153920159*G0_5_3_5_4 - 0.000769600769600796*G0_5_3_5_5 - 5.77200577200597e-05*G0_5_4_0_0 + 2.88600288600299e-05*G0_5_4_0_1 - 3.84800384800398e-05*G0_5_4_0_3 - 7.69600769600796e-05*G0_5_4_0_4 - 7.69600769600797e-05*G0_5_4_0_5 + 2.88600288600298e-05*G0_5_4_1_0 - 1.92400192400199e-05*G0_5_4_1_1 - 1.92400192400199e-05*G0_5_4_1_2 + 3.84800384800399e-05*G0_5_4_1_4 + 7.69600769600796e-05*G0_5_4_1_5 - 1.92400192400199e-05*G0_5_4_2_1 - 9.62000962000995e-06*G0_5_4_2_2 + 3.84800384800398e-05*G0_5_4_2_3 + 7.69600769600796e-05*G0_5_4_2_4 + 0.000115440115440119*G0_5_4_2_5 - 3.84800384800398e-05*G0_5_4_3_0 + 3.84800384800398e-05*G0_5_4_3_2 + 0.000153920153920159*G0_5_4_3_3 - 0.000153920153920159*G0_5_4_3_5 - 7.69600769600796e-05*G0_5_4_4_0 + 3.84800384800399e-05*G0_5_4_4_1 + 7.69600769600796e-05*G0_5_4_4_2 - 0.000153920153920159*G0_5_4_4_4 - 0.000307840307840319*G0_5_4_4_5 - 7.69600769600797e-05*G0_5_4_5_0 + 7.69600769600796e-05*G0_5_4_5_1 + 0.000115440115440119*G0_5_4_5_2 - 0.000153920153920159*G0_5_4_5_3 - 0.000307840307840319*G0_5_4_5_4 - 0.000923520923520956*G0_5_4_5_5 - 0.000230880230880239*G0_5_5_0_0 + 0.00013468013468014*G0_5_5_0_1 + 9.62000962001001e-06*G0_5_5_0_2 - 7.69600769600797e-05*G0_5_5_0_4 - 0.00015392015392016*G0_5_5_0_5 + 0.00013468013468014*G0_5_5_1_0 - 0.000192400192400199*G0_5_5_1_1 - 1.92400192400199e-05*G0_5_5_1_2 + 7.69600769600796e-05*G0_5_5_1_4 + 9.62000962001e-06*G0_5_5_2_0 - 1.92400192400199e-05*G0_5_5_2_1 - 3.84800384800398e-05*G0_5_5_2_2 + 7.69600769600796e-05*G0_5_5_2_3 + 0.00011544011544012*G0_5_5_2_4 + 0.000384800384800398*G0_5_5_2_5 + 7.69600769600796e-05*G0_5_5_3_2 - 0.000153920153920159*G0_5_5_3_4 - 0.000769600769600797*G0_5_5_3_5 - 7.69600769600797e-05*G0_5_5_4_0 + 7.69600769600796e-05*G0_5_5_4_1 + 0.000115440115440119*G0_5_5_4_2 - 0.000153920153920159*G0_5_5_4_3 - 0.000307840307840319*G0_5_5_4_4 - 0.000923520923520956*G0_5_5_4_5 - 0.00015392015392016*G0_5_5_5_0 + 0.000384800384800398*G0_5_5_5_2 - 0.000769600769600796*G0_5_5_5_3 - 0.000923520923520956*G0_5_5_5_4 - 0.00615680615680638*G0_5_5_5_5; + A[0] = 0.00371572871572884*G0_0_0_0_0 - 0.00027056277056278*G0_0_0_0_1 - 0.00027056277056278*G0_0_0_0_2 + 7.21500721500749e-05*G0_0_0_0_3 + 0.00115440115440119*G0_0_0_0_4 + 0.0011544011544012*G0_0_0_0_5 - 0.00027056277056278*G0_0_0_1_0 + 4.56950456950473e-05*G0_0_0_1_1 + 2.76575276575286e-05*G0_0_0_1_2 - 1.92400192400199e-05*G0_0_0_1_3 - 0.000120250120250124*G0_0_0_1_4 - 0.000192400192400199*G0_0_0_1_5 - 0.00027056277056278*G0_0_0_2_0 + 2.76575276575286e-05*G0_0_0_2_1 + 4.56950456950473e-05*G0_0_0_2_2 - 1.92400192400199e-05*G0_0_0_2_3 - 0.000192400192400199*G0_0_0_2_4 - 0.000120250120250124*G0_0_0_2_5 + 7.21500721500749e-05*G0_0_0_3_0 - 1.92400192400199e-05*G0_0_0_3_1 - 1.92400192400199e-05*G0_0_0_3_2 + 3.84800384800398e-05*G0_0_0_3_3 + 9.62000962000996e-05*G0_0_0_3_4 + 9.62000962000996e-05*G0_0_0_3_5 + 0.00115440115440119*G0_0_0_4_0 - 0.000120250120250124*G0_0_0_4_1 - 0.000192400192400199*G0_0_0_4_2 + 9.62000962000996e-05*G0_0_0_4_3 + 0.000962000962000995*G0_0_0_4_4 + 0.000481000481000498*G0_0_0_4_5 + 0.0011544011544012*G0_0_0_5_0 - 0.000192400192400199*G0_0_0_5_1 - 0.000120250120250124*G0_0_0_5_2 + 9.62000962000996e-05*G0_0_0_5_3 + 0.000481000481000498*G0_0_0_5_4 + 0.000962000962000996*G0_0_0_5_5 - 0.00027056277056278*G0_0_1_0_0 + 4.56950456950473e-05*G0_0_1_0_1 + 2.76575276575286e-05*G0_0_1_0_2 - 1.92400192400199e-05*G0_0_1_0_3 - 0.000120250120250124*G0_0_1_0_4 - 0.000192400192400199*G0_0_1_0_5 + 4.56950456950473e-05*G0_0_1_1_0 - 1.62337662337668e-05*G0_0_1_1_1 - 5.4112554112556e-06*G0_0_1_1_2 - 2.40500240500248e-06*G0_0_1_1_3 + 1.92400192400199e-05*G0_0_1_1_4 + 3.84800384800399e-05*G0_0_1_1_5 + 2.76575276575286e-05*G0_0_1_2_0 - 5.4112554112556e-06*G0_0_1_2_1 - 5.4112554112556e-06*G0_0_1_2_2 + 4.81000481000498e-06*G0_0_1_2_3 + 2.88600288600299e-05*G0_0_1_2_4 + 2.88600288600299e-05*G0_0_1_2_5 - 1.92400192400199e-05*G0_0_1_3_0 - 2.40500240500248e-06*G0_0_1_3_1 + 4.81000481000498e-06*G0_0_1_3_2 + 9.62000962000992e-06*G0_0_1_3_3 - 1.924001924002e-05*G0_0_1_3_5 - 0.000120250120250124*G0_0_1_4_0 + 1.92400192400199e-05*G0_0_1_4_1 + 2.88600288600299e-05*G0_0_1_4_2 - 9.62000962000995e-05*G0_0_1_4_4 - 9.62000962000996e-05*G0_0_1_4_5 - 0.000192400192400199*G0_0_1_5_0 + 3.84800384800398e-05*G0_0_1_5_1 + 2.88600288600299e-05*G0_0_1_5_2 - 1.92400192400199e-05*G0_0_1_5_3 - 9.62000962000996e-05*G0_0_1_5_4 - 0.000288600288600299*G0_0_1_5_5 - 0.00027056277056278*G0_0_2_0_0 + 2.76575276575286e-05*G0_0_2_0_1 + 4.56950456950473e-05*G0_0_2_0_2 - 1.92400192400199e-05*G0_0_2_0_3 - 0.000192400192400199*G0_0_2_0_4 - 0.000120250120250124*G0_0_2_0_5 + 2.76575276575286e-05*G0_0_2_1_0 - 5.4112554112556e-06*G0_0_2_1_1 - 5.4112554112556e-06*G0_0_2_1_2 + 4.81000481000498e-06*G0_0_2_1_3 + 2.88600288600299e-05*G0_0_2_1_4 + 2.88600288600299e-05*G0_0_2_1_5 + 4.56950456950473e-05*G0_0_2_2_0 - 5.4112554112556e-06*G0_0_2_2_1 - 1.62337662337668e-05*G0_0_2_2_2 - 2.40500240500248e-06*G0_0_2_2_3 + 3.84800384800398e-05*G0_0_2_2_4 + 1.92400192400199e-05*G0_0_2_2_5 - 1.92400192400199e-05*G0_0_2_3_0 + 4.81000481000498e-06*G0_0_2_3_1 - 2.40500240500248e-06*G0_0_2_3_2 + 9.62000962000993e-06*G0_0_2_3_3 - 1.92400192400199e-05*G0_0_2_3_4 - 0.000192400192400199*G0_0_2_4_0 + 2.88600288600299e-05*G0_0_2_4_1 + 3.84800384800398e-05*G0_0_2_4_2 - 1.92400192400199e-05*G0_0_2_4_3 - 0.000288600288600298*G0_0_2_4_4 - 9.62000962000996e-05*G0_0_2_4_5 - 0.000120250120250124*G0_0_2_5_0 + 2.88600288600299e-05*G0_0_2_5_1 + 1.92400192400199e-05*G0_0_2_5_2 - 9.62000962000995e-05*G0_0_2_5_4 - 9.62000962000997e-05*G0_0_2_5_5 + 7.21500721500749e-05*G0_0_3_0_0 - 1.92400192400199e-05*G0_0_3_0_1 - 1.92400192400199e-05*G0_0_3_0_2 + 3.84800384800398e-05*G0_0_3_0_3 + 9.62000962000996e-05*G0_0_3_0_4 + 9.62000962000996e-05*G0_0_3_0_5 - 1.92400192400199e-05*G0_0_3_1_0 - 2.40500240500248e-06*G0_0_3_1_1 + 4.81000481000498e-06*G0_0_3_1_2 + 9.62000962000992e-06*G0_0_3_1_3 - 1.924001924002e-05*G0_0_3_1_5 - 1.92400192400199e-05*G0_0_3_2_0 + 4.81000481000498e-06*G0_0_3_2_1 - 2.40500240500248e-06*G0_0_3_2_2 + 9.62000962000993e-06*G0_0_3_2_3 - 1.92400192400199e-05*G0_0_3_2_4 + 3.84800384800398e-05*G0_0_3_3_0 + 9.62000962000992e-06*G0_0_3_3_1 + 9.62000962000993e-06*G0_0_3_3_2 - 0.000115440115440119*G0_0_3_3_3 - 7.69600769600795e-05*G0_0_3_3_4 - 7.69600769600795e-05*G0_0_3_3_5 + 9.62000962000996e-05*G0_0_3_4_0 - 1.92400192400199e-05*G0_0_3_4_2 - 7.69600769600795e-05*G0_0_3_4_3 + 9.62000962000996e-05*G0_0_3_5_0 - 1.92400192400199e-05*G0_0_3_5_1 - 7.69600769600795e-05*G0_0_3_5_3 + 0.00115440115440119*G0_0_4_0_0 - 0.000120250120250124*G0_0_4_0_1 - 0.000192400192400199*G0_0_4_0_2 + 9.62000962000996e-05*G0_0_4_0_3 + 0.000962000962000995*G0_0_4_0_4 + 0.000481000481000498*G0_0_4_0_5 - 0.000120250120250124*G0_0_4_1_0 + 1.92400192400199e-05*G0_0_4_1_1 + 2.88600288600299e-05*G0_0_4_1_2 - 9.62000962000996e-05*G0_0_4_1_4 - 9.62000962000996e-05*G0_0_4_1_5 - 0.000192400192400199*G0_0_4_2_0 + 2.88600288600299e-05*G0_0_4_2_1 + 3.84800384800398e-05*G0_0_4_2_2 - 1.92400192400199e-05*G0_0_4_2_3 - 0.000288600288600298*G0_0_4_2_4 - 9.62000962000996e-05*G0_0_4_2_5 + 9.62000962000996e-05*G0_0_4_3_0 - 1.92400192400199e-05*G0_0_4_3_2 - 7.69600769600795e-05*G0_0_4_3_3 + 0.000962000962000995*G0_0_4_4_0 - 9.62000962000996e-05*G0_0_4_4_1 - 0.000288600288600298*G0_0_4_4_2 + 0.00115440115440119*G0_0_4_4_4 + 0.000384800384800398*G0_0_4_4_5 + 0.000481000481000498*G0_0_4_5_0 - 9.62000962000995e-05*G0_0_4_5_1 - 9.62000962000996e-05*G0_0_4_5_2 + 0.000384800384800398*G0_0_4_5_4 + 0.000384800384800398*G0_0_4_5_5 + 0.0011544011544012*G0_0_5_0_0 - 0.000192400192400199*G0_0_5_0_1 - 0.000120250120250124*G0_0_5_0_2 + 9.62000962000996e-05*G0_0_5_0_3 + 0.000481000481000498*G0_0_5_0_4 + 0.000962000962000996*G0_0_5_0_5 - 0.000192400192400199*G0_0_5_1_0 + 3.84800384800398e-05*G0_0_5_1_1 + 2.88600288600299e-05*G0_0_5_1_2 - 1.92400192400199e-05*G0_0_5_1_3 - 9.62000962000995e-05*G0_0_5_1_4 - 0.000288600288600299*G0_0_5_1_5 - 0.000120250120250124*G0_0_5_2_0 + 2.88600288600299e-05*G0_0_5_2_1 + 1.92400192400199e-05*G0_0_5_2_2 - 9.62000962000995e-05*G0_0_5_2_4 - 9.62000962000997e-05*G0_0_5_2_5 + 9.62000962000996e-05*G0_0_5_3_0 - 1.92400192400199e-05*G0_0_5_3_1 - 7.69600769600795e-05*G0_0_5_3_3 + 0.000481000481000498*G0_0_5_4_0 - 9.62000962000995e-05*G0_0_5_4_1 - 9.62000962000996e-05*G0_0_5_4_2 + 0.000384800384800398*G0_0_5_4_4 + 0.000384800384800398*G0_0_5_4_5 + 0.000962000962000996*G0_0_5_5_0 - 0.000288600288600299*G0_0_5_5_1 - 9.62000962000997e-05*G0_0_5_5_2 + 0.000384800384800398*G0_0_5_5_4 + 0.0011544011544012*G0_0_5_5_5 - 0.00027056277056278*G0_1_0_0_0 + 4.56950456950473e-05*G0_1_0_0_1 + 2.76575276575286e-05*G0_1_0_0_2 - 1.92400192400199e-05*G0_1_0_0_3 - 0.000120250120250124*G0_1_0_0_4 - 0.000192400192400199*G0_1_0_0_5 + 4.56950456950473e-05*G0_1_0_1_0 - 1.62337662337668e-05*G0_1_0_1_1 - 5.4112554112556e-06*G0_1_0_1_2 - 2.40500240500248e-06*G0_1_0_1_3 + 1.92400192400199e-05*G0_1_0_1_4 + 3.84800384800398e-05*G0_1_0_1_5 + 2.76575276575286e-05*G0_1_0_2_0 - 5.4112554112556e-06*G0_1_0_2_1 - 5.4112554112556e-06*G0_1_0_2_2 + 4.81000481000498e-06*G0_1_0_2_3 + 2.88600288600299e-05*G0_1_0_2_4 + 2.88600288600299e-05*G0_1_0_2_5 - 1.92400192400199e-05*G0_1_0_3_0 - 2.40500240500248e-06*G0_1_0_3_1 + 4.81000481000498e-06*G0_1_0_3_2 + 9.62000962000992e-06*G0_1_0_3_3 - 1.92400192400199e-05*G0_1_0_3_5 - 0.000120250120250124*G0_1_0_4_0 + 1.92400192400199e-05*G0_1_0_4_1 + 2.88600288600298e-05*G0_1_0_4_2 - 9.62000962000995e-05*G0_1_0_4_4 - 9.62000962000995e-05*G0_1_0_4_5 - 0.000192400192400199*G0_1_0_5_0 + 3.84800384800398e-05*G0_1_0_5_1 + 2.88600288600299e-05*G0_1_0_5_2 - 1.92400192400199e-05*G0_1_0_5_3 - 9.62000962000995e-05*G0_1_0_5_4 - 0.000288600288600299*G0_1_0_5_5 + 4.56950456950473e-05*G0_1_1_0_0 - 1.62337662337668e-05*G0_1_1_0_1 - 5.4112554112556e-06*G0_1_1_0_2 - 2.40500240500248e-06*G0_1_1_0_3 + 1.92400192400199e-05*G0_1_1_0_4 + 3.84800384800398e-05*G0_1_1_0_5 - 1.62337662337668e-05*G0_1_1_1_0 + 3.60750360750374e-05*G0_1_1_1_1 + 1.80375180375186e-06*G0_1_1_1_2 - 2.16450216450224e-05*G0_1_1_1_4 - 5.4112554112556e-06*G0_1_1_2_0 + 1.80375180375186e-06*G0_1_1_2_1 + 6.01250601250622e-06*G0_1_1_2_2 - 9.62000962000996e-06*G0_1_1_2_3 - 1.92400192400199e-05*G0_1_1_2_4 - 2.64550264550274e-05*G0_1_1_2_5 - 2.40500240500248e-06*G0_1_1_3_0 - 9.62000962000996e-06*G0_1_1_3_2 + 3.84800384800398e-05*G0_1_1_3_3 + 4.81000481000497e-05*G0_1_1_3_4 + 5.77200577200597e-05*G0_1_1_3_5 + 1.92400192400199e-05*G0_1_1_4_0 - 2.16450216450224e-05*G0_1_1_4_1 - 1.92400192400199e-05*G0_1_1_4_2 + 4.81000481000497e-05*G0_1_1_4_3 + 0.000115440115440119*G0_1_1_4_4 + 9.62000962000995e-05*G0_1_1_4_5 + 3.84800384800398e-05*G0_1_1_5_0 - 2.64550264550274e-05*G0_1_1_5_2 + 5.77200577200597e-05*G0_1_1_5_3 + 9.62000962000995e-05*G0_1_1_5_4 + 0.000230880230880239*G0_1_1_5_5 + 2.76575276575286e-05*G0_1_2_0_0 - 5.4112554112556e-06*G0_1_2_0_1 - 5.4112554112556e-06*G0_1_2_0_2 + 4.81000481000498e-06*G0_1_2_0_3 + 2.88600288600299e-05*G0_1_2_0_4 + 2.88600288600299e-05*G0_1_2_0_5 - 5.4112554112556e-06*G0_1_2_1_0 + 1.80375180375186e-06*G0_1_2_1_1 + 6.01250601250622e-06*G0_1_2_1_2 - 9.62000962000996e-06*G0_1_2_1_3 - 1.92400192400199e-05*G0_1_2_1_4 - 2.64550264550274e-05*G0_1_2_1_5 - 5.4112554112556e-06*G0_1_2_2_0 + 6.01250601250622e-06*G0_1_2_2_1 + 1.80375180375187e-06*G0_1_2_2_2 - 9.62000962000995e-06*G0_1_2_2_3 - 2.64550264550274e-05*G0_1_2_2_4 - 1.92400192400199e-05*G0_1_2_2_5 + 4.81000481000498e-06*G0_1_2_3_0 - 9.62000962000996e-06*G0_1_2_3_1 - 9.62000962000995e-06*G0_1_2_3_2 + 9.62000962000996e-06*G0_1_2_3_3 + 2.88600288600299e-05*G0_1_2_3_4 + 2.88600288600299e-05*G0_1_2_3_5 + 2.88600288600298e-05*G0_1_2_4_0 - 1.92400192400199e-05*G0_1_2_4_1 - 2.64550264550274e-05*G0_1_2_4_2 + 2.88600288600299e-05*G0_1_2_4_3 + 9.62000962000996e-05*G0_1_2_4_4 + 7.69600769600796e-05*G0_1_2_4_5 + 2.88600288600299e-05*G0_1_2_5_0 - 2.64550264550274e-05*G0_1_2_5_1 - 1.92400192400199e-05*G0_1_2_5_2 + 2.88600288600299e-05*G0_1_2_5_3 + 7.69600769600796e-05*G0_1_2_5_4 + 9.62000962000996e-05*G0_1_2_5_5 - 1.92400192400199e-05*G0_1_3_0_0 - 2.40500240500248e-06*G0_1_3_0_1 + 4.81000481000498e-06*G0_1_3_0_2 + 9.62000962000992e-06*G0_1_3_0_3 - 1.92400192400199e-05*G0_1_3_0_5 - 2.40500240500248e-06*G0_1_3_1_0 - 9.62000962000996e-06*G0_1_3_1_2 + 3.84800384800398e-05*G0_1_3_1_3 + 4.81000481000497e-05*G0_1_3_1_4 + 5.77200577200597e-05*G0_1_3_1_5 + 4.81000481000498e-06*G0_1_3_2_0 - 9.62000962000996e-06*G0_1_3_2_1 - 9.62000962000995e-06*G0_1_3_2_2 + 9.62000962000996e-06*G0_1_3_2_3 + 2.88600288600299e-05*G0_1_3_2_4 + 2.88600288600299e-05*G0_1_3_2_5 + 9.62000962000992e-06*G0_1_3_3_0 + 3.84800384800398e-05*G0_1_3_3_1 + 9.62000962000996e-06*G0_1_3_3_2 - 7.69600769600795e-05*G0_1_3_3_3 - 0.000115440115440119*G0_1_3_3_4 - 7.69600769600796e-05*G0_1_3_3_5 + 4.81000481000497e-05*G0_1_3_4_1 + 2.88600288600299e-05*G0_1_3_4_2 - 0.000115440115440119*G0_1_3_4_3 - 0.000230880230880239*G0_1_3_4_4 - 0.000153920153920159*G0_1_3_4_5 - 1.92400192400199e-05*G0_1_3_5_0 + 5.77200577200597e-05*G0_1_3_5_1 + 2.88600288600299e-05*G0_1_3_5_2 - 7.69600769600796e-05*G0_1_3_5_3 - 0.000153920153920159*G0_1_3_5_4 - 0.000153920153920159*G0_1_3_5_5 - 0.000120250120250124*G0_1_4_0_0 + 1.92400192400199e-05*G0_1_4_0_1 + 2.88600288600299e-05*G0_1_4_0_2 - 9.62000962000995e-05*G0_1_4_0_4 - 9.62000962000996e-05*G0_1_4_0_5 + 1.92400192400199e-05*G0_1_4_1_0 - 2.16450216450224e-05*G0_1_4_1_1 - 1.92400192400199e-05*G0_1_4_1_2 + 4.81000481000497e-05*G0_1_4_1_3 + 0.000115440115440119*G0_1_4_1_4 + 9.62000962000995e-05*G0_1_4_1_5 + 2.88600288600299e-05*G0_1_4_2_0 - 1.92400192400199e-05*G0_1_4_2_1 - 2.64550264550274e-05*G0_1_4_2_2 + 2.88600288600299e-05*G0_1_4_2_3 + 9.62000962000996e-05*G0_1_4_2_4 + 7.69600769600796e-05*G0_1_4_2_5 + 4.81000481000497e-05*G0_1_4_3_1 + 2.88600288600299e-05*G0_1_4_3_2 - 0.000115440115440119*G0_1_4_3_3 - 0.000230880230880239*G0_1_4_3_4 - 0.000153920153920159*G0_1_4_3_5 - 9.62000962000995e-05*G0_1_4_4_0 + 0.000115440115440119*G0_1_4_4_1 + 9.62000962000996e-05*G0_1_4_4_2 - 0.000230880230880239*G0_1_4_4_3 - 0.000769600769600796*G0_1_4_4_4 - 0.000384800384800398*G0_1_4_4_5 - 9.62000962000996e-05*G0_1_4_5_0 + 9.62000962000995e-05*G0_1_4_5_1 + 7.69600769600796e-05*G0_1_4_5_2 - 0.000153920153920159*G0_1_4_5_3 - 0.000384800384800398*G0_1_4_5_4 - 0.000384800384800398*G0_1_4_5_5 - 0.000192400192400199*G0_1_5_0_0 + 3.84800384800398e-05*G0_1_5_0_1 + 2.88600288600299e-05*G0_1_5_0_2 - 1.92400192400199e-05*G0_1_5_0_3 - 9.62000962000996e-05*G0_1_5_0_4 - 0.000288600288600299*G0_1_5_0_5 + 3.84800384800398e-05*G0_1_5_1_0 - 2.64550264550274e-05*G0_1_5_1_2 + 5.77200577200597e-05*G0_1_5_1_3 + 9.62000962000995e-05*G0_1_5_1_4 + 0.000230880230880239*G0_1_5_1_5 + 2.88600288600299e-05*G0_1_5_2_0 - 2.64550264550274e-05*G0_1_5_2_1 - 1.92400192400199e-05*G0_1_5_2_2 + 2.88600288600299e-05*G0_1_5_2_3 + 7.69600769600796e-05*G0_1_5_2_4 + 9.62000962000996e-05*G0_1_5_2_5 - 1.924001924002e-05*G0_1_5_3_0 + 5.77200577200597e-05*G0_1_5_3_1 + 2.88600288600299e-05*G0_1_5_3_2 - 7.69600769600796e-05*G0_1_5_3_3 - 0.000153920153920159*G0_1_5_3_4 - 0.000153920153920159*G0_1_5_3_5 - 9.62000962000995e-05*G0_1_5_4_0 + 9.62000962000995e-05*G0_1_5_4_1 + 7.69600769600796e-05*G0_1_5_4_2 - 0.000153920153920159*G0_1_5_4_3 - 0.000384800384800398*G0_1_5_4_4 - 0.000384800384800398*G0_1_5_4_5 - 0.000288600288600299*G0_1_5_5_0 + 0.000230880230880239*G0_1_5_5_1 + 9.62000962000996e-05*G0_1_5_5_2 - 0.000153920153920159*G0_1_5_5_3 - 0.000384800384800398*G0_1_5_5_4 - 0.000769600769600796*G0_1_5_5_5 - 0.00027056277056278*G0_2_0_0_0 + 2.76575276575286e-05*G0_2_0_0_1 + 4.56950456950473e-05*G0_2_0_0_2 - 1.92400192400199e-05*G0_2_0_0_3 - 0.000192400192400199*G0_2_0_0_4 - 0.000120250120250124*G0_2_0_0_5 + 2.76575276575286e-05*G0_2_0_1_0 - 5.4112554112556e-06*G0_2_0_1_1 - 5.4112554112556e-06*G0_2_0_1_2 + 4.81000481000498e-06*G0_2_0_1_3 + 2.88600288600299e-05*G0_2_0_1_4 + 2.88600288600299e-05*G0_2_0_1_5 + 4.56950456950473e-05*G0_2_0_2_0 - 5.4112554112556e-06*G0_2_0_2_1 - 1.62337662337668e-05*G0_2_0_2_2 - 2.40500240500248e-06*G0_2_0_2_3 + 3.84800384800398e-05*G0_2_0_2_4 + 1.92400192400199e-05*G0_2_0_2_5 - 1.92400192400199e-05*G0_2_0_3_0 + 4.81000481000498e-06*G0_2_0_3_1 - 2.40500240500248e-06*G0_2_0_3_2 + 9.62000962000993e-06*G0_2_0_3_3 - 1.92400192400199e-05*G0_2_0_3_4 - 0.000192400192400199*G0_2_0_4_0 + 2.88600288600299e-05*G0_2_0_4_1 + 3.84800384800398e-05*G0_2_0_4_2 - 1.92400192400199e-05*G0_2_0_4_3 - 0.000288600288600298*G0_2_0_4_4 - 9.62000962000996e-05*G0_2_0_4_5 - 0.000120250120250124*G0_2_0_5_0 + 2.88600288600299e-05*G0_2_0_5_1 + 1.92400192400199e-05*G0_2_0_5_2 - 9.62000962000996e-05*G0_2_0_5_4 - 9.62000962000997e-05*G0_2_0_5_5 + 2.76575276575286e-05*G0_2_1_0_0 - 5.4112554112556e-06*G0_2_1_0_1 - 5.4112554112556e-06*G0_2_1_0_2 + 4.81000481000498e-06*G0_2_1_0_3 + 2.88600288600299e-05*G0_2_1_0_4 + 2.88600288600299e-05*G0_2_1_0_5 - 5.4112554112556e-06*G0_2_1_1_0 + 1.80375180375186e-06*G0_2_1_1_1 + 6.01250601250622e-06*G0_2_1_1_2 - 9.62000962000996e-06*G0_2_1_1_3 - 1.92400192400199e-05*G0_2_1_1_4 - 2.64550264550274e-05*G0_2_1_1_5 - 5.4112554112556e-06*G0_2_1_2_0 + 6.01250601250622e-06*G0_2_1_2_1 + 1.80375180375187e-06*G0_2_1_2_2 - 9.62000962000995e-06*G0_2_1_2_3 - 2.64550264550274e-05*G0_2_1_2_4 - 1.92400192400199e-05*G0_2_1_2_5 + 4.81000481000498e-06*G0_2_1_3_0 - 9.62000962000996e-06*G0_2_1_3_1 - 9.62000962000995e-06*G0_2_1_3_2 + 9.62000962000996e-06*G0_2_1_3_3 + 2.88600288600299e-05*G0_2_1_3_4 + 2.88600288600299e-05*G0_2_1_3_5 + 2.88600288600299e-05*G0_2_1_4_0 - 1.92400192400199e-05*G0_2_1_4_1 - 2.64550264550274e-05*G0_2_1_4_2 + 2.88600288600299e-05*G0_2_1_4_3 + 9.62000962000996e-05*G0_2_1_4_4 + 7.69600769600796e-05*G0_2_1_4_5 + 2.88600288600299e-05*G0_2_1_5_0 - 2.64550264550274e-05*G0_2_1_5_1 - 1.92400192400199e-05*G0_2_1_5_2 + 2.88600288600299e-05*G0_2_1_5_3 + 7.69600769600796e-05*G0_2_1_5_4 + 9.62000962000996e-05*G0_2_1_5_5 + 4.56950456950473e-05*G0_2_2_0_0 - 5.4112554112556e-06*G0_2_2_0_1 - 1.62337662337668e-05*G0_2_2_0_2 - 2.40500240500248e-06*G0_2_2_0_3 + 3.84800384800398e-05*G0_2_2_0_4 + 1.92400192400199e-05*G0_2_2_0_5 - 5.4112554112556e-06*G0_2_2_1_0 + 6.01250601250622e-06*G0_2_2_1_1 + 1.80375180375187e-06*G0_2_2_1_2 - 9.62000962000995e-06*G0_2_2_1_3 - 2.64550264550274e-05*G0_2_2_1_4 - 1.92400192400199e-05*G0_2_2_1_5 - 1.62337662337668e-05*G0_2_2_2_0 + 1.80375180375187e-06*G0_2_2_2_1 + 3.60750360750373e-05*G0_2_2_2_2 - 2.16450216450224e-05*G0_2_2_2_5 - 2.40500240500248e-06*G0_2_2_3_0 - 9.62000962000995e-06*G0_2_2_3_1 + 3.84800384800398e-05*G0_2_2_3_3 + 5.77200577200597e-05*G0_2_2_3_4 + 4.81000481000498e-05*G0_2_2_3_5 + 3.84800384800398e-05*G0_2_2_4_0 - 2.64550264550274e-05*G0_2_2_4_1 + 5.77200577200597e-05*G0_2_2_4_3 + 0.000230880230880239*G0_2_2_4_4 + 9.62000962000995e-05*G0_2_2_4_5 + 1.92400192400199e-05*G0_2_2_5_0 - 1.92400192400199e-05*G0_2_2_5_1 - 2.16450216450224e-05*G0_2_2_5_2 + 4.81000481000498e-05*G0_2_2_5_3 + 9.62000962000995e-05*G0_2_2_5_4 + 0.000115440115440119*G0_2_2_5_5 - 1.92400192400199e-05*G0_2_3_0_0 + 4.81000481000498e-06*G0_2_3_0_1 - 2.40500240500248e-06*G0_2_3_0_2 + 9.62000962000993e-06*G0_2_3_0_3 - 1.92400192400199e-05*G0_2_3_0_4 + 4.81000481000498e-06*G0_2_3_1_0 - 9.62000962000996e-06*G0_2_3_1_1 - 9.62000962000995e-06*G0_2_3_1_2 + 9.62000962000996e-06*G0_2_3_1_3 + 2.88600288600299e-05*G0_2_3_1_4 + 2.88600288600299e-05*G0_2_3_1_5 - 2.40500240500248e-06*G0_2_3_2_0 - 9.62000962000995e-06*G0_2_3_2_1 + 3.84800384800398e-05*G0_2_3_2_3 + 5.77200577200597e-05*G0_2_3_2_4 + 4.81000481000498e-05*G0_2_3_2_5 + 9.62000962000993e-06*G0_2_3_3_0 + 9.62000962000996e-06*G0_2_3_3_1 + 3.84800384800398e-05*G0_2_3_3_2 - 7.69600769600796e-05*G0_2_3_3_3 - 7.69600769600796e-05*G0_2_3_3_4 - 0.000115440115440119*G0_2_3_3_5 - 1.92400192400199e-05*G0_2_3_4_0 + 2.88600288600299e-05*G0_2_3_4_1 + 5.77200577200597e-05*G0_2_3_4_2 - 7.69600769600796e-05*G0_2_3_4_3 - 0.000153920153920159*G0_2_3_4_4 - 0.000153920153920159*G0_2_3_4_5 + 2.88600288600299e-05*G0_2_3_5_1 + 4.81000481000498e-05*G0_2_3_5_2 - 0.000115440115440119*G0_2_3_5_3 - 0.000153920153920159*G0_2_3_5_4 - 0.000230880230880239*G0_2_3_5_5 - 0.000192400192400199*G0_2_4_0_0 + 2.88600288600298e-05*G0_2_4_0_1 + 3.84800384800398e-05*G0_2_4_0_2 - 1.92400192400199e-05*G0_2_4_0_3 - 0.000288600288600298*G0_2_4_0_4 - 9.62000962000996e-05*G0_2_4_0_5 + 2.88600288600298e-05*G0_2_4_1_0 - 1.92400192400199e-05*G0_2_4_1_1 - 2.64550264550274e-05*G0_2_4_1_2 + 2.88600288600299e-05*G0_2_4_1_3 + 9.62000962000996e-05*G0_2_4_1_4 + 7.69600769600796e-05*G0_2_4_1_5 + 3.84800384800398e-05*G0_2_4_2_0 - 2.64550264550274e-05*G0_2_4_2_1 + 5.77200577200597e-05*G0_2_4_2_3 + 0.000230880230880239*G0_2_4_2_4 + 9.62000962000995e-05*G0_2_4_2_5 - 1.92400192400199e-05*G0_2_4_3_0 + 2.88600288600299e-05*G0_2_4_3_1 + 5.77200577200597e-05*G0_2_4_3_2 - 7.69600769600796e-05*G0_2_4_3_3 - 0.000153920153920159*G0_2_4_3_4 - 0.000153920153920159*G0_2_4_3_5 - 0.000288600288600298*G0_2_4_4_0 + 9.62000962000996e-05*G0_2_4_4_1 + 0.000230880230880239*G0_2_4_4_2 - 0.000153920153920159*G0_2_4_4_3 - 0.000769600769600796*G0_2_4_4_4 - 0.000384800384800398*G0_2_4_4_5 - 9.62000962000996e-05*G0_2_4_5_0 + 7.69600769600796e-05*G0_2_4_5_1 + 9.62000962000995e-05*G0_2_4_5_2 - 0.000153920153920159*G0_2_4_5_3 - 0.000384800384800398*G0_2_4_5_4 - 0.000384800384800398*G0_2_4_5_5 - 0.000120250120250124*G0_2_5_0_0 + 2.88600288600299e-05*G0_2_5_0_1 + 1.92400192400199e-05*G0_2_5_0_2 - 9.62000962000996e-05*G0_2_5_0_4 - 9.62000962000997e-05*G0_2_5_0_5 + 2.88600288600299e-05*G0_2_5_1_0 - 2.64550264550274e-05*G0_2_5_1_1 - 1.92400192400199e-05*G0_2_5_1_2 + 2.88600288600299e-05*G0_2_5_1_3 + 7.69600769600796e-05*G0_2_5_1_4 + 9.62000962000996e-05*G0_2_5_1_5 + 1.92400192400199e-05*G0_2_5_2_0 - 1.92400192400199e-05*G0_2_5_2_1 - 2.16450216450224e-05*G0_2_5_2_2 + 4.81000481000498e-05*G0_2_5_2_3 + 9.62000962000995e-05*G0_2_5_2_4 + 0.000115440115440119*G0_2_5_2_5 + 2.88600288600299e-05*G0_2_5_3_1 + 4.81000481000498e-05*G0_2_5_3_2 - 0.000115440115440119*G0_2_5_3_3 - 0.000153920153920159*G0_2_5_3_4 - 0.000230880230880239*G0_2_5_3_5 - 9.62000962000996e-05*G0_2_5_4_0 + 7.69600769600796e-05*G0_2_5_4_1 + 9.62000962000995e-05*G0_2_5_4_2 - 0.000153920153920159*G0_2_5_4_3 - 0.000384800384800398*G0_2_5_4_4 - 0.000384800384800398*G0_2_5_4_5 - 9.62000962000997e-05*G0_2_5_5_0 + 9.62000962000996e-05*G0_2_5_5_1 + 0.000115440115440119*G0_2_5_5_2 - 0.000230880230880239*G0_2_5_5_3 - 0.000384800384800398*G0_2_5_5_4 - 0.000769600769600797*G0_2_5_5_5 + 7.21500721500749e-05*G0_3_0_0_0 - 1.92400192400199e-05*G0_3_0_0_1 - 1.92400192400199e-05*G0_3_0_0_2 + 3.84800384800398e-05*G0_3_0_0_3 + 9.62000962000996e-05*G0_3_0_0_4 + 9.62000962000996e-05*G0_3_0_0_5 - 1.92400192400199e-05*G0_3_0_1_0 - 2.40500240500248e-06*G0_3_0_1_1 + 4.81000481000498e-06*G0_3_0_1_2 + 9.62000962000992e-06*G0_3_0_1_3 - 1.924001924002e-05*G0_3_0_1_5 - 1.92400192400199e-05*G0_3_0_2_0 + 4.81000481000498e-06*G0_3_0_2_1 - 2.40500240500248e-06*G0_3_0_2_2 + 9.62000962000993e-06*G0_3_0_2_3 - 1.92400192400199e-05*G0_3_0_2_4 + 3.84800384800398e-05*G0_3_0_3_0 + 9.62000962000992e-06*G0_3_0_3_1 + 9.62000962000993e-06*G0_3_0_3_2 - 0.000115440115440119*G0_3_0_3_3 - 7.69600769600795e-05*G0_3_0_3_4 - 7.69600769600795e-05*G0_3_0_3_5 + 9.62000962000996e-05*G0_3_0_4_0 - 1.92400192400199e-05*G0_3_0_4_2 - 7.69600769600795e-05*G0_3_0_4_3 + 9.62000962000996e-05*G0_3_0_5_0 - 1.92400192400199e-05*G0_3_0_5_1 - 7.69600769600795e-05*G0_3_0_5_3 - 1.92400192400199e-05*G0_3_1_0_0 - 2.40500240500248e-06*G0_3_1_0_1 + 4.81000481000498e-06*G0_3_1_0_2 + 9.62000962000992e-06*G0_3_1_0_3 - 1.92400192400199e-05*G0_3_1_0_5 - 2.40500240500248e-06*G0_3_1_1_0 - 9.62000962000996e-06*G0_3_1_1_2 + 3.84800384800398e-05*G0_3_1_1_3 + 4.81000481000497e-05*G0_3_1_1_4 + 5.77200577200597e-05*G0_3_1_1_5 + 4.81000481000498e-06*G0_3_1_2_0 - 9.62000962000996e-06*G0_3_1_2_1 - 9.62000962000995e-06*G0_3_1_2_2 + 9.62000962000996e-06*G0_3_1_2_3 + 2.88600288600299e-05*G0_3_1_2_4 + 2.88600288600299e-05*G0_3_1_2_5 + 9.62000962000992e-06*G0_3_1_3_0 + 3.84800384800398e-05*G0_3_1_3_1 + 9.62000962000996e-06*G0_3_1_3_2 - 7.69600769600795e-05*G0_3_1_3_3 - 0.000115440115440119*G0_3_1_3_4 - 7.69600769600796e-05*G0_3_1_3_5 + 4.81000481000497e-05*G0_3_1_4_1 + 2.88600288600299e-05*G0_3_1_4_2 - 0.000115440115440119*G0_3_1_4_3 - 0.000230880230880239*G0_3_1_4_4 - 0.000153920153920159*G0_3_1_4_5 - 1.924001924002e-05*G0_3_1_5_0 + 5.77200577200597e-05*G0_3_1_5_1 + 2.88600288600299e-05*G0_3_1_5_2 - 7.69600769600796e-05*G0_3_1_5_3 - 0.000153920153920159*G0_3_1_5_4 - 0.000153920153920159*G0_3_1_5_5 - 1.92400192400199e-05*G0_3_2_0_0 + 4.81000481000498e-06*G0_3_2_0_1 - 2.40500240500248e-06*G0_3_2_0_2 + 9.62000962000993e-06*G0_3_2_0_3 - 1.92400192400199e-05*G0_3_2_0_4 + 4.81000481000498e-06*G0_3_2_1_0 - 9.62000962000996e-06*G0_3_2_1_1 - 9.62000962000995e-06*G0_3_2_1_2 + 9.62000962000996e-06*G0_3_2_1_3 + 2.88600288600299e-05*G0_3_2_1_4 + 2.88600288600299e-05*G0_3_2_1_5 - 2.40500240500248e-06*G0_3_2_2_0 - 9.62000962000995e-06*G0_3_2_2_1 + 3.84800384800398e-05*G0_3_2_2_3 + 5.77200577200597e-05*G0_3_2_2_4 + 4.81000481000498e-05*G0_3_2_2_5 + 9.62000962000993e-06*G0_3_2_3_0 + 9.62000962000996e-06*G0_3_2_3_1 + 3.84800384800398e-05*G0_3_2_3_2 - 7.69600769600796e-05*G0_3_2_3_3 - 7.69600769600796e-05*G0_3_2_3_4 - 0.000115440115440119*G0_3_2_3_5 - 1.92400192400199e-05*G0_3_2_4_0 + 2.88600288600299e-05*G0_3_2_4_1 + 5.77200577200597e-05*G0_3_2_4_2 - 7.69600769600796e-05*G0_3_2_4_3 - 0.000153920153920159*G0_3_2_4_4 - 0.000153920153920159*G0_3_2_4_5 + 2.88600288600299e-05*G0_3_2_5_1 + 4.81000481000498e-05*G0_3_2_5_2 - 0.000115440115440119*G0_3_2_5_3 - 0.000153920153920159*G0_3_2_5_4 - 0.000230880230880239*G0_3_2_5_5 + 3.84800384800398e-05*G0_3_3_0_0 + 9.62000962000992e-06*G0_3_3_0_1 + 9.62000962000993e-06*G0_3_3_0_2 - 0.000115440115440119*G0_3_3_0_3 - 7.69600769600795e-05*G0_3_3_0_4 - 7.69600769600795e-05*G0_3_3_0_5 + 9.62000962000992e-06*G0_3_3_1_0 + 3.84800384800398e-05*G0_3_3_1_1 + 9.62000962000996e-06*G0_3_3_1_2 - 7.69600769600795e-05*G0_3_3_1_3 - 0.000115440115440119*G0_3_3_1_4 - 7.69600769600796e-05*G0_3_3_1_5 + 9.62000962000993e-06*G0_3_3_2_0 + 9.62000962000996e-06*G0_3_3_2_1 + 3.84800384800398e-05*G0_3_3_2_2 - 7.69600769600796e-05*G0_3_3_2_3 - 7.69600769600796e-05*G0_3_3_2_4 - 0.000115440115440119*G0_3_3_2_5 - 0.000115440115440119*G0_3_3_3_0 - 7.69600769600795e-05*G0_3_3_3_1 - 7.69600769600796e-05*G0_3_3_3_2 + 0.000615680615680636*G0_3_3_3_3 + 0.000461760461760477*G0_3_3_3_4 + 0.000461760461760477*G0_3_3_3_5 - 7.69600769600795e-05*G0_3_3_4_0 - 0.000115440115440119*G0_3_3_4_1 - 7.69600769600796e-05*G0_3_3_4_2 + 0.000461760461760477*G0_3_3_4_3 + 0.000615680615680637*G0_3_3_4_4 + 0.000461760461760477*G0_3_3_4_5 - 7.69600769600795e-05*G0_3_3_5_0 - 7.69600769600796e-05*G0_3_3_5_1 - 0.000115440115440119*G0_3_3_5_2 + 0.000461760461760477*G0_3_3_5_3 + 0.000461760461760477*G0_3_3_5_4 + 0.000615680615680636*G0_3_3_5_5 + 9.62000962000996e-05*G0_3_4_0_0 - 1.92400192400199e-05*G0_3_4_0_2 - 7.69600769600795e-05*G0_3_4_0_3 + 4.81000481000497e-05*G0_3_4_1_1 + 2.88600288600299e-05*G0_3_4_1_2 - 0.000115440115440119*G0_3_4_1_3 - 0.000230880230880239*G0_3_4_1_4 - 0.000153920153920159*G0_3_4_1_5 - 1.92400192400199e-05*G0_3_4_2_0 + 2.88600288600299e-05*G0_3_4_2_1 + 5.77200577200597e-05*G0_3_4_2_2 - 7.69600769600796e-05*G0_3_4_2_3 - 0.000153920153920159*G0_3_4_2_4 - 0.000153920153920159*G0_3_4_2_5 - 7.69600769600795e-05*G0_3_4_3_0 - 0.000115440115440119*G0_3_4_3_1 - 7.69600769600796e-05*G0_3_4_3_2 + 0.000461760461760477*G0_3_4_3_3 + 0.000615680615680637*G0_3_4_3_4 + 0.000461760461760477*G0_3_4_3_5 - 0.000230880230880239*G0_3_4_4_1 - 0.000153920153920159*G0_3_4_4_2 + 0.000615680615680637*G0_3_4_4_3 + 0.00153920153920159*G0_3_4_4_4 + 0.000769600769600796*G0_3_4_4_5 - 0.000153920153920159*G0_3_4_5_1 - 0.000153920153920159*G0_3_4_5_2 + 0.000461760461760477*G0_3_4_5_3 + 0.000769600769600796*G0_3_4_5_4 + 0.000769600769600796*G0_3_4_5_5 + 9.62000962000996e-05*G0_3_5_0_0 - 1.92400192400199e-05*G0_3_5_0_1 - 7.69600769600795e-05*G0_3_5_0_3 - 1.92400192400199e-05*G0_3_5_1_0 + 5.77200577200597e-05*G0_3_5_1_1 + 2.88600288600299e-05*G0_3_5_1_2 - 7.69600769600796e-05*G0_3_5_1_3 - 0.000153920153920159*G0_3_5_1_4 - 0.000153920153920159*G0_3_5_1_5 + 2.88600288600299e-05*G0_3_5_2_1 + 4.81000481000498e-05*G0_3_5_2_2 - 0.000115440115440119*G0_3_5_2_3 - 0.000153920153920159*G0_3_5_2_4 - 0.000230880230880239*G0_3_5_2_5 - 7.69600769600795e-05*G0_3_5_3_0 - 7.69600769600796e-05*G0_3_5_3_1 - 0.000115440115440119*G0_3_5_3_2 + 0.000461760461760477*G0_3_5_3_3 + 0.000461760461760477*G0_3_5_3_4 + 0.000615680615680636*G0_3_5_3_5 - 0.000153920153920159*G0_3_5_4_1 - 0.000153920153920159*G0_3_5_4_2 + 0.000461760461760477*G0_3_5_4_3 + 0.000769600769600796*G0_3_5_4_4 + 0.000769600769600796*G0_3_5_4_5 - 0.000153920153920159*G0_3_5_5_1 - 0.000230880230880239*G0_3_5_5_2 + 0.000615680615680636*G0_3_5_5_3 + 0.000769600769600796*G0_3_5_5_4 + 0.00153920153920159*G0_3_5_5_5 + 0.00115440115440119*G0_4_0_0_0 - 0.000120250120250124*G0_4_0_0_1 - 0.000192400192400199*G0_4_0_0_2 + 9.62000962000996e-05*G0_4_0_0_3 + 0.000962000962000995*G0_4_0_0_4 + 0.000481000481000498*G0_4_0_0_5 - 0.000120250120250124*G0_4_0_1_0 + 1.92400192400199e-05*G0_4_0_1_1 + 2.88600288600299e-05*G0_4_0_1_2 - 9.62000962000995e-05*G0_4_0_1_4 - 9.62000962000995e-05*G0_4_0_1_5 - 0.000192400192400199*G0_4_0_2_0 + 2.88600288600298e-05*G0_4_0_2_1 + 3.84800384800398e-05*G0_4_0_2_2 - 1.92400192400199e-05*G0_4_0_2_3 - 0.000288600288600298*G0_4_0_2_4 - 9.62000962000996e-05*G0_4_0_2_5 + 9.62000962000996e-05*G0_4_0_3_0 - 1.92400192400199e-05*G0_4_0_3_2 - 7.69600769600795e-05*G0_4_0_3_3 + 0.000962000962000995*G0_4_0_4_0 - 9.62000962000995e-05*G0_4_0_4_1 - 0.000288600288600298*G0_4_0_4_2 + 0.00115440115440119*G0_4_0_4_4 + 0.000384800384800398*G0_4_0_4_5 + 0.000481000481000498*G0_4_0_5_0 - 9.62000962000996e-05*G0_4_0_5_1 - 9.62000962000996e-05*G0_4_0_5_2 + 0.000384800384800398*G0_4_0_5_4 + 0.000384800384800398*G0_4_0_5_5 - 0.000120250120250124*G0_4_1_0_0 + 1.92400192400199e-05*G0_4_1_0_1 + 2.88600288600299e-05*G0_4_1_0_2 - 9.62000962000995e-05*G0_4_1_0_4 - 9.62000962000996e-05*G0_4_1_0_5 + 1.92400192400199e-05*G0_4_1_1_0 - 2.16450216450224e-05*G0_4_1_1_1 - 1.92400192400199e-05*G0_4_1_1_2 + 4.81000481000497e-05*G0_4_1_1_3 + 0.000115440115440119*G0_4_1_1_4 + 9.62000962000995e-05*G0_4_1_1_5 + 2.88600288600299e-05*G0_4_1_2_0 - 1.92400192400199e-05*G0_4_1_2_1 - 2.64550264550274e-05*G0_4_1_2_2 + 2.88600288600299e-05*G0_4_1_2_3 + 9.62000962000996e-05*G0_4_1_2_4 + 7.69600769600796e-05*G0_4_1_2_5 + 4.81000481000497e-05*G0_4_1_3_1 + 2.88600288600299e-05*G0_4_1_3_2 - 0.000115440115440119*G0_4_1_3_3 - 0.000230880230880239*G0_4_1_3_4 - 0.000153920153920159*G0_4_1_3_5 - 9.62000962000995e-05*G0_4_1_4_0 + 0.000115440115440119*G0_4_1_4_1 + 9.62000962000996e-05*G0_4_1_4_2 - 0.000230880230880239*G0_4_1_4_3 - 0.000769600769600796*G0_4_1_4_4 - 0.000384800384800398*G0_4_1_4_5 - 9.62000962000996e-05*G0_4_1_5_0 + 9.62000962000995e-05*G0_4_1_5_1 + 7.69600769600796e-05*G0_4_1_5_2 - 0.000153920153920159*G0_4_1_5_3 - 0.000384800384800398*G0_4_1_5_4 - 0.000384800384800398*G0_4_1_5_5 - 0.000192400192400199*G0_4_2_0_0 + 2.88600288600298e-05*G0_4_2_0_1 + 3.84800384800398e-05*G0_4_2_0_2 - 1.92400192400199e-05*G0_4_2_0_3 - 0.000288600288600298*G0_4_2_0_4 - 9.62000962000996e-05*G0_4_2_0_5 + 2.88600288600298e-05*G0_4_2_1_0 - 1.92400192400199e-05*G0_4_2_1_1 - 2.64550264550274e-05*G0_4_2_1_2 + 2.88600288600299e-05*G0_4_2_1_3 + 9.62000962000996e-05*G0_4_2_1_4 + 7.69600769600796e-05*G0_4_2_1_5 + 3.84800384800398e-05*G0_4_2_2_0 - 2.64550264550274e-05*G0_4_2_2_1 + 5.77200577200597e-05*G0_4_2_2_3 + 0.000230880230880239*G0_4_2_2_4 + 9.62000962000995e-05*G0_4_2_2_5 - 1.92400192400199e-05*G0_4_2_3_0 + 2.88600288600299e-05*G0_4_2_3_1 + 5.77200577200597e-05*G0_4_2_3_2 - 7.69600769600796e-05*G0_4_2_3_3 - 0.000153920153920159*G0_4_2_3_4 - 0.000153920153920159*G0_4_2_3_5 - 0.000288600288600298*G0_4_2_4_0 + 9.62000962000996e-05*G0_4_2_4_1 + 0.000230880230880239*G0_4_2_4_2 - 0.000153920153920159*G0_4_2_4_3 - 0.000769600769600796*G0_4_2_4_4 - 0.000384800384800398*G0_4_2_4_5 - 9.62000962000996e-05*G0_4_2_5_0 + 7.69600769600796e-05*G0_4_2_5_1 + 9.62000962000995e-05*G0_4_2_5_2 - 0.000153920153920159*G0_4_2_5_3 - 0.000384800384800398*G0_4_2_5_4 - 0.000384800384800398*G0_4_2_5_5 + 9.62000962000996e-05*G0_4_3_0_0 - 1.92400192400199e-05*G0_4_3_0_2 - 7.69600769600795e-05*G0_4_3_0_3 + 4.81000481000497e-05*G0_4_3_1_1 + 2.88600288600299e-05*G0_4_3_1_2 - 0.000115440115440119*G0_4_3_1_3 - 0.000230880230880239*G0_4_3_1_4 - 0.000153920153920159*G0_4_3_1_5 - 1.92400192400199e-05*G0_4_3_2_0 + 2.88600288600299e-05*G0_4_3_2_1 + 5.77200577200597e-05*G0_4_3_2_2 - 7.69600769600796e-05*G0_4_3_2_3 - 0.000153920153920159*G0_4_3_2_4 - 0.000153920153920159*G0_4_3_2_5 - 7.69600769600795e-05*G0_4_3_3_0 - 0.000115440115440119*G0_4_3_3_1 - 7.69600769600796e-05*G0_4_3_3_2 + 0.000461760461760477*G0_4_3_3_3 + 0.000615680615680637*G0_4_3_3_4 + 0.000461760461760477*G0_4_3_3_5 - 0.000230880230880239*G0_4_3_4_1 - 0.000153920153920159*G0_4_3_4_2 + 0.000615680615680637*G0_4_3_4_3 + 0.00153920153920159*G0_4_3_4_4 + 0.000769600769600796*G0_4_3_4_5 - 0.000153920153920159*G0_4_3_5_1 - 0.000153920153920159*G0_4_3_5_2 + 0.000461760461760478*G0_4_3_5_3 + 0.000769600769600796*G0_4_3_5_4 + 0.000769600769600796*G0_4_3_5_5 + 0.000962000962000995*G0_4_4_0_0 - 9.62000962000995e-05*G0_4_4_0_1 - 0.000288600288600298*G0_4_4_0_2 + 0.00115440115440119*G0_4_4_0_4 + 0.000384800384800398*G0_4_4_0_5 - 9.62000962000995e-05*G0_4_4_1_0 + 0.000115440115440119*G0_4_4_1_1 + 9.62000962000996e-05*G0_4_4_1_2 - 0.000230880230880239*G0_4_4_1_3 - 0.000769600769600796*G0_4_4_1_4 - 0.000384800384800398*G0_4_4_1_5 - 0.000288600288600298*G0_4_4_2_0 + 9.62000962000996e-05*G0_4_4_2_1 + 0.000230880230880239*G0_4_4_2_2 - 0.000153920153920159*G0_4_4_2_3 - 0.000769600769600796*G0_4_4_2_4 - 0.000384800384800398*G0_4_4_2_5 - 0.000230880230880239*G0_4_4_3_1 - 0.000153920153920159*G0_4_4_3_2 + 0.000615680615680637*G0_4_4_3_3 + 0.00153920153920159*G0_4_4_3_4 + 0.000769600769600796*G0_4_4_3_5 + 0.00115440115440119*G0_4_4_4_0 - 0.000769600769600796*G0_4_4_4_1 - 0.000769600769600796*G0_4_4_4_2 + 0.00153920153920159*G0_4_4_4_3 + 0.00923520923520954*G0_4_4_4_4 + 0.00230880230880239*G0_4_4_4_5 + 0.000384800384800398*G0_4_4_5_0 - 0.000384800384800398*G0_4_4_5_1 - 0.000384800384800398*G0_4_4_5_2 + 0.000769600769600796*G0_4_4_5_3 + 0.00230880230880239*G0_4_4_5_4 + 0.00153920153920159*G0_4_4_5_5 + 0.000481000481000498*G0_4_5_0_0 - 9.62000962000996e-05*G0_4_5_0_1 - 9.62000962000995e-05*G0_4_5_0_2 + 0.000384800384800398*G0_4_5_0_4 + 0.000384800384800398*G0_4_5_0_5 - 9.62000962000996e-05*G0_4_5_1_0 + 9.62000962000995e-05*G0_4_5_1_1 + 7.69600769600796e-05*G0_4_5_1_2 - 0.000153920153920159*G0_4_5_1_3 - 0.000384800384800398*G0_4_5_1_4 - 0.000384800384800398*G0_4_5_1_5 - 9.62000962000996e-05*G0_4_5_2_0 + 7.69600769600796e-05*G0_4_5_2_1 + 9.62000962000995e-05*G0_4_5_2_2 - 0.000153920153920159*G0_4_5_2_3 - 0.000384800384800398*G0_4_5_2_4 - 0.000384800384800398*G0_4_5_2_5 - 0.000153920153920159*G0_4_5_3_1 - 0.000153920153920159*G0_4_5_3_2 + 0.000461760461760478*G0_4_5_3_3 + 0.000769600769600796*G0_4_5_3_4 + 0.000769600769600796*G0_4_5_3_5 + 0.000384800384800398*G0_4_5_4_0 - 0.000384800384800398*G0_4_5_4_1 - 0.000384800384800398*G0_4_5_4_2 + 0.000769600769600796*G0_4_5_4_3 + 0.00230880230880239*G0_4_5_4_4 + 0.00153920153920159*G0_4_5_4_5 + 0.000384800384800398*G0_4_5_5_0 - 0.000384800384800398*G0_4_5_5_1 - 0.000384800384800398*G0_4_5_5_2 + 0.000769600769600796*G0_4_5_5_3 + 0.00153920153920159*G0_4_5_5_4 + 0.00230880230880239*G0_4_5_5_5 + 0.0011544011544012*G0_5_0_0_0 - 0.000192400192400199*G0_5_0_0_1 - 0.000120250120250124*G0_5_0_0_2 + 9.62000962000996e-05*G0_5_0_0_3 + 0.000481000481000498*G0_5_0_0_4 + 0.000962000962000996*G0_5_0_0_5 - 0.000192400192400199*G0_5_0_1_0 + 3.84800384800398e-05*G0_5_0_1_1 + 2.88600288600299e-05*G0_5_0_1_2 - 1.92400192400199e-05*G0_5_0_1_3 - 9.62000962000995e-05*G0_5_0_1_4 - 0.000288600288600299*G0_5_0_1_5 - 0.000120250120250124*G0_5_0_2_0 + 2.88600288600299e-05*G0_5_0_2_1 + 1.92400192400199e-05*G0_5_0_2_2 - 9.62000962000996e-05*G0_5_0_2_4 - 9.62000962000997e-05*G0_5_0_2_5 + 9.62000962000996e-05*G0_5_0_3_0 - 1.92400192400199e-05*G0_5_0_3_1 - 7.69600769600795e-05*G0_5_0_3_3 + 0.000481000481000498*G0_5_0_4_0 - 9.62000962000995e-05*G0_5_0_4_1 - 9.62000962000996e-05*G0_5_0_4_2 + 0.000384800384800398*G0_5_0_4_4 + 0.000384800384800398*G0_5_0_4_5 + 0.000962000962000996*G0_5_0_5_0 - 0.000288600288600299*G0_5_0_5_1 - 9.62000962000997e-05*G0_5_0_5_2 + 0.000384800384800398*G0_5_0_5_4 + 0.0011544011544012*G0_5_0_5_5 - 0.000192400192400199*G0_5_1_0_0 + 3.84800384800398e-05*G0_5_1_0_1 + 2.88600288600299e-05*G0_5_1_0_2 - 1.92400192400199e-05*G0_5_1_0_3 - 9.62000962000996e-05*G0_5_1_0_4 - 0.000288600288600299*G0_5_1_0_5 + 3.84800384800398e-05*G0_5_1_1_0 - 2.64550264550274e-05*G0_5_1_1_2 + 5.77200577200597e-05*G0_5_1_1_3 + 9.62000962000995e-05*G0_5_1_1_4 + 0.000230880230880239*G0_5_1_1_5 + 2.88600288600299e-05*G0_5_1_2_0 - 2.64550264550274e-05*G0_5_1_2_1 - 1.92400192400199e-05*G0_5_1_2_2 + 2.88600288600299e-05*G0_5_1_2_3 + 7.69600769600796e-05*G0_5_1_2_4 + 9.62000962000996e-05*G0_5_1_2_5 - 1.924001924002e-05*G0_5_1_3_0 + 5.77200577200597e-05*G0_5_1_3_1 + 2.88600288600299e-05*G0_5_1_3_2 - 7.69600769600796e-05*G0_5_1_3_3 - 0.000153920153920159*G0_5_1_3_4 - 0.000153920153920159*G0_5_1_3_5 - 9.62000962000995e-05*G0_5_1_4_0 + 9.62000962000995e-05*G0_5_1_4_1 + 7.69600769600796e-05*G0_5_1_4_2 - 0.000153920153920159*G0_5_1_4_3 - 0.000384800384800398*G0_5_1_4_4 - 0.000384800384800398*G0_5_1_4_5 - 0.000288600288600299*G0_5_1_5_0 + 0.000230880230880239*G0_5_1_5_1 + 9.62000962000996e-05*G0_5_1_5_2 - 0.000153920153920159*G0_5_1_5_3 - 0.000384800384800398*G0_5_1_5_4 - 0.000769600769600796*G0_5_1_5_5 - 0.000120250120250124*G0_5_2_0_0 + 2.88600288600299e-05*G0_5_2_0_1 + 1.92400192400199e-05*G0_5_2_0_2 - 9.62000962000996e-05*G0_5_2_0_4 - 9.62000962000997e-05*G0_5_2_0_5 + 2.88600288600299e-05*G0_5_2_1_0 - 2.64550264550274e-05*G0_5_2_1_1 - 1.92400192400199e-05*G0_5_2_1_2 + 2.88600288600299e-05*G0_5_2_1_3 + 7.69600769600796e-05*G0_5_2_1_4 + 9.62000962000996e-05*G0_5_2_1_5 + 1.92400192400199e-05*G0_5_2_2_0 - 1.92400192400199e-05*G0_5_2_2_1 - 2.16450216450224e-05*G0_5_2_2_2 + 4.81000481000498e-05*G0_5_2_2_3 + 9.62000962000995e-05*G0_5_2_2_4 + 0.000115440115440119*G0_5_2_2_5 + 2.88600288600299e-05*G0_5_2_3_1 + 4.81000481000498e-05*G0_5_2_3_2 - 0.000115440115440119*G0_5_2_3_3 - 0.000153920153920159*G0_5_2_3_4 - 0.000230880230880239*G0_5_2_3_5 - 9.62000962000996e-05*G0_5_2_4_0 + 7.69600769600796e-05*G0_5_2_4_1 + 9.62000962000995e-05*G0_5_2_4_2 - 0.000153920153920159*G0_5_2_4_3 - 0.000384800384800398*G0_5_2_4_4 - 0.000384800384800398*G0_5_2_4_5 - 9.62000962000997e-05*G0_5_2_5_0 + 9.62000962000996e-05*G0_5_2_5_1 + 0.000115440115440119*G0_5_2_5_2 - 0.000230880230880239*G0_5_2_5_3 - 0.000384800384800398*G0_5_2_5_4 - 0.000769600769600797*G0_5_2_5_5 + 9.62000962000996e-05*G0_5_3_0_0 - 1.92400192400199e-05*G0_5_3_0_1 - 7.69600769600795e-05*G0_5_3_0_3 - 1.924001924002e-05*G0_5_3_1_0 + 5.77200577200597e-05*G0_5_3_1_1 + 2.88600288600299e-05*G0_5_3_1_2 - 7.69600769600796e-05*G0_5_3_1_3 - 0.000153920153920159*G0_5_3_1_4 - 0.000153920153920159*G0_5_3_1_5 + 2.88600288600299e-05*G0_5_3_2_1 + 4.81000481000498e-05*G0_5_3_2_2 - 0.000115440115440119*G0_5_3_2_3 - 0.000153920153920159*G0_5_3_2_4 - 0.000230880230880239*G0_5_3_2_5 - 7.69600769600795e-05*G0_5_3_3_0 - 7.69600769600796e-05*G0_5_3_3_1 - 0.000115440115440119*G0_5_3_3_2 + 0.000461760461760477*G0_5_3_3_3 + 0.000461760461760477*G0_5_3_3_4 + 0.000615680615680636*G0_5_3_3_5 - 0.000153920153920159*G0_5_3_4_1 - 0.000153920153920159*G0_5_3_4_2 + 0.000461760461760478*G0_5_3_4_3 + 0.000769600769600796*G0_5_3_4_4 + 0.000769600769600796*G0_5_3_4_5 - 0.000153920153920159*G0_5_3_5_1 - 0.000230880230880239*G0_5_3_5_2 + 0.000615680615680636*G0_5_3_5_3 + 0.000769600769600796*G0_5_3_5_4 + 0.00153920153920159*G0_5_3_5_5 + 0.000481000481000498*G0_5_4_0_0 - 9.62000962000995e-05*G0_5_4_0_1 - 9.62000962000996e-05*G0_5_4_0_2 + 0.000384800384800398*G0_5_4_0_4 + 0.000384800384800398*G0_5_4_0_5 - 9.62000962000996e-05*G0_5_4_1_0 + 9.62000962000995e-05*G0_5_4_1_1 + 7.69600769600796e-05*G0_5_4_1_2 - 0.000153920153920159*G0_5_4_1_3 - 0.000384800384800398*G0_5_4_1_4 - 0.000384800384800398*G0_5_4_1_5 - 9.62000962000996e-05*G0_5_4_2_0 + 7.69600769600796e-05*G0_5_4_2_1 + 9.62000962000995e-05*G0_5_4_2_2 - 0.000153920153920159*G0_5_4_2_3 - 0.000384800384800398*G0_5_4_2_4 - 0.000384800384800398*G0_5_4_2_5 - 0.000153920153920159*G0_5_4_3_1 - 0.000153920153920159*G0_5_4_3_2 + 0.000461760461760477*G0_5_4_3_3 + 0.000769600769600796*G0_5_4_3_4 + 0.000769600769600796*G0_5_4_3_5 + 0.000384800384800398*G0_5_4_4_0 - 0.000384800384800398*G0_5_4_4_1 - 0.000384800384800398*G0_5_4_4_2 + 0.000769600769600796*G0_5_4_4_3 + 0.00230880230880239*G0_5_4_4_4 + 0.00153920153920159*G0_5_4_4_5 + 0.000384800384800398*G0_5_4_5_0 - 0.000384800384800398*G0_5_4_5_1 - 0.000384800384800398*G0_5_4_5_2 + 0.000769600769600796*G0_5_4_5_3 + 0.00153920153920159*G0_5_4_5_4 + 0.00230880230880239*G0_5_4_5_5 + 0.000962000962000996*G0_5_5_0_0 - 0.000288600288600299*G0_5_5_0_1 - 9.62000962000997e-05*G0_5_5_0_2 + 0.000384800384800398*G0_5_5_0_4 + 0.0011544011544012*G0_5_5_0_5 - 0.000288600288600299*G0_5_5_1_0 + 0.000230880230880239*G0_5_5_1_1 + 9.62000962000996e-05*G0_5_5_1_2 - 0.000153920153920159*G0_5_5_1_3 - 0.000384800384800398*G0_5_5_1_4 - 0.000769600769600796*G0_5_5_1_5 - 9.62000962000997e-05*G0_5_5_2_0 + 9.62000962000996e-05*G0_5_5_2_1 + 0.000115440115440119*G0_5_5_2_2 - 0.000230880230880239*G0_5_5_2_3 - 0.000384800384800398*G0_5_5_2_4 - 0.000769600769600797*G0_5_5_2_5 - 0.000153920153920159*G0_5_5_3_1 - 0.000230880230880239*G0_5_5_3_2 + 0.000615680615680636*G0_5_5_3_3 + 0.000769600769600796*G0_5_5_3_4 + 0.00153920153920159*G0_5_5_3_5 + 0.000384800384800398*G0_5_5_4_0 - 0.000384800384800398*G0_5_5_4_1 - 0.000384800384800398*G0_5_5_4_2 + 0.000769600769600796*G0_5_5_4_3 + 0.00153920153920159*G0_5_5_4_4 + 0.00230880230880239*G0_5_5_4_5 + 0.0011544011544012*G0_5_5_5_0 - 0.000769600769600796*G0_5_5_5_1 - 0.000769600769600797*G0_5_5_5_2 + 0.00153920153920159*G0_5_5_5_3 + 0.00230880230880239*G0_5_5_5_4 + 0.00923520923520956*G0_5_5_5_5; + A[7] = A[5]; + A[6] = A[1] + 1.80375180375187e-05*G0_0_0_0_1 - 1.80375180375186e-05*G0_0_0_0_2 + 7.21500721500743e-05*G0_0_0_0_4 - 7.21500721500749e-05*G0_0_0_0_5 + 1.80375180375187e-05*G0_0_0_1_0 - 1.08225108225112e-05*G0_0_0_1_1 - 9.62000962000994e-06*G0_0_0_1_4 + 9.62000962001e-06*G0_0_0_1_5 - 1.80375180375186e-05*G0_0_0_2_0 + 1.08225108225112e-05*G0_0_0_2_2 - 9.62000962000993e-06*G0_0_0_2_4 + 9.62000962000998e-06*G0_0_0_2_5 + 1.92400192400199e-05*G0_0_0_3_4 - 1.92400192400199e-05*G0_0_0_3_5 + 7.21500721500743e-05*G0_0_0_4_0 - 9.62000962000994e-06*G0_0_0_4_1 - 9.62000962000993e-06*G0_0_0_4_2 + 1.92400192400199e-05*G0_0_0_4_3 + 0.000192400192400199*G0_0_0_4_4 - 7.21500721500749e-05*G0_0_0_5_0 + 9.62000962001e-06*G0_0_0_5_1 + 9.62000962000997e-06*G0_0_0_5_2 - 1.92400192400199e-05*G0_0_0_5_3 - 0.000192400192400199*G0_0_0_5_5 + 1.80375180375187e-05*G0_0_1_0_0 - 1.08225108225112e-05*G0_0_1_0_1 - 9.62000962000994e-06*G0_0_1_0_4 + 9.62000962000999e-06*G0_0_1_0_5 - 1.08225108225112e-05*G0_0_1_1_0 + 3.42712842712855e-05*G0_0_1_1_1 + 9.62000962000997e-06*G0_0_1_1_3 + 2.64550264550274e-05*G0_0_1_1_5 + 7.21500721500746e-06*G0_0_1_2_4 - 7.21500721500748e-06*G0_0_1_2_5 + 9.62000962000997e-06*G0_0_1_3_1 + 2.88600288600298e-05*G0_0_1_3_3 + 1.92400192400199e-05*G0_0_1_3_4 + 2.88600288600299e-05*G0_0_1_3_5 - 9.62000962000994e-06*G0_0_1_4_0 + 7.21500721500746e-06*G0_0_1_4_2 + 1.92400192400199e-05*G0_0_1_4_3 + 1.92400192400199e-05*G0_0_1_4_4 + 1.92400192400199e-05*G0_0_1_4_5 + 9.62000962001e-06*G0_0_1_5_0 + 2.64550264550274e-05*G0_0_1_5_1 - 7.21500721500748e-06*G0_0_1_5_2 + 2.88600288600299e-05*G0_0_1_5_3 + 1.92400192400199e-05*G0_0_1_5_4 + 0.00013468013468014*G0_0_1_5_5 - 1.80375180375186e-05*G0_0_2_0_0 + 1.08225108225112e-05*G0_0_2_0_2 - 9.62000962000993e-06*G0_0_2_0_4 + 9.62000962000997e-06*G0_0_2_0_5 + 7.21500721500746e-06*G0_0_2_1_4 - 7.21500721500747e-06*G0_0_2_1_5 + 1.08225108225112e-05*G0_0_2_2_0 - 3.42712842712854e-05*G0_0_2_2_2 - 9.62000962000995e-06*G0_0_2_2_3 - 2.64550264550274e-05*G0_0_2_2_4 - 9.62000962000995e-06*G0_0_2_3_2 - 2.88600288600298e-05*G0_0_2_3_3 - 2.88600288600298e-05*G0_0_2_3_4 - 1.92400192400199e-05*G0_0_2_3_5 - 9.62000962000993e-06*G0_0_2_4_0 + 7.21500721500746e-06*G0_0_2_4_1 - 2.64550264550274e-05*G0_0_2_4_2 - 2.88600288600298e-05*G0_0_2_4_3 - 0.000134680134680139*G0_0_2_4_4 - 1.92400192400199e-05*G0_0_2_4_5 + 9.62000962000997e-06*G0_0_2_5_0 - 7.21500721500748e-06*G0_0_2_5_1 - 1.92400192400199e-05*G0_0_2_5_3 - 1.92400192400199e-05*G0_0_2_5_4 - 1.92400192400198e-05*G0_0_2_5_5 + 1.92400192400199e-05*G0_0_3_0_4 - 1.92400192400199e-05*G0_0_3_0_5 + 9.62000962000997e-06*G0_0_3_1_1 + 2.88600288600298e-05*G0_0_3_1_3 + 1.92400192400199e-05*G0_0_3_1_4 + 2.88600288600299e-05*G0_0_3_1_5 - 9.62000962000995e-06*G0_0_3_2_2 - 2.88600288600298e-05*G0_0_3_2_3 - 2.88600288600298e-05*G0_0_3_2_4 - 1.92400192400199e-05*G0_0_3_2_5 + 2.88600288600298e-05*G0_0_3_3_1 - 2.88600288600298e-05*G0_0_3_3_2 - 3.84800384800397e-05*G0_0_3_3_4 + 3.84800384800398e-05*G0_0_3_3_5 + 1.92400192400199e-05*G0_0_3_4_0 + 1.92400192400199e-05*G0_0_3_4_1 - 2.88600288600298e-05*G0_0_3_4_2 - 3.84800384800397e-05*G0_0_3_4_3 - 7.69600769600796e-05*G0_0_3_4_4 - 1.92400192400199e-05*G0_0_3_5_0 + 2.88600288600299e-05*G0_0_3_5_1 - 1.92400192400199e-05*G0_0_3_5_2 + 3.84800384800398e-05*G0_0_3_5_3 + 7.69600769600795e-05*G0_0_3_5_5 + 7.21500721500743e-05*G0_0_4_0_0 - 9.62000962000994e-06*G0_0_4_0_1 - 9.62000962000993e-06*G0_0_4_0_2 + 1.92400192400199e-05*G0_0_4_0_3 + 0.000192400192400199*G0_0_4_0_4 - 9.62000962000994e-06*G0_0_4_1_0 + 7.21500721500745e-06*G0_0_4_1_2 + 1.92400192400199e-05*G0_0_4_1_3 + 1.92400192400199e-05*G0_0_4_1_4 + 1.92400192400199e-05*G0_0_4_1_5 - 9.62000962000993e-06*G0_0_4_2_0 + 7.21500721500745e-06*G0_0_4_2_1 - 2.64550264550273e-05*G0_0_4_2_2 - 2.88600288600298e-05*G0_0_4_2_3 - 0.000134680134680139*G0_0_4_2_4 - 1.92400192400199e-05*G0_0_4_2_5 + 1.92400192400199e-05*G0_0_4_3_0 + 1.92400192400199e-05*G0_0_4_3_1 - 2.88600288600298e-05*G0_0_4_3_2 - 3.84800384800397e-05*G0_0_4_3_3 - 7.69600769600796e-05*G0_0_4_3_4 + 0.000192400192400199*G0_0_4_4_0 + 1.92400192400199e-05*G0_0_4_4_1 - 0.000134680134680139*G0_0_4_4_2 - 7.69600769600796e-05*G0_0_4_4_3 + 1.92400192400199e-05*G0_0_4_5_1 - 1.92400192400199e-05*G0_0_4_5_2 - 7.21500721500749e-05*G0_0_5_0_0 + 9.62000962001e-06*G0_0_5_0_1 + 9.62000962000997e-06*G0_0_5_0_2 - 1.92400192400199e-05*G0_0_5_0_3 - 0.000192400192400199*G0_0_5_0_5 + 9.62000962001001e-06*G0_0_5_1_0 + 2.64550264550274e-05*G0_0_5_1_1 - 7.21500721500748e-06*G0_0_5_1_2 + 2.88600288600299e-05*G0_0_5_1_3 + 1.92400192400199e-05*G0_0_5_1_4 + 0.00013468013468014*G0_0_5_1_5 + 9.62000962000997e-06*G0_0_5_2_0 - 7.21500721500748e-06*G0_0_5_2_1 - 1.92400192400199e-05*G0_0_5_2_3 - 1.92400192400199e-05*G0_0_5_2_4 - 1.92400192400198e-05*G0_0_5_2_5 - 1.92400192400199e-05*G0_0_5_3_0 + 2.88600288600299e-05*G0_0_5_3_1 - 1.92400192400199e-05*G0_0_5_3_2 + 3.84800384800398e-05*G0_0_5_3_3 + 7.69600769600795e-05*G0_0_5_3_5 + 1.92400192400199e-05*G0_0_5_4_1 - 1.92400192400199e-05*G0_0_5_4_2 - 0.000192400192400199*G0_0_5_5_0 + 0.00013468013468014*G0_0_5_5_1 - 1.92400192400198e-05*G0_0_5_5_2 + 7.69600769600795e-05*G0_0_5_5_3 + 1.80375180375187e-05*G0_1_0_0_0 - 1.08225108225112e-05*G0_1_0_0_1 - 9.62000962000994e-06*G0_1_0_0_4 + 9.62000962000999e-06*G0_1_0_0_5 - 1.08225108225112e-05*G0_1_0_1_0 + 3.42712842712855e-05*G0_1_0_1_1 + 9.62000962000998e-06*G0_1_0_1_3 + 2.64550264550274e-05*G0_1_0_1_5 + 7.21500721500746e-06*G0_1_0_2_4 - 7.21500721500748e-06*G0_1_0_2_5 + 9.62000962000998e-06*G0_1_0_3_1 + 2.88600288600298e-05*G0_1_0_3_3 + 1.92400192400199e-05*G0_1_0_3_4 + 2.88600288600299e-05*G0_1_0_3_5 - 9.62000962000994e-06*G0_1_0_4_0 + 7.21500721500746e-06*G0_1_0_4_2 + 1.92400192400199e-05*G0_1_0_4_3 + 1.92400192400199e-05*G0_1_0_4_4 + 1.92400192400199e-05*G0_1_0_4_5 + 9.62000962001e-06*G0_1_0_5_0 + 2.64550264550274e-05*G0_1_0_5_1 - 7.21500721500748e-06*G0_1_0_5_2 + 2.88600288600299e-05*G0_1_0_5_3 + 1.92400192400199e-05*G0_1_0_5_4 + 0.00013468013468014*G0_1_0_5_5 - 1.08225108225112e-05*G0_1_1_0_0 + 3.42712842712855e-05*G0_1_1_0_1 + 9.62000962000998e-06*G0_1_1_0_3 + 2.64550264550274e-05*G0_1_1_0_5 + 3.42712842712855e-05*G0_1_1_1_0 - 0.000216450216450225*G0_1_1_1_1 + 1.62337662337668e-05*G0_1_1_1_2 - 7.21500721500748e-05*G0_1_1_1_3 - 1.44300144300149e-05*G0_1_1_1_4 - 0.00014430014430015*G0_1_1_1_5 + 1.62337662337668e-05*G0_1_1_2_1 + 1.68350168350174e-05*G0_1_1_2_3 + 1.92400192400199e-05*G0_1_1_2_5 + 9.62000962000998e-06*G0_1_1_3_0 - 7.21500721500748e-05*G0_1_1_3_1 + 1.68350168350174e-05*G0_1_1_3_2 - 3.84800384800399e-05*G0_1_1_3_3 + 9.62000962000993e-06*G0_1_1_3_4 - 5.77200577200598e-05*G0_1_1_3_5 - 1.44300144300149e-05*G0_1_1_4_1 + 9.62000962000992e-06*G0_1_1_4_3 + 3.84800384800398e-05*G0_1_1_4_4 - 9.62000962000997e-06*G0_1_1_4_5 + 2.64550264550274e-05*G0_1_1_5_0 - 0.00014430014430015*G0_1_1_5_1 + 1.92400192400199e-05*G0_1_1_5_2 - 5.77200577200598e-05*G0_1_1_5_3 - 9.62000962000997e-06*G0_1_1_5_4 - 0.000230880230880239*G0_1_1_5_5 + 7.21500721500746e-06*G0_1_2_0_4 - 7.21500721500747e-06*G0_1_2_0_5 + 1.62337662337668e-05*G0_1_2_1_1 + 1.68350168350174e-05*G0_1_2_1_3 + 1.92400192400199e-05*G0_1_2_1_5 - 1.62337662337668e-05*G0_1_2_2_2 - 1.68350168350174e-05*G0_1_2_2_3 - 1.92400192400199e-05*G0_1_2_2_4 + 1.68350168350174e-05*G0_1_2_3_1 - 1.68350168350174e-05*G0_1_2_3_2 + 7.21500721500746e-06*G0_1_2_4_0 - 1.92400192400199e-05*G0_1_2_4_2 - 9.62000962000992e-06*G0_1_2_4_4 - 7.21500721500747e-06*G0_1_2_5_0 + 1.92400192400199e-05*G0_1_2_5_1 + 9.62000962000997e-06*G0_1_2_5_5 + 9.62000962000997e-06*G0_1_3_0_1 + 2.88600288600299e-05*G0_1_3_0_3 + 1.92400192400199e-05*G0_1_3_0_4 + 2.88600288600299e-05*G0_1_3_0_5 + 9.62000962000998e-06*G0_1_3_1_0 - 7.21500721500748e-05*G0_1_3_1_1 + 1.68350168350174e-05*G0_1_3_1_2 - 3.84800384800399e-05*G0_1_3_1_3 + 9.62000962000993e-06*G0_1_3_1_4 - 5.77200577200598e-05*G0_1_3_1_5 + 1.68350168350174e-05*G0_1_3_2_1 - 1.68350168350174e-05*G0_1_3_2_2 + 2.88600288600298e-05*G0_1_3_3_0 - 3.84800384800399e-05*G0_1_3_3_1 - 0.000153920153920159*G0_1_3_3_3 - 7.69600769600795e-05*G0_1_3_3_4 - 7.69600769600796e-05*G0_1_3_3_5 + 1.92400192400199e-05*G0_1_3_4_0 + 9.62000962000993e-06*G0_1_3_4_1 - 7.69600769600795e-05*G0_1_3_4_3 - 0.000115440115440119*G0_1_3_4_4 - 3.84800384800397e-05*G0_1_3_4_5 + 2.88600288600299e-05*G0_1_3_5_0 - 5.77200577200598e-05*G0_1_3_5_1 - 7.69600769600796e-05*G0_1_3_5_3 - 3.84800384800397e-05*G0_1_3_5_4 - 7.69600769600796e-05*G0_1_3_5_5 - 9.62000962000994e-06*G0_1_4_0_0 + 7.21500721500745e-06*G0_1_4_0_2 + 1.92400192400199e-05*G0_1_4_0_3 + 1.92400192400199e-05*G0_1_4_0_4 + 1.92400192400199e-05*G0_1_4_0_5 - 1.44300144300149e-05*G0_1_4_1_1 + 9.62000962000992e-06*G0_1_4_1_3 + 3.84800384800398e-05*G0_1_4_1_4 - 9.62000962000997e-06*G0_1_4_1_5 + 7.21500721500745e-06*G0_1_4_2_0 - 1.92400192400199e-05*G0_1_4_2_2 - 9.62000962000992e-06*G0_1_4_2_4 + 1.92400192400199e-05*G0_1_4_3_0 + 9.62000962000993e-06*G0_1_4_3_1 - 7.69600769600795e-05*G0_1_4_3_3 - 0.000115440115440119*G0_1_4_3_4 - 3.84800384800398e-05*G0_1_4_3_5 + 1.92400192400199e-05*G0_1_4_4_0 + 3.84800384800398e-05*G0_1_4_4_1 - 9.62000962000992e-06*G0_1_4_4_2 - 0.000115440115440119*G0_1_4_4_3 - 0.000384800384800398*G0_1_4_4_4 - 7.69600769600795e-05*G0_1_4_4_5 + 1.92400192400199e-05*G0_1_4_5_0 - 9.62000962000997e-06*G0_1_4_5_1 - 3.84800384800397e-05*G0_1_4_5_3 - 7.69600769600795e-05*G0_1_4_5_4 + 9.62000962001001e-06*G0_1_5_0_0 + 2.64550264550274e-05*G0_1_5_0_1 - 7.21500721500748e-06*G0_1_5_0_2 + 2.88600288600299e-05*G0_1_5_0_3 + 1.92400192400199e-05*G0_1_5_0_4 + 0.00013468013468014*G0_1_5_0_5 + 2.64550264550274e-05*G0_1_5_1_0 - 0.00014430014430015*G0_1_5_1_1 + 1.92400192400199e-05*G0_1_5_1_2 - 5.77200577200598e-05*G0_1_5_1_3 - 9.62000962000997e-06*G0_1_5_1_4 - 0.000230880230880239*G0_1_5_1_5 - 7.21500721500748e-06*G0_1_5_2_0 + 1.92400192400199e-05*G0_1_5_2_1 + 9.62000962000997e-06*G0_1_5_2_5 + 2.88600288600299e-05*G0_1_5_3_0 - 5.77200577200598e-05*G0_1_5_3_1 - 7.69600769600796e-05*G0_1_5_3_3 - 3.84800384800397e-05*G0_1_5_3_4 - 7.69600769600797e-05*G0_1_5_3_5 + 1.92400192400199e-05*G0_1_5_4_0 - 9.62000962000997e-06*G0_1_5_4_1 - 3.84800384800397e-05*G0_1_5_4_3 - 7.69600769600796e-05*G0_1_5_4_4 + 0.00013468013468014*G0_1_5_5_0 - 0.000230880230880239*G0_1_5_5_1 + 9.62000962000998e-06*G0_1_5_5_2 - 7.69600769600796e-05*G0_1_5_5_3 - 0.00015392015392016*G0_1_5_5_5 - 1.80375180375186e-05*G0_2_0_0_0 + 1.08225108225112e-05*G0_2_0_0_2 - 9.62000962000993e-06*G0_2_0_0_4 + 9.62000962000997e-06*G0_2_0_0_5 + 7.21500721500746e-06*G0_2_0_1_4 - 7.21500721500748e-06*G0_2_0_1_5 + 1.08225108225112e-05*G0_2_0_2_0 - 3.42712842712854e-05*G0_2_0_2_2 - 9.62000962000995e-06*G0_2_0_2_3 - 2.64550264550274e-05*G0_2_0_2_4 - 9.62000962000995e-06*G0_2_0_3_2 - 2.88600288600298e-05*G0_2_0_3_3 - 2.88600288600298e-05*G0_2_0_3_4 - 1.92400192400199e-05*G0_2_0_3_5 - 9.62000962000993e-06*G0_2_0_4_0 + 7.21500721500746e-06*G0_2_0_4_1 - 2.64550264550274e-05*G0_2_0_4_2 - 2.88600288600298e-05*G0_2_0_4_3 - 0.000134680134680139*G0_2_0_4_4 - 1.92400192400199e-05*G0_2_0_4_5 + 9.62000962000997e-06*G0_2_0_5_0 - 7.21500721500748e-06*G0_2_0_5_1 - 1.92400192400199e-05*G0_2_0_5_3 - 1.92400192400199e-05*G0_2_0_5_4 - 1.92400192400198e-05*G0_2_0_5_5 + 7.21500721500746e-06*G0_2_1_0_4 - 7.21500721500748e-06*G0_2_1_0_5 + 1.62337662337668e-05*G0_2_1_1_1 + 1.68350168350174e-05*G0_2_1_1_3 + 1.92400192400199e-05*G0_2_1_1_5 - 1.62337662337668e-05*G0_2_1_2_2 - 1.68350168350174e-05*G0_2_1_2_3 - 1.92400192400199e-05*G0_2_1_2_4 + 1.68350168350174e-05*G0_2_1_3_1 - 1.68350168350174e-05*G0_2_1_3_2 + 7.21500721500745e-06*G0_2_1_4_0 - 1.92400192400199e-05*G0_2_1_4_2 - 9.62000962000993e-06*G0_2_1_4_4 - 7.21500721500748e-06*G0_2_1_5_0 + 1.92400192400199e-05*G0_2_1_5_1 + 9.62000962000997e-06*G0_2_1_5_5 + 1.08225108225112e-05*G0_2_2_0_0 - 3.42712842712854e-05*G0_2_2_0_2 - 9.62000962000995e-06*G0_2_2_0_3 - 2.64550264550274e-05*G0_2_2_0_4 - 1.62337662337668e-05*G0_2_2_1_2 - 1.68350168350174e-05*G0_2_2_1_3 - 1.92400192400199e-05*G0_2_2_1_4 - 3.42712842712854e-05*G0_2_2_2_0 - 1.62337662337668e-05*G0_2_2_2_1 + 0.000216450216450224*G0_2_2_2_2 + 7.21500721500746e-05*G0_2_2_2_3 + 0.000144300144300149*G0_2_2_2_4 + 1.44300144300149e-05*G0_2_2_2_5 - 9.62000962000995e-06*G0_2_2_3_0 - 1.68350168350174e-05*G0_2_2_3_1 + 7.21500721500746e-05*G0_2_2_3_2 + 3.84800384800398e-05*G0_2_2_3_3 + 5.77200577200597e-05*G0_2_2_3_4 - 9.62000962000996e-06*G0_2_2_3_5 - 2.64550264550274e-05*G0_2_2_4_0 - 1.92400192400199e-05*G0_2_2_4_1 + 0.000144300144300149*G0_2_2_4_2 + 5.77200577200597e-05*G0_2_2_4_3 + 0.000230880230880239*G0_2_2_4_4 + 9.62000962000995e-06*G0_2_2_4_5 + 1.44300144300149e-05*G0_2_2_5_2 - 9.62000962000995e-06*G0_2_2_5_3 + 9.62000962000995e-06*G0_2_2_5_4 - 3.84800384800398e-05*G0_2_2_5_5 - 9.62000962000995e-06*G0_2_3_0_2 - 2.88600288600298e-05*G0_2_3_0_3 - 2.88600288600298e-05*G0_2_3_0_4 - 1.92400192400199e-05*G0_2_3_0_5 + 1.68350168350174e-05*G0_2_3_1_1 - 1.68350168350174e-05*G0_2_3_1_2 - 9.62000962000995e-06*G0_2_3_2_0 - 1.68350168350174e-05*G0_2_3_2_1 + 7.21500721500746e-05*G0_2_3_2_2 + 3.84800384800398e-05*G0_2_3_2_3 + 5.77200577200597e-05*G0_2_3_2_4 - 9.62000962000996e-06*G0_2_3_2_5 - 2.88600288600298e-05*G0_2_3_3_0 + 3.84800384800398e-05*G0_2_3_3_2 + 0.000153920153920159*G0_2_3_3_3 + 7.69600769600796e-05*G0_2_3_3_4 + 7.69600769600796e-05*G0_2_3_3_5 - 2.88600288600298e-05*G0_2_3_4_0 + 5.77200577200597e-05*G0_2_3_4_2 + 7.69600769600796e-05*G0_2_3_4_3 + 7.69600769600796e-05*G0_2_3_4_4 + 3.84800384800398e-05*G0_2_3_4_5 - 1.92400192400199e-05*G0_2_3_5_0 - 9.62000962000995e-06*G0_2_3_5_2 + 7.69600769600796e-05*G0_2_3_5_3 + 3.84800384800398e-05*G0_2_3_5_4 + 0.000115440115440119*G0_2_3_5_5 - 9.62000962000993e-06*G0_2_4_0_0 + 7.21500721500745e-06*G0_2_4_0_1 - 2.64550264550274e-05*G0_2_4_0_2 - 2.88600288600298e-05*G0_2_4_0_3 - 0.000134680134680139*G0_2_4_0_4 - 1.92400192400199e-05*G0_2_4_0_5 + 7.21500721500746e-06*G0_2_4_1_0 - 1.92400192400199e-05*G0_2_4_1_2 - 9.62000962000994e-06*G0_2_4_1_4 - 2.64550264550274e-05*G0_2_4_2_0 - 1.92400192400199e-05*G0_2_4_2_1 + 0.000144300144300149*G0_2_4_2_2 + 5.77200577200597e-05*G0_2_4_2_3 + 0.000230880230880239*G0_2_4_2_4 + 9.62000962000994e-06*G0_2_4_2_5 - 2.88600288600298e-05*G0_2_4_3_0 + 5.77200577200597e-05*G0_2_4_3_2 + 7.69600769600796e-05*G0_2_4_3_3 + 7.69600769600796e-05*G0_2_4_3_4 + 3.84800384800398e-05*G0_2_4_3_5 - 0.000134680134680139*G0_2_4_4_0 - 9.62000962000993e-06*G0_2_4_4_1 + 0.000230880230880239*G0_2_4_4_2 + 7.69600769600796e-05*G0_2_4_4_3 + 0.000153920153920159*G0_2_4_4_4 - 1.92400192400199e-05*G0_2_4_5_0 + 9.62000962000995e-06*G0_2_4_5_2 + 3.84800384800398e-05*G0_2_4_5_3 + 7.69600769600797e-05*G0_2_4_5_5 + 9.62000962000997e-06*G0_2_5_0_0 - 7.21500721500748e-06*G0_2_5_0_1 - 1.92400192400199e-05*G0_2_5_0_3 - 1.92400192400199e-05*G0_2_5_0_4 - 1.92400192400198e-05*G0_2_5_0_5 - 7.21500721500748e-06*G0_2_5_1_0 + 1.92400192400199e-05*G0_2_5_1_1 + 9.62000962000997e-06*G0_2_5_1_5 + 1.44300144300149e-05*G0_2_5_2_2 - 9.62000962000995e-06*G0_2_5_2_3 + 9.62000962000995e-06*G0_2_5_2_4 - 3.84800384800398e-05*G0_2_5_2_5 - 1.92400192400199e-05*G0_2_5_3_0 - 9.62000962000995e-06*G0_2_5_3_2 + 7.69600769600796e-05*G0_2_5_3_3 + 3.84800384800398e-05*G0_2_5_3_4 + 0.000115440115440119*G0_2_5_3_5 - 1.92400192400199e-05*G0_2_5_4_0 + 9.62000962000995e-06*G0_2_5_4_2 + 3.84800384800398e-05*G0_2_5_4_3 + 7.69600769600797e-05*G0_2_5_4_5 - 1.92400192400198e-05*G0_2_5_5_0 + 9.62000962000997e-06*G0_2_5_5_1 - 3.84800384800398e-05*G0_2_5_5_2 + 0.000115440115440119*G0_2_5_5_3 + 7.69600769600797e-05*G0_2_5_5_4 + 0.000384800384800398*G0_2_5_5_5 + 1.92400192400199e-05*G0_3_0_0_4 - 1.92400192400199e-05*G0_3_0_0_5 + 9.62000962000997e-06*G0_3_0_1_1 + 2.88600288600299e-05*G0_3_0_1_3 + 1.92400192400199e-05*G0_3_0_1_4 + 2.88600288600299e-05*G0_3_0_1_5 - 9.62000962000995e-06*G0_3_0_2_2 - 2.88600288600298e-05*G0_3_0_2_3 - 2.88600288600298e-05*G0_3_0_2_4 - 1.92400192400199e-05*G0_3_0_2_5 + 2.88600288600299e-05*G0_3_0_3_1 - 2.88600288600298e-05*G0_3_0_3_2 - 3.84800384800397e-05*G0_3_0_3_4 + 3.84800384800398e-05*G0_3_0_3_5 + 1.92400192400199e-05*G0_3_0_4_0 + 1.92400192400199e-05*G0_3_0_4_1 - 2.88600288600298e-05*G0_3_0_4_2 - 3.84800384800397e-05*G0_3_0_4_3 - 7.69600769600796e-05*G0_3_0_4_4 - 1.92400192400199e-05*G0_3_0_5_0 + 2.88600288600299e-05*G0_3_0_5_1 - 1.92400192400199e-05*G0_3_0_5_2 + 3.84800384800398e-05*G0_3_0_5_3 + 7.69600769600795e-05*G0_3_0_5_5 + 9.62000962000997e-06*G0_3_1_0_1 + 2.88600288600299e-05*G0_3_1_0_3 + 1.92400192400199e-05*G0_3_1_0_4 + 2.88600288600299e-05*G0_3_1_0_5 + 9.62000962000997e-06*G0_3_1_1_0 - 7.21500721500748e-05*G0_3_1_1_1 + 1.68350168350174e-05*G0_3_1_1_2 - 3.84800384800399e-05*G0_3_1_1_3 + 9.62000962000993e-06*G0_3_1_1_4 - 5.77200577200598e-05*G0_3_1_1_5 + 1.68350168350174e-05*G0_3_1_2_1 - 1.68350168350174e-05*G0_3_1_2_2 + 2.88600288600299e-05*G0_3_1_3_0 - 3.84800384800399e-05*G0_3_1_3_1 - 0.000153920153920159*G0_3_1_3_3 - 7.69600769600795e-05*G0_3_1_3_4 - 7.69600769600796e-05*G0_3_1_3_5 + 1.92400192400199e-05*G0_3_1_4_0 + 9.62000962000993e-06*G0_3_1_4_1 - 7.69600769600796e-05*G0_3_1_4_3 - 0.000115440115440119*G0_3_1_4_4 - 3.84800384800397e-05*G0_3_1_4_5 + 2.88600288600299e-05*G0_3_1_5_0 - 5.77200577200598e-05*G0_3_1_5_1 - 7.69600769600796e-05*G0_3_1_5_3 - 3.84800384800397e-05*G0_3_1_5_4 - 7.69600769600796e-05*G0_3_1_5_5 - 9.62000962000995e-06*G0_3_2_0_2 - 2.88600288600298e-05*G0_3_2_0_3 - 2.88600288600298e-05*G0_3_2_0_4 - 1.92400192400199e-05*G0_3_2_0_5 + 1.68350168350174e-05*G0_3_2_1_1 - 1.68350168350174e-05*G0_3_2_1_2 - 9.62000962000995e-06*G0_3_2_2_0 - 1.68350168350174e-05*G0_3_2_2_1 + 7.21500721500746e-05*G0_3_2_2_2 + 3.84800384800398e-05*G0_3_2_2_3 + 5.77200577200597e-05*G0_3_2_2_4 - 9.62000962000996e-06*G0_3_2_2_5 - 2.88600288600298e-05*G0_3_2_3_0 + 3.84800384800398e-05*G0_3_2_3_2 + 0.000153920153920159*G0_3_2_3_3 + 7.69600769600796e-05*G0_3_2_3_4 + 7.69600769600796e-05*G0_3_2_3_5 - 2.88600288600298e-05*G0_3_2_4_0 + 5.77200577200597e-05*G0_3_2_4_2 + 7.69600769600796e-05*G0_3_2_4_3 + 7.69600769600796e-05*G0_3_2_4_4 + 3.84800384800398e-05*G0_3_2_4_5 - 1.92400192400199e-05*G0_3_2_5_0 - 9.62000962000995e-06*G0_3_2_5_2 + 7.69600769600796e-05*G0_3_2_5_3 + 3.84800384800398e-05*G0_3_2_5_4 + 0.000115440115440119*G0_3_2_5_5 + 2.88600288600298e-05*G0_3_3_0_1 - 2.88600288600298e-05*G0_3_3_0_2 - 3.84800384800397e-05*G0_3_3_0_4 + 3.84800384800398e-05*G0_3_3_0_5 + 2.88600288600298e-05*G0_3_3_1_0 - 3.84800384800399e-05*G0_3_3_1_1 - 0.000153920153920159*G0_3_3_1_3 - 7.69600769600795e-05*G0_3_3_1_4 - 7.69600769600796e-05*G0_3_3_1_5 - 2.88600288600298e-05*G0_3_3_2_0 + 3.84800384800398e-05*G0_3_3_2_2 + 0.000153920153920159*G0_3_3_2_3 + 7.69600769600796e-05*G0_3_3_2_4 + 7.69600769600796e-05*G0_3_3_2_5 - 0.000153920153920159*G0_3_3_3_1 + 0.000153920153920159*G0_3_3_3_2 + 0.000153920153920159*G0_3_3_3_4 - 0.00015392015392016*G0_3_3_3_5 - 3.84800384800397e-05*G0_3_3_4_0 - 7.69600769600795e-05*G0_3_3_4_1 + 7.69600769600796e-05*G0_3_3_4_2 + 0.000153920153920159*G0_3_3_4_3 + 0.000307840307840318*G0_3_3_4_4 + 3.84800384800398e-05*G0_3_3_5_0 - 7.69600769600796e-05*G0_3_3_5_1 + 7.69600769600796e-05*G0_3_3_5_2 - 0.00015392015392016*G0_3_3_5_3 - 0.000307840307840318*G0_3_3_5_5 + 1.92400192400199e-05*G0_3_4_0_0 + 1.92400192400199e-05*G0_3_4_0_1 - 2.88600288600298e-05*G0_3_4_0_2 - 3.84800384800397e-05*G0_3_4_0_3 - 7.69600769600796e-05*G0_3_4_0_4 + 1.92400192400199e-05*G0_3_4_1_0 + 9.62000962000993e-06*G0_3_4_1_1 - 7.69600769600795e-05*G0_3_4_1_3 - 0.000115440115440119*G0_3_4_1_4 - 3.84800384800397e-05*G0_3_4_1_5 - 2.88600288600298e-05*G0_3_4_2_0 + 5.77200577200597e-05*G0_3_4_2_2 + 7.69600769600796e-05*G0_3_4_2_3 + 7.69600769600796e-05*G0_3_4_2_4 + 3.84800384800398e-05*G0_3_4_2_5 - 3.84800384800397e-05*G0_3_4_3_0 - 7.69600769600795e-05*G0_3_4_3_1 + 7.69600769600796e-05*G0_3_4_3_2 + 0.000153920153920159*G0_3_4_3_3 + 0.000307840307840318*G0_3_4_3_4 - 7.69600769600796e-05*G0_3_4_4_0 - 0.000115440115440119*G0_3_4_4_1 + 7.69600769600796e-05*G0_3_4_4_2 + 0.000307840307840318*G0_3_4_4_3 + 0.000923520923520955*G0_3_4_4_4 + 0.000153920153920159*G0_3_4_4_5 - 3.84800384800397e-05*G0_3_4_5_1 + 3.84800384800398e-05*G0_3_4_5_2 + 0.000153920153920159*G0_3_4_5_4 - 0.000153920153920159*G0_3_4_5_5 - 1.92400192400199e-05*G0_3_5_0_0 + 2.88600288600299e-05*G0_3_5_0_1 - 1.92400192400199e-05*G0_3_5_0_2 + 3.84800384800398e-05*G0_3_5_0_3 + 7.69600769600795e-05*G0_3_5_0_5 + 2.88600288600299e-05*G0_3_5_1_0 - 5.77200577200598e-05*G0_3_5_1_1 - 7.69600769600796e-05*G0_3_5_1_3 - 3.84800384800398e-05*G0_3_5_1_4 - 7.69600769600797e-05*G0_3_5_1_5 - 1.92400192400199e-05*G0_3_5_2_0 - 9.62000962000995e-06*G0_3_5_2_2 + 7.69600769600796e-05*G0_3_5_2_3 + 3.84800384800398e-05*G0_3_5_2_4 + 0.000115440115440119*G0_3_5_2_5 + 3.84800384800398e-05*G0_3_5_3_0 - 7.69600769600796e-05*G0_3_5_3_1 + 7.69600769600796e-05*G0_3_5_3_2 - 0.00015392015392016*G0_3_5_3_3 - 0.000307840307840318*G0_3_5_3_5 - 3.84800384800398e-05*G0_3_5_4_1 + 3.84800384800398e-05*G0_3_5_4_2 + 0.000153920153920159*G0_3_5_4_4 - 0.000153920153920159*G0_3_5_4_5 + 7.69600769600795e-05*G0_3_5_5_0 - 7.69600769600797e-05*G0_3_5_5_1 + 0.000115440115440119*G0_3_5_5_2 - 0.000307840307840318*G0_3_5_5_3 - 0.000153920153920159*G0_3_5_5_4 - 0.000923520923520956*G0_3_5_5_5 + 7.21500721500743e-05*G0_4_0_0_0 - 9.62000962000994e-06*G0_4_0_0_1 - 9.62000962000993e-06*G0_4_0_0_2 + 1.92400192400199e-05*G0_4_0_0_3 + 0.000192400192400199*G0_4_0_0_4 - 9.62000962000994e-06*G0_4_0_1_0 + 7.21500721500745e-06*G0_4_0_1_2 + 1.92400192400199e-05*G0_4_0_1_3 + 1.92400192400199e-05*G0_4_0_1_4 + 1.92400192400199e-05*G0_4_0_1_5 - 9.62000962000993e-06*G0_4_0_2_0 + 7.21500721500746e-06*G0_4_0_2_1 - 2.64550264550274e-05*G0_4_0_2_2 - 2.88600288600298e-05*G0_4_0_2_3 - 0.000134680134680139*G0_4_0_2_4 - 1.92400192400199e-05*G0_4_0_2_5 + 1.92400192400199e-05*G0_4_0_3_0 + 1.92400192400199e-05*G0_4_0_3_1 - 2.88600288600298e-05*G0_4_0_3_2 - 3.84800384800397e-05*G0_4_0_3_3 - 7.69600769600796e-05*G0_4_0_3_4 + 0.000192400192400199*G0_4_0_4_0 + 1.92400192400199e-05*G0_4_0_4_1 - 0.000134680134680139*G0_4_0_4_2 - 7.69600769600796e-05*G0_4_0_4_3 + 1.92400192400199e-05*G0_4_0_5_1 - 1.92400192400199e-05*G0_4_0_5_2 - 9.62000962000994e-06*G0_4_1_0_0 + 7.21500721500746e-06*G0_4_1_0_2 + 1.92400192400199e-05*G0_4_1_0_3 + 1.92400192400199e-05*G0_4_1_0_4 + 1.92400192400199e-05*G0_4_1_0_5 - 1.44300144300149e-05*G0_4_1_1_1 + 9.62000962000993e-06*G0_4_1_1_3 + 3.84800384800398e-05*G0_4_1_1_4 - 9.62000962000998e-06*G0_4_1_1_5 + 7.21500721500746e-06*G0_4_1_2_0 - 1.92400192400199e-05*G0_4_1_2_2 - 9.62000962000993e-06*G0_4_1_2_4 + 1.92400192400199e-05*G0_4_1_3_0 + 9.62000962000992e-06*G0_4_1_3_1 - 7.69600769600795e-05*G0_4_1_3_3 - 0.000115440115440119*G0_4_1_3_4 - 3.84800384800397e-05*G0_4_1_3_5 + 1.92400192400199e-05*G0_4_1_4_0 + 3.84800384800398e-05*G0_4_1_4_1 - 9.62000962000993e-06*G0_4_1_4_2 - 0.000115440115440119*G0_4_1_4_3 - 0.000384800384800398*G0_4_1_4_4 - 7.69600769600795e-05*G0_4_1_4_5 + 1.92400192400199e-05*G0_4_1_5_0 - 9.62000962000997e-06*G0_4_1_5_1 - 3.84800384800397e-05*G0_4_1_5_3 - 7.69600769600795e-05*G0_4_1_5_4 - 9.62000962000992e-06*G0_4_2_0_0 + 7.21500721500745e-06*G0_4_2_0_1 - 2.64550264550274e-05*G0_4_2_0_2 - 2.88600288600298e-05*G0_4_2_0_3 - 0.000134680134680139*G0_4_2_0_4 - 1.92400192400199e-05*G0_4_2_0_5 + 7.21500721500746e-06*G0_4_2_1_0 - 1.92400192400199e-05*G0_4_2_1_2 - 9.62000962000994e-06*G0_4_2_1_4 - 2.64550264550274e-05*G0_4_2_2_0 - 1.92400192400199e-05*G0_4_2_2_1 + 0.000144300144300149*G0_4_2_2_2 + 5.77200577200597e-05*G0_4_2_2_3 + 0.000230880230880239*G0_4_2_2_4 + 9.62000962000994e-06*G0_4_2_2_5 - 2.88600288600298e-05*G0_4_2_3_0 + 5.77200577200597e-05*G0_4_2_3_2 + 7.69600769600796e-05*G0_4_2_3_3 + 7.69600769600796e-05*G0_4_2_3_4 + 3.84800384800398e-05*G0_4_2_3_5 - 0.000134680134680139*G0_4_2_4_0 - 9.62000962000993e-06*G0_4_2_4_1 + 0.000230880230880239*G0_4_2_4_2 + 7.69600769600796e-05*G0_4_2_4_3 + 0.000153920153920159*G0_4_2_4_4 - 1.92400192400199e-05*G0_4_2_5_0 + 9.62000962000995e-06*G0_4_2_5_2 + 3.84800384800398e-05*G0_4_2_5_3 + 7.69600769600797e-05*G0_4_2_5_5 + 1.92400192400199e-05*G0_4_3_0_0 + 1.92400192400199e-05*G0_4_3_0_1 - 2.88600288600298e-05*G0_4_3_0_2 - 3.84800384800397e-05*G0_4_3_0_3 - 7.69600769600796e-05*G0_4_3_0_4 + 1.92400192400199e-05*G0_4_3_1_0 + 9.62000962000992e-06*G0_4_3_1_1 - 7.69600769600795e-05*G0_4_3_1_3 - 0.000115440115440119*G0_4_3_1_4 - 3.84800384800397e-05*G0_4_3_1_5 - 2.88600288600298e-05*G0_4_3_2_0 + 5.77200577200597e-05*G0_4_3_2_2 + 7.69600769600796e-05*G0_4_3_2_3 + 7.69600769600796e-05*G0_4_3_2_4 + 3.84800384800398e-05*G0_4_3_2_5 - 3.84800384800397e-05*G0_4_3_3_0 - 7.69600769600795e-05*G0_4_3_3_1 + 7.69600769600796e-05*G0_4_3_3_2 + 0.000153920153920159*G0_4_3_3_3 + 0.000307840307840318*G0_4_3_3_4 - 7.69600769600796e-05*G0_4_3_4_0 - 0.000115440115440119*G0_4_3_4_1 + 7.69600769600796e-05*G0_4_3_4_2 + 0.000307840307840318*G0_4_3_4_3 + 0.000923520923520955*G0_4_3_4_4 + 0.000153920153920159*G0_4_3_4_5 - 3.84800384800397e-05*G0_4_3_5_1 + 3.84800384800398e-05*G0_4_3_5_2 + 0.000153920153920159*G0_4_3_5_4 - 0.000153920153920159*G0_4_3_5_5 + 0.000192400192400199*G0_4_4_0_0 + 1.92400192400199e-05*G0_4_4_0_1 - 0.000134680134680139*G0_4_4_0_2 - 7.69600769600796e-05*G0_4_4_0_3 + 1.92400192400199e-05*G0_4_4_1_0 + 3.84800384800398e-05*G0_4_4_1_1 - 9.62000962000994e-06*G0_4_4_1_2 - 0.000115440115440119*G0_4_4_1_3 - 0.000384800384800398*G0_4_4_1_4 - 7.69600769600795e-05*G0_4_4_1_5 - 0.000134680134680139*G0_4_4_2_0 - 9.62000962000994e-06*G0_4_4_2_1 + 0.000230880230880239*G0_4_4_2_2 + 7.69600769600796e-05*G0_4_4_2_3 + 0.000153920153920159*G0_4_4_2_4 - 7.69600769600796e-05*G0_4_4_3_0 - 0.000115440115440119*G0_4_4_3_1 + 7.69600769600796e-05*G0_4_4_3_2 + 0.000307840307840318*G0_4_4_3_3 + 0.000923520923520955*G0_4_4_3_4 + 0.000153920153920159*G0_4_4_3_5 - 0.000384800384800398*G0_4_4_4_1 + 0.000153920153920159*G0_4_4_4_2 + 0.000923520923520955*G0_4_4_4_3 + 0.00615680615680636*G0_4_4_4_4 + 0.000769600769600795*G0_4_4_4_5 - 7.69600769600795e-05*G0_4_4_5_1 + 0.000153920153920159*G0_4_4_5_3 + 0.000769600769600795*G0_4_4_5_4 + 1.92400192400199e-05*G0_4_5_0_1 - 1.92400192400199e-05*G0_4_5_0_2 + 1.92400192400199e-05*G0_4_5_1_0 - 9.62000962000998e-06*G0_4_5_1_1 - 3.84800384800397e-05*G0_4_5_1_3 - 7.69600769600795e-05*G0_4_5_1_4 - 1.92400192400199e-05*G0_4_5_2_0 + 9.62000962000995e-06*G0_4_5_2_2 + 3.84800384800398e-05*G0_4_5_2_3 + 7.69600769600797e-05*G0_4_5_2_5 - 3.84800384800397e-05*G0_4_5_3_1 + 3.84800384800398e-05*G0_4_5_3_2 + 0.000153920153920159*G0_4_5_3_4 - 0.000153920153920159*G0_4_5_3_5 - 7.69600769600796e-05*G0_4_5_4_1 + 0.000153920153920159*G0_4_5_4_3 + 0.000769600769600795*G0_4_5_4_4 + 7.69600769600797e-05*G0_4_5_5_2 - 0.000153920153920159*G0_4_5_5_3 - 0.000769600769600796*G0_4_5_5_5 - 7.21500721500749e-05*G0_5_0_0_0 + 9.62000962001e-06*G0_5_0_0_1 + 9.62000962000997e-06*G0_5_0_0_2 - 1.92400192400199e-05*G0_5_0_0_3 - 0.000192400192400199*G0_5_0_0_5 + 9.62000962001001e-06*G0_5_0_1_0 + 2.64550264550274e-05*G0_5_0_1_1 - 7.21500721500748e-06*G0_5_0_1_2 + 2.88600288600299e-05*G0_5_0_1_3 + 1.92400192400199e-05*G0_5_0_1_4 + 0.00013468013468014*G0_5_0_1_5 + 9.62000962000997e-06*G0_5_0_2_0 - 7.21500721500748e-06*G0_5_0_2_1 - 1.92400192400199e-05*G0_5_0_2_3 - 1.92400192400199e-05*G0_5_0_2_4 - 1.92400192400199e-05*G0_5_0_2_5 - 1.92400192400199e-05*G0_5_0_3_0 + 2.88600288600299e-05*G0_5_0_3_1 - 1.92400192400199e-05*G0_5_0_3_2 + 3.84800384800398e-05*G0_5_0_3_3 + 7.69600769600795e-05*G0_5_0_3_5 + 1.92400192400199e-05*G0_5_0_4_1 - 1.92400192400199e-05*G0_5_0_4_2 - 0.000192400192400199*G0_5_0_5_0 + 0.00013468013468014*G0_5_0_5_1 - 1.92400192400198e-05*G0_5_0_5_2 + 7.69600769600795e-05*G0_5_0_5_3 + 9.62000962001001e-06*G0_5_1_0_0 + 2.64550264550274e-05*G0_5_1_0_1 - 7.21500721500748e-06*G0_5_1_0_2 + 2.88600288600299e-05*G0_5_1_0_3 + 1.92400192400199e-05*G0_5_1_0_4 + 0.00013468013468014*G0_5_1_0_5 + 2.64550264550274e-05*G0_5_1_1_0 - 0.00014430014430015*G0_5_1_1_1 + 1.92400192400199e-05*G0_5_1_1_2 - 5.77200577200598e-05*G0_5_1_1_3 - 9.62000962000997e-06*G0_5_1_1_4 - 0.000230880230880239*G0_5_1_1_5 - 7.21500721500748e-06*G0_5_1_2_0 + 1.92400192400199e-05*G0_5_1_2_1 + 9.62000962000997e-06*G0_5_1_2_5 + 2.88600288600299e-05*G0_5_1_3_0 - 5.77200577200598e-05*G0_5_1_3_1 - 7.69600769600796e-05*G0_5_1_3_3 - 3.84800384800397e-05*G0_5_1_3_4 - 7.69600769600797e-05*G0_5_1_3_5 + 1.92400192400199e-05*G0_5_1_4_0 - 9.62000962000997e-06*G0_5_1_4_1 - 3.84800384800397e-05*G0_5_1_4_3 - 7.69600769600795e-05*G0_5_1_4_4 + 0.00013468013468014*G0_5_1_5_0 - 0.000230880230880239*G0_5_1_5_1 + 9.62000962000998e-06*G0_5_1_5_2 - 7.69600769600797e-05*G0_5_1_5_3 - 0.00015392015392016*G0_5_1_5_5 + 9.62000962000997e-06*G0_5_2_0_0 - 7.21500721500748e-06*G0_5_2_0_1 - 1.92400192400199e-05*G0_5_2_0_3 - 1.92400192400199e-05*G0_5_2_0_4 - 1.92400192400198e-05*G0_5_2_0_5 - 7.21500721500748e-06*G0_5_2_1_0 + 1.92400192400199e-05*G0_5_2_1_1 + 9.62000962000998e-06*G0_5_2_1_5 + 1.44300144300149e-05*G0_5_2_2_2 - 9.62000962000996e-06*G0_5_2_2_3 + 9.62000962000995e-06*G0_5_2_2_4 - 3.84800384800398e-05*G0_5_2_2_5 - 1.92400192400199e-05*G0_5_2_3_0 - 9.62000962000996e-06*G0_5_2_3_2 + 7.69600769600796e-05*G0_5_2_3_3 + 3.84800384800398e-05*G0_5_2_3_4 + 0.000115440115440119*G0_5_2_3_5 - 1.92400192400199e-05*G0_5_2_4_0 + 9.62000962000995e-06*G0_5_2_4_2 + 3.84800384800398e-05*G0_5_2_4_3 + 7.69600769600797e-05*G0_5_2_4_5 - 1.92400192400198e-05*G0_5_2_5_0 + 9.62000962000998e-06*G0_5_2_5_1 - 3.84800384800398e-05*G0_5_2_5_2 + 0.000115440115440119*G0_5_2_5_3 + 7.69600769600796e-05*G0_5_2_5_4 + 0.000384800384800398*G0_5_2_5_5 - 1.92400192400199e-05*G0_5_3_0_0 + 2.88600288600299e-05*G0_5_3_0_1 - 1.92400192400199e-05*G0_5_3_0_2 + 3.84800384800398e-05*G0_5_3_0_3 + 7.69600769600795e-05*G0_5_3_0_5 + 2.88600288600299e-05*G0_5_3_1_0 - 5.77200577200598e-05*G0_5_3_1_1 - 7.69600769600796e-05*G0_5_3_1_3 - 3.84800384800397e-05*G0_5_3_1_4 - 7.69600769600797e-05*G0_5_3_1_5 - 1.92400192400199e-05*G0_5_3_2_0 - 9.62000962000995e-06*G0_5_3_2_2 + 7.69600769600796e-05*G0_5_3_2_3 + 3.84800384800398e-05*G0_5_3_2_4 + 0.000115440115440119*G0_5_3_2_5 + 3.84800384800398e-05*G0_5_3_3_0 - 7.69600769600796e-05*G0_5_3_3_1 + 7.69600769600796e-05*G0_5_3_3_2 - 0.00015392015392016*G0_5_3_3_3 - 0.000307840307840318*G0_5_3_3_5 - 3.84800384800397e-05*G0_5_3_4_1 + 3.84800384800398e-05*G0_5_3_4_2 + 0.000153920153920159*G0_5_3_4_4 - 0.000153920153920159*G0_5_3_4_5 + 7.69600769600795e-05*G0_5_3_5_0 - 7.69600769600797e-05*G0_5_3_5_1 + 0.000115440115440119*G0_5_3_5_2 - 0.000307840307840318*G0_5_3_5_3 - 0.000153920153920159*G0_5_3_5_4 - 0.000923520923520956*G0_5_3_5_5 + 1.92400192400199e-05*G0_5_4_0_1 - 1.92400192400199e-05*G0_5_4_0_2 + 1.92400192400199e-05*G0_5_4_1_0 - 9.62000962000998e-06*G0_5_4_1_1 - 3.84800384800397e-05*G0_5_4_1_3 - 7.69600769600795e-05*G0_5_4_1_4 - 1.92400192400199e-05*G0_5_4_2_0 + 9.62000962000995e-06*G0_5_4_2_2 + 3.84800384800398e-05*G0_5_4_2_3 + 7.69600769600797e-05*G0_5_4_2_5 - 3.84800384800397e-05*G0_5_4_3_1 + 3.84800384800398e-05*G0_5_4_3_2 + 0.000153920153920159*G0_5_4_3_4 - 0.000153920153920159*G0_5_4_3_5 - 7.69600769600796e-05*G0_5_4_4_1 + 0.000153920153920159*G0_5_4_4_3 + 0.000769600769600795*G0_5_4_4_4 + 7.69600769600797e-05*G0_5_4_5_2 - 0.000153920153920159*G0_5_4_5_3 - 0.000769600769600796*G0_5_4_5_5 - 0.000192400192400199*G0_5_5_0_0 + 0.00013468013468014*G0_5_5_0_1 - 1.92400192400198e-05*G0_5_5_0_2 + 7.69600769600795e-05*G0_5_5_0_3 + 0.00013468013468014*G0_5_5_1_0 - 0.000230880230880239*G0_5_5_1_1 + 9.62000962000997e-06*G0_5_5_1_2 - 7.69600769600796e-05*G0_5_5_1_3 - 0.00015392015392016*G0_5_5_1_5 - 1.92400192400199e-05*G0_5_5_2_0 + 9.62000962000996e-06*G0_5_5_2_1 - 3.84800384800398e-05*G0_5_5_2_2 + 0.000115440115440119*G0_5_5_2_3 + 7.69600769600797e-05*G0_5_5_2_4 + 0.000384800384800398*G0_5_5_2_5 + 7.69600769600795e-05*G0_5_5_3_0 - 7.69600769600797e-05*G0_5_5_3_1 + 0.000115440115440119*G0_5_5_3_2 - 0.000307840307840318*G0_5_5_3_3 - 0.000153920153920159*G0_5_5_3_4 - 0.000923520923520956*G0_5_5_3_5 + 7.69600769600797e-05*G0_5_5_4_2 - 0.000153920153920159*G0_5_5_4_3 - 0.000769600769600796*G0_5_5_4_5 - 0.000153920153920159*G0_5_5_5_1 + 0.000384800384800398*G0_5_5_5_2 - 0.000923520923520956*G0_5_5_5_3 - 0.000769600769600796*G0_5_5_5_4 - 0.00615680615680637*G0_5_5_5_5; + A[2] = A[6]; + A[8] = 3.60750360750373e-05*G0_0_0_0_0 + 1.80375180375186e-06*G0_0_0_0_1 - 1.62337662337668e-05*G0_0_0_0_2 - 2.16450216450224e-05*G0_0_0_0_3 + 1.80375180375186e-06*G0_0_0_1_0 + 6.01250601250621e-06*G0_0_0_1_1 - 5.41125541125559e-06*G0_0_0_1_2 - 1.92400192400199e-05*G0_0_0_1_3 - 2.64550264550273e-05*G0_0_0_1_4 - 9.62000962000994e-06*G0_0_0_1_5 - 1.62337662337668e-05*G0_0_0_2_0 - 5.41125541125559e-06*G0_0_0_2_1 + 4.56950456950473e-05*G0_0_0_2_2 + 1.92400192400199e-05*G0_0_0_2_3 + 3.84800384800398e-05*G0_0_0_2_4 - 2.40500240500248e-06*G0_0_0_2_5 - 2.16450216450224e-05*G0_0_0_3_0 - 1.92400192400199e-05*G0_0_0_3_1 + 1.92400192400199e-05*G0_0_0_3_2 + 0.000115440115440119*G0_0_0_3_3 + 9.62000962000994e-05*G0_0_0_3_4 + 4.81000481000497e-05*G0_0_0_3_5 - 2.64550264550273e-05*G0_0_0_4_1 + 3.84800384800398e-05*G0_0_0_4_2 + 9.62000962000994e-05*G0_0_0_4_3 + 0.000230880230880239*G0_0_0_4_4 + 5.77200577200597e-05*G0_0_0_4_5 - 9.62000962000994e-06*G0_0_0_5_1 - 2.40500240500248e-06*G0_0_0_5_2 + 4.81000481000497e-05*G0_0_0_5_3 + 5.77200577200597e-05*G0_0_0_5_4 + 3.84800384800398e-05*G0_0_0_5_5 + 1.80375180375186e-06*G0_0_1_0_0 + 6.01250601250621e-06*G0_0_1_0_1 - 5.41125541125559e-06*G0_0_1_0_2 - 1.92400192400199e-05*G0_0_1_0_3 - 2.64550264550273e-05*G0_0_1_0_4 - 9.62000962000994e-06*G0_0_1_0_5 + 6.01250601250621e-06*G0_0_1_1_0 + 1.80375180375185e-06*G0_0_1_1_1 - 5.41125541125559e-06*G0_0_1_1_2 - 2.64550264550273e-05*G0_0_1_1_3 - 1.92400192400199e-05*G0_0_1_1_4 - 9.62000962000994e-06*G0_0_1_1_5 - 5.41125541125559e-06*G0_0_1_2_0 - 5.41125541125559e-06*G0_0_1_2_1 + 2.76575276575286e-05*G0_0_1_2_2 + 2.88600288600298e-05*G0_0_1_2_3 + 2.88600288600298e-05*G0_0_1_2_4 + 4.81000481000498e-06*G0_0_1_2_5 - 1.92400192400199e-05*G0_0_1_3_0 - 2.64550264550273e-05*G0_0_1_3_1 + 2.88600288600298e-05*G0_0_1_3_2 + 9.62000962000994e-05*G0_0_1_3_3 + 7.69600769600795e-05*G0_0_1_3_4 + 2.88600288600298e-05*G0_0_1_3_5 - 2.64550264550273e-05*G0_0_1_4_0 - 1.92400192400199e-05*G0_0_1_4_1 + 2.88600288600298e-05*G0_0_1_4_2 + 7.69600769600795e-05*G0_0_1_4_3 + 9.62000962000994e-05*G0_0_1_4_4 + 2.88600288600298e-05*G0_0_1_4_5 - 9.62000962000993e-06*G0_0_1_5_0 - 9.62000962000994e-06*G0_0_1_5_1 + 4.81000481000498e-06*G0_0_1_5_2 + 2.88600288600298e-05*G0_0_1_5_3 + 2.88600288600298e-05*G0_0_1_5_4 + 9.62000962000993e-06*G0_0_1_5_5 - 1.62337662337668e-05*G0_0_2_0_0 - 5.41125541125559e-06*G0_0_2_0_1 + 4.56950456950473e-05*G0_0_2_0_2 + 1.92400192400199e-05*G0_0_2_0_3 + 3.84800384800398e-05*G0_0_2_0_4 - 2.40500240500248e-06*G0_0_2_0_5 - 5.41125541125559e-06*G0_0_2_1_0 - 5.41125541125559e-06*G0_0_2_1_1 + 2.76575276575286e-05*G0_0_2_1_2 + 2.88600288600298e-05*G0_0_2_1_3 + 2.88600288600298e-05*G0_0_2_1_4 + 4.81000481000498e-06*G0_0_2_1_5 + 4.56950456950473e-05*G0_0_2_2_0 + 2.76575276575286e-05*G0_0_2_2_1 - 0.00027056277056278*G0_0_2_2_2 - 0.000120250120250124*G0_0_2_2_3 - 0.000192400192400199*G0_0_2_2_4 - 1.92400192400199e-05*G0_0_2_2_5 + 1.92400192400199e-05*G0_0_2_3_0 + 2.88600288600298e-05*G0_0_2_3_1 - 0.000120250120250124*G0_0_2_3_2 - 9.62000962000995e-05*G0_0_2_3_3 - 9.62000962000995e-05*G0_0_2_3_4 + 3.84800384800398e-05*G0_0_2_4_0 + 2.88600288600298e-05*G0_0_2_4_1 - 0.000192400192400199*G0_0_2_4_2 - 9.62000962000995e-05*G0_0_2_4_3 - 0.000288600288600299*G0_0_2_4_4 - 1.92400192400199e-05*G0_0_2_4_5 - 2.40500240500248e-06*G0_0_2_5_0 + 4.81000481000497e-06*G0_0_2_5_1 - 1.92400192400199e-05*G0_0_2_5_2 - 1.92400192400199e-05*G0_0_2_5_4 + 9.62000962000994e-06*G0_0_2_5_5 - 2.16450216450224e-05*G0_0_3_0_0 - 1.92400192400199e-05*G0_0_3_0_1 + 1.92400192400199e-05*G0_0_3_0_2 + 0.000115440115440119*G0_0_3_0_3 + 9.62000962000994e-05*G0_0_3_0_4 + 4.81000481000497e-05*G0_0_3_0_5 - 1.92400192400199e-05*G0_0_3_1_0 - 2.64550264550274e-05*G0_0_3_1_1 + 2.88600288600298e-05*G0_0_3_1_2 + 9.62000962000994e-05*G0_0_3_1_3 + 7.69600769600795e-05*G0_0_3_1_4 + 2.88600288600298e-05*G0_0_3_1_5 + 1.92400192400199e-05*G0_0_3_2_0 + 2.88600288600298e-05*G0_0_3_2_1 - 0.000120250120250124*G0_0_3_2_2 - 9.62000962000995e-05*G0_0_3_2_3 - 9.62000962000995e-05*G0_0_3_2_4 + 0.000115440115440119*G0_0_3_3_0 + 9.62000962000994e-05*G0_0_3_3_1 - 9.62000962000995e-05*G0_0_3_3_2 - 0.000769600769600795*G0_0_3_3_3 - 0.000384800384800398*G0_0_3_3_4 - 0.000230880230880239*G0_0_3_3_5 + 9.62000962000994e-05*G0_0_3_4_0 + 7.69600769600795e-05*G0_0_3_4_1 - 9.62000962000995e-05*G0_0_3_4_2 - 0.000384800384800398*G0_0_3_4_3 - 0.000384800384800398*G0_0_3_4_4 - 0.000153920153920159*G0_0_3_4_5 + 4.81000481000497e-05*G0_0_3_5_0 + 2.88600288600298e-05*G0_0_3_5_1 - 0.000230880230880239*G0_0_3_5_3 - 0.000153920153920159*G0_0_3_5_4 - 0.000115440115440119*G0_0_3_5_5 - 2.64550264550273e-05*G0_0_4_0_1 + 3.84800384800398e-05*G0_0_4_0_2 + 9.62000962000994e-05*G0_0_4_0_3 + 0.000230880230880239*G0_0_4_0_4 + 5.77200577200597e-05*G0_0_4_0_5 - 2.64550264550273e-05*G0_0_4_1_0 - 1.92400192400199e-05*G0_0_4_1_1 + 2.88600288600298e-05*G0_0_4_1_2 + 7.69600769600795e-05*G0_0_4_1_3 + 9.62000962000994e-05*G0_0_4_1_4 + 2.88600288600298e-05*G0_0_4_1_5 + 3.84800384800398e-05*G0_0_4_2_0 + 2.88600288600298e-05*G0_0_4_2_1 - 0.000192400192400199*G0_0_4_2_2 - 9.62000962000995e-05*G0_0_4_2_3 - 0.000288600288600299*G0_0_4_2_4 - 1.92400192400199e-05*G0_0_4_2_5 + 9.62000962000994e-05*G0_0_4_3_0 + 7.69600769600795e-05*G0_0_4_3_1 - 9.62000962000995e-05*G0_0_4_3_2 - 0.000384800384800398*G0_0_4_3_3 - 0.000384800384800398*G0_0_4_3_4 - 0.000153920153920159*G0_0_4_3_5 + 0.000230880230880239*G0_0_4_4_0 + 9.62000962000994e-05*G0_0_4_4_1 - 0.000288600288600299*G0_0_4_4_2 - 0.000384800384800398*G0_0_4_4_3 - 0.000769600769600796*G0_0_4_4_4 - 0.000153920153920159*G0_0_4_4_5 + 5.77200577200597e-05*G0_0_4_5_0 + 2.88600288600298e-05*G0_0_4_5_1 - 1.92400192400199e-05*G0_0_4_5_2 - 0.000153920153920159*G0_0_4_5_3 - 0.000153920153920159*G0_0_4_5_4 - 7.69600769600795e-05*G0_0_4_5_5 - 9.62000962000993e-06*G0_0_5_0_1 - 2.40500240500248e-06*G0_0_5_0_2 + 4.81000481000497e-05*G0_0_5_0_3 + 5.77200577200597e-05*G0_0_5_0_4 + 3.84800384800398e-05*G0_0_5_0_5 - 9.62000962000993e-06*G0_0_5_1_0 - 9.62000962000994e-06*G0_0_5_1_1 + 4.81000481000498e-06*G0_0_5_1_2 + 2.88600288600298e-05*G0_0_5_1_3 + 2.88600288600298e-05*G0_0_5_1_4 + 9.62000962000994e-06*G0_0_5_1_5 - 2.40500240500248e-06*G0_0_5_2_0 + 4.81000481000498e-06*G0_0_5_2_1 - 1.92400192400199e-05*G0_0_5_2_2 - 1.92400192400199e-05*G0_0_5_2_4 + 9.62000962000994e-06*G0_0_5_2_5 + 4.81000481000497e-05*G0_0_5_3_0 + 2.88600288600298e-05*G0_0_5_3_1 - 0.000230880230880239*G0_0_5_3_3 - 0.000153920153920159*G0_0_5_3_4 - 0.000115440115440119*G0_0_5_3_5 + 5.77200577200597e-05*G0_0_5_4_0 + 2.88600288600298e-05*G0_0_5_4_1 - 1.92400192400199e-05*G0_0_5_4_2 - 0.000153920153920159*G0_0_5_4_3 - 0.000153920153920159*G0_0_5_4_4 - 7.69600769600795e-05*G0_0_5_4_5 + 3.84800384800398e-05*G0_0_5_5_0 + 9.62000962000994e-06*G0_0_5_5_1 + 9.62000962000994e-06*G0_0_5_5_2 - 0.000115440115440119*G0_0_5_5_3 - 7.69600769600795e-05*G0_0_5_5_4 - 7.69600769600795e-05*G0_0_5_5_5 + 1.80375180375186e-06*G0_1_0_0_0 + 6.01250601250621e-06*G0_1_0_0_1 - 5.41125541125559e-06*G0_1_0_0_2 - 1.92400192400199e-05*G0_1_0_0_3 - 2.64550264550273e-05*G0_1_0_0_4 - 9.62000962000994e-06*G0_1_0_0_5 + 6.01250601250621e-06*G0_1_0_1_0 + 1.80375180375185e-06*G0_1_0_1_1 - 5.41125541125559e-06*G0_1_0_1_2 - 2.64550264550273e-05*G0_1_0_1_3 - 1.92400192400199e-05*G0_1_0_1_4 - 9.62000962000994e-06*G0_1_0_1_5 - 5.41125541125559e-06*G0_1_0_2_0 - 5.41125541125559e-06*G0_1_0_2_1 + 2.76575276575286e-05*G0_1_0_2_2 + 2.88600288600298e-05*G0_1_0_2_3 + 2.88600288600298e-05*G0_1_0_2_4 + 4.81000481000498e-06*G0_1_0_2_5 - 1.92400192400199e-05*G0_1_0_3_0 - 2.64550264550273e-05*G0_1_0_3_1 + 2.88600288600298e-05*G0_1_0_3_2 + 9.62000962000994e-05*G0_1_0_3_3 + 7.69600769600795e-05*G0_1_0_3_4 + 2.88600288600298e-05*G0_1_0_3_5 - 2.64550264550273e-05*G0_1_0_4_0 - 1.92400192400199e-05*G0_1_0_4_1 + 2.88600288600298e-05*G0_1_0_4_2 + 7.69600769600795e-05*G0_1_0_4_3 + 9.62000962000994e-05*G0_1_0_4_4 + 2.88600288600298e-05*G0_1_0_4_5 - 9.62000962000993e-06*G0_1_0_5_0 - 9.62000962000994e-06*G0_1_0_5_1 + 4.81000481000498e-06*G0_1_0_5_2 + 2.88600288600298e-05*G0_1_0_5_3 + 2.88600288600298e-05*G0_1_0_5_4 + 9.62000962000993e-06*G0_1_0_5_5 + 6.01250601250621e-06*G0_1_1_0_0 + 1.80375180375185e-06*G0_1_1_0_1 - 5.41125541125559e-06*G0_1_1_0_2 - 2.64550264550273e-05*G0_1_1_0_3 - 1.92400192400199e-05*G0_1_1_0_4 - 9.62000962000994e-06*G0_1_1_0_5 + 1.80375180375185e-06*G0_1_1_1_0 + 3.60750360750373e-05*G0_1_1_1_1 - 1.62337662337668e-05*G0_1_1_1_2 - 2.16450216450224e-05*G0_1_1_1_4 - 5.41125541125559e-06*G0_1_1_2_0 - 1.62337662337668e-05*G0_1_1_2_1 + 4.56950456950472e-05*G0_1_1_2_2 + 3.84800384800398e-05*G0_1_1_2_3 + 1.92400192400199e-05*G0_1_1_2_4 - 2.40500240500249e-06*G0_1_1_2_5 - 2.64550264550273e-05*G0_1_1_3_0 + 3.84800384800398e-05*G0_1_1_3_2 + 0.000230880230880239*G0_1_1_3_3 + 9.62000962000994e-05*G0_1_1_3_4 + 5.77200577200597e-05*G0_1_1_3_5 - 1.92400192400199e-05*G0_1_1_4_0 - 2.16450216450224e-05*G0_1_1_4_1 + 1.92400192400199e-05*G0_1_1_4_2 + 9.62000962000994e-05*G0_1_1_4_3 + 0.000115440115440119*G0_1_1_4_4 + 4.81000481000497e-05*G0_1_1_4_5 - 9.62000962000994e-06*G0_1_1_5_0 - 2.40500240500249e-06*G0_1_1_5_2 + 5.77200577200597e-05*G0_1_1_5_3 + 4.81000481000497e-05*G0_1_1_5_4 + 3.84800384800398e-05*G0_1_1_5_5 - 5.41125541125559e-06*G0_1_2_0_0 - 5.41125541125559e-06*G0_1_2_0_1 + 2.76575276575286e-05*G0_1_2_0_2 + 2.88600288600298e-05*G0_1_2_0_3 + 2.88600288600298e-05*G0_1_2_0_4 + 4.81000481000498e-06*G0_1_2_0_5 - 5.41125541125559e-06*G0_1_2_1_0 - 1.62337662337668e-05*G0_1_2_1_1 + 4.56950456950472e-05*G0_1_2_1_2 + 3.84800384800398e-05*G0_1_2_1_3 + 1.92400192400199e-05*G0_1_2_1_4 - 2.40500240500249e-06*G0_1_2_1_5 + 2.76575276575286e-05*G0_1_2_2_0 + 4.56950456950472e-05*G0_1_2_2_1 - 0.00027056277056278*G0_1_2_2_2 - 0.000192400192400199*G0_1_2_2_3 - 0.000120250120250124*G0_1_2_2_4 - 1.92400192400199e-05*G0_1_2_2_5 + 2.88600288600298e-05*G0_1_2_3_0 + 3.84800384800398e-05*G0_1_2_3_1 - 0.000192400192400199*G0_1_2_3_2 - 0.000288600288600299*G0_1_2_3_3 - 9.62000962000995e-05*G0_1_2_3_4 - 1.92400192400199e-05*G0_1_2_3_5 + 2.88600288600298e-05*G0_1_2_4_0 + 1.92400192400199e-05*G0_1_2_4_1 - 0.000120250120250124*G0_1_2_4_2 - 9.62000962000995e-05*G0_1_2_4_3 - 9.62000962000994e-05*G0_1_2_4_4 + 4.81000481000498e-06*G0_1_2_5_0 - 2.40500240500249e-06*G0_1_2_5_1 - 1.92400192400199e-05*G0_1_2_5_2 - 1.92400192400199e-05*G0_1_2_5_3 + 9.62000962000995e-06*G0_1_2_5_5 - 1.92400192400199e-05*G0_1_3_0_0 - 2.64550264550273e-05*G0_1_3_0_1 + 2.88600288600298e-05*G0_1_3_0_2 + 9.62000962000994e-05*G0_1_3_0_3 + 7.69600769600795e-05*G0_1_3_0_4 + 2.88600288600298e-05*G0_1_3_0_5 - 2.64550264550273e-05*G0_1_3_1_0 + 3.84800384800398e-05*G0_1_3_1_2 + 0.000230880230880239*G0_1_3_1_3 + 9.62000962000994e-05*G0_1_3_1_4 + 5.77200577200597e-05*G0_1_3_1_5 + 2.88600288600298e-05*G0_1_3_2_0 + 3.84800384800398e-05*G0_1_3_2_1 - 0.000192400192400199*G0_1_3_2_2 - 0.000288600288600299*G0_1_3_2_3 - 9.62000962000995e-05*G0_1_3_2_4 - 1.92400192400199e-05*G0_1_3_2_5 + 9.62000962000994e-05*G0_1_3_3_0 + 0.000230880230880239*G0_1_3_3_1 - 0.000288600288600299*G0_1_3_3_2 - 0.000769600769600795*G0_1_3_3_3 - 0.000384800384800397*G0_1_3_3_4 - 0.000153920153920159*G0_1_3_3_5 + 7.69600769600795e-05*G0_1_3_4_0 + 9.62000962000994e-05*G0_1_3_4_1 - 9.62000962000995e-05*G0_1_3_4_2 - 0.000384800384800398*G0_1_3_4_3 - 0.000384800384800398*G0_1_3_4_4 - 0.000153920153920159*G0_1_3_4_5 + 2.88600288600298e-05*G0_1_3_5_0 + 5.77200577200597e-05*G0_1_3_5_1 - 1.92400192400199e-05*G0_1_3_5_2 - 0.000153920153920159*G0_1_3_5_3 - 0.000153920153920159*G0_1_3_5_4 - 7.69600769600795e-05*G0_1_3_5_5 - 2.64550264550273e-05*G0_1_4_0_0 - 1.92400192400199e-05*G0_1_4_0_1 + 2.88600288600298e-05*G0_1_4_0_2 + 7.69600769600795e-05*G0_1_4_0_3 + 9.62000962000994e-05*G0_1_4_0_4 + 2.88600288600298e-05*G0_1_4_0_5 - 1.92400192400199e-05*G0_1_4_1_0 - 2.16450216450224e-05*G0_1_4_1_1 + 1.92400192400199e-05*G0_1_4_1_2 + 9.62000962000994e-05*G0_1_4_1_3 + 0.000115440115440119*G0_1_4_1_4 + 4.81000481000497e-05*G0_1_4_1_5 + 2.88600288600298e-05*G0_1_4_2_0 + 1.92400192400199e-05*G0_1_4_2_1 - 0.000120250120250124*G0_1_4_2_2 - 9.62000962000995e-05*G0_1_4_2_3 - 9.62000962000994e-05*G0_1_4_2_4 + 7.69600769600795e-05*G0_1_4_3_0 + 9.62000962000994e-05*G0_1_4_3_1 - 9.62000962000995e-05*G0_1_4_3_2 - 0.000384800384800398*G0_1_4_3_3 - 0.000384800384800398*G0_1_4_3_4 - 0.000153920153920159*G0_1_4_3_5 + 9.62000962000994e-05*G0_1_4_4_0 + 0.000115440115440119*G0_1_4_4_1 - 9.62000962000994e-05*G0_1_4_4_2 - 0.000384800384800398*G0_1_4_4_3 - 0.000769600769600796*G0_1_4_4_4 - 0.000230880230880239*G0_1_4_4_5 + 2.88600288600298e-05*G0_1_4_5_0 + 4.81000481000497e-05*G0_1_4_5_1 - 0.000153920153920159*G0_1_4_5_3 - 0.000230880230880239*G0_1_4_5_4 - 0.000115440115440119*G0_1_4_5_5 - 9.62000962000993e-06*G0_1_5_0_0 - 9.62000962000994e-06*G0_1_5_0_1 + 4.81000481000498e-06*G0_1_5_0_2 + 2.88600288600298e-05*G0_1_5_0_3 + 2.88600288600298e-05*G0_1_5_0_4 + 9.62000962000993e-06*G0_1_5_0_5 - 9.62000962000994e-06*G0_1_5_1_0 - 2.40500240500249e-06*G0_1_5_1_2 + 5.77200577200597e-05*G0_1_5_1_3 + 4.81000481000497e-05*G0_1_5_1_4 + 3.84800384800398e-05*G0_1_5_1_5 + 4.81000481000498e-06*G0_1_5_2_0 - 2.40500240500249e-06*G0_1_5_2_1 - 1.92400192400199e-05*G0_1_5_2_2 - 1.92400192400199e-05*G0_1_5_2_3 + 9.62000962000995e-06*G0_1_5_2_5 + 2.88600288600298e-05*G0_1_5_3_0 + 5.77200577200597e-05*G0_1_5_3_1 - 1.92400192400199e-05*G0_1_5_3_2 - 0.000153920153920159*G0_1_5_3_3 - 0.000153920153920159*G0_1_5_3_4 - 7.69600769600795e-05*G0_1_5_3_5 + 2.88600288600298e-05*G0_1_5_4_0 + 4.81000481000497e-05*G0_1_5_4_1 - 0.000153920153920159*G0_1_5_4_3 - 0.000230880230880239*G0_1_5_4_4 - 0.000115440115440119*G0_1_5_4_5 + 9.62000962000993e-06*G0_1_5_5_0 + 3.84800384800398e-05*G0_1_5_5_1 + 9.62000962000995e-06*G0_1_5_5_2 - 7.69600769600795e-05*G0_1_5_5_3 - 0.000115440115440119*G0_1_5_5_4 - 7.69600769600795e-05*G0_1_5_5_5 - 1.62337662337668e-05*G0_2_0_0_0 - 5.41125541125559e-06*G0_2_0_0_1 + 4.56950456950473e-05*G0_2_0_0_2 + 1.92400192400199e-05*G0_2_0_0_3 + 3.84800384800398e-05*G0_2_0_0_4 - 2.40500240500248e-06*G0_2_0_0_5 - 5.41125541125559e-06*G0_2_0_1_0 - 5.41125541125559e-06*G0_2_0_1_1 + 2.76575276575286e-05*G0_2_0_1_2 + 2.88600288600298e-05*G0_2_0_1_3 + 2.88600288600298e-05*G0_2_0_1_4 + 4.81000481000498e-06*G0_2_0_1_5 + 4.56950456950473e-05*G0_2_0_2_0 + 2.76575276575286e-05*G0_2_0_2_1 - 0.00027056277056278*G0_2_0_2_2 - 0.000120250120250124*G0_2_0_2_3 - 0.000192400192400199*G0_2_0_2_4 - 1.92400192400199e-05*G0_2_0_2_5 + 1.92400192400199e-05*G0_2_0_3_0 + 2.88600288600298e-05*G0_2_0_3_1 - 0.000120250120250124*G0_2_0_3_2 - 9.62000962000995e-05*G0_2_0_3_3 - 9.62000962000995e-05*G0_2_0_3_4 + 3.84800384800398e-05*G0_2_0_4_0 + 2.88600288600298e-05*G0_2_0_4_1 - 0.000192400192400199*G0_2_0_4_2 - 9.62000962000995e-05*G0_2_0_4_3 - 0.000288600288600299*G0_2_0_4_4 - 1.92400192400199e-05*G0_2_0_4_5 - 2.40500240500248e-06*G0_2_0_5_0 + 4.81000481000498e-06*G0_2_0_5_1 - 1.92400192400199e-05*G0_2_0_5_2 - 1.92400192400199e-05*G0_2_0_5_4 + 9.62000962000994e-06*G0_2_0_5_5 - 5.41125541125559e-06*G0_2_1_0_0 - 5.41125541125559e-06*G0_2_1_0_1 + 2.76575276575286e-05*G0_2_1_0_2 + 2.88600288600298e-05*G0_2_1_0_3 + 2.88600288600298e-05*G0_2_1_0_4 + 4.81000481000498e-06*G0_2_1_0_5 - 5.41125541125559e-06*G0_2_1_1_0 - 1.62337662337668e-05*G0_2_1_1_1 + 4.56950456950472e-05*G0_2_1_1_2 + 3.84800384800398e-05*G0_2_1_1_3 + 1.92400192400199e-05*G0_2_1_1_4 - 2.40500240500249e-06*G0_2_1_1_5 + 2.76575276575286e-05*G0_2_1_2_0 + 4.56950456950472e-05*G0_2_1_2_1 - 0.00027056277056278*G0_2_1_2_2 - 0.000192400192400199*G0_2_1_2_3 - 0.000120250120250124*G0_2_1_2_4 - 1.92400192400199e-05*G0_2_1_2_5 + 2.88600288600298e-05*G0_2_1_3_0 + 3.84800384800398e-05*G0_2_1_3_1 - 0.000192400192400199*G0_2_1_3_2 - 0.000288600288600299*G0_2_1_3_3 - 9.62000962000995e-05*G0_2_1_3_4 - 1.92400192400199e-05*G0_2_1_3_5 + 2.88600288600298e-05*G0_2_1_4_0 + 1.92400192400199e-05*G0_2_1_4_1 - 0.000120250120250124*G0_2_1_4_2 - 9.62000962000995e-05*G0_2_1_4_3 - 9.62000962000994e-05*G0_2_1_4_4 + 4.81000481000498e-06*G0_2_1_5_0 - 2.40500240500249e-06*G0_2_1_5_1 - 1.92400192400199e-05*G0_2_1_5_2 - 1.92400192400199e-05*G0_2_1_5_3 + 9.62000962000995e-06*G0_2_1_5_5 + 4.56950456950473e-05*G0_2_2_0_0 + 2.76575276575286e-05*G0_2_2_0_1 - 0.00027056277056278*G0_2_2_0_2 - 0.000120250120250124*G0_2_2_0_3 - 0.000192400192400199*G0_2_2_0_4 - 1.92400192400199e-05*G0_2_2_0_5 + 2.76575276575286e-05*G0_2_2_1_0 + 4.56950456950472e-05*G0_2_2_1_1 - 0.00027056277056278*G0_2_2_1_2 - 0.000192400192400199*G0_2_2_1_3 - 0.000120250120250124*G0_2_2_1_4 - 1.92400192400199e-05*G0_2_2_1_5 - 0.00027056277056278*G0_2_2_2_0 - 0.00027056277056278*G0_2_2_2_1 + 0.00371572871572884*G0_2_2_2_2 + 0.00115440115440119*G0_2_2_2_3 + 0.00115440115440119*G0_2_2_2_4 + 7.21500721500748e-05*G0_2_2_2_5 - 0.000120250120250124*G0_2_2_3_0 - 0.000192400192400199*G0_2_2_3_1 + 0.00115440115440119*G0_2_2_3_2 + 0.000962000962000995*G0_2_2_3_3 + 0.000481000481000498*G0_2_2_3_4 + 9.62000962000996e-05*G0_2_2_3_5 - 0.000192400192400199*G0_2_2_4_0 - 0.000120250120250124*G0_2_2_4_1 + 0.00115440115440119*G0_2_2_4_2 + 0.000481000481000498*G0_2_2_4_3 + 0.000962000962000995*G0_2_2_4_4 + 9.62000962000996e-05*G0_2_2_4_5 - 1.92400192400199e-05*G0_2_2_5_0 - 1.92400192400199e-05*G0_2_2_5_1 + 7.21500721500748e-05*G0_2_2_5_2 + 9.62000962000996e-05*G0_2_2_5_3 + 9.62000962000996e-05*G0_2_2_5_4 + 3.84800384800398e-05*G0_2_2_5_5 + 1.92400192400199e-05*G0_2_3_0_0 + 2.88600288600298e-05*G0_2_3_0_1 - 0.000120250120250124*G0_2_3_0_2 - 9.62000962000995e-05*G0_2_3_0_3 - 9.62000962000995e-05*G0_2_3_0_4 + 2.88600288600298e-05*G0_2_3_1_0 + 3.84800384800398e-05*G0_2_3_1_1 - 0.000192400192400199*G0_2_3_1_2 - 0.000288600288600299*G0_2_3_1_3 - 9.62000962000995e-05*G0_2_3_1_4 - 1.92400192400199e-05*G0_2_3_1_5 - 0.000120250120250124*G0_2_3_2_0 - 0.000192400192400199*G0_2_3_2_1 + 0.00115440115440119*G0_2_3_2_2 + 0.000962000962000995*G0_2_3_2_3 + 0.000481000481000498*G0_2_3_2_4 + 9.62000962000996e-05*G0_2_3_2_5 - 9.62000962000995e-05*G0_2_3_3_0 - 0.000288600288600299*G0_2_3_3_1 + 0.000962000962000995*G0_2_3_3_2 + 0.00115440115440119*G0_2_3_3_3 + 0.000384800384800398*G0_2_3_3_4 - 9.62000962000995e-05*G0_2_3_4_0 - 9.62000962000995e-05*G0_2_3_4_1 + 0.000481000481000498*G0_2_3_4_2 + 0.000384800384800398*G0_2_3_4_3 + 0.000384800384800398*G0_2_3_4_4 - 1.92400192400199e-05*G0_2_3_5_1 + 9.62000962000996e-05*G0_2_3_5_2 - 7.69600769600796e-05*G0_2_3_5_5 + 3.84800384800398e-05*G0_2_4_0_0 + 2.88600288600298e-05*G0_2_4_0_1 - 0.000192400192400199*G0_2_4_0_2 - 9.62000962000995e-05*G0_2_4_0_3 - 0.000288600288600299*G0_2_4_0_4 - 1.92400192400199e-05*G0_2_4_0_5 + 2.88600288600298e-05*G0_2_4_1_0 + 1.92400192400199e-05*G0_2_4_1_1 - 0.000120250120250124*G0_2_4_1_2 - 9.62000962000995e-05*G0_2_4_1_3 - 9.62000962000994e-05*G0_2_4_1_4 - 0.000192400192400199*G0_2_4_2_0 - 0.000120250120250124*G0_2_4_2_1 + 0.00115440115440119*G0_2_4_2_2 + 0.000481000481000498*G0_2_4_2_3 + 0.000962000962000995*G0_2_4_2_4 + 9.62000962000996e-05*G0_2_4_2_5 - 9.62000962000995e-05*G0_2_4_3_0 - 9.62000962000995e-05*G0_2_4_3_1 + 0.000481000481000498*G0_2_4_3_2 + 0.000384800384800398*G0_2_4_3_3 + 0.000384800384800398*G0_2_4_3_4 - 0.000288600288600299*G0_2_4_4_0 - 9.62000962000994e-05*G0_2_4_4_1 + 0.000962000962000995*G0_2_4_4_2 + 0.000384800384800398*G0_2_4_4_3 + 0.00115440115440119*G0_2_4_4_4 - 1.92400192400199e-05*G0_2_4_5_0 + 9.62000962000996e-05*G0_2_4_5_2 - 7.69600769600796e-05*G0_2_4_5_5 - 2.40500240500248e-06*G0_2_5_0_0 + 4.81000481000498e-06*G0_2_5_0_1 - 1.92400192400199e-05*G0_2_5_0_2 - 1.92400192400199e-05*G0_2_5_0_4 + 9.62000962000994e-06*G0_2_5_0_5 + 4.81000481000498e-06*G0_2_5_1_0 - 2.40500240500249e-06*G0_2_5_1_1 - 1.92400192400199e-05*G0_2_5_1_2 - 1.92400192400199e-05*G0_2_5_1_3 + 9.62000962000994e-06*G0_2_5_1_5 - 1.92400192400199e-05*G0_2_5_2_0 - 1.92400192400199e-05*G0_2_5_2_1 + 7.21500721500748e-05*G0_2_5_2_2 + 9.62000962000996e-05*G0_2_5_2_3 + 9.62000962000996e-05*G0_2_5_2_4 + 3.84800384800398e-05*G0_2_5_2_5 - 1.92400192400199e-05*G0_2_5_3_1 + 9.62000962000996e-05*G0_2_5_3_2 - 7.69600769600796e-05*G0_2_5_3_5 - 1.92400192400199e-05*G0_2_5_4_0 + 9.62000962000996e-05*G0_2_5_4_2 - 7.69600769600796e-05*G0_2_5_4_5 + 9.62000962000994e-06*G0_2_5_5_0 + 9.62000962000994e-06*G0_2_5_5_1 + 3.84800384800398e-05*G0_2_5_5_2 - 7.69600769600796e-05*G0_2_5_5_3 - 7.69600769600796e-05*G0_2_5_5_4 - 0.000115440115440119*G0_2_5_5_5 - 2.16450216450224e-05*G0_3_0_0_0 - 1.92400192400199e-05*G0_3_0_0_1 + 1.92400192400199e-05*G0_3_0_0_2 + 0.000115440115440119*G0_3_0_0_3 + 9.62000962000994e-05*G0_3_0_0_4 + 4.81000481000497e-05*G0_3_0_0_5 - 1.92400192400199e-05*G0_3_0_1_0 - 2.64550264550274e-05*G0_3_0_1_1 + 2.88600288600298e-05*G0_3_0_1_2 + 9.62000962000994e-05*G0_3_0_1_3 + 7.69600769600795e-05*G0_3_0_1_4 + 2.88600288600298e-05*G0_3_0_1_5 + 1.92400192400199e-05*G0_3_0_2_0 + 2.88600288600298e-05*G0_3_0_2_1 - 0.000120250120250124*G0_3_0_2_2 - 9.62000962000995e-05*G0_3_0_2_3 - 9.62000962000995e-05*G0_3_0_2_4 + 0.000115440115440119*G0_3_0_3_0 + 9.62000962000994e-05*G0_3_0_3_1 - 9.62000962000995e-05*G0_3_0_3_2 - 0.000769600769600795*G0_3_0_3_3 - 0.000384800384800398*G0_3_0_3_4 - 0.000230880230880239*G0_3_0_3_5 + 9.62000962000994e-05*G0_3_0_4_0 + 7.69600769600795e-05*G0_3_0_4_1 - 9.62000962000995e-05*G0_3_0_4_2 - 0.000384800384800398*G0_3_0_4_3 - 0.000384800384800398*G0_3_0_4_4 - 0.000153920153920159*G0_3_0_4_5 + 4.81000481000497e-05*G0_3_0_5_0 + 2.88600288600298e-05*G0_3_0_5_1 - 0.000230880230880239*G0_3_0_5_3 - 0.000153920153920159*G0_3_0_5_4 - 0.000115440115440119*G0_3_0_5_5 - 1.92400192400199e-05*G0_3_1_0_0 - 2.64550264550273e-05*G0_3_1_0_1 + 2.88600288600298e-05*G0_3_1_0_2 + 9.62000962000994e-05*G0_3_1_0_3 + 7.69600769600795e-05*G0_3_1_0_4 + 2.88600288600298e-05*G0_3_1_0_5 - 2.64550264550273e-05*G0_3_1_1_0 + 3.84800384800398e-05*G0_3_1_1_2 + 0.000230880230880239*G0_3_1_1_3 + 9.62000962000994e-05*G0_3_1_1_4 + 5.77200577200597e-05*G0_3_1_1_5 + 2.88600288600298e-05*G0_3_1_2_0 + 3.84800384800398e-05*G0_3_1_2_1 - 0.000192400192400199*G0_3_1_2_2 - 0.000288600288600299*G0_3_1_2_3 - 9.62000962000995e-05*G0_3_1_2_4 - 1.92400192400199e-05*G0_3_1_2_5 + 9.62000962000994e-05*G0_3_1_3_0 + 0.000230880230880239*G0_3_1_3_1 - 0.000288600288600299*G0_3_1_3_2 - 0.000769600769600795*G0_3_1_3_3 - 0.000384800384800398*G0_3_1_3_4 - 0.000153920153920159*G0_3_1_3_5 + 7.69600769600795e-05*G0_3_1_4_0 + 9.62000962000994e-05*G0_3_1_4_1 - 9.62000962000995e-05*G0_3_1_4_2 - 0.000384800384800398*G0_3_1_4_3 - 0.000384800384800398*G0_3_1_4_4 - 0.000153920153920159*G0_3_1_4_5 + 2.88600288600298e-05*G0_3_1_5_0 + 5.77200577200597e-05*G0_3_1_5_1 - 1.92400192400199e-05*G0_3_1_5_2 - 0.000153920153920159*G0_3_1_5_3 - 0.000153920153920159*G0_3_1_5_4 - 7.69600769600795e-05*G0_3_1_5_5 + 1.92400192400199e-05*G0_3_2_0_0 + 2.88600288600298e-05*G0_3_2_0_1 - 0.000120250120250124*G0_3_2_0_2 - 9.62000962000995e-05*G0_3_2_0_3 - 9.62000962000995e-05*G0_3_2_0_4 + 2.88600288600298e-05*G0_3_2_1_0 + 3.84800384800398e-05*G0_3_2_1_1 - 0.000192400192400199*G0_3_2_1_2 - 0.000288600288600299*G0_3_2_1_3 - 9.62000962000995e-05*G0_3_2_1_4 - 1.92400192400199e-05*G0_3_2_1_5 - 0.000120250120250124*G0_3_2_2_0 - 0.000192400192400199*G0_3_2_2_1 + 0.00115440115440119*G0_3_2_2_2 + 0.000962000962000995*G0_3_2_2_3 + 0.000481000481000498*G0_3_2_2_4 + 9.62000962000996e-05*G0_3_2_2_5 - 9.62000962000995e-05*G0_3_2_3_0 - 0.000288600288600299*G0_3_2_3_1 + 0.000962000962000995*G0_3_2_3_2 + 0.00115440115440119*G0_3_2_3_3 + 0.000384800384800398*G0_3_2_3_4 - 9.62000962000995e-05*G0_3_2_4_0 - 9.62000962000995e-05*G0_3_2_4_1 + 0.000481000481000498*G0_3_2_4_2 + 0.000384800384800398*G0_3_2_4_3 + 0.000384800384800398*G0_3_2_4_4 - 1.92400192400199e-05*G0_3_2_5_1 + 9.62000962000996e-05*G0_3_2_5_2 - 7.69600769600796e-05*G0_3_2_5_5 + 0.000115440115440119*G0_3_3_0_0 + 9.62000962000994e-05*G0_3_3_0_1 - 9.62000962000995e-05*G0_3_3_0_2 - 0.000769600769600795*G0_3_3_0_3 - 0.000384800384800398*G0_3_3_0_4 - 0.000230880230880239*G0_3_3_0_5 + 9.62000962000994e-05*G0_3_3_1_0 + 0.000230880230880239*G0_3_3_1_1 - 0.000288600288600299*G0_3_3_1_2 - 0.000769600769600795*G0_3_3_1_3 - 0.000384800384800398*G0_3_3_1_4 - 0.000153920153920159*G0_3_3_1_5 - 9.62000962000995e-05*G0_3_3_2_0 - 0.000288600288600299*G0_3_3_2_1 + 0.000962000962000995*G0_3_3_2_2 + 0.00115440115440119*G0_3_3_2_3 + 0.000384800384800398*G0_3_3_2_4 - 0.000769600769600795*G0_3_3_3_0 - 0.000769600769600795*G0_3_3_3_1 + 0.00115440115440119*G0_3_3_3_2 + 0.00923520923520956*G0_3_3_3_3 + 0.00230880230880239*G0_3_3_3_4 + 0.00153920153920159*G0_3_3_3_5 - 0.000384800384800398*G0_3_3_4_0 - 0.000384800384800397*G0_3_3_4_1 + 0.000384800384800398*G0_3_3_4_2 + 0.00230880230880239*G0_3_3_4_3 + 0.00153920153920159*G0_3_3_4_4 + 0.000769600769600795*G0_3_3_4_5 - 0.000230880230880239*G0_3_3_5_0 - 0.000153920153920159*G0_3_3_5_1 + 0.00153920153920159*G0_3_3_5_3 + 0.000769600769600795*G0_3_3_5_4 + 0.000615680615680636*G0_3_3_5_5 + 9.62000962000994e-05*G0_3_4_0_0 + 7.69600769600795e-05*G0_3_4_0_1 - 9.62000962000995e-05*G0_3_4_0_2 - 0.000384800384800398*G0_3_4_0_3 - 0.000384800384800398*G0_3_4_0_4 - 0.000153920153920159*G0_3_4_0_5 + 7.69600769600795e-05*G0_3_4_1_0 + 9.62000962000994e-05*G0_3_4_1_1 - 9.62000962000995e-05*G0_3_4_1_2 - 0.000384800384800398*G0_3_4_1_3 - 0.000384800384800398*G0_3_4_1_4 - 0.000153920153920159*G0_3_4_1_5 - 9.62000962000995e-05*G0_3_4_2_0 - 9.62000962000995e-05*G0_3_4_2_1 + 0.000481000481000498*G0_3_4_2_2 + 0.000384800384800398*G0_3_4_2_3 + 0.000384800384800398*G0_3_4_2_4 - 0.000384800384800398*G0_3_4_3_0 - 0.000384800384800398*G0_3_4_3_1 + 0.000384800384800398*G0_3_4_3_2 + 0.00230880230880239*G0_3_4_3_3 + 0.00153920153920159*G0_3_4_3_4 + 0.000769600769600795*G0_3_4_3_5 - 0.000384800384800398*G0_3_4_4_0 - 0.000384800384800398*G0_3_4_4_1 + 0.000384800384800398*G0_3_4_4_2 + 0.00153920153920159*G0_3_4_4_3 + 0.00230880230880239*G0_3_4_4_4 + 0.000769600769600796*G0_3_4_4_5 - 0.000153920153920159*G0_3_4_5_0 - 0.000153920153920159*G0_3_4_5_1 + 0.000769600769600795*G0_3_4_5_3 + 0.000769600769600796*G0_3_4_5_4 + 0.000461760461760477*G0_3_4_5_5 + 4.81000481000497e-05*G0_3_5_0_0 + 2.88600288600298e-05*G0_3_5_0_1 - 0.000230880230880239*G0_3_5_0_3 - 0.000153920153920159*G0_3_5_0_4 - 0.000115440115440119*G0_3_5_0_5 + 2.88600288600298e-05*G0_3_5_1_0 + 5.77200577200597e-05*G0_3_5_1_1 - 1.92400192400199e-05*G0_3_5_1_2 - 0.000153920153920159*G0_3_5_1_3 - 0.000153920153920159*G0_3_5_1_4 - 7.69600769600795e-05*G0_3_5_1_5 - 1.92400192400199e-05*G0_3_5_2_1 + 9.62000962000996e-05*G0_3_5_2_2 - 7.69600769600796e-05*G0_3_5_2_5 - 0.000230880230880239*G0_3_5_3_0 - 0.000153920153920159*G0_3_5_3_1 + 0.00153920153920159*G0_3_5_3_3 + 0.000769600769600795*G0_3_5_3_4 + 0.000615680615680636*G0_3_5_3_5 - 0.000153920153920159*G0_3_5_4_0 - 0.000153920153920159*G0_3_5_4_1 + 0.000769600769600795*G0_3_5_4_3 + 0.000769600769600796*G0_3_5_4_4 + 0.000461760461760477*G0_3_5_4_5 - 0.000115440115440119*G0_3_5_5_0 - 7.69600769600795e-05*G0_3_5_5_1 - 7.69600769600796e-05*G0_3_5_5_2 + 0.000615680615680636*G0_3_5_5_3 + 0.000461760461760477*G0_3_5_5_4 + 0.000461760461760477*G0_3_5_5_5 - 2.64550264550273e-05*G0_4_0_0_1 + 3.84800384800398e-05*G0_4_0_0_2 + 9.62000962000994e-05*G0_4_0_0_3 + 0.000230880230880239*G0_4_0_0_4 + 5.77200577200597e-05*G0_4_0_0_5 - 2.64550264550273e-05*G0_4_0_1_0 - 1.92400192400199e-05*G0_4_0_1_1 + 2.88600288600298e-05*G0_4_0_1_2 + 7.69600769600795e-05*G0_4_0_1_3 + 9.62000962000994e-05*G0_4_0_1_4 + 2.88600288600298e-05*G0_4_0_1_5 + 3.84800384800398e-05*G0_4_0_2_0 + 2.88600288600298e-05*G0_4_0_2_1 - 0.000192400192400199*G0_4_0_2_2 - 9.62000962000995e-05*G0_4_0_2_3 - 0.000288600288600299*G0_4_0_2_4 - 1.92400192400199e-05*G0_4_0_2_5 + 9.62000962000994e-05*G0_4_0_3_0 + 7.69600769600795e-05*G0_4_0_3_1 - 9.62000962000995e-05*G0_4_0_3_2 - 0.000384800384800398*G0_4_0_3_3 - 0.000384800384800398*G0_4_0_3_4 - 0.000153920153920159*G0_4_0_3_5 + 0.000230880230880239*G0_4_0_4_0 + 9.62000962000994e-05*G0_4_0_4_1 - 0.000288600288600299*G0_4_0_4_2 - 0.000384800384800398*G0_4_0_4_3 - 0.000769600769600796*G0_4_0_4_4 - 0.000153920153920159*G0_4_0_4_5 + 5.77200577200597e-05*G0_4_0_5_0 + 2.88600288600298e-05*G0_4_0_5_1 - 1.92400192400199e-05*G0_4_0_5_2 - 0.000153920153920159*G0_4_0_5_3 - 0.000153920153920159*G0_4_0_5_4 - 7.69600769600795e-05*G0_4_0_5_5 - 2.64550264550273e-05*G0_4_1_0_0 - 1.92400192400199e-05*G0_4_1_0_1 + 2.88600288600298e-05*G0_4_1_0_2 + 7.69600769600795e-05*G0_4_1_0_3 + 9.62000962000994e-05*G0_4_1_0_4 + 2.88600288600298e-05*G0_4_1_0_5 - 1.92400192400199e-05*G0_4_1_1_0 - 2.16450216450224e-05*G0_4_1_1_1 + 1.92400192400199e-05*G0_4_1_1_2 + 9.62000962000994e-05*G0_4_1_1_3 + 0.000115440115440119*G0_4_1_1_4 + 4.81000481000497e-05*G0_4_1_1_5 + 2.88600288600298e-05*G0_4_1_2_0 + 1.92400192400199e-05*G0_4_1_2_1 - 0.000120250120250124*G0_4_1_2_2 - 9.62000962000995e-05*G0_4_1_2_3 - 9.62000962000994e-05*G0_4_1_2_4 + 7.69600769600795e-05*G0_4_1_3_0 + 9.62000962000994e-05*G0_4_1_3_1 - 9.62000962000995e-05*G0_4_1_3_2 - 0.000384800384800398*G0_4_1_3_3 - 0.000384800384800398*G0_4_1_3_4 - 0.000153920153920159*G0_4_1_3_5 + 9.62000962000994e-05*G0_4_1_4_0 + 0.000115440115440119*G0_4_1_4_1 - 9.62000962000994e-05*G0_4_1_4_2 - 0.000384800384800398*G0_4_1_4_3 - 0.000769600769600796*G0_4_1_4_4 - 0.000230880230880239*G0_4_1_4_5 + 2.88600288600298e-05*G0_4_1_5_0 + 4.81000481000497e-05*G0_4_1_5_1 - 0.000153920153920159*G0_4_1_5_3 - 0.000230880230880239*G0_4_1_5_4 - 0.000115440115440119*G0_4_1_5_5 + 3.84800384800398e-05*G0_4_2_0_0 + 2.88600288600298e-05*G0_4_2_0_1 - 0.000192400192400199*G0_4_2_0_2 - 9.62000962000995e-05*G0_4_2_0_3 - 0.000288600288600299*G0_4_2_0_4 - 1.92400192400199e-05*G0_4_2_0_5 + 2.88600288600298e-05*G0_4_2_1_0 + 1.92400192400199e-05*G0_4_2_1_1 - 0.000120250120250124*G0_4_2_1_2 - 9.62000962000995e-05*G0_4_2_1_3 - 9.62000962000994e-05*G0_4_2_1_4 - 0.000192400192400199*G0_4_2_2_0 - 0.000120250120250124*G0_4_2_2_1 + 0.00115440115440119*G0_4_2_2_2 + 0.000481000481000498*G0_4_2_2_3 + 0.000962000962000995*G0_4_2_2_4 + 9.62000962000996e-05*G0_4_2_2_5 - 9.62000962000995e-05*G0_4_2_3_0 - 9.62000962000995e-05*G0_4_2_3_1 + 0.000481000481000498*G0_4_2_3_2 + 0.000384800384800398*G0_4_2_3_3 + 0.000384800384800398*G0_4_2_3_4 - 0.000288600288600299*G0_4_2_4_0 - 9.62000962000994e-05*G0_4_2_4_1 + 0.000962000962000995*G0_4_2_4_2 + 0.000384800384800398*G0_4_2_4_3 + 0.00115440115440119*G0_4_2_4_4 - 1.92400192400199e-05*G0_4_2_5_0 + 9.62000962000996e-05*G0_4_2_5_2 - 7.69600769600796e-05*G0_4_2_5_5 + 9.62000962000994e-05*G0_4_3_0_0 + 7.69600769600795e-05*G0_4_3_0_1 - 9.62000962000995e-05*G0_4_3_0_2 - 0.000384800384800398*G0_4_3_0_3 - 0.000384800384800398*G0_4_3_0_4 - 0.000153920153920159*G0_4_3_0_5 + 7.69600769600795e-05*G0_4_3_1_0 + 9.62000962000994e-05*G0_4_3_1_1 - 9.62000962000995e-05*G0_4_3_1_2 - 0.000384800384800398*G0_4_3_1_3 - 0.000384800384800398*G0_4_3_1_4 - 0.000153920153920159*G0_4_3_1_5 - 9.62000962000995e-05*G0_4_3_2_0 - 9.62000962000995e-05*G0_4_3_2_1 + 0.000481000481000498*G0_4_3_2_2 + 0.000384800384800398*G0_4_3_2_3 + 0.000384800384800398*G0_4_3_2_4 - 0.000384800384800398*G0_4_3_3_0 - 0.000384800384800397*G0_4_3_3_1 + 0.000384800384800398*G0_4_3_3_2 + 0.00230880230880239*G0_4_3_3_3 + 0.00153920153920159*G0_4_3_3_4 + 0.000769600769600795*G0_4_3_3_5 - 0.000384800384800398*G0_4_3_4_0 - 0.000384800384800398*G0_4_3_4_1 + 0.000384800384800398*G0_4_3_4_2 + 0.00153920153920159*G0_4_3_4_3 + 0.00230880230880239*G0_4_3_4_4 + 0.000769600769600796*G0_4_3_4_5 - 0.000153920153920159*G0_4_3_5_0 - 0.000153920153920159*G0_4_3_5_1 + 0.000769600769600795*G0_4_3_5_3 + 0.000769600769600796*G0_4_3_5_4 + 0.000461760461760477*G0_4_3_5_5 + 0.000230880230880239*G0_4_4_0_0 + 9.62000962000994e-05*G0_4_4_0_1 - 0.000288600288600299*G0_4_4_0_2 - 0.000384800384800398*G0_4_4_0_3 - 0.000769600769600796*G0_4_4_0_4 - 0.000153920153920159*G0_4_4_0_5 + 9.62000962000994e-05*G0_4_4_1_0 + 0.000115440115440119*G0_4_4_1_1 - 9.62000962000995e-05*G0_4_4_1_2 - 0.000384800384800398*G0_4_4_1_3 - 0.000769600769600796*G0_4_4_1_4 - 0.000230880230880239*G0_4_4_1_5 - 0.000288600288600299*G0_4_4_2_0 - 9.62000962000994e-05*G0_4_4_2_1 + 0.000962000962000995*G0_4_4_2_2 + 0.000384800384800398*G0_4_4_2_3 + 0.00115440115440119*G0_4_4_2_4 - 0.000384800384800398*G0_4_4_3_0 - 0.000384800384800398*G0_4_4_3_1 + 0.000384800384800398*G0_4_4_3_2 + 0.00153920153920159*G0_4_4_3_3 + 0.00230880230880239*G0_4_4_3_4 + 0.000769600769600796*G0_4_4_3_5 - 0.000769600769600796*G0_4_4_4_0 - 0.000769600769600796*G0_4_4_4_1 + 0.00115440115440119*G0_4_4_4_2 + 0.00230880230880239*G0_4_4_4_3 + 0.00923520923520955*G0_4_4_4_4 + 0.00153920153920159*G0_4_4_4_5 - 0.000153920153920159*G0_4_4_5_0 - 0.000230880230880239*G0_4_4_5_1 + 0.000769600769600796*G0_4_4_5_3 + 0.00153920153920159*G0_4_4_5_4 + 0.000615680615680637*G0_4_4_5_5 + 5.77200577200597e-05*G0_4_5_0_0 + 2.88600288600298e-05*G0_4_5_0_1 - 1.92400192400199e-05*G0_4_5_0_2 - 0.000153920153920159*G0_4_5_0_3 - 0.000153920153920159*G0_4_5_0_4 - 7.69600769600795e-05*G0_4_5_0_5 + 2.88600288600298e-05*G0_4_5_1_0 + 4.81000481000497e-05*G0_4_5_1_1 - 0.000153920153920159*G0_4_5_1_3 - 0.000230880230880239*G0_4_5_1_4 - 0.000115440115440119*G0_4_5_1_5 - 1.92400192400199e-05*G0_4_5_2_0 + 9.62000962000996e-05*G0_4_5_2_2 - 7.69600769600796e-05*G0_4_5_2_5 - 0.000153920153920159*G0_4_5_3_0 - 0.000153920153920159*G0_4_5_3_1 + 0.000769600769600795*G0_4_5_3_3 + 0.000769600769600796*G0_4_5_3_4 + 0.000461760461760477*G0_4_5_3_5 - 0.000153920153920159*G0_4_5_4_0 - 0.000230880230880239*G0_4_5_4_1 + 0.000769600769600796*G0_4_5_4_3 + 0.00153920153920159*G0_4_5_4_4 + 0.000615680615680637*G0_4_5_4_5 - 7.69600769600795e-05*G0_4_5_5_0 - 0.000115440115440119*G0_4_5_5_1 - 7.69600769600796e-05*G0_4_5_5_2 + 0.000461760461760477*G0_4_5_5_3 + 0.000615680615680637*G0_4_5_5_4 + 0.000461760461760477*G0_4_5_5_5 - 9.62000962000993e-06*G0_5_0_0_1 - 2.40500240500248e-06*G0_5_0_0_2 + 4.81000481000497e-05*G0_5_0_0_3 + 5.77200577200597e-05*G0_5_0_0_4 + 3.84800384800398e-05*G0_5_0_0_5 - 9.62000962000993e-06*G0_5_0_1_0 - 9.62000962000994e-06*G0_5_0_1_1 + 4.81000481000498e-06*G0_5_0_1_2 + 2.88600288600298e-05*G0_5_0_1_3 + 2.88600288600298e-05*G0_5_0_1_4 + 9.62000962000994e-06*G0_5_0_1_5 - 2.40500240500248e-06*G0_5_0_2_0 + 4.81000481000498e-06*G0_5_0_2_1 - 1.92400192400199e-05*G0_5_0_2_2 - 1.92400192400199e-05*G0_5_0_2_4 + 9.62000962000994e-06*G0_5_0_2_5 + 4.81000481000497e-05*G0_5_0_3_0 + 2.88600288600298e-05*G0_5_0_3_1 - 0.000230880230880239*G0_5_0_3_3 - 0.000153920153920159*G0_5_0_3_4 - 0.000115440115440119*G0_5_0_3_5 + 5.77200577200597e-05*G0_5_0_4_0 + 2.88600288600298e-05*G0_5_0_4_1 - 1.92400192400199e-05*G0_5_0_4_2 - 0.000153920153920159*G0_5_0_4_3 - 0.000153920153920159*G0_5_0_4_4 - 7.69600769600795e-05*G0_5_0_4_5 + 3.84800384800398e-05*G0_5_0_5_0 + 9.62000962000994e-06*G0_5_0_5_1 + 9.62000962000994e-06*G0_5_0_5_2 - 0.000115440115440119*G0_5_0_5_3 - 7.69600769600795e-05*G0_5_0_5_4 - 7.69600769600795e-05*G0_5_0_5_5 - 9.62000962000993e-06*G0_5_1_0_0 - 9.62000962000994e-06*G0_5_1_0_1 + 4.81000481000498e-06*G0_5_1_0_2 + 2.88600288600298e-05*G0_5_1_0_3 + 2.88600288600298e-05*G0_5_1_0_4 + 9.62000962000993e-06*G0_5_1_0_5 - 9.62000962000994e-06*G0_5_1_1_0 - 2.40500240500249e-06*G0_5_1_1_2 + 5.77200577200597e-05*G0_5_1_1_3 + 4.81000481000497e-05*G0_5_1_1_4 + 3.84800384800398e-05*G0_5_1_1_5 + 4.81000481000498e-06*G0_5_1_2_0 - 2.40500240500249e-06*G0_5_1_2_1 - 1.92400192400199e-05*G0_5_1_2_2 - 1.92400192400199e-05*G0_5_1_2_3 + 9.62000962000994e-06*G0_5_1_2_5 + 2.88600288600298e-05*G0_5_1_3_0 + 5.77200577200597e-05*G0_5_1_3_1 - 1.92400192400199e-05*G0_5_1_3_2 - 0.000153920153920159*G0_5_1_3_3 - 0.000153920153920159*G0_5_1_3_4 - 7.69600769600795e-05*G0_5_1_3_5 + 2.88600288600298e-05*G0_5_1_4_0 + 4.81000481000497e-05*G0_5_1_4_1 - 0.000153920153920159*G0_5_1_4_3 - 0.000230880230880239*G0_5_1_4_4 - 0.000115440115440119*G0_5_1_4_5 + 9.62000962000994e-06*G0_5_1_5_0 + 3.84800384800398e-05*G0_5_1_5_1 + 9.62000962000994e-06*G0_5_1_5_2 - 7.69600769600795e-05*G0_5_1_5_3 - 0.000115440115440119*G0_5_1_5_4 - 7.69600769600795e-05*G0_5_1_5_5 - 2.40500240500248e-06*G0_5_2_0_0 + 4.81000481000498e-06*G0_5_2_0_1 - 1.92400192400199e-05*G0_5_2_0_2 - 1.92400192400199e-05*G0_5_2_0_4 + 9.62000962000994e-06*G0_5_2_0_5 + 4.81000481000498e-06*G0_5_2_1_0 - 2.40500240500249e-06*G0_5_2_1_1 - 1.92400192400199e-05*G0_5_2_1_2 - 1.92400192400199e-05*G0_5_2_1_3 + 9.62000962000994e-06*G0_5_2_1_5 - 1.92400192400199e-05*G0_5_2_2_0 - 1.92400192400199e-05*G0_5_2_2_1 + 7.21500721500748e-05*G0_5_2_2_2 + 9.62000962000996e-05*G0_5_2_2_3 + 9.62000962000996e-05*G0_5_2_2_4 + 3.84800384800398e-05*G0_5_2_2_5 - 1.92400192400199e-05*G0_5_2_3_1 + 9.62000962000996e-05*G0_5_2_3_2 - 7.69600769600796e-05*G0_5_2_3_5 - 1.92400192400199e-05*G0_5_2_4_0 + 9.62000962000996e-05*G0_5_2_4_2 - 7.69600769600796e-05*G0_5_2_4_5 + 9.62000962000994e-06*G0_5_2_5_0 + 9.62000962000994e-06*G0_5_2_5_1 + 3.84800384800398e-05*G0_5_2_5_2 - 7.69600769600796e-05*G0_5_2_5_3 - 7.69600769600796e-05*G0_5_2_5_4 - 0.000115440115440119*G0_5_2_5_5 + 4.81000481000497e-05*G0_5_3_0_0 + 2.88600288600298e-05*G0_5_3_0_1 - 0.000230880230880239*G0_5_3_0_3 - 0.000153920153920159*G0_5_3_0_4 - 0.000115440115440119*G0_5_3_0_5 + 2.88600288600298e-05*G0_5_3_1_0 + 5.77200577200597e-05*G0_5_3_1_1 - 1.92400192400199e-05*G0_5_3_1_2 - 0.000153920153920159*G0_5_3_1_3 - 0.000153920153920159*G0_5_3_1_4 - 7.69600769600795e-05*G0_5_3_1_5 - 1.92400192400199e-05*G0_5_3_2_1 + 9.62000962000996e-05*G0_5_3_2_2 - 7.69600769600796e-05*G0_5_3_2_5 - 0.000230880230880239*G0_5_3_3_0 - 0.000153920153920159*G0_5_3_3_1 + 0.00153920153920159*G0_5_3_3_3 + 0.000769600769600795*G0_5_3_3_4 + 0.000615680615680636*G0_5_3_3_5 - 0.000153920153920159*G0_5_3_4_0 - 0.000153920153920159*G0_5_3_4_1 + 0.000769600769600795*G0_5_3_4_3 + 0.000769600769600796*G0_5_3_4_4 + 0.000461760461760477*G0_5_3_4_5 - 0.000115440115440119*G0_5_3_5_0 - 7.69600769600795e-05*G0_5_3_5_1 - 7.69600769600796e-05*G0_5_3_5_2 + 0.000615680615680636*G0_5_3_5_3 + 0.000461760461760477*G0_5_3_5_4 + 0.000461760461760477*G0_5_3_5_5 + 5.77200577200597e-05*G0_5_4_0_0 + 2.88600288600298e-05*G0_5_4_0_1 - 1.92400192400199e-05*G0_5_4_0_2 - 0.000153920153920159*G0_5_4_0_3 - 0.000153920153920159*G0_5_4_0_4 - 7.69600769600795e-05*G0_5_4_0_5 + 2.88600288600298e-05*G0_5_4_1_0 + 4.81000481000497e-05*G0_5_4_1_1 - 0.000153920153920159*G0_5_4_1_3 - 0.000230880230880239*G0_5_4_1_4 - 0.000115440115440119*G0_5_4_1_5 - 1.92400192400199e-05*G0_5_4_2_0 + 9.62000962000996e-05*G0_5_4_2_2 - 7.69600769600796e-05*G0_5_4_2_5 - 0.000153920153920159*G0_5_4_3_0 - 0.000153920153920159*G0_5_4_3_1 + 0.000769600769600795*G0_5_4_3_3 + 0.000769600769600796*G0_5_4_3_4 + 0.000461760461760477*G0_5_4_3_5 - 0.000153920153920159*G0_5_4_4_0 - 0.000230880230880239*G0_5_4_4_1 + 0.000769600769600796*G0_5_4_4_3 + 0.00153920153920159*G0_5_4_4_4 + 0.000615680615680637*G0_5_4_4_5 - 7.69600769600795e-05*G0_5_4_5_0 - 0.000115440115440119*G0_5_4_5_1 - 7.69600769600796e-05*G0_5_4_5_2 + 0.000461760461760477*G0_5_4_5_3 + 0.000615680615680637*G0_5_4_5_4 + 0.000461760461760477*G0_5_4_5_5 + 3.84800384800398e-05*G0_5_5_0_0 + 9.62000962000993e-06*G0_5_5_0_1 + 9.62000962000994e-06*G0_5_5_0_2 - 0.000115440115440119*G0_5_5_0_3 - 7.69600769600795e-05*G0_5_5_0_4 - 7.69600769600795e-05*G0_5_5_0_5 + 9.62000962000994e-06*G0_5_5_1_0 + 3.84800384800398e-05*G0_5_5_1_1 + 9.62000962000995e-06*G0_5_5_1_2 - 7.69600769600795e-05*G0_5_5_1_3 - 0.000115440115440119*G0_5_5_1_4 - 7.69600769600796e-05*G0_5_5_1_5 + 9.62000962000994e-06*G0_5_5_2_0 + 9.62000962000994e-06*G0_5_5_2_1 + 3.84800384800398e-05*G0_5_5_2_2 - 7.69600769600796e-05*G0_5_5_2_3 - 7.69600769600796e-05*G0_5_5_2_4 - 0.000115440115440119*G0_5_5_2_5 - 0.000115440115440119*G0_5_5_3_0 - 7.69600769600795e-05*G0_5_5_3_1 - 7.69600769600796e-05*G0_5_5_3_2 + 0.000615680615680636*G0_5_5_3_3 + 0.000461760461760477*G0_5_5_3_4 + 0.000461760461760477*G0_5_5_3_5 - 7.69600769600795e-05*G0_5_5_4_0 - 0.000115440115440119*G0_5_5_4_1 - 7.69600769600796e-05*G0_5_5_4_2 + 0.000461760461760477*G0_5_5_4_3 + 0.000615680615680637*G0_5_5_4_4 + 0.000461760461760477*G0_5_5_4_5 - 7.69600769600795e-05*G0_5_5_5_0 - 7.69600769600796e-05*G0_5_5_5_1 - 0.000115440115440119*G0_5_5_5_2 + 0.000461760461760477*G0_5_5_5_3 + 0.000461760461760477*G0_5_5_5_4 + 0.000615680615680636*G0_5_5_5_5; + A[3] = A[1]; + A[4] = 3.60750360750374e-05*G0_0_0_0_0 - 1.62337662337668e-05*G0_0_0_0_1 + 1.80375180375186e-06*G0_0_0_0_2 - 2.16450216450224e-05*G0_0_0_0_3 - 1.62337662337668e-05*G0_0_0_1_0 + 4.56950456950474e-05*G0_0_0_1_1 - 5.4112554112556e-06*G0_0_0_1_2 + 1.92400192400199e-05*G0_0_0_1_3 - 2.40500240500249e-06*G0_0_0_1_4 + 3.84800384800398e-05*G0_0_0_1_5 + 1.80375180375186e-06*G0_0_0_2_0 - 5.4112554112556e-06*G0_0_0_2_1 + 6.01250601250622e-06*G0_0_0_2_2 - 1.92400192400199e-05*G0_0_0_2_3 - 9.62000962000995e-06*G0_0_0_2_4 - 2.64550264550274e-05*G0_0_0_2_5 - 2.16450216450224e-05*G0_0_0_3_0 + 1.92400192400199e-05*G0_0_0_3_1 - 1.92400192400199e-05*G0_0_0_3_2 + 0.000115440115440119*G0_0_0_3_3 + 4.81000481000497e-05*G0_0_0_3_4 + 9.62000962000995e-05*G0_0_0_3_5 - 2.40500240500249e-06*G0_0_0_4_1 - 9.62000962000995e-06*G0_0_0_4_2 + 4.81000481000497e-05*G0_0_0_4_3 + 3.84800384800398e-05*G0_0_0_4_4 + 5.77200577200597e-05*G0_0_0_4_5 + 3.84800384800398e-05*G0_0_0_5_1 - 2.64550264550274e-05*G0_0_0_5_2 + 9.62000962000995e-05*G0_0_0_5_3 + 5.77200577200597e-05*G0_0_0_5_4 + 0.000230880230880239*G0_0_0_5_5 - 1.62337662337668e-05*G0_0_1_0_0 + 4.56950456950474e-05*G0_0_1_0_1 - 5.4112554112556e-06*G0_0_1_0_2 + 1.92400192400199e-05*G0_0_1_0_3 - 2.40500240500249e-06*G0_0_1_0_4 + 3.84800384800398e-05*G0_0_1_0_5 + 4.56950456950474e-05*G0_0_1_1_0 - 0.000270562770562781*G0_0_1_1_1 + 2.76575276575287e-05*G0_0_1_1_2 - 0.000120250120250125*G0_0_1_1_3 - 1.92400192400199e-05*G0_0_1_1_4 - 0.000192400192400199*G0_0_1_1_5 - 5.4112554112556e-06*G0_0_1_2_0 + 2.76575276575287e-05*G0_0_1_2_1 - 5.41125541125561e-06*G0_0_1_2_2 + 2.88600288600299e-05*G0_0_1_2_3 + 4.81000481000498e-06*G0_0_1_2_4 + 2.88600288600299e-05*G0_0_1_2_5 + 1.92400192400199e-05*G0_0_1_3_0 - 0.000120250120250125*G0_0_1_3_1 + 2.88600288600299e-05*G0_0_1_3_2 - 9.62000962000999e-05*G0_0_1_3_3 - 9.62000962000997e-05*G0_0_1_3_5 - 2.40500240500249e-06*G0_0_1_4_0 - 1.92400192400199e-05*G0_0_1_4_1 + 4.81000481000498e-06*G0_0_1_4_2 + 9.62000962000994e-06*G0_0_1_4_4 - 1.92400192400199e-05*G0_0_1_4_5 + 3.84800384800398e-05*G0_0_1_5_0 - 0.000192400192400199*G0_0_1_5_1 + 2.88600288600299e-05*G0_0_1_5_2 - 9.62000962000997e-05*G0_0_1_5_3 - 1.92400192400199e-05*G0_0_1_5_4 - 0.000288600288600299*G0_0_1_5_5 + 1.80375180375186e-06*G0_0_2_0_0 - 5.4112554112556e-06*G0_0_2_0_1 + 6.01250601250622e-06*G0_0_2_0_2 - 1.92400192400199e-05*G0_0_2_0_3 - 9.62000962000995e-06*G0_0_2_0_4 - 2.64550264550274e-05*G0_0_2_0_5 - 5.4112554112556e-06*G0_0_2_1_0 + 2.76575276575287e-05*G0_0_2_1_1 - 5.41125541125561e-06*G0_0_2_1_2 + 2.88600288600299e-05*G0_0_2_1_3 + 4.81000481000498e-06*G0_0_2_1_4 + 2.88600288600299e-05*G0_0_2_1_5 + 6.01250601250622e-06*G0_0_2_2_0 - 5.41125541125561e-06*G0_0_2_2_1 + 1.80375180375187e-06*G0_0_2_2_2 - 2.64550264550274e-05*G0_0_2_2_3 - 9.62000962000995e-06*G0_0_2_2_4 - 1.92400192400199e-05*G0_0_2_2_5 - 1.92400192400199e-05*G0_0_2_3_0 + 2.88600288600299e-05*G0_0_2_3_1 - 2.64550264550274e-05*G0_0_2_3_2 + 9.62000962000996e-05*G0_0_2_3_3 + 2.88600288600298e-05*G0_0_2_3_4 + 7.69600769600796e-05*G0_0_2_3_5 - 9.62000962000995e-06*G0_0_2_4_0 + 4.81000481000498e-06*G0_0_2_4_1 - 9.62000962000995e-06*G0_0_2_4_2 + 2.88600288600298e-05*G0_0_2_4_3 + 9.62000962000994e-06*G0_0_2_4_4 + 2.88600288600298e-05*G0_0_2_4_5 - 2.64550264550274e-05*G0_0_2_5_0 + 2.88600288600299e-05*G0_0_2_5_1 - 1.92400192400199e-05*G0_0_2_5_2 + 7.69600769600796e-05*G0_0_2_5_3 + 2.88600288600298e-05*G0_0_2_5_4 + 9.62000962000995e-05*G0_0_2_5_5 - 2.16450216450224e-05*G0_0_3_0_0 + 1.92400192400199e-05*G0_0_3_0_1 - 1.92400192400199e-05*G0_0_3_0_2 + 0.000115440115440119*G0_0_3_0_3 + 4.81000481000497e-05*G0_0_3_0_4 + 9.62000962000995e-05*G0_0_3_0_5 + 1.92400192400199e-05*G0_0_3_1_0 - 0.000120250120250125*G0_0_3_1_1 + 2.88600288600299e-05*G0_0_3_1_2 - 9.62000962000999e-05*G0_0_3_1_3 - 9.62000962000997e-05*G0_0_3_1_5 - 1.92400192400199e-05*G0_0_3_2_0 + 2.88600288600299e-05*G0_0_3_2_1 - 2.64550264550274e-05*G0_0_3_2_2 + 9.62000962000996e-05*G0_0_3_2_3 + 2.88600288600298e-05*G0_0_3_2_4 + 7.69600769600796e-05*G0_0_3_2_5 + 0.000115440115440119*G0_0_3_3_0 - 9.62000962000999e-05*G0_0_3_3_1 + 9.62000962000996e-05*G0_0_3_3_2 - 0.000769600769600796*G0_0_3_3_3 - 0.000230880230880239*G0_0_3_3_4 - 0.000384800384800398*G0_0_3_3_5 + 4.81000481000497e-05*G0_0_3_4_0 + 2.88600288600298e-05*G0_0_3_4_2 - 0.000230880230880239*G0_0_3_4_3 - 0.000115440115440119*G0_0_3_4_4 - 0.000153920153920159*G0_0_3_4_5 + 9.62000962000995e-05*G0_0_3_5_0 - 9.62000962000997e-05*G0_0_3_5_1 + 7.69600769600796e-05*G0_0_3_5_2 - 0.000384800384800398*G0_0_3_5_3 - 0.000153920153920159*G0_0_3_5_4 - 0.000384800384800398*G0_0_3_5_5 - 2.40500240500249e-06*G0_0_4_0_1 - 9.62000962000995e-06*G0_0_4_0_2 + 4.81000481000497e-05*G0_0_4_0_3 + 3.84800384800398e-05*G0_0_4_0_4 + 5.77200577200597e-05*G0_0_4_0_5 - 2.40500240500249e-06*G0_0_4_1_0 - 1.92400192400199e-05*G0_0_4_1_1 + 4.81000481000498e-06*G0_0_4_1_2 + 9.62000962000994e-06*G0_0_4_1_4 - 1.92400192400199e-05*G0_0_4_1_5 - 9.62000962000995e-06*G0_0_4_2_0 + 4.81000481000498e-06*G0_0_4_2_1 - 9.62000962000995e-06*G0_0_4_2_2 + 2.88600288600298e-05*G0_0_4_2_3 + 9.62000962000994e-06*G0_0_4_2_4 + 2.88600288600298e-05*G0_0_4_2_5 + 4.81000481000497e-05*G0_0_4_3_0 + 2.88600288600298e-05*G0_0_4_3_2 - 0.000230880230880239*G0_0_4_3_3 - 0.000115440115440119*G0_0_4_3_4 - 0.000153920153920159*G0_0_4_3_5 + 3.84800384800398e-05*G0_0_4_4_0 + 9.62000962000994e-06*G0_0_4_4_1 + 9.62000962000994e-06*G0_0_4_4_2 - 0.000115440115440119*G0_0_4_4_3 - 7.69600769600795e-05*G0_0_4_4_4 - 7.69600769600795e-05*G0_0_4_4_5 + 5.77200577200597e-05*G0_0_4_5_0 - 1.92400192400199e-05*G0_0_4_5_1 + 2.88600288600298e-05*G0_0_4_5_2 - 0.000153920153920159*G0_0_4_5_3 - 7.69600769600795e-05*G0_0_4_5_4 - 0.000153920153920159*G0_0_4_5_5 + 3.84800384800398e-05*G0_0_5_0_1 - 2.64550264550274e-05*G0_0_5_0_2 + 9.62000962000995e-05*G0_0_5_0_3 + 5.77200577200597e-05*G0_0_5_0_4 + 0.000230880230880239*G0_0_5_0_5 + 3.84800384800398e-05*G0_0_5_1_0 - 0.000192400192400199*G0_0_5_1_1 + 2.88600288600299e-05*G0_0_5_1_2 - 9.62000962000997e-05*G0_0_5_1_3 - 1.92400192400199e-05*G0_0_5_1_4 - 0.000288600288600299*G0_0_5_1_5 - 2.64550264550274e-05*G0_0_5_2_0 + 2.88600288600299e-05*G0_0_5_2_1 - 1.92400192400199e-05*G0_0_5_2_2 + 7.69600769600796e-05*G0_0_5_2_3 + 2.88600288600298e-05*G0_0_5_2_4 + 9.62000962000995e-05*G0_0_5_2_5 + 9.62000962000995e-05*G0_0_5_3_0 - 9.62000962000997e-05*G0_0_5_3_1 + 7.69600769600796e-05*G0_0_5_3_2 - 0.000384800384800398*G0_0_5_3_3 - 0.000153920153920159*G0_0_5_3_4 - 0.000384800384800398*G0_0_5_3_5 + 5.77200577200597e-05*G0_0_5_4_0 - 1.92400192400199e-05*G0_0_5_4_1 + 2.88600288600298e-05*G0_0_5_4_2 - 0.000153920153920159*G0_0_5_4_3 - 7.69600769600795e-05*G0_0_5_4_4 - 0.000153920153920159*G0_0_5_4_5 + 0.000230880230880239*G0_0_5_5_0 - 0.000288600288600299*G0_0_5_5_1 + 9.62000962000995e-05*G0_0_5_5_2 - 0.000384800384800398*G0_0_5_5_3 - 0.000153920153920159*G0_0_5_5_4 - 0.000769600769600796*G0_0_5_5_5 - 1.62337662337668e-05*G0_1_0_0_0 + 4.56950456950474e-05*G0_1_0_0_1 - 5.4112554112556e-06*G0_1_0_0_2 + 1.92400192400199e-05*G0_1_0_0_3 - 2.40500240500249e-06*G0_1_0_0_4 + 3.84800384800398e-05*G0_1_0_0_5 + 4.56950456950474e-05*G0_1_0_1_0 - 0.000270562770562781*G0_1_0_1_1 + 2.76575276575287e-05*G0_1_0_1_2 - 0.000120250120250125*G0_1_0_1_3 - 1.92400192400199e-05*G0_1_0_1_4 - 0.000192400192400199*G0_1_0_1_5 - 5.4112554112556e-06*G0_1_0_2_0 + 2.76575276575287e-05*G0_1_0_2_1 - 5.41125541125561e-06*G0_1_0_2_2 + 2.88600288600299e-05*G0_1_0_2_3 + 4.81000481000498e-06*G0_1_0_2_4 + 2.88600288600299e-05*G0_1_0_2_5 + 1.92400192400199e-05*G0_1_0_3_0 - 0.000120250120250125*G0_1_0_3_1 + 2.88600288600299e-05*G0_1_0_3_2 - 9.62000962000999e-05*G0_1_0_3_3 - 9.62000962000997e-05*G0_1_0_3_5 - 2.40500240500249e-06*G0_1_0_4_0 - 1.92400192400199e-05*G0_1_0_4_1 + 4.81000481000498e-06*G0_1_0_4_2 + 9.62000962000994e-06*G0_1_0_4_4 - 1.92400192400199e-05*G0_1_0_4_5 + 3.84800384800398e-05*G0_1_0_5_0 - 0.000192400192400199*G0_1_0_5_1 + 2.88600288600299e-05*G0_1_0_5_2 - 9.62000962000997e-05*G0_1_0_5_3 - 1.92400192400199e-05*G0_1_0_5_4 - 0.000288600288600299*G0_1_0_5_5 + 4.56950456950474e-05*G0_1_1_0_0 - 0.000270562770562781*G0_1_1_0_1 + 2.76575276575287e-05*G0_1_1_0_2 - 0.000120250120250125*G0_1_1_0_3 - 1.92400192400199e-05*G0_1_1_0_4 - 0.000192400192400199*G0_1_1_0_5 - 0.000270562770562781*G0_1_1_1_0 + 0.00371572871572885*G0_1_1_1_1 - 0.00027056277056278*G0_1_1_1_2 + 0.0011544011544012*G0_1_1_1_3 + 7.21500721500745e-05*G0_1_1_1_4 + 0.0011544011544012*G0_1_1_1_5 + 2.76575276575287e-05*G0_1_1_2_0 - 0.00027056277056278*G0_1_1_2_1 + 4.56950456950473e-05*G0_1_1_2_2 - 0.000192400192400199*G0_1_1_2_3 - 1.92400192400199e-05*G0_1_1_2_4 - 0.000120250120250125*G0_1_1_2_5 - 0.000120250120250125*G0_1_1_3_0 + 0.0011544011544012*G0_1_1_3_1 - 0.000192400192400199*G0_1_1_3_2 + 0.000962000962000996*G0_1_1_3_3 + 9.62000962000996e-05*G0_1_1_3_4 + 0.000481000481000499*G0_1_1_3_5 - 1.92400192400199e-05*G0_1_1_4_0 + 7.21500721500745e-05*G0_1_1_4_1 - 1.92400192400199e-05*G0_1_1_4_2 + 9.62000962000996e-05*G0_1_1_4_3 + 3.84800384800398e-05*G0_1_1_4_4 + 9.62000962000995e-05*G0_1_1_4_5 - 0.000192400192400199*G0_1_1_5_0 + 0.0011544011544012*G0_1_1_5_1 - 0.000120250120250125*G0_1_1_5_2 + 0.000481000481000499*G0_1_1_5_3 + 9.62000962000995e-05*G0_1_1_5_4 + 0.000962000962000997*G0_1_1_5_5 - 5.4112554112556e-06*G0_1_2_0_0 + 2.76575276575287e-05*G0_1_2_0_1 - 5.41125541125561e-06*G0_1_2_0_2 + 2.88600288600299e-05*G0_1_2_0_3 + 4.81000481000498e-06*G0_1_2_0_4 + 2.88600288600299e-05*G0_1_2_0_5 + 2.76575276575287e-05*G0_1_2_1_0 - 0.00027056277056278*G0_1_2_1_1 + 4.56950456950473e-05*G0_1_2_1_2 - 0.000192400192400199*G0_1_2_1_3 - 1.92400192400199e-05*G0_1_2_1_4 - 0.000120250120250125*G0_1_2_1_5 - 5.41125541125561e-06*G0_1_2_2_0 + 4.56950456950473e-05*G0_1_2_2_1 - 1.62337662337668e-05*G0_1_2_2_2 + 3.84800384800399e-05*G0_1_2_2_3 - 2.40500240500249e-06*G0_1_2_2_4 + 1.924001924002e-05*G0_1_2_2_5 + 2.88600288600299e-05*G0_1_2_3_0 - 0.000192400192400199*G0_1_2_3_1 + 3.84800384800399e-05*G0_1_2_3_2 - 0.000288600288600299*G0_1_2_3_3 - 1.92400192400199e-05*G0_1_2_3_4 - 9.62000962000997e-05*G0_1_2_3_5 + 4.81000481000498e-06*G0_1_2_4_0 - 1.92400192400199e-05*G0_1_2_4_1 - 2.40500240500249e-06*G0_1_2_4_2 - 1.92400192400199e-05*G0_1_2_4_3 + 9.62000962000996e-06*G0_1_2_4_4 + 2.88600288600299e-05*G0_1_2_5_0 - 0.000120250120250125*G0_1_2_5_1 + 1.924001924002e-05*G0_1_2_5_2 - 9.62000962000997e-05*G0_1_2_5_3 - 9.62000962000997e-05*G0_1_2_5_5 + 1.92400192400199e-05*G0_1_3_0_0 - 0.000120250120250125*G0_1_3_0_1 + 2.88600288600299e-05*G0_1_3_0_2 - 9.62000962000999e-05*G0_1_3_0_3 - 9.62000962000997e-05*G0_1_3_0_5 - 0.000120250120250125*G0_1_3_1_0 + 0.0011544011544012*G0_1_3_1_1 - 0.000192400192400199*G0_1_3_1_2 + 0.000962000962000996*G0_1_3_1_3 + 9.62000962000996e-05*G0_1_3_1_4 + 0.000481000481000499*G0_1_3_1_5 + 2.88600288600299e-05*G0_1_3_2_0 - 0.000192400192400199*G0_1_3_2_1 + 3.84800384800399e-05*G0_1_3_2_2 - 0.000288600288600299*G0_1_3_2_3 - 1.92400192400199e-05*G0_1_3_2_4 - 9.62000962000997e-05*G0_1_3_2_5 - 9.62000962000998e-05*G0_1_3_3_0 + 0.000962000962000996*G0_1_3_3_1 - 0.000288600288600299*G0_1_3_3_2 + 0.0011544011544012*G0_1_3_3_3 + 0.000384800384800399*G0_1_3_3_5 + 9.62000962000996e-05*G0_1_3_4_1 - 1.92400192400199e-05*G0_1_3_4_2 - 7.69600769600796e-05*G0_1_3_4_4 - 9.62000962000997e-05*G0_1_3_5_0 + 0.000481000481000499*G0_1_3_5_1 - 9.62000962000997e-05*G0_1_3_5_2 + 0.000384800384800399*G0_1_3_5_3 + 0.000384800384800399*G0_1_3_5_5 - 2.40500240500249e-06*G0_1_4_0_0 - 1.92400192400199e-05*G0_1_4_0_1 + 4.81000481000498e-06*G0_1_4_0_2 + 9.62000962000994e-06*G0_1_4_0_4 - 1.92400192400199e-05*G0_1_4_0_5 - 1.92400192400199e-05*G0_1_4_1_0 + 7.21500721500745e-05*G0_1_4_1_1 - 1.92400192400199e-05*G0_1_4_1_2 + 9.62000962000996e-05*G0_1_4_1_3 + 3.84800384800398e-05*G0_1_4_1_4 + 9.62000962000995e-05*G0_1_4_1_5 + 4.81000481000498e-06*G0_1_4_2_0 - 1.92400192400199e-05*G0_1_4_2_1 - 2.40500240500249e-06*G0_1_4_2_2 - 1.92400192400199e-05*G0_1_4_2_3 + 9.62000962000995e-06*G0_1_4_2_4 + 9.62000962000996e-05*G0_1_4_3_1 - 1.92400192400199e-05*G0_1_4_3_2 - 7.69600769600796e-05*G0_1_4_3_4 + 9.62000962000994e-06*G0_1_4_4_0 + 3.84800384800398e-05*G0_1_4_4_1 + 9.62000962000996e-06*G0_1_4_4_2 - 7.69600769600796e-05*G0_1_4_4_3 - 0.000115440115440119*G0_1_4_4_4 - 7.69600769600796e-05*G0_1_4_4_5 - 1.92400192400199e-05*G0_1_4_5_0 + 9.62000962000995e-05*G0_1_4_5_1 - 7.69600769600796e-05*G0_1_4_5_4 + 3.84800384800398e-05*G0_1_5_0_0 - 0.000192400192400199*G0_1_5_0_1 + 2.88600288600299e-05*G0_1_5_0_2 - 9.62000962000997e-05*G0_1_5_0_3 - 1.92400192400199e-05*G0_1_5_0_4 - 0.000288600288600299*G0_1_5_0_5 - 0.000192400192400199*G0_1_5_1_0 + 0.0011544011544012*G0_1_5_1_1 - 0.000120250120250125*G0_1_5_1_2 + 0.000481000481000499*G0_1_5_1_3 + 9.62000962000995e-05*G0_1_5_1_4 + 0.000962000962000997*G0_1_5_1_5 + 2.88600288600299e-05*G0_1_5_2_0 - 0.000120250120250125*G0_1_5_2_1 + 1.924001924002e-05*G0_1_5_2_2 - 9.62000962000997e-05*G0_1_5_2_3 - 9.62000962000997e-05*G0_1_5_2_5 - 9.62000962000997e-05*G0_1_5_3_0 + 0.000481000481000499*G0_1_5_3_1 - 9.62000962000997e-05*G0_1_5_3_2 + 0.000384800384800399*G0_1_5_3_3 + 0.000384800384800399*G0_1_5_3_5 - 1.92400192400199e-05*G0_1_5_4_0 + 9.62000962000995e-05*G0_1_5_4_1 - 7.69600769600796e-05*G0_1_5_4_4 - 0.000288600288600299*G0_1_5_5_0 + 0.000962000962000997*G0_1_5_5_1 - 9.62000962000997e-05*G0_1_5_5_2 + 0.000384800384800399*G0_1_5_5_3 + 0.0011544011544012*G0_1_5_5_5 + 1.80375180375186e-06*G0_2_0_0_0 - 5.4112554112556e-06*G0_2_0_0_1 + 6.01250601250622e-06*G0_2_0_0_2 - 1.92400192400199e-05*G0_2_0_0_3 - 9.62000962000995e-06*G0_2_0_0_4 - 2.64550264550274e-05*G0_2_0_0_5 - 5.4112554112556e-06*G0_2_0_1_0 + 2.76575276575287e-05*G0_2_0_1_1 - 5.41125541125561e-06*G0_2_0_1_2 + 2.88600288600299e-05*G0_2_0_1_3 + 4.81000481000498e-06*G0_2_0_1_4 + 2.88600288600299e-05*G0_2_0_1_5 + 6.01250601250622e-06*G0_2_0_2_0 - 5.41125541125561e-06*G0_2_0_2_1 + 1.80375180375187e-06*G0_2_0_2_2 - 2.64550264550274e-05*G0_2_0_2_3 - 9.62000962000995e-06*G0_2_0_2_4 - 1.92400192400199e-05*G0_2_0_2_5 - 1.92400192400199e-05*G0_2_0_3_0 + 2.88600288600299e-05*G0_2_0_3_1 - 2.64550264550274e-05*G0_2_0_3_2 + 9.62000962000996e-05*G0_2_0_3_3 + 2.88600288600298e-05*G0_2_0_3_4 + 7.69600769600796e-05*G0_2_0_3_5 - 9.62000962000995e-06*G0_2_0_4_0 + 4.81000481000498e-06*G0_2_0_4_1 - 9.62000962000995e-06*G0_2_0_4_2 + 2.88600288600298e-05*G0_2_0_4_3 + 9.62000962000994e-06*G0_2_0_4_4 + 2.88600288600298e-05*G0_2_0_4_5 - 2.64550264550274e-05*G0_2_0_5_0 + 2.88600288600299e-05*G0_2_0_5_1 - 1.92400192400199e-05*G0_2_0_5_2 + 7.69600769600796e-05*G0_2_0_5_3 + 2.88600288600298e-05*G0_2_0_5_4 + 9.62000962000995e-05*G0_2_0_5_5 - 5.4112554112556e-06*G0_2_1_0_0 + 2.76575276575287e-05*G0_2_1_0_1 - 5.41125541125561e-06*G0_2_1_0_2 + 2.88600288600299e-05*G0_2_1_0_3 + 4.81000481000498e-06*G0_2_1_0_4 + 2.88600288600299e-05*G0_2_1_0_5 + 2.76575276575287e-05*G0_2_1_1_0 - 0.00027056277056278*G0_2_1_1_1 + 4.56950456950473e-05*G0_2_1_1_2 - 0.000192400192400199*G0_2_1_1_3 - 1.92400192400199e-05*G0_2_1_1_4 - 0.000120250120250125*G0_2_1_1_5 - 5.41125541125561e-06*G0_2_1_2_0 + 4.56950456950473e-05*G0_2_1_2_1 - 1.62337662337668e-05*G0_2_1_2_2 + 3.84800384800399e-05*G0_2_1_2_3 - 2.40500240500249e-06*G0_2_1_2_4 + 1.924001924002e-05*G0_2_1_2_5 + 2.88600288600299e-05*G0_2_1_3_0 - 0.000192400192400199*G0_2_1_3_1 + 3.84800384800399e-05*G0_2_1_3_2 - 0.000288600288600299*G0_2_1_3_3 - 1.92400192400199e-05*G0_2_1_3_4 - 9.62000962000997e-05*G0_2_1_3_5 + 4.81000481000498e-06*G0_2_1_4_0 - 1.92400192400199e-05*G0_2_1_4_1 - 2.40500240500249e-06*G0_2_1_4_2 - 1.92400192400199e-05*G0_2_1_4_3 + 9.62000962000995e-06*G0_2_1_4_4 + 2.88600288600299e-05*G0_2_1_5_0 - 0.000120250120250125*G0_2_1_5_1 + 1.924001924002e-05*G0_2_1_5_2 - 9.62000962000997e-05*G0_2_1_5_3 - 9.62000962000997e-05*G0_2_1_5_5 + 6.01250601250622e-06*G0_2_2_0_0 - 5.41125541125561e-06*G0_2_2_0_1 + 1.80375180375187e-06*G0_2_2_0_2 - 2.64550264550274e-05*G0_2_2_0_3 - 9.62000962000995e-06*G0_2_2_0_4 - 1.92400192400199e-05*G0_2_2_0_5 - 5.41125541125561e-06*G0_2_2_1_0 + 4.56950456950473e-05*G0_2_2_1_1 - 1.62337662337668e-05*G0_2_2_1_2 + 3.84800384800399e-05*G0_2_2_1_3 - 2.40500240500249e-06*G0_2_2_1_4 + 1.924001924002e-05*G0_2_2_1_5 + 1.80375180375187e-06*G0_2_2_2_0 - 1.62337662337668e-05*G0_2_2_2_1 + 3.60750360750373e-05*G0_2_2_2_2 - 2.16450216450224e-05*G0_2_2_2_5 - 2.64550264550274e-05*G0_2_2_3_0 + 3.84800384800399e-05*G0_2_2_3_1 + 0.000230880230880239*G0_2_2_3_3 + 5.77200577200597e-05*G0_2_2_3_4 + 9.62000962000995e-05*G0_2_2_3_5 - 9.62000962000995e-06*G0_2_2_4_0 - 2.40500240500249e-06*G0_2_2_4_1 + 5.77200577200597e-05*G0_2_2_4_3 + 3.84800384800398e-05*G0_2_2_4_4 + 4.81000481000498e-05*G0_2_2_4_5 - 1.92400192400199e-05*G0_2_2_5_0 + 1.924001924002e-05*G0_2_2_5_1 - 2.16450216450224e-05*G0_2_2_5_2 + 9.62000962000995e-05*G0_2_2_5_3 + 4.81000481000498e-05*G0_2_2_5_4 + 0.000115440115440119*G0_2_2_5_5 - 1.92400192400199e-05*G0_2_3_0_0 + 2.88600288600299e-05*G0_2_3_0_1 - 2.64550264550274e-05*G0_2_3_0_2 + 9.62000962000996e-05*G0_2_3_0_3 + 2.88600288600298e-05*G0_2_3_0_4 + 7.69600769600796e-05*G0_2_3_0_5 + 2.88600288600299e-05*G0_2_3_1_0 - 0.000192400192400199*G0_2_3_1_1 + 3.84800384800399e-05*G0_2_3_1_2 - 0.000288600288600299*G0_2_3_1_3 - 1.92400192400199e-05*G0_2_3_1_4 - 9.62000962000997e-05*G0_2_3_1_5 - 2.64550264550274e-05*G0_2_3_2_0 + 3.84800384800399e-05*G0_2_3_2_1 + 0.000230880230880239*G0_2_3_2_3 + 5.77200577200597e-05*G0_2_3_2_4 + 9.62000962000996e-05*G0_2_3_2_5 + 9.62000962000996e-05*G0_2_3_3_0 - 0.000288600288600299*G0_2_3_3_1 + 0.000230880230880239*G0_2_3_3_2 - 0.000769600769600796*G0_2_3_3_3 - 0.000153920153920159*G0_2_3_3_4 - 0.000384800384800398*G0_2_3_3_5 + 2.88600288600298e-05*G0_2_3_4_0 - 1.92400192400199e-05*G0_2_3_4_1 + 5.77200577200597e-05*G0_2_3_4_2 - 0.000153920153920159*G0_2_3_4_3 - 7.69600769600796e-05*G0_2_3_4_4 - 0.000153920153920159*G0_2_3_4_5 + 7.69600769600796e-05*G0_2_3_5_0 - 9.62000962000997e-05*G0_2_3_5_1 + 9.62000962000995e-05*G0_2_3_5_2 - 0.000384800384800398*G0_2_3_5_3 - 0.000153920153920159*G0_2_3_5_4 - 0.000384800384800398*G0_2_3_5_5 - 9.62000962000995e-06*G0_2_4_0_0 + 4.81000481000498e-06*G0_2_4_0_1 - 9.62000962000995e-06*G0_2_4_0_2 + 2.88600288600298e-05*G0_2_4_0_3 + 9.62000962000994e-06*G0_2_4_0_4 + 2.88600288600298e-05*G0_2_4_0_5 + 4.81000481000498e-06*G0_2_4_1_0 - 1.92400192400199e-05*G0_2_4_1_1 - 2.40500240500249e-06*G0_2_4_1_2 - 1.92400192400199e-05*G0_2_4_1_3 + 9.62000962000996e-06*G0_2_4_1_4 - 9.62000962000995e-06*G0_2_4_2_0 - 2.40500240500249e-06*G0_2_4_2_1 + 5.77200577200597e-05*G0_2_4_2_3 + 3.84800384800398e-05*G0_2_4_2_4 + 4.81000481000498e-05*G0_2_4_2_5 + 2.88600288600298e-05*G0_2_4_3_0 - 1.92400192400199e-05*G0_2_4_3_1 + 5.77200577200597e-05*G0_2_4_3_2 - 0.000153920153920159*G0_2_4_3_3 - 7.69600769600796e-05*G0_2_4_3_4 - 0.000153920153920159*G0_2_4_3_5 + 9.62000962000994e-06*G0_2_4_4_0 + 9.62000962000995e-06*G0_2_4_4_1 + 3.84800384800398e-05*G0_2_4_4_2 - 7.69600769600796e-05*G0_2_4_4_3 - 7.69600769600796e-05*G0_2_4_4_4 - 0.000115440115440119*G0_2_4_4_5 + 2.88600288600298e-05*G0_2_4_5_0 + 4.81000481000498e-05*G0_2_4_5_2 - 0.000153920153920159*G0_2_4_5_3 - 0.000115440115440119*G0_2_4_5_4 - 0.000230880230880239*G0_2_4_5_5 - 2.64550264550274e-05*G0_2_5_0_0 + 2.88600288600299e-05*G0_2_5_0_1 - 1.92400192400199e-05*G0_2_5_0_2 + 7.69600769600796e-05*G0_2_5_0_3 + 2.88600288600298e-05*G0_2_5_0_4 + 9.62000962000994e-05*G0_2_5_0_5 + 2.88600288600299e-05*G0_2_5_1_0 - 0.000120250120250125*G0_2_5_1_1 + 1.924001924002e-05*G0_2_5_1_2 - 9.62000962000997e-05*G0_2_5_1_3 - 9.62000962000997e-05*G0_2_5_1_5 - 1.92400192400199e-05*G0_2_5_2_0 + 1.924001924002e-05*G0_2_5_2_1 - 2.16450216450224e-05*G0_2_5_2_2 + 9.62000962000995e-05*G0_2_5_2_3 + 4.81000481000497e-05*G0_2_5_2_4 + 0.000115440115440119*G0_2_5_2_5 + 7.69600769600796e-05*G0_2_5_3_0 - 9.62000962000997e-05*G0_2_5_3_1 + 9.62000962000995e-05*G0_2_5_3_2 - 0.000384800384800398*G0_2_5_3_3 - 0.000153920153920159*G0_2_5_3_4 - 0.000384800384800398*G0_2_5_3_5 + 2.88600288600298e-05*G0_2_5_4_0 + 4.81000481000497e-05*G0_2_5_4_2 - 0.000153920153920159*G0_2_5_4_3 - 0.000115440115440119*G0_2_5_4_4 - 0.000230880230880239*G0_2_5_4_5 + 9.62000962000995e-05*G0_2_5_5_0 - 9.62000962000997e-05*G0_2_5_5_1 + 0.000115440115440119*G0_2_5_5_2 - 0.000384800384800398*G0_2_5_5_3 - 0.000230880230880239*G0_2_5_5_4 - 0.000769600769600797*G0_2_5_5_5 - 2.16450216450224e-05*G0_3_0_0_0 + 1.92400192400199e-05*G0_3_0_0_1 - 1.92400192400199e-05*G0_3_0_0_2 + 0.000115440115440119*G0_3_0_0_3 + 4.81000481000497e-05*G0_3_0_0_4 + 9.62000962000995e-05*G0_3_0_0_5 + 1.92400192400199e-05*G0_3_0_1_0 - 0.000120250120250125*G0_3_0_1_1 + 2.88600288600299e-05*G0_3_0_1_2 - 9.62000962000998e-05*G0_3_0_1_3 - 9.62000962000997e-05*G0_3_0_1_5 - 1.92400192400199e-05*G0_3_0_2_0 + 2.88600288600299e-05*G0_3_0_2_1 - 2.64550264550274e-05*G0_3_0_2_2 + 9.62000962000996e-05*G0_3_0_2_3 + 2.88600288600298e-05*G0_3_0_2_4 + 7.69600769600796e-05*G0_3_0_2_5 + 0.000115440115440119*G0_3_0_3_0 - 9.62000962000998e-05*G0_3_0_3_1 + 9.62000962000996e-05*G0_3_0_3_2 - 0.000769600769600796*G0_3_0_3_3 - 0.000230880230880239*G0_3_0_3_4 - 0.000384800384800398*G0_3_0_3_5 + 4.81000481000497e-05*G0_3_0_4_0 + 2.88600288600298e-05*G0_3_0_4_2 - 0.000230880230880239*G0_3_0_4_3 - 0.000115440115440119*G0_3_0_4_4 - 0.000153920153920159*G0_3_0_4_5 + 9.62000962000995e-05*G0_3_0_5_0 - 9.62000962000997e-05*G0_3_0_5_1 + 7.69600769600796e-05*G0_3_0_5_2 - 0.000384800384800398*G0_3_0_5_3 - 0.000153920153920159*G0_3_0_5_4 - 0.000384800384800398*G0_3_0_5_5 + 1.92400192400199e-05*G0_3_1_0_0 - 0.000120250120250125*G0_3_1_0_1 + 2.88600288600299e-05*G0_3_1_0_2 - 9.62000962000998e-05*G0_3_1_0_3 - 9.62000962000997e-05*G0_3_1_0_5 - 0.000120250120250125*G0_3_1_1_0 + 0.0011544011544012*G0_3_1_1_1 - 0.000192400192400199*G0_3_1_1_2 + 0.000962000962000996*G0_3_1_1_3 + 9.62000962000996e-05*G0_3_1_1_4 + 0.000481000481000499*G0_3_1_1_5 + 2.88600288600299e-05*G0_3_1_2_0 - 0.000192400192400199*G0_3_1_2_1 + 3.84800384800399e-05*G0_3_1_2_2 - 0.000288600288600299*G0_3_1_2_3 - 1.92400192400199e-05*G0_3_1_2_4 - 9.62000962000997e-05*G0_3_1_2_5 - 9.62000962000998e-05*G0_3_1_3_0 + 0.000962000962000996*G0_3_1_3_1 - 0.000288600288600299*G0_3_1_3_2 + 0.0011544011544012*G0_3_1_3_3 + 0.000384800384800399*G0_3_1_3_5 + 9.62000962000996e-05*G0_3_1_4_1 - 1.92400192400199e-05*G0_3_1_4_2 - 7.69600769600796e-05*G0_3_1_4_4 - 9.62000962000997e-05*G0_3_1_5_0 + 0.000481000481000499*G0_3_1_5_1 - 9.62000962000997e-05*G0_3_1_5_2 + 0.000384800384800399*G0_3_1_5_3 + 0.000384800384800399*G0_3_1_5_5 - 1.92400192400199e-05*G0_3_2_0_0 + 2.88600288600299e-05*G0_3_2_0_1 - 2.64550264550274e-05*G0_3_2_0_2 + 9.62000962000996e-05*G0_3_2_0_3 + 2.88600288600298e-05*G0_3_2_0_4 + 7.69600769600796e-05*G0_3_2_0_5 + 2.88600288600299e-05*G0_3_2_1_0 - 0.000192400192400199*G0_3_2_1_1 + 3.84800384800399e-05*G0_3_2_1_2 - 0.000288600288600299*G0_3_2_1_3 - 1.92400192400199e-05*G0_3_2_1_4 - 9.62000962000997e-05*G0_3_2_1_5 - 2.64550264550274e-05*G0_3_2_2_0 + 3.84800384800399e-05*G0_3_2_2_1 + 0.000230880230880239*G0_3_2_2_3 + 5.77200577200597e-05*G0_3_2_2_4 + 9.62000962000995e-05*G0_3_2_2_5 + 9.62000962000996e-05*G0_3_2_3_0 - 0.000288600288600299*G0_3_2_3_1 + 0.000230880230880239*G0_3_2_3_2 - 0.000769600769600796*G0_3_2_3_3 - 0.000153920153920159*G0_3_2_3_4 - 0.000384800384800398*G0_3_2_3_5 + 2.88600288600298e-05*G0_3_2_4_0 - 1.92400192400199e-05*G0_3_2_4_1 + 5.77200577200597e-05*G0_3_2_4_2 - 0.000153920153920159*G0_3_2_4_3 - 7.69600769600796e-05*G0_3_2_4_4 - 0.000153920153920159*G0_3_2_4_5 + 7.69600769600796e-05*G0_3_2_5_0 - 9.62000962000997e-05*G0_3_2_5_1 + 9.62000962000995e-05*G0_3_2_5_2 - 0.000384800384800398*G0_3_2_5_3 - 0.000153920153920159*G0_3_2_5_4 - 0.000384800384800398*G0_3_2_5_5 + 0.000115440115440119*G0_3_3_0_0 - 9.62000962000998e-05*G0_3_3_0_1 + 9.62000962000996e-05*G0_3_3_0_2 - 0.000769600769600796*G0_3_3_0_3 - 0.000230880230880239*G0_3_3_0_4 - 0.000384800384800398*G0_3_3_0_5 - 9.62000962000998e-05*G0_3_3_1_0 + 0.000962000962000996*G0_3_3_1_1 - 0.000288600288600299*G0_3_3_1_2 + 0.0011544011544012*G0_3_3_1_3 + 0.000384800384800399*G0_3_3_1_5 + 9.62000962000996e-05*G0_3_3_2_0 - 0.000288600288600299*G0_3_3_2_1 + 0.000230880230880239*G0_3_3_2_2 - 0.000769600769600796*G0_3_3_2_3 - 0.000153920153920159*G0_3_3_2_4 - 0.000384800384800398*G0_3_3_2_5 - 0.000769600769600796*G0_3_3_3_0 + 0.0011544011544012*G0_3_3_3_1 - 0.000769600769600796*G0_3_3_3_2 + 0.00923520923520956*G0_3_3_3_3 + 0.00153920153920159*G0_3_3_3_4 + 0.00230880230880239*G0_3_3_3_5 - 0.000230880230880239*G0_3_3_4_0 - 0.000153920153920159*G0_3_3_4_2 + 0.00153920153920159*G0_3_3_4_3 + 0.000615680615680636*G0_3_3_4_4 + 0.000769600769600796*G0_3_3_4_5 - 0.000384800384800398*G0_3_3_5_0 + 0.000384800384800399*G0_3_3_5_1 - 0.000384800384800398*G0_3_3_5_2 + 0.00230880230880239*G0_3_3_5_3 + 0.000769600769600796*G0_3_3_5_4 + 0.00153920153920159*G0_3_3_5_5 + 4.81000481000497e-05*G0_3_4_0_0 + 2.88600288600298e-05*G0_3_4_0_2 - 0.000230880230880239*G0_3_4_0_3 - 0.000115440115440119*G0_3_4_0_4 - 0.000153920153920159*G0_3_4_0_5 + 9.62000962000996e-05*G0_3_4_1_1 - 1.92400192400199e-05*G0_3_4_1_2 - 7.69600769600796e-05*G0_3_4_1_4 + 2.88600288600298e-05*G0_3_4_2_0 - 1.92400192400199e-05*G0_3_4_2_1 + 5.77200577200597e-05*G0_3_4_2_2 - 0.000153920153920159*G0_3_4_2_3 - 7.69600769600796e-05*G0_3_4_2_4 - 0.000153920153920159*G0_3_4_2_5 - 0.000230880230880239*G0_3_4_3_0 - 0.000153920153920159*G0_3_4_3_2 + 0.00153920153920159*G0_3_4_3_3 + 0.000615680615680636*G0_3_4_3_4 + 0.000769600769600796*G0_3_4_3_5 - 0.000115440115440119*G0_3_4_4_0 - 7.69600769600796e-05*G0_3_4_4_1 - 7.69600769600796e-05*G0_3_4_4_2 + 0.000615680615680636*G0_3_4_4_3 + 0.000461760461760477*G0_3_4_4_4 + 0.000461760461760477*G0_3_4_4_5 - 0.000153920153920159*G0_3_4_5_0 - 0.000153920153920159*G0_3_4_5_2 + 0.000769600769600796*G0_3_4_5_3 + 0.000461760461760477*G0_3_4_5_4 + 0.000769600769600796*G0_3_4_5_5 + 9.62000962000995e-05*G0_3_5_0_0 - 9.62000962000997e-05*G0_3_5_0_1 + 7.69600769600796e-05*G0_3_5_0_2 - 0.000384800384800398*G0_3_5_0_3 - 0.000153920153920159*G0_3_5_0_4 - 0.000384800384800398*G0_3_5_0_5 - 9.62000962000997e-05*G0_3_5_1_0 + 0.000481000481000499*G0_3_5_1_1 - 9.62000962000997e-05*G0_3_5_1_2 + 0.000384800384800399*G0_3_5_1_3 + 0.000384800384800399*G0_3_5_1_5 + 7.69600769600796e-05*G0_3_5_2_0 - 9.62000962000997e-05*G0_3_5_2_1 + 9.62000962000995e-05*G0_3_5_2_2 - 0.000384800384800398*G0_3_5_2_3 - 0.000153920153920159*G0_3_5_2_4 - 0.000384800384800398*G0_3_5_2_5 - 0.000384800384800398*G0_3_5_3_0 + 0.000384800384800399*G0_3_5_3_1 - 0.000384800384800398*G0_3_5_3_2 + 0.00230880230880239*G0_3_5_3_3 + 0.000769600769600796*G0_3_5_3_4 + 0.00153920153920159*G0_3_5_3_5 - 0.000153920153920159*G0_3_5_4_0 - 0.000153920153920159*G0_3_5_4_2 + 0.000769600769600796*G0_3_5_4_3 + 0.000461760461760477*G0_3_5_4_4 + 0.000769600769600796*G0_3_5_4_5 - 0.000384800384800398*G0_3_5_5_0 + 0.000384800384800399*G0_3_5_5_1 - 0.000384800384800398*G0_3_5_5_2 + 0.00153920153920159*G0_3_5_5_3 + 0.000769600769600796*G0_3_5_5_4 + 0.00230880230880239*G0_3_5_5_5 - 2.40500240500249e-06*G0_4_0_0_1 - 9.62000962000995e-06*G0_4_0_0_2 + 4.81000481000497e-05*G0_4_0_0_3 + 3.84800384800398e-05*G0_4_0_0_4 + 5.77200577200597e-05*G0_4_0_0_5 - 2.40500240500249e-06*G0_4_0_1_0 - 1.92400192400199e-05*G0_4_0_1_1 + 4.81000481000498e-06*G0_4_0_1_2 + 9.62000962000994e-06*G0_4_0_1_4 - 1.92400192400199e-05*G0_4_0_1_5 - 9.62000962000995e-06*G0_4_0_2_0 + 4.81000481000498e-06*G0_4_0_2_1 - 9.62000962000995e-06*G0_4_0_2_2 + 2.88600288600298e-05*G0_4_0_2_3 + 9.62000962000994e-06*G0_4_0_2_4 + 2.88600288600298e-05*G0_4_0_2_5 + 4.81000481000497e-05*G0_4_0_3_0 + 2.88600288600298e-05*G0_4_0_3_2 - 0.000230880230880239*G0_4_0_3_3 - 0.000115440115440119*G0_4_0_3_4 - 0.000153920153920159*G0_4_0_3_5 + 3.84800384800398e-05*G0_4_0_4_0 + 9.62000962000994e-06*G0_4_0_4_1 + 9.62000962000994e-06*G0_4_0_4_2 - 0.000115440115440119*G0_4_0_4_3 - 7.69600769600795e-05*G0_4_0_4_4 - 7.69600769600795e-05*G0_4_0_4_5 + 5.77200577200597e-05*G0_4_0_5_0 - 1.92400192400199e-05*G0_4_0_5_1 + 2.88600288600298e-05*G0_4_0_5_2 - 0.000153920153920159*G0_4_0_5_3 - 7.69600769600795e-05*G0_4_0_5_4 - 0.000153920153920159*G0_4_0_5_5 - 2.40500240500249e-06*G0_4_1_0_0 - 1.92400192400199e-05*G0_4_1_0_1 + 4.81000481000498e-06*G0_4_1_0_2 + 9.62000962000994e-06*G0_4_1_0_4 - 1.92400192400199e-05*G0_4_1_0_5 - 1.92400192400199e-05*G0_4_1_1_0 + 7.21500721500745e-05*G0_4_1_1_1 - 1.92400192400199e-05*G0_4_1_1_2 + 9.62000962000996e-05*G0_4_1_1_3 + 3.84800384800398e-05*G0_4_1_1_4 + 9.62000962000995e-05*G0_4_1_1_5 + 4.81000481000498e-06*G0_4_1_2_0 - 1.92400192400199e-05*G0_4_1_2_1 - 2.40500240500249e-06*G0_4_1_2_2 - 1.92400192400199e-05*G0_4_1_2_3 + 9.62000962000995e-06*G0_4_1_2_4 + 9.62000962000996e-05*G0_4_1_3_1 - 1.92400192400199e-05*G0_4_1_3_2 - 7.69600769600796e-05*G0_4_1_3_4 + 9.62000962000994e-06*G0_4_1_4_0 + 3.84800384800398e-05*G0_4_1_4_1 + 9.62000962000996e-06*G0_4_1_4_2 - 7.69600769600796e-05*G0_4_1_4_3 - 0.000115440115440119*G0_4_1_4_4 - 7.69600769600796e-05*G0_4_1_4_5 - 1.92400192400199e-05*G0_4_1_5_0 + 9.62000962000995e-05*G0_4_1_5_1 - 7.69600769600796e-05*G0_4_1_5_4 - 9.62000962000995e-06*G0_4_2_0_0 + 4.81000481000498e-06*G0_4_2_0_1 - 9.62000962000995e-06*G0_4_2_0_2 + 2.88600288600298e-05*G0_4_2_0_3 + 9.62000962000994e-06*G0_4_2_0_4 + 2.88600288600298e-05*G0_4_2_0_5 + 4.81000481000498e-06*G0_4_2_1_0 - 1.92400192400199e-05*G0_4_2_1_1 - 2.40500240500249e-06*G0_4_2_1_2 - 1.92400192400199e-05*G0_4_2_1_3 + 9.62000962000995e-06*G0_4_2_1_4 - 9.62000962000995e-06*G0_4_2_2_0 - 2.40500240500249e-06*G0_4_2_2_1 + 5.77200577200597e-05*G0_4_2_2_3 + 3.84800384800398e-05*G0_4_2_2_4 + 4.81000481000498e-05*G0_4_2_2_5 + 2.88600288600298e-05*G0_4_2_3_0 - 1.92400192400199e-05*G0_4_2_3_1 + 5.77200577200597e-05*G0_4_2_3_2 - 0.000153920153920159*G0_4_2_3_3 - 7.69600769600796e-05*G0_4_2_3_4 - 0.000153920153920159*G0_4_2_3_5 + 9.62000962000994e-06*G0_4_2_4_0 + 9.62000962000995e-06*G0_4_2_4_1 + 3.84800384800398e-05*G0_4_2_4_2 - 7.69600769600796e-05*G0_4_2_4_3 - 7.69600769600796e-05*G0_4_2_4_4 - 0.000115440115440119*G0_4_2_4_5 + 2.88600288600298e-05*G0_4_2_5_0 + 4.81000481000497e-05*G0_4_2_5_2 - 0.000153920153920159*G0_4_2_5_3 - 0.000115440115440119*G0_4_2_5_4 - 0.000230880230880239*G0_4_2_5_5 + 4.81000481000497e-05*G0_4_3_0_0 + 2.88600288600298e-05*G0_4_3_0_2 - 0.000230880230880239*G0_4_3_0_3 - 0.000115440115440119*G0_4_3_0_4 - 0.000153920153920159*G0_4_3_0_5 + 9.62000962000996e-05*G0_4_3_1_1 - 1.92400192400199e-05*G0_4_3_1_2 - 7.69600769600796e-05*G0_4_3_1_4 + 2.88600288600298e-05*G0_4_3_2_0 - 1.92400192400199e-05*G0_4_3_2_1 + 5.77200577200597e-05*G0_4_3_2_2 - 0.000153920153920159*G0_4_3_2_3 - 7.69600769600796e-05*G0_4_3_2_4 - 0.000153920153920159*G0_4_3_2_5 - 0.000230880230880239*G0_4_3_3_0 - 0.000153920153920159*G0_4_3_3_2 + 0.00153920153920159*G0_4_3_3_3 + 0.000615680615680636*G0_4_3_3_4 + 0.000769600769600796*G0_4_3_3_5 - 0.000115440115440119*G0_4_3_4_0 - 7.69600769600796e-05*G0_4_3_4_1 - 7.69600769600796e-05*G0_4_3_4_2 + 0.000615680615680636*G0_4_3_4_3 + 0.000461760461760477*G0_4_3_4_4 + 0.000461760461760477*G0_4_3_4_5 - 0.000153920153920159*G0_4_3_5_0 - 0.000153920153920159*G0_4_3_5_2 + 0.000769600769600796*G0_4_3_5_3 + 0.000461760461760477*G0_4_3_5_4 + 0.000769600769600796*G0_4_3_5_5 + 3.84800384800398e-05*G0_4_4_0_0 + 9.62000962000994e-06*G0_4_4_0_1 + 9.62000962000994e-06*G0_4_4_0_2 - 0.000115440115440119*G0_4_4_0_3 - 7.69600769600795e-05*G0_4_4_0_4 - 7.69600769600795e-05*G0_4_4_0_5 + 9.62000962000994e-06*G0_4_4_1_0 + 3.84800384800398e-05*G0_4_4_1_1 + 9.62000962000996e-06*G0_4_4_1_2 - 7.69600769600796e-05*G0_4_4_1_3 - 0.000115440115440119*G0_4_4_1_4 - 7.69600769600796e-05*G0_4_4_1_5 + 9.62000962000994e-06*G0_4_4_2_0 + 9.62000962000995e-06*G0_4_4_2_1 + 3.84800384800398e-05*G0_4_4_2_2 - 7.69600769600796e-05*G0_4_4_2_3 - 7.69600769600796e-05*G0_4_4_2_4 - 0.000115440115440119*G0_4_4_2_5 - 0.000115440115440119*G0_4_4_3_0 - 7.69600769600796e-05*G0_4_4_3_1 - 7.69600769600796e-05*G0_4_4_3_2 + 0.000615680615680636*G0_4_4_3_3 + 0.000461760461760477*G0_4_4_3_4 + 0.000461760461760477*G0_4_4_3_5 - 7.69600769600795e-05*G0_4_4_4_0 - 0.000115440115440119*G0_4_4_4_1 - 7.69600769600796e-05*G0_4_4_4_2 + 0.000461760461760477*G0_4_4_4_3 + 0.000615680615680637*G0_4_4_4_4 + 0.000461760461760477*G0_4_4_4_5 - 7.69600769600795e-05*G0_4_4_5_0 - 7.69600769600796e-05*G0_4_4_5_1 - 0.000115440115440119*G0_4_4_5_2 + 0.000461760461760477*G0_4_4_5_3 + 0.000461760461760477*G0_4_4_5_4 + 0.000615680615680636*G0_4_4_5_5 + 5.77200577200597e-05*G0_4_5_0_0 - 1.92400192400199e-05*G0_4_5_0_1 + 2.88600288600298e-05*G0_4_5_0_2 - 0.000153920153920159*G0_4_5_0_3 - 7.69600769600795e-05*G0_4_5_0_4 - 0.000153920153920159*G0_4_5_0_5 - 1.92400192400199e-05*G0_4_5_1_0 + 9.62000962000995e-05*G0_4_5_1_1 - 7.69600769600796e-05*G0_4_5_1_4 + 2.88600288600298e-05*G0_4_5_2_0 + 4.81000481000497e-05*G0_4_5_2_2 - 0.000153920153920159*G0_4_5_2_3 - 0.000115440115440119*G0_4_5_2_4 - 0.000230880230880239*G0_4_5_2_5 - 0.000153920153920159*G0_4_5_3_0 - 0.000153920153920159*G0_4_5_3_2 + 0.000769600769600796*G0_4_5_3_3 + 0.000461760461760477*G0_4_5_3_4 + 0.000769600769600796*G0_4_5_3_5 - 7.69600769600795e-05*G0_4_5_4_0 - 7.69600769600796e-05*G0_4_5_4_1 - 0.000115440115440119*G0_4_5_4_2 + 0.000461760461760477*G0_4_5_4_3 + 0.000461760461760477*G0_4_5_4_4 + 0.000615680615680637*G0_4_5_4_5 - 0.000153920153920159*G0_4_5_5_0 - 0.000230880230880239*G0_4_5_5_2 + 0.000769600769600796*G0_4_5_5_3 + 0.000615680615680637*G0_4_5_5_4 + 0.00153920153920159*G0_4_5_5_5 + 3.84800384800398e-05*G0_5_0_0_1 - 2.64550264550274e-05*G0_5_0_0_2 + 9.62000962000995e-05*G0_5_0_0_3 + 5.77200577200597e-05*G0_5_0_0_4 + 0.000230880230880239*G0_5_0_0_5 + 3.84800384800398e-05*G0_5_0_1_0 - 0.000192400192400199*G0_5_0_1_1 + 2.88600288600299e-05*G0_5_0_1_2 - 9.62000962000997e-05*G0_5_0_1_3 - 1.92400192400199e-05*G0_5_0_1_4 - 0.000288600288600299*G0_5_0_1_5 - 2.64550264550274e-05*G0_5_0_2_0 + 2.88600288600299e-05*G0_5_0_2_1 - 1.92400192400199e-05*G0_5_0_2_2 + 7.69600769600796e-05*G0_5_0_2_3 + 2.88600288600298e-05*G0_5_0_2_4 + 9.62000962000995e-05*G0_5_0_2_5 + 9.62000962000995e-05*G0_5_0_3_0 - 9.62000962000997e-05*G0_5_0_3_1 + 7.69600769600796e-05*G0_5_0_3_2 - 0.000384800384800398*G0_5_0_3_3 - 0.000153920153920159*G0_5_0_3_4 - 0.000384800384800398*G0_5_0_3_5 + 5.77200577200597e-05*G0_5_0_4_0 - 1.92400192400199e-05*G0_5_0_4_1 + 2.88600288600298e-05*G0_5_0_4_2 - 0.000153920153920159*G0_5_0_4_3 - 7.69600769600795e-05*G0_5_0_4_4 - 0.000153920153920159*G0_5_0_4_5 + 0.000230880230880239*G0_5_0_5_0 - 0.000288600288600299*G0_5_0_5_1 + 9.62000962000995e-05*G0_5_0_5_2 - 0.000384800384800398*G0_5_0_5_3 - 0.000153920153920159*G0_5_0_5_4 - 0.000769600769600796*G0_5_0_5_5 + 3.84800384800398e-05*G0_5_1_0_0 - 0.000192400192400199*G0_5_1_0_1 + 2.88600288600299e-05*G0_5_1_0_2 - 9.62000962000997e-05*G0_5_1_0_3 - 1.92400192400199e-05*G0_5_1_0_4 - 0.000288600288600299*G0_5_1_0_5 - 0.000192400192400199*G0_5_1_1_0 + 0.0011544011544012*G0_5_1_1_1 - 0.000120250120250125*G0_5_1_1_2 + 0.000481000481000499*G0_5_1_1_3 + 9.62000962000995e-05*G0_5_1_1_4 + 0.000962000962000997*G0_5_1_1_5 + 2.88600288600299e-05*G0_5_1_2_0 - 0.000120250120250125*G0_5_1_2_1 + 1.924001924002e-05*G0_5_1_2_2 - 9.62000962000997e-05*G0_5_1_2_3 - 9.62000962000997e-05*G0_5_1_2_5 - 9.62000962000997e-05*G0_5_1_3_0 + 0.000481000481000499*G0_5_1_3_1 - 9.62000962000997e-05*G0_5_1_3_2 + 0.000384800384800399*G0_5_1_3_3 + 0.000384800384800399*G0_5_1_3_5 - 1.92400192400199e-05*G0_5_1_4_0 + 9.62000962000995e-05*G0_5_1_4_1 - 7.69600769600796e-05*G0_5_1_4_4 - 0.000288600288600299*G0_5_1_5_0 + 0.000962000962000997*G0_5_1_5_1 - 9.62000962000997e-05*G0_5_1_5_2 + 0.000384800384800399*G0_5_1_5_3 + 0.0011544011544012*G0_5_1_5_5 - 2.64550264550274e-05*G0_5_2_0_0 + 2.88600288600299e-05*G0_5_2_0_1 - 1.92400192400199e-05*G0_5_2_0_2 + 7.69600769600796e-05*G0_5_2_0_3 + 2.88600288600298e-05*G0_5_2_0_4 + 9.62000962000994e-05*G0_5_2_0_5 + 2.88600288600299e-05*G0_5_2_1_0 - 0.000120250120250125*G0_5_2_1_1 + 1.924001924002e-05*G0_5_2_1_2 - 9.62000962000997e-05*G0_5_2_1_3 - 9.62000962000997e-05*G0_5_2_1_5 - 1.92400192400199e-05*G0_5_2_2_0 + 1.924001924002e-05*G0_5_2_2_1 - 2.16450216450224e-05*G0_5_2_2_2 + 9.62000962000995e-05*G0_5_2_2_3 + 4.81000481000497e-05*G0_5_2_2_4 + 0.000115440115440119*G0_5_2_2_5 + 7.69600769600796e-05*G0_5_2_3_0 - 9.62000962000997e-05*G0_5_2_3_1 + 9.62000962000995e-05*G0_5_2_3_2 - 0.000384800384800398*G0_5_2_3_3 - 0.000153920153920159*G0_5_2_3_4 - 0.000384800384800398*G0_5_2_3_5 + 2.88600288600298e-05*G0_5_2_4_0 + 4.81000481000497e-05*G0_5_2_4_2 - 0.000153920153920159*G0_5_2_4_3 - 0.000115440115440119*G0_5_2_4_4 - 0.000230880230880239*G0_5_2_4_5 + 9.62000962000995e-05*G0_5_2_5_0 - 9.62000962000997e-05*G0_5_2_5_1 + 0.000115440115440119*G0_5_2_5_2 - 0.000384800384800398*G0_5_2_5_3 - 0.000230880230880239*G0_5_2_5_4 - 0.000769600769600797*G0_5_2_5_5 + 9.62000962000995e-05*G0_5_3_0_0 - 9.62000962000997e-05*G0_5_3_0_1 + 7.69600769600796e-05*G0_5_3_0_2 - 0.000384800384800398*G0_5_3_0_3 - 0.000153920153920159*G0_5_3_0_4 - 0.000384800384800398*G0_5_3_0_5 - 9.62000962000997e-05*G0_5_3_1_0 + 0.000481000481000499*G0_5_3_1_1 - 9.62000962000997e-05*G0_5_3_1_2 + 0.000384800384800399*G0_5_3_1_3 + 0.000384800384800399*G0_5_3_1_5 + 7.69600769600796e-05*G0_5_3_2_0 - 9.62000962000997e-05*G0_5_3_2_1 + 9.62000962000995e-05*G0_5_3_2_2 - 0.000384800384800398*G0_5_3_2_3 - 0.000153920153920159*G0_5_3_2_4 - 0.000384800384800398*G0_5_3_2_5 - 0.000384800384800398*G0_5_3_3_0 + 0.000384800384800399*G0_5_3_3_1 - 0.000384800384800398*G0_5_3_3_2 + 0.00230880230880239*G0_5_3_3_3 + 0.000769600769600796*G0_5_3_3_4 + 0.00153920153920159*G0_5_3_3_5 - 0.000153920153920159*G0_5_3_4_0 - 0.000153920153920159*G0_5_3_4_2 + 0.000769600769600796*G0_5_3_4_3 + 0.000461760461760477*G0_5_3_4_4 + 0.000769600769600796*G0_5_3_4_5 - 0.000384800384800398*G0_5_3_5_0 + 0.000384800384800399*G0_5_3_5_1 - 0.000384800384800398*G0_5_3_5_2 + 0.00153920153920159*G0_5_3_5_3 + 0.000769600769600796*G0_5_3_5_4 + 0.00230880230880239*G0_5_3_5_5 + 5.77200577200597e-05*G0_5_4_0_0 - 1.92400192400199e-05*G0_5_4_0_1 + 2.88600288600298e-05*G0_5_4_0_2 - 0.000153920153920159*G0_5_4_0_3 - 7.69600769600795e-05*G0_5_4_0_4 - 0.000153920153920159*G0_5_4_0_5 - 1.92400192400199e-05*G0_5_4_1_0 + 9.62000962000995e-05*G0_5_4_1_1 - 7.69600769600796e-05*G0_5_4_1_4 + 2.88600288600298e-05*G0_5_4_2_0 + 4.81000481000497e-05*G0_5_4_2_2 - 0.000153920153920159*G0_5_4_2_3 - 0.000115440115440119*G0_5_4_2_4 - 0.000230880230880239*G0_5_4_2_5 - 0.000153920153920159*G0_5_4_3_0 - 0.000153920153920159*G0_5_4_3_2 + 0.000769600769600796*G0_5_4_3_3 + 0.000461760461760477*G0_5_4_3_4 + 0.000769600769600796*G0_5_4_3_5 - 7.69600769600795e-05*G0_5_4_4_0 - 7.69600769600796e-05*G0_5_4_4_1 - 0.000115440115440119*G0_5_4_4_2 + 0.000461760461760477*G0_5_4_4_3 + 0.000461760461760478*G0_5_4_4_4 + 0.000615680615680637*G0_5_4_4_5 - 0.000153920153920159*G0_5_4_5_0 - 0.000230880230880239*G0_5_4_5_2 + 0.000769600769600796*G0_5_4_5_3 + 0.000615680615680637*G0_5_4_5_4 + 0.00153920153920159*G0_5_4_5_5 + 0.000230880230880239*G0_5_5_0_0 - 0.000288600288600299*G0_5_5_0_1 + 9.62000962000995e-05*G0_5_5_0_2 - 0.000384800384800398*G0_5_5_0_3 - 0.000153920153920159*G0_5_5_0_4 - 0.000769600769600796*G0_5_5_0_5 - 0.000288600288600299*G0_5_5_1_0 + 0.000962000962000997*G0_5_5_1_1 - 9.62000962000997e-05*G0_5_5_1_2 + 0.000384800384800399*G0_5_5_1_3 + 0.0011544011544012*G0_5_5_1_5 + 9.62000962000995e-05*G0_5_5_2_0 - 9.62000962000997e-05*G0_5_5_2_1 + 0.000115440115440119*G0_5_5_2_2 - 0.000384800384800398*G0_5_5_2_3 - 0.000230880230880239*G0_5_5_2_4 - 0.000769600769600797*G0_5_5_2_5 - 0.000384800384800398*G0_5_5_3_0 + 0.000384800384800399*G0_5_5_3_1 - 0.000384800384800398*G0_5_5_3_2 + 0.00153920153920159*G0_5_5_3_3 + 0.000769600769600796*G0_5_5_3_4 + 0.00230880230880239*G0_5_5_3_5 - 0.000153920153920159*G0_5_5_4_0 - 0.000230880230880239*G0_5_5_4_2 + 0.000769600769600796*G0_5_5_4_3 + 0.000615680615680637*G0_5_5_4_4 + 0.00153920153920159*G0_5_5_4_5 - 0.000769600769600796*G0_5_5_5_0 + 0.0011544011544012*G0_5_5_5_1 - 0.000769600769600797*G0_5_5_5_2 + 0.00230880230880239*G0_5_5_5_3 + 0.00153920153920159*G0_5_5_5_4 + 0.00923520923520956*G0_5_5_5_5; + } + + /// 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 mass_matrix_f4_p2_q1_tensor_form_0: public ufc::form +{ +public: + + /// Constructor + mass_matrix_f4_p2_q1_tensor_form_0() : ufc::form() + { + // Do nothing + } + + /// Destructor + virtual ~mass_matrix_f4_p2_q1_tensor_form_0() + { + // Do nothing + } + + /// Return a string identifying the form + virtual const char* signature() const + { + return "Form([Integral(Product(Product(Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 0), Argument(FiniteElement('Lagrange', Cell('triangle', Space(2)), 1, None), 1)), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 3), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 2), Product(Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 0), Coefficient(FiniteElement('Lagrange', Cell('triangle', Space(2)), 2, None), 1))))), 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 4; + } + + /// 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 mass_matrix_f4_p2_q1_tensor_finite_element_1(); + break; + } + case 1: + { + return new mass_matrix_f4_p2_q1_tensor_finite_element_1(); + break; + } + case 2: + { + return new mass_matrix_f4_p2_q1_tensor_finite_element_0(); + break; + } + case 3: + { + return new mass_matrix_f4_p2_q1_tensor_finite_element_0(); + break; + } + case 4: + { + return new mass_matrix_f4_p2_q1_tensor_finite_element_0(); + break; + } + case 5: + { + return new mass_matrix_f4_p2_q1_tensor_finite_element_0(); + 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 mass_matrix_f4_p2_q1_tensor_dofmap_1(); + break; + } + case 1: + { + return new mass_matrix_f4_p2_q1_tensor_dofmap_1(); + break; + } + case 2: + { + return new mass_matrix_f4_p2_q1_tensor_dofmap_0(); + break; + } + case 3: + { + return new mass_matrix_f4_p2_q1_tensor_dofmap_0(); + break; + } + case 4: + { + return new mass_matrix_f4_p2_q1_tensor_dofmap_0(); + break; + } + case 5: + { + return new mass_matrix_f4_p2_q1_tensor_dofmap_0(); + break; + } + } + + return 0; + } + + /// Create a new cell integral on sub domain i + virtual ufc::cell_integral* create_cell_integral(unsigned int i) const + { + switch (i) + { + case 0: + { + return new mass_matrix_f4_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