From b4a4bd1f537398bc5a7d42909c592e1e9bee0968 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Tue, 24 Jan 2023 14:42:41 -0500 Subject: [PATCH] Introduce DEAL_II_IF_CONSTEXPR --- .clang-format | 3 + include/deal.II/base/config.h.in | 13 + include/deal.II/base/partitioner.templates.h | 24 +- include/deal.II/base/utilities.h | 135 +- include/deal.II/lac/sparse_matrix.templates.h | 12 +- .../deal.II/lac/vector_operations_internal.h | 25 +- source/base/polynomials_rt_bubbles.cc | 1280 ++++++++--------- 7 files changed, 736 insertions(+), 756 deletions(-) diff --git a/.clang-format b/.clang-format index 2975f20f50..9b627cecdf 100644 --- a/.clang-format +++ b/.clang-format @@ -65,6 +65,9 @@ DerivePointerAlignment: false FixNamespaceComments: true +# Should be IfMacros in clang-format 13 and higher +ForEachMacros: ['DEAL_II_IF_CONSTEXPR'] + IncludeBlocks: Regroup IncludeCategories: # config.h must always be first: diff --git a/include/deal.II/base/config.h.in b/include/deal.II/base/config.h.in index b391ed6388..dc29536bcc 100644 --- a/include/deal.II/base/config.h.in +++ b/include/deal.II/base/config.h.in @@ -545,6 +545,19 @@ _Pragma("GCC diagnostic pop") #define DEAL_II_WARNING(desc) DEAL_II_DO_PRAGMA(message(#desc)) #endif +/*********************************************************************** + * Some places in deal.II require or benefit from using "if constexpr". + * However, this feature is only available in C++17 and above. + * The macro defined here expands to "if constexpr(...)" when C++17 is supported + * and to "if (...)" otherwise. + */ +#ifdef DEAL_II_HAVE_CXX17 + #define DEAL_II_IF_CONSTEXPR(x) if constexpr x +#else + #define DEAL_II_IF_CONSTEXPR(x) if x +#endif + + /*********************************************************************** * Final inclusions: */ diff --git a/include/deal.II/base/partitioner.templates.h b/include/deal.II/base/partitioner.templates.h index c1d7a6856e..7cbb1f02d6 100644 --- a/include/deal.II/base/partitioner.templates.h +++ b/include/deal.II/base/partitioner.templates.h @@ -533,18 +533,18 @@ namespace Utilities else # endif { -# ifdef DEAL_II_HAVE_CXX17 - if constexpr (std::is_trivial::value) -# else - if (std::is_trivial::value) -# endif - std::memset(ghost_array.data(), - 0, - sizeof(Number) * ghost_array.size()); + DEAL_II_IF_CONSTEXPR ((std::is_trivial::value)) + { + std::memset(ghost_array.data(), + 0, + sizeof(Number) * ghost_array.size()); + } else + { std::fill(ghost_array.data(), ghost_array.data() + ghost_array.size(), 0); + } } return; } @@ -736,20 +736,18 @@ namespace Utilities else # endif { -# ifdef DEAL_II_HAVE_CXX17 - if constexpr (std::is_trivial::value) -# else - if (std::is_trivial::value) -# endif + DEAL_II_IF_CONSTEXPR ((std::is_trivial::value)) { std::memset(ghost_array.data(), 0, sizeof(Number) * n_ghost_indices()); } else + { std::fill(ghost_array.data(), ghost_array.data() + n_ghost_indices(), 0); + } } } diff --git a/include/deal.II/base/utilities.h b/include/deal.II/base/utilities.h index 519add5db3..9c8e2de969 100644 --- a/include/deal.II/base/utilities.h +++ b/include/deal.II/base/utilities.h @@ -1341,11 +1341,7 @@ namespace Utilities // see if the object is small and copyable via memcpy. if so, use // this fast path. otherwise, we have to go through the BOOST // serialization machinery -#ifdef DEAL_II_HAVE_CXX17 - if constexpr (std::is_trivially_copyable() && sizeof(T) < 256) -#else - if (std::is_trivially_copyable() && sizeof(T) < 256) -#endif + DEAL_II_IF_CONSTEXPR ((std::is_trivially_copyable() && sizeof(T) < 256)) { // Determine the size. There are places where we would like to use a // truly empty type, for which we use std::tuple<> (i.e., a tuple @@ -1369,40 +1365,40 @@ namespace Utilities // the data. else if (internal::IsVectorOfTriviallyCopyable::value && (allow_compression == false)) - { - const std::size_t previous_size = dest_buffer.size(); + { + const std::size_t previous_size = dest_buffer.size(); - // When we have DEAL_II_HAVE_CXX17 set by default, we can just - // inline the code of the following function here and make the 'if' - // above a 'if constexpr'. Without the 'constexpr', we need to keep - // the general template of the function that throws an exception. - internal::append_vector_of_trivially_copyable_to_buffer(object, - dest_buffer); + // When we have DEAL_II_HAVE_CXX17 set by default, we can just + // inline the code of the following function here and make the 'if' + // above a 'if constexpr'. Without the 'constexpr', we need to keep + // the general template of the function that throws an exception. + internal::append_vector_of_trivially_copyable_to_buffer(object, + dest_buffer); - size = dest_buffer.size() - previous_size; - } + size = dest_buffer.size() - previous_size; + } else + { + // use buffer as the target of a compressing + // stream into which we serialize the current object + const std::size_t previous_size = dest_buffer.size(); { - // use buffer as the target of a compressing - // stream into which we serialize the current object - const std::size_t previous_size = dest_buffer.size(); - { - boost::iostreams::filtering_ostreambuf fosb; + boost::iostreams::filtering_ostreambuf fosb; #ifdef DEAL_II_WITH_ZLIB - if (allow_compression) - fosb.push(boost::iostreams::gzip_compressor()); + if (allow_compression) + fosb.push(boost::iostreams::gzip_compressor()); #else - (void)allow_compression; + (void)allow_compression; #endif - fosb.push(boost::iostreams::back_inserter(dest_buffer)); + fosb.push(boost::iostreams::back_inserter(dest_buffer)); - boost::archive::binary_oarchive boa(fosb); - boa << object; - // the stream object has to be destroyed before the return statement - // to ensure that all data has been written in the buffer - } - size = dest_buffer.size() - previous_size; + boost::archive::binary_oarchive boa(fosb); + boa << object; + // the stream object has to be destroyed before the return statement + // to ensure that all data has been written in the buffer } + size = dest_buffer.size() - previous_size; + } return size; } @@ -1428,11 +1424,7 @@ namespace Utilities // see if the object is small and copyable via memcpy. if so, use // this fast path. otherwise, we have to go through the BOOST // serialization machinery -#ifdef DEAL_II_HAVE_CXX17 - if constexpr (std::is_trivially_copyable() && sizeof(T) < 256) -#else - if (std::is_trivially_copyable() && sizeof(T) < 256) -#endif + DEAL_II_IF_CONSTEXPR ((std::is_trivially_copyable() && sizeof(T) < 256)) { // Determine the size. There are places where we would like to use a // truly empty type, for which we use std::tuple<> (i.e., a tuple @@ -1460,35 +1452,35 @@ namespace Utilities // are not asked to compress the data. else if (internal::IsVectorOfTriviallyCopyable::value && (allow_compression == false)) - { - // When we have DEAL_II_HAVE_CXX17 set by default, we can just - // inline the code of the following function here and make the 'if' - // above a 'if constexpr'. Without the 'constexpr', we need to keep - // the general template of the function that throws an exception. - T object; - internal::create_vector_of_trivially_copyable_from_buffer(cbegin, - cend, - object); - return object; - } + { + // When we have DEAL_II_HAVE_CXX17 set by default, we can just + // inline the code of the following function here and make the 'if' + // above a 'if constexpr'. Without the 'constexpr', we need to keep + // the general template of the function that throws an exception. + T object; + internal::create_vector_of_trivially_copyable_from_buffer(cbegin, + cend, + object); + return object; + } else - { - // decompress the buffer section into the object - boost::iostreams::filtering_istreambuf fisb; + { + // decompress the buffer section into the object + boost::iostreams::filtering_istreambuf fisb; #ifdef DEAL_II_WITH_ZLIB - if (allow_compression) - fisb.push(boost::iostreams::gzip_decompressor()); + if (allow_compression) + fisb.push(boost::iostreams::gzip_decompressor()); #else - (void)allow_compression; + (void)allow_compression; #endif - fisb.push(boost::iostreams::array_source(&*cbegin, cend - cbegin)); + fisb.push(boost::iostreams::array_source(&*cbegin, cend - cbegin)); - boost::archive::binary_iarchive bia(fisb); + boost::archive::binary_iarchive bia(fisb); - T object; - bia >> object; - return object; - } + T object; + bia >> object; + return object; + } return T(); } @@ -1512,31 +1504,28 @@ namespace Utilities // see if the object is small and copyable via memcpy. if so, use // this fast path. otherwise, we have to go through the BOOST // serialization machinery -#ifdef DEAL_II_HAVE_CXX17 - if constexpr (std::is_trivially_copyable() && sizeof(T) * N < 256) -#else - if (std::is_trivially_copyable() && sizeof(T) * N < 256) -#endif + DEAL_II_IF_CONSTEXPR ( + (std::is_trivially_copyable() && sizeof(T) * N < 256)) { Assert(std::distance(cbegin, cend) == sizeof(T) * N, ExcInternalError()); std::memcpy(unpacked_object, &*cbegin, sizeof(T) * N); } else - { - // decompress the buffer section into the object - boost::iostreams::filtering_istreambuf fisb; + { + // decompress the buffer section into the object + boost::iostreams::filtering_istreambuf fisb; #ifdef DEAL_II_WITH_ZLIB - if (allow_compression) - fisb.push(boost::iostreams::gzip_decompressor()); + if (allow_compression) + fisb.push(boost::iostreams::gzip_decompressor()); #else - (void)allow_compression; + (void)allow_compression; #endif - fisb.push(boost::iostreams::array_source(&*cbegin, cend - cbegin)); + fisb.push(boost::iostreams::array_source(&*cbegin, cend - cbegin)); - boost::archive::binary_iarchive bia(fisb); - bia >> unpacked_object; - } + boost::archive::binary_iarchive bia(fisb); + bia >> unpacked_object; + } } diff --git a/include/deal.II/lac/sparse_matrix.templates.h b/include/deal.II/lac/sparse_matrix.templates.h index 8e1370e635..06986c0b19 100644 --- a/include/deal.II/lac/sparse_matrix.templates.h +++ b/include/deal.II/lac/sparse_matrix.templates.h @@ -219,14 +219,14 @@ SparseMatrix::operator=(const double d) grain_size); else if (matrix_size > 0) { -#ifdef DEAL_II_HAVE_CXX17 - if constexpr (std::is_trivial::value) -#else - if (std::is_trivial::value) -#endif - std::memset(val.get(), 0, matrix_size * sizeof(number)); + DEAL_II_IF_CONSTEXPR ((std::is_trivial::value)) + { + std::memset(val.get(), 0, matrix_size * sizeof(number)); + } else + { std::fill(val.get(), val.get() + matrix_size, 0); + } } return *this; diff --git a/include/deal.II/lac/vector_operations_internal.h b/include/deal.II/lac/vector_operations_internal.h index b86b64ba86..3ffb977881 100644 --- a/include/deal.II/lac/vector_operations_internal.h +++ b/include/deal.II/lac/vector_operations_internal.h @@ -214,11 +214,7 @@ namespace internal if (value == Number()) { -#ifdef DEAL_II_HAVE_CXX17 - if constexpr (std::is_trivial::value) -#else - if (std::is_trivial::value) -#endif + DEAL_II_IF_CONSTEXPR ((std::is_trivial::value)) { std::memset(dst + begin, 0, sizeof(Number) * (end - begin)); return; @@ -247,20 +243,15 @@ namespace internal { Assert(end >= begin, ExcInternalError()); -#ifdef DEAL_II_HAVE_CXX17 - if constexpr (std::is_trivially_copyable() && - std::is_same::value) -#else - if (std::is_trivially_copyable() && - std::is_same::value) -#endif + DEAL_II_IF_CONSTEXPR ((std::is_trivially_copyable() && + std::is_same::value)) std::memcpy(dst + begin, src + begin, (end - begin) * sizeof(Number)); else - { - DEAL_II_OPENMP_SIMD_PRAGMA - for (size_type i = begin; i < end; ++i) - dst[i] = src[i]; - } + { + DEAL_II_OPENMP_SIMD_PRAGMA + for (size_type i = begin; i < end; ++i) + dst[i] = src[i]; + } } const OtherNumber *const src; diff --git a/source/base/polynomials_rt_bubbles.cc b/source/base/polynomials_rt_bubbles.cc index 8b7aadeb83..95270e6ea1 100644 --- a/source/base/polynomials_rt_bubbles.cc +++ b/source/base/polynomials_rt_bubbles.cc @@ -110,22 +110,14 @@ PolynomialsRT_Bubbles::evaluate( double monoval_i[dim][n_derivatives + 1]; -#ifdef DEAL_II_HAVE_CXX17 - if constexpr (dim <= 1) -#else - if (dim <= 1) -#endif + DEAL_II_IF_CONSTEXPR ((dim <= 1)) { (void)monoval_plus; (void)monoval_i; } unsigned int start = n_sub; -#ifdef DEAL_II_HAVE_CXX17 - if constexpr (dim == 2) -#else - if (dim == 2) -#endif + DEAL_II_IF_CONSTEXPR ((dim == 2)) { // In 2d the curl part of the space is spanned by the vectors // of two types. The first one is @@ -208,645 +200,639 @@ PolynomialsRT_Bubbles::evaluate( } Assert(start == this->n() - my_degree - 1, ExcInternalError()); } -#ifdef DEAL_II_HAVE_CXX17 - else if constexpr (dim == 3) -#else - else if (dim == 3) -#endif - { - double monoval[dim][n_derivatives + 1]; - double monoval_j[dim][n_derivatives + 1]; - double monoval_jplus[dim][n_derivatives + 1]; - - // In 3d the first type of basis vector is - // [ x^i * y^j * z^k * (j+k+2) ] - // [ -[x^i]' * y^(j+1) * z^k ] - // [ -[x^i]' * y^j * z^(k+1) ], - // For the second type of basis vector y and z - // are swapped. Then for each of these, - // two more are obtained by the cyclic rotation - // of the coordinates. - // monoval = x^k, monoval_plus = x^(k+1) - // monoval_* = x^*, monoval_jplus = x^(j+1) - for (unsigned int d = 0; d < dim; ++d) - { - monomials[my_degree + 1].value(unit_point(d), - n_derivatives, - monoval_plus[d]); - monomials[my_degree].value(unit_point(d), n_derivatives, monoval[d]); - } - - const unsigned int n_curls = (my_degree + 1) * (2 * my_degree + 1); - // Span of $\tilde{B}$ - for (unsigned int i = 0; i <= my_degree; ++i) - { - for (unsigned int d = 0; d < dim; ++d) - monomials[i].value(unit_point(d), n_derivatives, monoval_i[d]); - - for (unsigned int j = 0; j <= my_degree; ++j) - { - for (unsigned int d = 0; d < dim; ++d) - { - monomials[j].value(unit_point(d), - n_derivatives, - monoval_j[d]); - monomials[j + 1].value(unit_point(d), - n_derivatives, - monoval_jplus[d]); - } - - if (values.size() != 0) - { - values[start][0] = monoval_i[0][0] * monoval_j[1][0] * + else DEAL_II_IF_CONSTEXPR ((dim == 3)) + { + double monoval[dim][n_derivatives + 1]; + double monoval_j[dim][n_derivatives + 1]; + double monoval_jplus[dim][n_derivatives + 1]; + + // In 3d the first type of basis vector is + // [ x^i * y^j * z^k * (j+k+2) ] + // [ -[x^i]' * y^(j+1) * z^k ] + // [ -[x^i]' * y^j * z^(k+1) ], + // For the second type of basis vector y and z + // are swapped. Then for each of these, + // two more are obtained by the cyclic rotation + // of the coordinates. + // monoval = x^k, monoval_plus = x^(k+1) + // monoval_* = x^*, monoval_jplus = x^(j+1) + for (unsigned int d = 0; d < dim; ++d) + { + monomials[my_degree + 1].value(unit_point(d), + n_derivatives, + monoval_plus[d]); + monomials[my_degree].value(unit_point(d), n_derivatives, monoval[d]); + } + + const unsigned int n_curls = (my_degree + 1) * (2 * my_degree + 1); + // Span of $\tilde{B}$ + for (unsigned int i = 0; i <= my_degree; ++i) + { + for (unsigned int d = 0; d < dim; ++d) + monomials[i].value(unit_point(d), n_derivatives, monoval_i[d]); + + for (unsigned int j = 0; j <= my_degree; ++j) + { + for (unsigned int d = 0; d < dim; ++d) + { + monomials[j].value(unit_point(d), n_derivatives, monoval_j[d]); + monomials[j + 1].value(unit_point(d), + n_derivatives, + monoval_jplus[d]); + } + + if (values.size() != 0) + { + values[start][0] = monoval_i[0][0] * monoval_j[1][0] * + monoval[2][0] * + static_cast(j + my_degree + 2); + values[start][1] = + -monoval_i[0][1] * monoval_jplus[1][0] * monoval[2][0]; + values[start][2] = + -monoval_i[0][1] * monoval_j[1][0] * monoval_plus[2][0]; + + values[start + n_curls][0] = + -monoval_jplus[0][0] * monoval_i[1][1] * monoval[2][0]; + values[start + n_curls][1] = + monoval_j[0][0] * monoval_i[1][0] * monoval[2][0] * + static_cast(j + my_degree + 2); + values[start + n_curls][2] = + -monoval_j[0][0] * monoval_i[1][1] * monoval_plus[2][0]; + + values[start + 2 * n_curls][0] = + -monoval_jplus[0][0] * monoval[1][0] * monoval_i[2][1]; + values[start + 2 * n_curls][1] = + -monoval_j[0][0] * monoval_plus[1][0] * monoval_i[2][1]; + values[start + 2 * n_curls][2] = + monoval_j[0][0] * monoval[1][0] * monoval_i[2][0] * + static_cast(j + my_degree + 2); + + // Only unique triples of powers (i j k) + // and (i k j) are allowed, 0 <= i,j <= k + if (j != my_degree) + { + values[start + 1][0] = + monoval_i[0][0] * monoval[1][0] * monoval_j[2][0] * + static_cast(j + my_degree + 2); + values[start + 1][1] = + -monoval_i[0][1] * monoval_plus[1][0] * monoval_j[2][0]; + values[start + 1][2] = + -monoval_i[0][1] * monoval[1][0] * monoval_jplus[2][0]; + + values[start + n_curls + 1][0] = + -monoval_plus[0][0] * monoval_i[1][1] * monoval_j[2][0]; + values[start + n_curls + 1][1] = + monoval[0][0] * monoval_i[1][0] * monoval_j[2][0] * + static_cast(j + my_degree + 2); + values[start + n_curls + 1][2] = + -monoval[0][0] * monoval_i[1][1] * monoval_jplus[2][0]; + + values[start + 2 * n_curls + 1][0] = + -monoval_plus[0][0] * monoval_j[1][0] * monoval_i[2][1]; + values[start + 2 * n_curls + 1][1] = + -monoval[0][0] * monoval_jplus[1][0] * monoval_i[2][1]; + values[start + 2 * n_curls + 1][2] = + monoval[0][0] * monoval_j[1][0] * monoval_i[2][0] * + static_cast(j + my_degree + 2); + } + } + + if (grads.size() != 0) + { + grads[start][0][0] = monoval_i[0][1] * monoval_j[1][0] * monoval[2][0] * static_cast(j + my_degree + 2); - values[start][1] = - -monoval_i[0][1] * monoval_jplus[1][0] * monoval[2][0]; - values[start][2] = - -monoval_i[0][1] * monoval_j[1][0] * monoval_plus[2][0]; - - values[start + n_curls][0] = - -monoval_jplus[0][0] * monoval_i[1][1] * monoval[2][0]; - values[start + n_curls][1] = - monoval_j[0][0] * monoval_i[1][0] * monoval[2][0] * - static_cast(j + my_degree + 2); - values[start + n_curls][2] = - -monoval_j[0][0] * monoval_i[1][1] * monoval_plus[2][0]; - - values[start + 2 * n_curls][0] = - -monoval_jplus[0][0] * monoval[1][0] * monoval_i[2][1]; - values[start + 2 * n_curls][1] = - -monoval_j[0][0] * monoval_plus[1][0] * monoval_i[2][1]; - values[start + 2 * n_curls][2] = - monoval_j[0][0] * monoval[1][0] * monoval_i[2][0] * - static_cast(j + my_degree + 2); - - // Only unique triples of powers (i j k) - // and (i k j) are allowed, 0 <= i,j <= k - if (j != my_degree) - { - values[start + 1][0] = - monoval_i[0][0] * monoval[1][0] * monoval_j[2][0] * - static_cast(j + my_degree + 2); - values[start + 1][1] = - -monoval_i[0][1] * monoval_plus[1][0] * monoval_j[2][0]; - values[start + 1][2] = - -monoval_i[0][1] * monoval[1][0] * monoval_jplus[2][0]; - - values[start + n_curls + 1][0] = - -monoval_plus[0][0] * monoval_i[1][1] * monoval_j[2][0]; - values[start + n_curls + 1][1] = - monoval[0][0] * monoval_i[1][0] * monoval_j[2][0] * - static_cast(j + my_degree + 2); - values[start + n_curls + 1][2] = - -monoval[0][0] * monoval_i[1][1] * monoval_jplus[2][0]; - - values[start + 2 * n_curls + 1][0] = - -monoval_plus[0][0] * monoval_j[1][0] * monoval_i[2][1]; - values[start + 2 * n_curls + 1][1] = - -monoval[0][0] * monoval_jplus[1][0] * monoval_i[2][1]; - values[start + 2 * n_curls + 1][2] = - monoval[0][0] * monoval_j[1][0] * monoval_i[2][0] * - static_cast(j + my_degree + 2); - } - } - - if (grads.size() != 0) - { - grads[start][0][0] = monoval_i[0][1] * monoval_j[1][0] * - monoval[2][0] * - static_cast(j + my_degree + 2); - grads[start][0][1] = monoval_i[0][0] * monoval_j[1][1] * - monoval[2][0] * - static_cast(j + my_degree + 2); - grads[start][0][2] = monoval_i[0][0] * monoval_j[1][0] * - monoval[2][1] * - static_cast(j + my_degree + 2); - grads[start][1][0] = - -monoval_i[0][2] * monoval_jplus[1][0] * monoval[2][0]; - grads[start][1][1] = - -monoval_i[0][1] * monoval_jplus[1][1] * monoval[2][0]; - grads[start][1][2] = - -monoval_i[0][1] * monoval_jplus[1][0] * monoval[2][1]; - grads[start][2][0] = - -monoval_i[0][2] * monoval_j[1][0] * monoval_plus[2][0]; - grads[start][2][1] = - -monoval_i[0][1] * monoval_j[1][1] * monoval_plus[2][0]; - grads[start][2][2] = - -monoval_i[0][1] * monoval_j[1][0] * monoval_plus[2][1]; - - grads[start + n_curls][0][0] = - -monoval_jplus[0][1] * monoval_i[1][1] * monoval[2][0]; - grads[start + n_curls][0][1] = - -monoval_jplus[0][0] * monoval_i[1][2] * monoval[2][0]; - grads[start + n_curls][0][2] = - -monoval_jplus[0][0] * monoval_i[1][1] * monoval[2][1]; - grads[start + n_curls][1][0] = - monoval_j[0][1] * monoval_i[1][0] * monoval[2][0] * - static_cast(j + my_degree + 2); - grads[start + n_curls][1][1] = - monoval_j[0][0] * monoval_i[1][1] * monoval[2][0] * - static_cast(j + my_degree + 2); - grads[start + n_curls][1][2] = - monoval_j[0][0] * monoval_i[1][0] * monoval[2][1] * - static_cast(j + my_degree + 2); - grads[start + n_curls][2][0] = - -monoval_j[0][1] * monoval_i[1][1] * monoval_plus[2][0]; - grads[start + n_curls][2][1] = - -monoval_j[0][0] * monoval_i[1][2] * monoval_plus[2][0]; - grads[start + n_curls][2][2] = - -monoval_j[0][0] * monoval_i[1][1] * monoval_plus[2][1]; - - grads[start + 2 * n_curls][0][0] = - -monoval_jplus[0][1] * monoval[1][0] * monoval_i[2][1]; - grads[start + 2 * n_curls][0][1] = - -monoval_jplus[0][0] * monoval[1][1] * monoval_i[2][1]; - grads[start + 2 * n_curls][0][2] = - -monoval_jplus[0][0] * monoval[1][0] * monoval_i[2][2]; - grads[start + 2 * n_curls][1][0] = - -monoval_j[0][1] * monoval_plus[1][0] * monoval_i[2][1]; - grads[start + 2 * n_curls][1][1] = - -monoval_j[0][0] * monoval_plus[1][1] * monoval_i[2][1]; - grads[start + 2 * n_curls][1][2] = - -monoval_j[0][0] * monoval_plus[1][0] * monoval_i[2][2]; - grads[start + 2 * n_curls][2][0] = - monoval_j[0][1] * monoval[1][0] * monoval_i[2][0] * - static_cast(j + my_degree + 2); - grads[start + 2 * n_curls][2][1] = - monoval_j[0][0] * monoval[1][1] * monoval_i[2][0] * - static_cast(j + my_degree + 2); - grads[start + 2 * n_curls][2][2] = - monoval_j[0][0] * monoval[1][0] * monoval_i[2][1] * - static_cast(j + my_degree + 2); - - if (j != my_degree) - { - grads[start + 1][0][0] = - monoval_i[0][1] * monoval[1][0] * monoval_j[2][0] * - static_cast(j + my_degree + 2); - grads[start + 1][0][1] = - monoval_i[0][0] * monoval[1][1] * monoval_j[2][0] * - static_cast(j + my_degree + 2); - grads[start + 1][0][2] = - monoval_i[0][0] * monoval[1][0] * monoval_j[2][1] * - static_cast(j + my_degree + 2); - grads[start + 1][1][0] = - -monoval_i[0][2] * monoval_plus[1][0] * monoval_j[2][0]; - grads[start + 1][1][1] = - -monoval_i[0][1] * monoval_plus[1][1] * monoval_j[2][0]; - grads[start + 1][1][2] = - -monoval_i[0][1] * monoval_plus[1][0] * monoval_j[2][1]; - grads[start + 1][2][0] = - -monoval_i[0][2] * monoval[1][0] * monoval_jplus[2][0]; - grads[start + 1][2][1] = - -monoval_i[0][1] * monoval[1][1] * monoval_jplus[2][0]; - grads[start + 1][2][2] = - -monoval_i[0][1] * monoval[1][0] * monoval_jplus[2][1]; - - grads[start + n_curls + 1][0][0] = - -monoval_plus[0][1] * monoval_i[1][1] * monoval_j[2][0]; - grads[start + n_curls + 1][0][1] = - -monoval_plus[0][0] * monoval_i[1][2] * monoval_j[2][0]; - grads[start + n_curls + 1][0][2] = - -monoval_plus[0][0] * monoval_i[1][1] * monoval_j[2][1]; - grads[start + n_curls + 1][1][0] = - monoval[0][1] * monoval_i[1][0] * monoval_j[2][0] * - static_cast(j + my_degree + 2); - grads[start + n_curls + 1][1][1] = - monoval[0][0] * monoval_i[1][1] * monoval_j[2][0] * - static_cast(j + my_degree + 2); - grads[start + n_curls + 1][1][2] = - monoval[0][0] * monoval_i[1][0] * monoval_j[2][1] * - static_cast(j + my_degree + 2); - grads[start + n_curls + 1][2][0] = - -monoval[0][1] * monoval_i[1][1] * monoval_jplus[2][0]; - grads[start + n_curls + 1][2][1] = - -monoval[0][0] * monoval_i[1][2] * monoval_jplus[2][0]; - grads[start + n_curls + 1][2][2] = - -monoval[0][0] * monoval_i[1][1] * monoval_jplus[2][1]; - - grads[start + 2 * n_curls + 1][0][0] = - -monoval_plus[0][1] * monoval_j[1][0] * monoval_i[2][1]; - grads[start + 2 * n_curls + 1][0][1] = - -monoval_plus[0][0] * monoval_j[1][1] * monoval_i[2][1]; - grads[start + 2 * n_curls + 1][0][2] = - -monoval_plus[0][0] * monoval_j[1][0] * monoval_i[2][2]; - grads[start + 2 * n_curls + 1][1][0] = - -monoval[0][1] * monoval_jplus[1][0] * monoval_i[2][1]; - grads[start + 2 * n_curls + 1][1][1] = - -monoval[0][0] * monoval_jplus[1][1] * monoval_i[2][1]; - grads[start + 2 * n_curls + 1][1][2] = - -monoval[0][0] * monoval_jplus[1][0] * monoval_i[2][2]; - grads[start + 2 * n_curls + 1][2][0] = - monoval[0][1] * monoval_j[1][0] * monoval_i[2][0] * - static_cast(j + my_degree + 2); - grads[start + 2 * n_curls + 1][2][1] = - monoval[0][0] * monoval_j[1][1] * monoval_i[2][0] * - static_cast(j + my_degree + 2); - grads[start + 2 * n_curls + 1][2][2] = - monoval[0][0] * monoval_j[1][0] * monoval_i[2][1] * - static_cast(j + my_degree + 2); - } - } - - if (grad_grads.size() != 0) - { - grad_grads[start][0][0][0] = - monoval_i[0][2] * monoval_j[1][0] * monoval[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start][0][0][1] = - monoval_i[0][1] * monoval_j[1][1] * monoval[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start][0][0][2] = - monoval_i[0][1] * monoval_j[1][0] * monoval[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start][0][1][0] = - monoval_i[0][1] * monoval_j[1][1] * monoval[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start][0][1][1] = - monoval_i[0][0] * monoval_j[1][2] * monoval[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start][0][1][2] = - monoval_i[0][0] * monoval_j[1][1] * monoval[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start][0][2][0] = - monoval_i[0][1] * monoval_j[1][0] * monoval[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start][0][2][1] = - monoval_i[0][0] * monoval_j[1][1] * monoval[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start][0][2][2] = - monoval_i[0][0] * monoval_j[1][0] * monoval[2][2] * - static_cast(j + my_degree + 2); - grad_grads[start][1][0][0] = - -monoval_i[0][3] * monoval_jplus[1][0] * monoval[2][0]; - grad_grads[start][1][0][1] = - -monoval_i[0][2] * monoval_jplus[1][1] * monoval[2][0]; - grad_grads[start][1][0][2] = - -monoval_i[0][2] * monoval_jplus[1][0] * monoval[2][1]; - grad_grads[start][1][1][0] = - -monoval_i[0][2] * monoval_jplus[1][1] * monoval[2][0]; - grad_grads[start][1][1][1] = - -monoval_i[0][1] * monoval_jplus[1][2] * monoval[2][0]; - grad_grads[start][1][1][2] = - -monoval_i[0][1] * monoval_jplus[1][1] * monoval[2][1]; - grad_grads[start][1][2][0] = - -monoval_i[0][2] * monoval_jplus[1][0] * monoval[2][1]; - grad_grads[start][1][2][1] = - -monoval_i[0][1] * monoval_jplus[1][1] * monoval[2][1]; - grad_grads[start][1][2][2] = - -monoval_i[0][1] * monoval_jplus[1][0] * monoval[2][2]; - grad_grads[start][2][0][0] = - -monoval_i[0][3] * monoval_j[1][0] * monoval_plus[2][0]; - grad_grads[start][2][0][1] = - -monoval_i[0][2] * monoval_j[1][1] * monoval_plus[2][0]; - grad_grads[start][2][0][2] = - -monoval_i[0][2] * monoval_j[1][0] * monoval_plus[2][1]; - grad_grads[start][2][1][0] = - -monoval_i[0][2] * monoval_j[1][1] * monoval_plus[2][0]; - grad_grads[start][2][1][1] = - -monoval_i[0][1] * monoval_j[1][2] * monoval_plus[2][0]; - grad_grads[start][2][1][2] = - -monoval_i[0][1] * monoval_j[1][1] * monoval_plus[2][1]; - grad_grads[start][2][2][0] = - -monoval_i[0][2] * monoval_j[1][0] * monoval_plus[2][1]; - grad_grads[start][2][2][1] = - -monoval_i[0][1] * monoval_j[1][1] * monoval_plus[2][1]; - grad_grads[start][2][2][2] = - -monoval_i[0][1] * monoval_j[1][0] * monoval_plus[2][2]; - - grad_grads[start + n_curls][0][0][0] = - -monoval_jplus[0][2] * monoval_i[1][1] * monoval[2][0]; - grad_grads[start + n_curls][0][0][1] = - -monoval_jplus[0][1] * monoval_i[1][2] * monoval[2][0]; - grad_grads[start + n_curls][0][0][2] = - -monoval_jplus[0][1] * monoval_i[1][1] * monoval[2][1]; - grad_grads[start + n_curls][0][1][0] = - -monoval_jplus[0][1] * monoval_i[1][2] * monoval[2][0]; - grad_grads[start + n_curls][0][1][1] = - -monoval_jplus[0][0] * monoval_i[1][3] * monoval[2][0]; - grad_grads[start + n_curls][0][1][2] = - -monoval_jplus[0][0] * monoval_i[1][2] * monoval[2][1]; - grad_grads[start + n_curls][0][2][0] = - -monoval_jplus[0][1] * monoval_i[1][1] * monoval[2][1]; - grad_grads[start + n_curls][0][2][1] = - -monoval_jplus[0][0] * monoval_i[1][2] * monoval[2][1]; - grad_grads[start + n_curls][0][2][2] = - -monoval_jplus[0][0] * monoval_i[1][1] * monoval[2][2]; - grad_grads[start + n_curls][1][0][0] = - monoval_j[0][2] * monoval_i[1][0] * monoval[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start + n_curls][1][0][1] = - monoval_j[0][1] * monoval_i[1][1] * monoval[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start + n_curls][1][0][2] = - monoval_j[0][1] * monoval_i[1][0] * monoval[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start + n_curls][1][1][0] = - monoval_j[0][1] * monoval_i[1][1] * monoval[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start + n_curls][1][1][1] = - monoval_j[0][0] * monoval_i[1][2] * monoval[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start + n_curls][1][1][2] = - monoval_j[0][0] * monoval_i[1][1] * monoval[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start + n_curls][1][2][0] = - monoval_j[0][1] * monoval_i[1][0] * monoval[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start + n_curls][1][2][1] = - monoval_j[0][0] * monoval_i[1][1] * monoval[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start + n_curls][1][2][2] = - monoval_j[0][0] * monoval_i[1][0] * monoval[2][2] * - static_cast(j + my_degree + 2); - grad_grads[start + n_curls][2][0][0] = - -monoval_j[0][2] * monoval_i[1][1] * monoval_plus[2][0]; - grad_grads[start + n_curls][2][0][1] = - -monoval_j[0][1] * monoval_i[1][2] * monoval_plus[2][0]; - grad_grads[start + n_curls][2][0][2] = - -monoval_j[0][1] * monoval_i[1][1] * monoval_plus[2][1]; - grad_grads[start + n_curls][2][1][0] = - -monoval_j[0][1] * monoval_i[1][2] * monoval_plus[2][0]; - grad_grads[start + n_curls][2][1][1] = - -monoval_j[0][0] * monoval_i[1][3] * monoval_plus[2][0]; - grad_grads[start + n_curls][2][1][2] = - -monoval_j[0][0] * monoval_i[1][2] * monoval_plus[2][1]; - grad_grads[start + n_curls][2][2][0] = - -monoval_j[0][1] * monoval_i[1][1] * monoval_plus[2][1]; - grad_grads[start + n_curls][2][2][1] = - -monoval_j[0][0] * monoval_i[1][2] * monoval_plus[2][1]; - grad_grads[start + n_curls][2][2][2] = - -monoval_j[0][0] * monoval_i[1][1] * monoval_plus[2][2]; - - grad_grads[start + 2 * n_curls][0][0][0] = - -monoval_jplus[0][2] * monoval[1][0] * monoval_i[2][1]; - grad_grads[start + 2 * n_curls][0][0][1] = - -monoval_jplus[0][1] * monoval[1][1] * monoval_i[2][1]; - grad_grads[start + 2 * n_curls][0][0][2] = - -monoval_jplus[0][1] * monoval[1][0] * monoval_i[2][2]; - grad_grads[start + 2 * n_curls][0][1][0] = - -monoval_jplus[0][1] * monoval[1][1] * monoval_i[2][1]; - grad_grads[start + 2 * n_curls][0][1][1] = - -monoval_jplus[0][0] * monoval[1][2] * monoval_i[2][1]; - grad_grads[start + 2 * n_curls][0][1][2] = - -monoval_jplus[0][0] * monoval[1][1] * monoval_i[2][2]; - grad_grads[start + 2 * n_curls][0][2][0] = - -monoval_jplus[0][1] * monoval[1][0] * monoval_i[2][2]; - grad_grads[start + 2 * n_curls][0][2][1] = - -monoval_jplus[0][0] * monoval[1][1] * monoval_i[2][2]; - grad_grads[start + 2 * n_curls][0][2][2] = - -monoval_jplus[0][0] * monoval[1][0] * monoval_i[2][3]; - grad_grads[start + 2 * n_curls][1][0][0] = - -monoval_j[0][2] * monoval_plus[1][0] * monoval_i[2][1]; - grad_grads[start + 2 * n_curls][1][0][1] = - -monoval_j[0][1] * monoval_plus[1][1] * monoval_i[2][1]; - grad_grads[start + 2 * n_curls][1][0][2] = - -monoval_j[0][1] * monoval_plus[1][0] * monoval_i[2][2]; - grad_grads[start + 2 * n_curls][1][1][0] = - -monoval_j[0][1] * monoval_plus[1][1] * monoval_i[2][1]; - grad_grads[start + 2 * n_curls][1][1][1] = - -monoval_j[0][0] * monoval_plus[1][2] * monoval_i[2][1]; - grad_grads[start + 2 * n_curls][1][1][2] = - -monoval_j[0][0] * monoval_plus[1][1] * monoval_i[2][2]; - grad_grads[start + 2 * n_curls][1][2][0] = - -monoval_j[0][1] * monoval_plus[1][0] * monoval_i[2][2]; - grad_grads[start + 2 * n_curls][1][2][1] = - -monoval_j[0][0] * monoval_plus[1][1] * monoval_i[2][2]; - grad_grads[start + 2 * n_curls][1][2][2] = - -monoval_j[0][0] * monoval_plus[1][0] * monoval_i[2][3]; - grad_grads[start + 2 * n_curls][2][0][0] = - monoval_j[0][2] * monoval[1][0] * monoval_i[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start + 2 * n_curls][2][0][1] = - monoval_j[0][1] * monoval[1][1] * monoval_i[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start + 2 * n_curls][2][0][2] = - monoval_j[0][1] * monoval[1][0] * monoval_i[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start + 2 * n_curls][2][1][0] = - monoval_j[0][1] * monoval[1][1] * monoval_i[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start + 2 * n_curls][2][1][1] = - monoval_j[0][0] * monoval[1][2] * monoval_i[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start + 2 * n_curls][2][1][2] = - monoval_j[0][0] * monoval[1][1] * monoval_i[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start + 2 * n_curls][2][2][0] = - monoval_j[0][1] * monoval[1][0] * monoval_i[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start + 2 * n_curls][2][2][1] = - monoval_j[0][0] * monoval[1][1] * monoval_i[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start + 2 * n_curls][2][2][2] = - monoval_j[0][0] * monoval[1][0] * monoval_i[2][2] * - static_cast(j + my_degree + 2); - - if (j != my_degree) - { - grad_grads[start + 1][0][0][0] = - monoval_i[0][2] * monoval[1][0] * monoval_j[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start + 1][0][0][1] = - monoval_i[0][1] * monoval[1][1] * monoval_j[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start + 1][0][0][2] = - monoval_i[0][1] * monoval[1][0] * monoval_j[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start + 1][0][1][0] = - monoval_i[0][1] * monoval[1][1] * monoval_j[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start + 1][0][1][1] = - monoval_i[0][0] * monoval[1][2] * monoval_j[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start + 1][0][1][2] = - monoval_i[0][0] * monoval[1][1] * monoval_j[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start + 1][0][2][0] = - monoval_i[0][1] * monoval[1][0] * monoval_j[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start + 1][0][2][1] = - monoval_i[0][0] * monoval[1][1] * monoval_j[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start + 1][0][2][2] = - monoval_i[0][0] * monoval[1][0] * monoval_j[2][2] * - static_cast(j + my_degree + 2); - grad_grads[start + 1][1][0][0] = - -monoval_i[0][3] * monoval_plus[1][0] * monoval_j[2][0]; - grad_grads[start + 1][1][0][1] = - -monoval_i[0][2] * monoval_plus[1][1] * monoval_j[2][0]; - grad_grads[start + 1][1][0][2] = - -monoval_i[0][2] * monoval_plus[1][0] * monoval_j[2][1]; - grad_grads[start + 1][1][1][0] = - -monoval_i[0][2] * monoval_plus[1][1] * monoval_j[2][0]; - grad_grads[start + 1][1][1][1] = - -monoval_i[0][1] * monoval_plus[1][2] * monoval_j[2][0]; - grad_grads[start + 1][1][1][2] = - -monoval_i[0][1] * monoval_plus[1][1] * monoval_j[2][1]; - grad_grads[start + 1][1][2][0] = - -monoval_i[0][2] * monoval_plus[1][0] * monoval_j[2][1]; - grad_grads[start + 1][1][2][1] = - -monoval_i[0][1] * monoval_plus[1][1] * monoval_j[2][1]; - grad_grads[start + 1][1][2][2] = - -monoval_i[0][1] * monoval_plus[1][0] * monoval_j[2][2]; - grad_grads[start + 1][2][0][0] = - -monoval_i[0][3] * monoval[1][0] * monoval_jplus[2][0]; - grad_grads[start + 1][2][0][1] = - -monoval_i[0][2] * monoval[1][1] * monoval_jplus[2][0]; - grad_grads[start + 1][2][0][2] = - -monoval_i[0][2] * monoval[1][0] * monoval_jplus[2][1]; - grad_grads[start + 1][2][1][0] = - -monoval_i[0][2] * monoval[1][1] * monoval_jplus[2][0]; - grad_grads[start + 1][2][1][1] = - -monoval_i[0][1] * monoval[1][2] * monoval_jplus[2][0]; - grad_grads[start + 1][2][1][2] = - -monoval_i[0][1] * monoval[1][1] * monoval_jplus[2][1]; - grad_grads[start + 1][2][2][0] = - -monoval_i[0][2] * monoval[1][0] * monoval_jplus[2][1]; - grad_grads[start + 1][2][2][1] = - -monoval_i[0][1] * monoval[1][1] * monoval_jplus[2][1]; - grad_grads[start + 1][2][2][2] = - -monoval_i[0][1] * monoval[1][0] * monoval_jplus[2][2]; - - grad_grads[start + n_curls + 1][0][0][0] = - -monoval_plus[0][2] * monoval_i[1][1] * monoval_j[2][0]; - grad_grads[start + n_curls + 1][0][0][1] = - -monoval_plus[0][1] * monoval_i[1][2] * monoval_j[2][0]; - grad_grads[start + n_curls + 1][0][0][2] = - -monoval_plus[0][1] * monoval_i[1][1] * monoval_j[2][1]; - grad_grads[start + n_curls + 1][0][1][0] = - -monoval_plus[0][1] * monoval_i[1][2] * monoval_j[2][0]; - grad_grads[start + n_curls + 1][0][1][1] = - -monoval_plus[0][0] * monoval_i[1][3] * monoval_j[2][0]; - grad_grads[start + n_curls + 1][0][1][2] = - -monoval_plus[0][0] * monoval_i[1][2] * monoval_j[2][1]; - grad_grads[start + n_curls + 1][0][2][0] = - -monoval_plus[0][1] * monoval_i[1][1] * monoval_j[2][1]; - grad_grads[start + n_curls + 1][0][2][1] = - -monoval_plus[0][0] * monoval_i[1][2] * monoval_j[2][1]; - grad_grads[start + n_curls + 1][0][2][2] = - -monoval_plus[0][0] * monoval_i[1][1] * monoval_j[2][2]; - grad_grads[start + n_curls + 1][1][0][0] = - monoval[0][2] * monoval_i[1][0] * monoval_j[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start + n_curls + 1][1][0][1] = - monoval[0][1] * monoval_i[1][1] * monoval_j[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start + n_curls + 1][1][0][2] = - monoval[0][1] * monoval_i[1][0] * monoval_j[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start + n_curls + 1][1][1][0] = - monoval[0][1] * monoval_i[1][1] * monoval_j[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start + n_curls + 1][1][1][1] = - monoval[0][0] * monoval_i[1][2] * monoval_j[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start + n_curls + 1][1][1][2] = - monoval[0][0] * monoval_i[1][1] * monoval_j[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start + n_curls + 1][1][2][0] = - monoval[0][1] * monoval_i[1][0] * monoval_j[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start + n_curls + 1][1][2][1] = - monoval[0][0] * monoval_i[1][1] * monoval_j[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start + n_curls + 1][1][2][2] = - monoval[0][0] * monoval_i[1][0] * monoval_j[2][2] * - static_cast(j + my_degree + 2); - grad_grads[start + n_curls + 1][2][0][0] = - -monoval[0][2] * monoval_i[1][1] * monoval_jplus[2][0]; - grad_grads[start + n_curls + 1][2][0][1] = - -monoval[0][1] * monoval_i[1][2] * monoval_jplus[2][0]; - grad_grads[start + n_curls + 1][2][0][2] = - -monoval[0][1] * monoval_i[1][1] * monoval_jplus[2][1]; - grad_grads[start + n_curls + 1][2][1][0] = - -monoval[0][1] * monoval_i[1][2] * monoval_jplus[2][0]; - grad_grads[start + n_curls + 1][2][1][1] = - -monoval[0][0] * monoval_i[1][3] * monoval_jplus[2][0]; - grad_grads[start + n_curls + 1][2][1][2] = - -monoval[0][0] * monoval_i[1][2] * monoval_jplus[2][1]; - grad_grads[start + n_curls + 1][2][2][0] = - -monoval[0][1] * monoval_i[1][1] * monoval_jplus[2][1]; - grad_grads[start + n_curls + 1][2][2][1] = - -monoval[0][0] * monoval_i[1][2] * monoval_jplus[2][1]; - grad_grads[start + n_curls + 1][2][2][2] = - -monoval[0][0] * monoval_i[1][1] * monoval_jplus[2][2]; - - grad_grads[start + 2 * n_curls + 1][0][0][0] = - -monoval_plus[0][2] * monoval_j[1][0] * monoval_i[2][1]; - grad_grads[start + 2 * n_curls + 1][0][0][1] = - -monoval_plus[0][1] * monoval_j[1][1] * monoval_i[2][1]; - grad_grads[start + 2 * n_curls + 1][0][0][2] = - -monoval_plus[0][1] * monoval_j[1][0] * monoval_i[2][2]; - grad_grads[start + 2 * n_curls + 1][0][1][0] = - -monoval_plus[0][1] * monoval_j[1][1] * monoval_i[2][1]; - grad_grads[start + 2 * n_curls + 1][0][1][1] = - -monoval_plus[0][0] * monoval_j[1][2] * monoval_i[2][1]; - grad_grads[start + 2 * n_curls + 1][0][1][2] = - -monoval_plus[0][0] * monoval_j[1][1] * monoval_i[2][2]; - grad_grads[start + 2 * n_curls + 1][0][2][0] = - -monoval_plus[0][1] * monoval_j[1][0] * monoval_i[2][2]; - grad_grads[start + 2 * n_curls + 1][0][2][1] = - -monoval_plus[0][0] * monoval_j[1][1] * monoval_i[2][2]; - grad_grads[start + 2 * n_curls + 1][0][2][2] = - -monoval_plus[0][0] * monoval_j[1][0] * monoval_i[2][3]; - grad_grads[start + 2 * n_curls + 1][1][0][0] = - -monoval[0][2] * monoval_jplus[1][0] * monoval_i[2][1]; - grad_grads[start + 2 * n_curls + 1][1][0][1] = - -monoval[0][1] * monoval_jplus[1][1] * monoval_i[2][1]; - grad_grads[start + 2 * n_curls + 1][1][0][2] = - -monoval[0][1] * monoval_jplus[1][0] * monoval_i[2][2]; - grad_grads[start + 2 * n_curls + 1][1][1][0] = - -monoval[0][1] * monoval_jplus[1][1] * monoval_i[2][1]; - grad_grads[start + 2 * n_curls + 1][1][1][1] = - -monoval[0][0] * monoval_jplus[1][2] * monoval_i[2][1]; - grad_grads[start + 2 * n_curls + 1][1][1][2] = - -monoval[0][0] * monoval_jplus[1][1] * monoval_i[2][2]; - grad_grads[start + 2 * n_curls + 1][1][2][0] = - -monoval[0][1] * monoval_jplus[1][0] * monoval_i[2][2]; - grad_grads[start + 2 * n_curls + 1][1][2][1] = - -monoval[0][0] * monoval_jplus[1][1] * monoval_i[2][2]; - grad_grads[start + 2 * n_curls + 1][1][2][2] = - -monoval[0][0] * monoval_jplus[1][0] * monoval_i[2][3]; - grad_grads[start + 2 * n_curls + 1][2][0][0] = - monoval[0][2] * monoval_j[1][0] * monoval_i[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start + 2 * n_curls + 1][2][0][1] = - monoval[0][1] * monoval_j[1][1] * monoval_i[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start + 2 * n_curls + 1][2][0][2] = - monoval[0][1] * monoval_j[1][0] * monoval_i[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start + 2 * n_curls + 1][2][1][0] = - monoval[0][1] * monoval_j[1][1] * monoval_i[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start + 2 * n_curls + 1][2][1][1] = - monoval[0][0] * monoval_j[1][2] * monoval_i[2][0] * - static_cast(j + my_degree + 2); - grad_grads[start + 2 * n_curls + 1][2][1][2] = - monoval[0][0] * monoval_j[1][1] * monoval_i[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start + 2 * n_curls + 1][2][2][0] = - monoval[0][1] * monoval_j[1][0] * monoval_i[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start + 2 * n_curls + 1][2][2][1] = - monoval[0][0] * monoval_j[1][1] * monoval_i[2][1] * - static_cast(j + my_degree + 2); - grad_grads[start + 2 * n_curls + 1][2][2][2] = - monoval[0][0] * monoval_j[1][0] * monoval_i[2][2] * - static_cast(j + my_degree + 2); - } - } - - if (j == my_degree) - start += 1; - else - start += 2; - } - } - Assert(start == this->n() - 2 * n_curls, ExcInternalError()); - } + grads[start][0][1] = monoval_i[0][0] * monoval_j[1][1] * + monoval[2][0] * + static_cast(j + my_degree + 2); + grads[start][0][2] = monoval_i[0][0] * monoval_j[1][0] * + monoval[2][1] * + static_cast(j + my_degree + 2); + grads[start][1][0] = + -monoval_i[0][2] * monoval_jplus[1][0] * monoval[2][0]; + grads[start][1][1] = + -monoval_i[0][1] * monoval_jplus[1][1] * monoval[2][0]; + grads[start][1][2] = + -monoval_i[0][1] * monoval_jplus[1][0] * monoval[2][1]; + grads[start][2][0] = + -monoval_i[0][2] * monoval_j[1][0] * monoval_plus[2][0]; + grads[start][2][1] = + -monoval_i[0][1] * monoval_j[1][1] * monoval_plus[2][0]; + grads[start][2][2] = + -monoval_i[0][1] * monoval_j[1][0] * monoval_plus[2][1]; + + grads[start + n_curls][0][0] = + -monoval_jplus[0][1] * monoval_i[1][1] * monoval[2][0]; + grads[start + n_curls][0][1] = + -monoval_jplus[0][0] * monoval_i[1][2] * monoval[2][0]; + grads[start + n_curls][0][2] = + -monoval_jplus[0][0] * monoval_i[1][1] * monoval[2][1]; + grads[start + n_curls][1][0] = + monoval_j[0][1] * monoval_i[1][0] * monoval[2][0] * + static_cast(j + my_degree + 2); + grads[start + n_curls][1][1] = + monoval_j[0][0] * monoval_i[1][1] * monoval[2][0] * + static_cast(j + my_degree + 2); + grads[start + n_curls][1][2] = + monoval_j[0][0] * monoval_i[1][0] * monoval[2][1] * + static_cast(j + my_degree + 2); + grads[start + n_curls][2][0] = + -monoval_j[0][1] * monoval_i[1][1] * monoval_plus[2][0]; + grads[start + n_curls][2][1] = + -monoval_j[0][0] * monoval_i[1][2] * monoval_plus[2][0]; + grads[start + n_curls][2][2] = + -monoval_j[0][0] * monoval_i[1][1] * monoval_plus[2][1]; + + grads[start + 2 * n_curls][0][0] = + -monoval_jplus[0][1] * monoval[1][0] * monoval_i[2][1]; + grads[start + 2 * n_curls][0][1] = + -monoval_jplus[0][0] * monoval[1][1] * monoval_i[2][1]; + grads[start + 2 * n_curls][0][2] = + -monoval_jplus[0][0] * monoval[1][0] * monoval_i[2][2]; + grads[start + 2 * n_curls][1][0] = + -monoval_j[0][1] * monoval_plus[1][0] * monoval_i[2][1]; + grads[start + 2 * n_curls][1][1] = + -monoval_j[0][0] * monoval_plus[1][1] * monoval_i[2][1]; + grads[start + 2 * n_curls][1][2] = + -monoval_j[0][0] * monoval_plus[1][0] * monoval_i[2][2]; + grads[start + 2 * n_curls][2][0] = + monoval_j[0][1] * monoval[1][0] * monoval_i[2][0] * + static_cast(j + my_degree + 2); + grads[start + 2 * n_curls][2][1] = + monoval_j[0][0] * monoval[1][1] * monoval_i[2][0] * + static_cast(j + my_degree + 2); + grads[start + 2 * n_curls][2][2] = + monoval_j[0][0] * monoval[1][0] * monoval_i[2][1] * + static_cast(j + my_degree + 2); + + if (j != my_degree) + { + grads[start + 1][0][0] = + monoval_i[0][1] * monoval[1][0] * monoval_j[2][0] * + static_cast(j + my_degree + 2); + grads[start + 1][0][1] = + monoval_i[0][0] * monoval[1][1] * monoval_j[2][0] * + static_cast(j + my_degree + 2); + grads[start + 1][0][2] = + monoval_i[0][0] * monoval[1][0] * monoval_j[2][1] * + static_cast(j + my_degree + 2); + grads[start + 1][1][0] = + -monoval_i[0][2] * monoval_plus[1][0] * monoval_j[2][0]; + grads[start + 1][1][1] = + -monoval_i[0][1] * monoval_plus[1][1] * monoval_j[2][0]; + grads[start + 1][1][2] = + -monoval_i[0][1] * monoval_plus[1][0] * monoval_j[2][1]; + grads[start + 1][2][0] = + -monoval_i[0][2] * monoval[1][0] * monoval_jplus[2][0]; + grads[start + 1][2][1] = + -monoval_i[0][1] * monoval[1][1] * monoval_jplus[2][0]; + grads[start + 1][2][2] = + -monoval_i[0][1] * monoval[1][0] * monoval_jplus[2][1]; + + grads[start + n_curls + 1][0][0] = + -monoval_plus[0][1] * monoval_i[1][1] * monoval_j[2][0]; + grads[start + n_curls + 1][0][1] = + -monoval_plus[0][0] * monoval_i[1][2] * monoval_j[2][0]; + grads[start + n_curls + 1][0][2] = + -monoval_plus[0][0] * monoval_i[1][1] * monoval_j[2][1]; + grads[start + n_curls + 1][1][0] = + monoval[0][1] * monoval_i[1][0] * monoval_j[2][0] * + static_cast(j + my_degree + 2); + grads[start + n_curls + 1][1][1] = + monoval[0][0] * monoval_i[1][1] * monoval_j[2][0] * + static_cast(j + my_degree + 2); + grads[start + n_curls + 1][1][2] = + monoval[0][0] * monoval_i[1][0] * monoval_j[2][1] * + static_cast(j + my_degree + 2); + grads[start + n_curls + 1][2][0] = + -monoval[0][1] * monoval_i[1][1] * monoval_jplus[2][0]; + grads[start + n_curls + 1][2][1] = + -monoval[0][0] * monoval_i[1][2] * monoval_jplus[2][0]; + grads[start + n_curls + 1][2][2] = + -monoval[0][0] * monoval_i[1][1] * monoval_jplus[2][1]; + + grads[start + 2 * n_curls + 1][0][0] = + -monoval_plus[0][1] * monoval_j[1][0] * monoval_i[2][1]; + grads[start + 2 * n_curls + 1][0][1] = + -monoval_plus[0][0] * monoval_j[1][1] * monoval_i[2][1]; + grads[start + 2 * n_curls + 1][0][2] = + -monoval_plus[0][0] * monoval_j[1][0] * monoval_i[2][2]; + grads[start + 2 * n_curls + 1][1][0] = + -monoval[0][1] * monoval_jplus[1][0] * monoval_i[2][1]; + grads[start + 2 * n_curls + 1][1][1] = + -monoval[0][0] * monoval_jplus[1][1] * monoval_i[2][1]; + grads[start + 2 * n_curls + 1][1][2] = + -monoval[0][0] * monoval_jplus[1][0] * monoval_i[2][2]; + grads[start + 2 * n_curls + 1][2][0] = + monoval[0][1] * monoval_j[1][0] * monoval_i[2][0] * + static_cast(j + my_degree + 2); + grads[start + 2 * n_curls + 1][2][1] = + monoval[0][0] * monoval_j[1][1] * monoval_i[2][0] * + static_cast(j + my_degree + 2); + grads[start + 2 * n_curls + 1][2][2] = + monoval[0][0] * monoval_j[1][0] * monoval_i[2][1] * + static_cast(j + my_degree + 2); + } + } + + if (grad_grads.size() != 0) + { + grad_grads[start][0][0][0] = + monoval_i[0][2] * monoval_j[1][0] * monoval[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start][0][0][1] = + monoval_i[0][1] * monoval_j[1][1] * monoval[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start][0][0][2] = + monoval_i[0][1] * monoval_j[1][0] * monoval[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start][0][1][0] = + monoval_i[0][1] * monoval_j[1][1] * monoval[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start][0][1][1] = + monoval_i[0][0] * monoval_j[1][2] * monoval[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start][0][1][2] = + monoval_i[0][0] * monoval_j[1][1] * monoval[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start][0][2][0] = + monoval_i[0][1] * monoval_j[1][0] * monoval[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start][0][2][1] = + monoval_i[0][0] * monoval_j[1][1] * monoval[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start][0][2][2] = + monoval_i[0][0] * monoval_j[1][0] * monoval[2][2] * + static_cast(j + my_degree + 2); + grad_grads[start][1][0][0] = + -monoval_i[0][3] * monoval_jplus[1][0] * monoval[2][0]; + grad_grads[start][1][0][1] = + -monoval_i[0][2] * monoval_jplus[1][1] * monoval[2][0]; + grad_grads[start][1][0][2] = + -monoval_i[0][2] * monoval_jplus[1][0] * monoval[2][1]; + grad_grads[start][1][1][0] = + -monoval_i[0][2] * monoval_jplus[1][1] * monoval[2][0]; + grad_grads[start][1][1][1] = + -monoval_i[0][1] * monoval_jplus[1][2] * monoval[2][0]; + grad_grads[start][1][1][2] = + -monoval_i[0][1] * monoval_jplus[1][1] * monoval[2][1]; + grad_grads[start][1][2][0] = + -monoval_i[0][2] * monoval_jplus[1][0] * monoval[2][1]; + grad_grads[start][1][2][1] = + -monoval_i[0][1] * monoval_jplus[1][1] * monoval[2][1]; + grad_grads[start][1][2][2] = + -monoval_i[0][1] * monoval_jplus[1][0] * monoval[2][2]; + grad_grads[start][2][0][0] = + -monoval_i[0][3] * monoval_j[1][0] * monoval_plus[2][0]; + grad_grads[start][2][0][1] = + -monoval_i[0][2] * monoval_j[1][1] * monoval_plus[2][0]; + grad_grads[start][2][0][2] = + -monoval_i[0][2] * monoval_j[1][0] * monoval_plus[2][1]; + grad_grads[start][2][1][0] = + -monoval_i[0][2] * monoval_j[1][1] * monoval_plus[2][0]; + grad_grads[start][2][1][1] = + -monoval_i[0][1] * monoval_j[1][2] * monoval_plus[2][0]; + grad_grads[start][2][1][2] = + -monoval_i[0][1] * monoval_j[1][1] * monoval_plus[2][1]; + grad_grads[start][2][2][0] = + -monoval_i[0][2] * monoval_j[1][0] * monoval_plus[2][1]; + grad_grads[start][2][2][1] = + -monoval_i[0][1] * monoval_j[1][1] * monoval_plus[2][1]; + grad_grads[start][2][2][2] = + -monoval_i[0][1] * monoval_j[1][0] * monoval_plus[2][2]; + + grad_grads[start + n_curls][0][0][0] = + -monoval_jplus[0][2] * monoval_i[1][1] * monoval[2][0]; + grad_grads[start + n_curls][0][0][1] = + -monoval_jplus[0][1] * monoval_i[1][2] * monoval[2][0]; + grad_grads[start + n_curls][0][0][2] = + -monoval_jplus[0][1] * monoval_i[1][1] * monoval[2][1]; + grad_grads[start + n_curls][0][1][0] = + -monoval_jplus[0][1] * monoval_i[1][2] * monoval[2][0]; + grad_grads[start + n_curls][0][1][1] = + -monoval_jplus[0][0] * monoval_i[1][3] * monoval[2][0]; + grad_grads[start + n_curls][0][1][2] = + -monoval_jplus[0][0] * monoval_i[1][2] * monoval[2][1]; + grad_grads[start + n_curls][0][2][0] = + -monoval_jplus[0][1] * monoval_i[1][1] * monoval[2][1]; + grad_grads[start + n_curls][0][2][1] = + -monoval_jplus[0][0] * monoval_i[1][2] * monoval[2][1]; + grad_grads[start + n_curls][0][2][2] = + -monoval_jplus[0][0] * monoval_i[1][1] * monoval[2][2]; + grad_grads[start + n_curls][1][0][0] = + monoval_j[0][2] * monoval_i[1][0] * monoval[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start + n_curls][1][0][1] = + monoval_j[0][1] * monoval_i[1][1] * monoval[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start + n_curls][1][0][2] = + monoval_j[0][1] * monoval_i[1][0] * monoval[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start + n_curls][1][1][0] = + monoval_j[0][1] * monoval_i[1][1] * monoval[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start + n_curls][1][1][1] = + monoval_j[0][0] * monoval_i[1][2] * monoval[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start + n_curls][1][1][2] = + monoval_j[0][0] * monoval_i[1][1] * monoval[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start + n_curls][1][2][0] = + monoval_j[0][1] * monoval_i[1][0] * monoval[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start + n_curls][1][2][1] = + monoval_j[0][0] * monoval_i[1][1] * monoval[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start + n_curls][1][2][2] = + monoval_j[0][0] * monoval_i[1][0] * monoval[2][2] * + static_cast(j + my_degree + 2); + grad_grads[start + n_curls][2][0][0] = + -monoval_j[0][2] * monoval_i[1][1] * monoval_plus[2][0]; + grad_grads[start + n_curls][2][0][1] = + -monoval_j[0][1] * monoval_i[1][2] * monoval_plus[2][0]; + grad_grads[start + n_curls][2][0][2] = + -monoval_j[0][1] * monoval_i[1][1] * monoval_plus[2][1]; + grad_grads[start + n_curls][2][1][0] = + -monoval_j[0][1] * monoval_i[1][2] * monoval_plus[2][0]; + grad_grads[start + n_curls][2][1][1] = + -monoval_j[0][0] * monoval_i[1][3] * monoval_plus[2][0]; + grad_grads[start + n_curls][2][1][2] = + -monoval_j[0][0] * monoval_i[1][2] * monoval_plus[2][1]; + grad_grads[start + n_curls][2][2][0] = + -monoval_j[0][1] * monoval_i[1][1] * monoval_plus[2][1]; + grad_grads[start + n_curls][2][2][1] = + -monoval_j[0][0] * monoval_i[1][2] * monoval_plus[2][1]; + grad_grads[start + n_curls][2][2][2] = + -monoval_j[0][0] * monoval_i[1][1] * monoval_plus[2][2]; + + grad_grads[start + 2 * n_curls][0][0][0] = + -monoval_jplus[0][2] * monoval[1][0] * monoval_i[2][1]; + grad_grads[start + 2 * n_curls][0][0][1] = + -monoval_jplus[0][1] * monoval[1][1] * monoval_i[2][1]; + grad_grads[start + 2 * n_curls][0][0][2] = + -monoval_jplus[0][1] * monoval[1][0] * monoval_i[2][2]; + grad_grads[start + 2 * n_curls][0][1][0] = + -monoval_jplus[0][1] * monoval[1][1] * monoval_i[2][1]; + grad_grads[start + 2 * n_curls][0][1][1] = + -monoval_jplus[0][0] * monoval[1][2] * monoval_i[2][1]; + grad_grads[start + 2 * n_curls][0][1][2] = + -monoval_jplus[0][0] * monoval[1][1] * monoval_i[2][2]; + grad_grads[start + 2 * n_curls][0][2][0] = + -monoval_jplus[0][1] * monoval[1][0] * monoval_i[2][2]; + grad_grads[start + 2 * n_curls][0][2][1] = + -monoval_jplus[0][0] * monoval[1][1] * monoval_i[2][2]; + grad_grads[start + 2 * n_curls][0][2][2] = + -monoval_jplus[0][0] * monoval[1][0] * monoval_i[2][3]; + grad_grads[start + 2 * n_curls][1][0][0] = + -monoval_j[0][2] * monoval_plus[1][0] * monoval_i[2][1]; + grad_grads[start + 2 * n_curls][1][0][1] = + -monoval_j[0][1] * monoval_plus[1][1] * monoval_i[2][1]; + grad_grads[start + 2 * n_curls][1][0][2] = + -monoval_j[0][1] * monoval_plus[1][0] * monoval_i[2][2]; + grad_grads[start + 2 * n_curls][1][1][0] = + -monoval_j[0][1] * monoval_plus[1][1] * monoval_i[2][1]; + grad_grads[start + 2 * n_curls][1][1][1] = + -monoval_j[0][0] * monoval_plus[1][2] * monoval_i[2][1]; + grad_grads[start + 2 * n_curls][1][1][2] = + -monoval_j[0][0] * monoval_plus[1][1] * monoval_i[2][2]; + grad_grads[start + 2 * n_curls][1][2][0] = + -monoval_j[0][1] * monoval_plus[1][0] * monoval_i[2][2]; + grad_grads[start + 2 * n_curls][1][2][1] = + -monoval_j[0][0] * monoval_plus[1][1] * monoval_i[2][2]; + grad_grads[start + 2 * n_curls][1][2][2] = + -monoval_j[0][0] * monoval_plus[1][0] * monoval_i[2][3]; + grad_grads[start + 2 * n_curls][2][0][0] = + monoval_j[0][2] * monoval[1][0] * monoval_i[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start + 2 * n_curls][2][0][1] = + monoval_j[0][1] * monoval[1][1] * monoval_i[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start + 2 * n_curls][2][0][2] = + monoval_j[0][1] * monoval[1][0] * monoval_i[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start + 2 * n_curls][2][1][0] = + monoval_j[0][1] * monoval[1][1] * monoval_i[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start + 2 * n_curls][2][1][1] = + monoval_j[0][0] * monoval[1][2] * monoval_i[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start + 2 * n_curls][2][1][2] = + monoval_j[0][0] * monoval[1][1] * monoval_i[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start + 2 * n_curls][2][2][0] = + monoval_j[0][1] * monoval[1][0] * monoval_i[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start + 2 * n_curls][2][2][1] = + monoval_j[0][0] * monoval[1][1] * monoval_i[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start + 2 * n_curls][2][2][2] = + monoval_j[0][0] * monoval[1][0] * monoval_i[2][2] * + static_cast(j + my_degree + 2); + + if (j != my_degree) + { + grad_grads[start + 1][0][0][0] = + monoval_i[0][2] * monoval[1][0] * monoval_j[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start + 1][0][0][1] = + monoval_i[0][1] * monoval[1][1] * monoval_j[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start + 1][0][0][2] = + monoval_i[0][1] * monoval[1][0] * monoval_j[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start + 1][0][1][0] = + monoval_i[0][1] * monoval[1][1] * monoval_j[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start + 1][0][1][1] = + monoval_i[0][0] * monoval[1][2] * monoval_j[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start + 1][0][1][2] = + monoval_i[0][0] * monoval[1][1] * monoval_j[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start + 1][0][2][0] = + monoval_i[0][1] * monoval[1][0] * monoval_j[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start + 1][0][2][1] = + monoval_i[0][0] * monoval[1][1] * monoval_j[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start + 1][0][2][2] = + monoval_i[0][0] * monoval[1][0] * monoval_j[2][2] * + static_cast(j + my_degree + 2); + grad_grads[start + 1][1][0][0] = + -monoval_i[0][3] * monoval_plus[1][0] * monoval_j[2][0]; + grad_grads[start + 1][1][0][1] = + -monoval_i[0][2] * monoval_plus[1][1] * monoval_j[2][0]; + grad_grads[start + 1][1][0][2] = + -monoval_i[0][2] * monoval_plus[1][0] * monoval_j[2][1]; + grad_grads[start + 1][1][1][0] = + -monoval_i[0][2] * monoval_plus[1][1] * monoval_j[2][0]; + grad_grads[start + 1][1][1][1] = + -monoval_i[0][1] * monoval_plus[1][2] * monoval_j[2][0]; + grad_grads[start + 1][1][1][2] = + -monoval_i[0][1] * monoval_plus[1][1] * monoval_j[2][1]; + grad_grads[start + 1][1][2][0] = + -monoval_i[0][2] * monoval_plus[1][0] * monoval_j[2][1]; + grad_grads[start + 1][1][2][1] = + -monoval_i[0][1] * monoval_plus[1][1] * monoval_j[2][1]; + grad_grads[start + 1][1][2][2] = + -monoval_i[0][1] * monoval_plus[1][0] * monoval_j[2][2]; + grad_grads[start + 1][2][0][0] = + -monoval_i[0][3] * monoval[1][0] * monoval_jplus[2][0]; + grad_grads[start + 1][2][0][1] = + -monoval_i[0][2] * monoval[1][1] * monoval_jplus[2][0]; + grad_grads[start + 1][2][0][2] = + -monoval_i[0][2] * monoval[1][0] * monoval_jplus[2][1]; + grad_grads[start + 1][2][1][0] = + -monoval_i[0][2] * monoval[1][1] * monoval_jplus[2][0]; + grad_grads[start + 1][2][1][1] = + -monoval_i[0][1] * monoval[1][2] * monoval_jplus[2][0]; + grad_grads[start + 1][2][1][2] = + -monoval_i[0][1] * monoval[1][1] * monoval_jplus[2][1]; + grad_grads[start + 1][2][2][0] = + -monoval_i[0][2] * monoval[1][0] * monoval_jplus[2][1]; + grad_grads[start + 1][2][2][1] = + -monoval_i[0][1] * monoval[1][1] * monoval_jplus[2][1]; + grad_grads[start + 1][2][2][2] = + -monoval_i[0][1] * monoval[1][0] * monoval_jplus[2][2]; + + grad_grads[start + n_curls + 1][0][0][0] = + -monoval_plus[0][2] * monoval_i[1][1] * monoval_j[2][0]; + grad_grads[start + n_curls + 1][0][0][1] = + -monoval_plus[0][1] * monoval_i[1][2] * monoval_j[2][0]; + grad_grads[start + n_curls + 1][0][0][2] = + -monoval_plus[0][1] * monoval_i[1][1] * monoval_j[2][1]; + grad_grads[start + n_curls + 1][0][1][0] = + -monoval_plus[0][1] * monoval_i[1][2] * monoval_j[2][0]; + grad_grads[start + n_curls + 1][0][1][1] = + -monoval_plus[0][0] * monoval_i[1][3] * monoval_j[2][0]; + grad_grads[start + n_curls + 1][0][1][2] = + -monoval_plus[0][0] * monoval_i[1][2] * monoval_j[2][1]; + grad_grads[start + n_curls + 1][0][2][0] = + -monoval_plus[0][1] * monoval_i[1][1] * monoval_j[2][1]; + grad_grads[start + n_curls + 1][0][2][1] = + -monoval_plus[0][0] * monoval_i[1][2] * monoval_j[2][1]; + grad_grads[start + n_curls + 1][0][2][2] = + -monoval_plus[0][0] * monoval_i[1][1] * monoval_j[2][2]; + grad_grads[start + n_curls + 1][1][0][0] = + monoval[0][2] * monoval_i[1][0] * monoval_j[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start + n_curls + 1][1][0][1] = + monoval[0][1] * monoval_i[1][1] * monoval_j[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start + n_curls + 1][1][0][2] = + monoval[0][1] * monoval_i[1][0] * monoval_j[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start + n_curls + 1][1][1][0] = + monoval[0][1] * monoval_i[1][1] * monoval_j[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start + n_curls + 1][1][1][1] = + monoval[0][0] * monoval_i[1][2] * monoval_j[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start + n_curls + 1][1][1][2] = + monoval[0][0] * monoval_i[1][1] * monoval_j[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start + n_curls + 1][1][2][0] = + monoval[0][1] * monoval_i[1][0] * monoval_j[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start + n_curls + 1][1][2][1] = + monoval[0][0] * monoval_i[1][1] * monoval_j[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start + n_curls + 1][1][2][2] = + monoval[0][0] * monoval_i[1][0] * monoval_j[2][2] * + static_cast(j + my_degree + 2); + grad_grads[start + n_curls + 1][2][0][0] = + -monoval[0][2] * monoval_i[1][1] * monoval_jplus[2][0]; + grad_grads[start + n_curls + 1][2][0][1] = + -monoval[0][1] * monoval_i[1][2] * monoval_jplus[2][0]; + grad_grads[start + n_curls + 1][2][0][2] = + -monoval[0][1] * monoval_i[1][1] * monoval_jplus[2][1]; + grad_grads[start + n_curls + 1][2][1][0] = + -monoval[0][1] * monoval_i[1][2] * monoval_jplus[2][0]; + grad_grads[start + n_curls + 1][2][1][1] = + -monoval[0][0] * monoval_i[1][3] * monoval_jplus[2][0]; + grad_grads[start + n_curls + 1][2][1][2] = + -monoval[0][0] * monoval_i[1][2] * monoval_jplus[2][1]; + grad_grads[start + n_curls + 1][2][2][0] = + -monoval[0][1] * monoval_i[1][1] * monoval_jplus[2][1]; + grad_grads[start + n_curls + 1][2][2][1] = + -monoval[0][0] * monoval_i[1][2] * monoval_jplus[2][1]; + grad_grads[start + n_curls + 1][2][2][2] = + -monoval[0][0] * monoval_i[1][1] * monoval_jplus[2][2]; + + grad_grads[start + 2 * n_curls + 1][0][0][0] = + -monoval_plus[0][2] * monoval_j[1][0] * monoval_i[2][1]; + grad_grads[start + 2 * n_curls + 1][0][0][1] = + -monoval_plus[0][1] * monoval_j[1][1] * monoval_i[2][1]; + grad_grads[start + 2 * n_curls + 1][0][0][2] = + -monoval_plus[0][1] * monoval_j[1][0] * monoval_i[2][2]; + grad_grads[start + 2 * n_curls + 1][0][1][0] = + -monoval_plus[0][1] * monoval_j[1][1] * monoval_i[2][1]; + grad_grads[start + 2 * n_curls + 1][0][1][1] = + -monoval_plus[0][0] * monoval_j[1][2] * monoval_i[2][1]; + grad_grads[start + 2 * n_curls + 1][0][1][2] = + -monoval_plus[0][0] * monoval_j[1][1] * monoval_i[2][2]; + grad_grads[start + 2 * n_curls + 1][0][2][0] = + -monoval_plus[0][1] * monoval_j[1][0] * monoval_i[2][2]; + grad_grads[start + 2 * n_curls + 1][0][2][1] = + -monoval_plus[0][0] * monoval_j[1][1] * monoval_i[2][2]; + grad_grads[start + 2 * n_curls + 1][0][2][2] = + -monoval_plus[0][0] * monoval_j[1][0] * monoval_i[2][3]; + grad_grads[start + 2 * n_curls + 1][1][0][0] = + -monoval[0][2] * monoval_jplus[1][0] * monoval_i[2][1]; + grad_grads[start + 2 * n_curls + 1][1][0][1] = + -monoval[0][1] * monoval_jplus[1][1] * monoval_i[2][1]; + grad_grads[start + 2 * n_curls + 1][1][0][2] = + -monoval[0][1] * monoval_jplus[1][0] * monoval_i[2][2]; + grad_grads[start + 2 * n_curls + 1][1][1][0] = + -monoval[0][1] * monoval_jplus[1][1] * monoval_i[2][1]; + grad_grads[start + 2 * n_curls + 1][1][1][1] = + -monoval[0][0] * monoval_jplus[1][2] * monoval_i[2][1]; + grad_grads[start + 2 * n_curls + 1][1][1][2] = + -monoval[0][0] * monoval_jplus[1][1] * monoval_i[2][2]; + grad_grads[start + 2 * n_curls + 1][1][2][0] = + -monoval[0][1] * monoval_jplus[1][0] * monoval_i[2][2]; + grad_grads[start + 2 * n_curls + 1][1][2][1] = + -monoval[0][0] * monoval_jplus[1][1] * monoval_i[2][2]; + grad_grads[start + 2 * n_curls + 1][1][2][2] = + -monoval[0][0] * monoval_jplus[1][0] * monoval_i[2][3]; + grad_grads[start + 2 * n_curls + 1][2][0][0] = + monoval[0][2] * monoval_j[1][0] * monoval_i[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start + 2 * n_curls + 1][2][0][1] = + monoval[0][1] * monoval_j[1][1] * monoval_i[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start + 2 * n_curls + 1][2][0][2] = + monoval[0][1] * monoval_j[1][0] * monoval_i[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start + 2 * n_curls + 1][2][1][0] = + monoval[0][1] * monoval_j[1][1] * monoval_i[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start + 2 * n_curls + 1][2][1][1] = + monoval[0][0] * monoval_j[1][2] * monoval_i[2][0] * + static_cast(j + my_degree + 2); + grad_grads[start + 2 * n_curls + 1][2][1][2] = + monoval[0][0] * monoval_j[1][1] * monoval_i[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start + 2 * n_curls + 1][2][2][0] = + monoval[0][1] * monoval_j[1][0] * monoval_i[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start + 2 * n_curls + 1][2][2][1] = + monoval[0][0] * monoval_j[1][1] * monoval_i[2][1] * + static_cast(j + my_degree + 2); + grad_grads[start + 2 * n_curls + 1][2][2][2] = + monoval[0][0] * monoval_j[1][0] * monoval_i[2][2] * + static_cast(j + my_degree + 2); + } + } + + if (j == my_degree) + start += 1; + else + start += 2; + } + } + Assert(start == this->n() - 2 * n_curls, ExcInternalError()); + } } -- 2.39.5