From 5b80464795a56cbd59cf9bf0508bee9b1231f8e2 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Sat, 5 Aug 2017 00:11:42 +0200 Subject: [PATCH] Choose appropriate tensorized evaluation template instantiation at run-time --- .../deal.II/matrix_free/evaluation_kernels.h | 3 +- .../deal.II/matrix_free/evaluation_selector.h | 574 ++++++++++++++++++ include/deal.II/matrix_free/fe_evaluation.h | 129 +--- 3 files changed, 585 insertions(+), 121 deletions(-) create mode 100644 include/deal.II/matrix_free/evaluation_selector.h diff --git a/include/deal.II/matrix_free/evaluation_kernels.h b/include/deal.II/matrix_free/evaluation_kernels.h index 2da6db4316..105f47ed1f 100644 --- a/include/deal.II/matrix_free/evaluation_kernels.h +++ b/include/deal.II/matrix_free/evaluation_kernels.h @@ -376,7 +376,8 @@ namespace internal : (Eval::dofs_per_cell > Eval::n_q_points ? Eval::dofs_per_cell : Eval::n_q_points); const unsigned int max_stack_size = 100; - VectorizedArray temp_data[(temp_size > 0 && temp_size < max_stack_size) ? 2*temp_size : 1]; + AlignedVector> temp_data; + temp_data.resize_fast((temp_size > 0 && temp_size < max_stack_size) ? 2*temp_size : 1); VectorizedArray *temp1; VectorizedArray *temp2; if (temp_size == 0) diff --git a/include/deal.II/matrix_free/evaluation_selector.h b/include/deal.II/matrix_free/evaluation_selector.h new file mode 100644 index 0000000000..680be1b330 --- /dev/null +++ b/include/deal.II/matrix_free/evaluation_selector.h @@ -0,0 +1,574 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2017 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE at +// the top level of the deal.II distribution. +// +// --------------------------------------------------------------------- + + +#ifndef dealii__matrix_free_evaluation_selector_h +#define dealii__matrix_free_evaluation_selector_h + +#include + +DEAL_II_NAMESPACE_OPEN + +#ifndef DOXYGEN +namespace +{ +// The following classes serve the purpose of choosing the correct template +// specialization of the FEEvaluationImpl* classes in case fe_degree +// and n_q_points_1d are only given as runtime parameters. +// The logic is the following: +// 1. Start with fe_degree=0, n_q_points_1d=0 and DEPTH=0. +// 2. If the current assumption on fe_degree doesn't match the runtime +// parameter, increase fe_degree by one and try again. +// If fe_degree==10 use the class Default which serves as a fallback. +// 3. After fixing the fe_degree, DEPTH is increased (DEPTH=1) and we start with +// n_q_points=fe_degree-1. +// 4. If the current assumption on n_q_points_1d doesn't match the runtime +// parameter, increase n_q_points_1d by one and try again. +// If n_q_points_1d==degree+2 use the class Default which serves as a fallback. + + /** + * This class serves as a fallback in case we don't have the appropriate template + * specialization for the run time and template parameters given. + */ + template + struct Default + { + static inline void evaluate (const internal::MatrixFreeFunctions::ShapeInfo > &shape_info, + VectorizedArray *values_dofs_actual[], + VectorizedArray *values_quad[], + VectorizedArray *gradients_quad[][dim], + VectorizedArray *hessians_quad[][(dim*(dim+1))/2], + VectorizedArray *scratch_data, + const bool evaluate_values, + const bool evaluate_gradients, + const bool evaluate_hessians) + { + internal::FEEvaluationImpl + ::evaluate(shape_info, values_dofs_actual, values_quad, + gradients_quad, hessians_quad, scratch_data, + evaluate_values, evaluate_gradients, evaluate_hessians); + } + + static inline void integrate (const internal::MatrixFreeFunctions::ShapeInfo > &shape_info, + VectorizedArray *values_dofs_actual[], + VectorizedArray *values_quad[], + VectorizedArray *gradients_quad[][dim], + VectorizedArray *scratch_data, + const bool integrate_values, + const bool integrate_gradients) + { + internal::FEEvaluationImpl + ::integrate(shape_info, values_dofs_actual, values_quad, + gradients_quad, scratch_data, + integrate_values, integrate_gradients); + } + }; + + + /** + * This class implements the actual choice of the template specialization. + */ + template + struct Factory : Default {}; + + /** + * This specialization sets the maximal fe_degree for + * which we want to determine the correct template parameters based at runtime. + */ + template + struct Factory : Default {}; + + /** + * This specialization sets the maximal number of n_q_points_1d for + * which we want to determine the correct template parameters based at runtime. + */ + template + struct Factory::type> : Default {}; + + /** + * This class chooses the correct template degree. + */ + template + struct Factory + { + static inline void evaluate ( + const internal::MatrixFreeFunctions::ShapeInfo > &shape_info, + VectorizedArray *values_dofs_actual[], + VectorizedArray *values_quad[], + VectorizedArray *gradients_quad[][dim], + VectorizedArray *hessians_quad[][(dim*(dim+1))/2], + VectorizedArray *scratch_data, + const bool evaluate_values, + const bool evaluate_gradients, + const bool evaluate_hessians) + { + const unsigned int runtime_degree = shape_info.fe_degree; + constexpr unsigned int nonnegative_start_n_q_points = (degree>0)?degree-1:0; + if (runtime_degree == degree) + Factory::evaluate + (shape_info, values_dofs_actual, values_quad, gradients_quad, hessians_quad, + scratch_data, evaluate_values, evaluate_gradients, evaluate_hessians); + else + Factory::evaluate + (shape_info, values_dofs_actual, values_quad, gradients_quad, hessians_quad, + scratch_data, evaluate_values, evaluate_gradients, evaluate_hessians); + } + + static inline void integrate ( + const internal::MatrixFreeFunctions::ShapeInfo > &shape_info, + VectorizedArray *values_dofs_actual[], + VectorizedArray *values_quad[], + VectorizedArray *gradients_quad[][dim], + VectorizedArray *scratch_data, + const bool integrate_values, + const bool integrate_gradients) + { + const int runtime_degree = shape_info.fe_degree; + constexpr unsigned int nonnegative_start_n_q_points = (degree>0)?degree-1:0; + if (runtime_degree == degree) + Factory::integrate + (shape_info, values_dofs_actual, values_quad, gradients_quad, + scratch_data, integrate_values, integrate_gradients); + else + Factory::integrate + (shape_info, values_dofs_actual, values_quad, gradients_quad, + scratch_data, integrate_values, integrate_gradients); + } + }; + + /** + * This class chooses the correct template n_q_points_1d after degree was chosen. + */ + template + struct Factory::type> + { + static inline void evaluate (const internal::MatrixFreeFunctions::ShapeInfo > &shape_info, + VectorizedArray *values_dofs_actual[], + VectorizedArray *values_quad[], + VectorizedArray *gradients_quad[][dim], + VectorizedArray *hessians_quad[][(dim*(dim+1))/2], + VectorizedArray *scratch_data, + const bool evaluate_values, + const bool evaluate_gradients, + const bool evaluate_hessians) + { + const int runtime_n_q_points_1d = shape_info.n_q_points_1d; + if (runtime_n_q_points_1d == n_q_points_1d) + { + if (n_q_points_1d == degree+1) + { + if (shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric_collocation) + internal::FEEvaluationImplCollocation + ::evaluate(shape_info, values_dofs_actual, values_quad, + gradients_quad, hessians_quad, scratch_data, + evaluate_values, evaluate_gradients, evaluate_hessians); + else + internal::FEEvaluationImplTransformToCollocation + ::evaluate(shape_info, values_dofs_actual, values_quad, + gradients_quad, hessians_quad, scratch_data, + evaluate_values, evaluate_gradients, evaluate_hessians); + } + else + internal::FEEvaluationImpl + ::evaluate(shape_info, values_dofs_actual, values_quad, + gradients_quad, hessians_quad, scratch_data, + evaluate_values, evaluate_gradients, evaluate_hessians); + } + else + Factory::evaluate (shape_info, values_dofs_actual, values_quad, + gradients_quad, hessians_quad, scratch_data, + evaluate_values, evaluate_gradients, evaluate_hessians); + } + + static inline void integrate (const internal::MatrixFreeFunctions::ShapeInfo > &shape_info, + VectorizedArray *values_dofs_actual[], + VectorizedArray *values_quad[], + VectorizedArray *gradients_quad[][dim], + VectorizedArray *scratch_data, + const bool integrate_values, + const bool integrate_gradients) + { + const int runtime_n_q_points_1d = shape_info.n_q_points_1d; + if (runtime_n_q_points_1d == n_q_points_1d) + { + if (n_q_points_1d == degree+1) + { + if (shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric_collocation) + internal::FEEvaluationImplCollocation + ::integrate(shape_info, values_dofs_actual, values_quad, + gradients_quad, scratch_data, + integrate_values, integrate_gradients); + else + internal::FEEvaluationImplTransformToCollocation + ::integrate(shape_info, values_dofs_actual, values_quad, + gradients_quad, scratch_data, + integrate_values, integrate_gradients); + } + else + internal::FEEvaluationImpl + ::integrate(shape_info, values_dofs_actual, values_quad, gradients_quad, + scratch_data, integrate_values, integrate_gradients); + } + else + Factory + ::integrate (shape_info, values_dofs_actual, values_quad, gradients_quad, + scratch_data, integrate_values, integrate_gradients); + } + }; + + + + /** + * This is the entry point for choosing the correct runtime parameters + * for the 'evaluate' function. + */ + template + void symmetric_selector_evaluate (const internal::MatrixFreeFunctions::ShapeInfo > &shape_info, + VectorizedArray *values_dofs_actual[], + VectorizedArray *values_quad[], + VectorizedArray *gradients_quad[][dim], + VectorizedArray *hessians_quad[][(dim*(dim+1))/2], + VectorizedArray *scratch_data, + const bool evaluate_values, + const bool evaluate_gradients, + const bool evaluate_hessians) + { + Assert(shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric|| + shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric_collocation, + ExcInternalError()); + Factory::evaluate + (shape_info, values_dofs_actual, values_quad, gradients_quad, hessians_quad, + scratch_data, evaluate_values, evaluate_gradients, evaluate_hessians); + } + + + + /** + * This is the entry point for choosing the correct runtime parameters + * for the 'integrate' function. + */ + template + void symmetric_selector_integrate (const internal::MatrixFreeFunctions::ShapeInfo > &shape_info, + VectorizedArray *values_dofs_actual[], + VectorizedArray *values_quad[], + VectorizedArray *gradients_quad[][dim], + VectorizedArray *scratch_data, + const bool integrate_values, + const bool integrate_gradients) + { + Assert(shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric|| + shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric_collocation, + ExcInternalError()); + Factory::integrate + (shape_info, values_dofs_actual, values_quad, gradients_quad, + scratch_data, integrate_values, integrate_gradients); + } +} +#endif + + +/** + * This class chooses an appropriate evaluation strategy based on the + * template parameters and the shape_info variable which contains runtime + * parameters. In case the template parameters fe_degree and n_q_points_1d + * contain valid information (i.e. fe_degree>-1 and n_q_points_1d>0), we simply + * pass these values to the respective template specializations. + * Otherwise, we perform a runtime matching of the runtime parameters to find + * the correct specialization. This matching currently supports + * $0\leq fe\_degree$ and $degree-1\leq n_q_points_1d\leq degree+1$. + */ +template +struct SelectEvaluator +{ + static void evaluate(const internal::MatrixFreeFunctions::ShapeInfo > &shape_info, + VectorizedArray *values_dofs_actual[], + VectorizedArray *values_quad[], + VectorizedArray *gradients_quad[][dim], + VectorizedArray *hessians_quad[][(dim*(dim+1))/2], + VectorizedArray *scratch_data, + const bool evaluate_values, + const bool evaluate_gradients, + const bool evaluate_hessians); + + static void integrate(const internal::MatrixFreeFunctions::ShapeInfo > &shape_info, + VectorizedArray *values_dofs_actual[], + VectorizedArray *values_quad[], + VectorizedArray *gradients_quad[][dim], + VectorizedArray *scratch_data, + const bool integrate_values, + const bool integrate_gradients); +}; + +/** + * Specialization for invalid template parameters, i.e. fe_degree==-1. + */ +template +struct SelectEvaluator +{ + static void evaluate(const internal::MatrixFreeFunctions::ShapeInfo > &shape_info, + VectorizedArray *values_dofs_actual[], + VectorizedArray *values_quad[], + VectorizedArray *gradients_quad[][dim], + VectorizedArray *hessians_quad[][(dim*(dim+1))/2], + VectorizedArray *scratch_data, + const bool evaluate_values, + const bool evaluate_gradients, + const bool evaluate_hessians); + + static void integrate(const internal::MatrixFreeFunctions::ShapeInfo > &shape_info, + VectorizedArray *values_dofs_actual[], + VectorizedArray *values_quad[], + VectorizedArray *gradients_quad[][dim], + VectorizedArray *scratch_data, + const bool integrate_values, + const bool integrate_gradients); +}; + +//----------------------Implementation for SelectEvaluator--------------------- +#ifndef DOXYGEN + +template +inline +void +SelectEvaluator::evaluate +(const internal::MatrixFreeFunctions::ShapeInfo > &shape_info, + VectorizedArray *values_dofs_actual[], + VectorizedArray *values_quad[], + VectorizedArray *gradients_quad[][dim], + VectorizedArray *hessians_quad[][(dim*(dim+1))/2], + VectorizedArray *scratch_data, + const bool evaluate_values, + const bool evaluate_gradients, + const bool evaluate_hessians) +{ + Assert(fe_degree>=0 && n_q_points_1d>0, ExcInternalError()); + + if (fe_degree+1 == n_q_points_1d && + shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric_collocation) + { + internal::FEEvaluationImplCollocation + ::evaluate(shape_info, values_dofs_actual, values_quad, + gradients_quad, hessians_quad, scratch_data, + evaluate_values, evaluate_gradients, evaluate_hessians); + } + else if (fe_degree+1 == n_q_points_1d && + shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric) + { + internal::FEEvaluationImplTransformToCollocation + ::evaluate(shape_info, values_dofs_actual, values_quad, + gradients_quad, hessians_quad, scratch_data, + evaluate_values, evaluate_gradients, evaluate_hessians); + } + else if (shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric) + { + internal::FEEvaluationImpl + ::evaluate(shape_info, values_dofs_actual, values_quad, + gradients_quad, hessians_quad, scratch_data, + evaluate_values, evaluate_gradients, evaluate_hessians); + } + else if (shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric_plus_dg0) + { + internal::FEEvaluationImpl + ::evaluate(shape_info, values_dofs_actual, values_quad, + gradients_quad, hessians_quad, scratch_data, + evaluate_values, evaluate_gradients, evaluate_hessians); + } + else if (shape_info.element_type == internal::MatrixFreeFunctions::truncated_tensor) + { + internal::FEEvaluationImpl + ::evaluate(shape_info, values_dofs_actual, values_quad, + gradients_quad, hessians_quad, scratch_data, + evaluate_values, evaluate_gradients, evaluate_hessians); + } + else if (shape_info.element_type == internal::MatrixFreeFunctions::tensor_general) + { + internal::FEEvaluationImpl + ::evaluate(shape_info, values_dofs_actual, values_quad, + gradients_quad, hessians_quad, scratch_data, + evaluate_values, evaluate_gradients, evaluate_hessians); + } + else + AssertThrow(false, ExcNotImplemented()); +} + + + +template +inline +void +SelectEvaluator::integrate +(const internal::MatrixFreeFunctions::ShapeInfo > &shape_info, + VectorizedArray *values_dofs_actual[], + VectorizedArray *values_quad[], + VectorizedArray *gradients_quad[][dim], + VectorizedArray *scratch_data, + const bool integrate_values, + const bool integrate_gradients) +{ + Assert(fe_degree>=0 && n_q_points_1d>0, ExcInternalError()); + + if (fe_degree+1 == n_q_points_1d && + shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric_collocation) + { + internal::FEEvaluationImplCollocation + ::integrate(shape_info, values_dofs_actual, values_quad, + gradients_quad, scratch_data, + integrate_values, integrate_gradients); + } + else if (fe_degree+1 == n_q_points_1d && + shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric) + { + internal::FEEvaluationImplTransformToCollocation + ::integrate(shape_info, values_dofs_actual, values_quad, + gradients_quad, scratch_data, + integrate_values, integrate_gradients); + } + else if (shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric) + { + internal::FEEvaluationImpl + ::integrate(shape_info, values_dofs_actual, values_quad, + gradients_quad, scratch_data, + integrate_values, integrate_gradients); + } + else if (shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric_plus_dg0) + { + internal::FEEvaluationImpl + ::integrate(shape_info, values_dofs_actual, values_quad, + gradients_quad, scratch_data, + integrate_values, integrate_gradients); + } + else if (shape_info.element_type == internal::MatrixFreeFunctions::truncated_tensor) + { + internal::FEEvaluationImpl + ::integrate(shape_info, values_dofs_actual, values_quad, + gradients_quad, scratch_data, + integrate_values, integrate_gradients); + } + else if (shape_info.element_type == internal::MatrixFreeFunctions::tensor_general) + { + internal::FEEvaluationImpl + ::integrate(shape_info, values_dofs_actual, values_quad, + gradients_quad, scratch_data, + integrate_values, integrate_gradients); + } + else + AssertThrow(false, ExcNotImplemented()); +} + + + +template +inline +void +SelectEvaluator::evaluate +(const internal::MatrixFreeFunctions::ShapeInfo > &shape_info, + VectorizedArray *values_dofs_actual[], + VectorizedArray *values_quad[], + VectorizedArray *gradients_quad[][dim], + VectorizedArray *hessians_quad[][(dim*(dim+1))/2], + VectorizedArray *scratch_data, + const bool evaluate_values, + const bool evaluate_gradients, + const bool evaluate_hessians) +{ + if (shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric_plus_dg0) + { + internal::FEEvaluationImpl + ::evaluate(shape_info, values_dofs_actual, values_quad, + gradients_quad, hessians_quad, scratch_data, + evaluate_values, evaluate_gradients, evaluate_hessians); + } + else if (shape_info.element_type == internal::MatrixFreeFunctions::truncated_tensor) + { + internal::FEEvaluationImpl + ::evaluate(shape_info, values_dofs_actual, values_quad, + gradients_quad, hessians_quad, scratch_data, + evaluate_values, evaluate_gradients, evaluate_hessians); + } + else if (shape_info.element_type == internal::MatrixFreeFunctions::tensor_general) + internal::FEEvaluationImpl + ::evaluate(shape_info, values_dofs_actual, values_quad, + gradients_quad, hessians_quad, scratch_data, + evaluate_values, evaluate_gradients, evaluate_hessians); + else + symmetric_selector_evaluate + (shape_info, values_dofs_actual, values_quad, + gradients_quad, hessians_quad, scratch_data, + evaluate_values, evaluate_gradients, evaluate_hessians); +} + + + +template +inline +void +SelectEvaluator::integrate +(const internal::MatrixFreeFunctions::ShapeInfo > &shape_info, + VectorizedArray *values_dofs_actual[], + VectorizedArray *values_quad[], + VectorizedArray *gradients_quad[][dim], + VectorizedArray *scratch_data, + const bool integrate_values, + const bool integrate_gradients) +{ + if (shape_info.element_type == internal::MatrixFreeFunctions::tensor_symmetric_plus_dg0) + { + internal::FEEvaluationImpl + ::integrate(shape_info, values_dofs_actual, values_quad, + gradients_quad, scratch_data, + integrate_values, integrate_gradients); + } + else if (shape_info.element_type == internal::MatrixFreeFunctions::truncated_tensor) + { + internal::FEEvaluationImpl + ::integrate(shape_info, values_dofs_actual, values_quad, + gradients_quad, scratch_data, + integrate_values, integrate_gradients); + } + else if (shape_info.element_type == internal::MatrixFreeFunctions::tensor_general) + internal::FEEvaluationImpl + ::integrate(shape_info, values_dofs_actual, values_quad, + gradients_quad, scratch_data, + integrate_values, integrate_gradients); + else + symmetric_selector_integrate + (shape_info, values_dofs_actual, values_quad, + gradients_quad, scratch_data, + integrate_values, integrate_gradients); +} +#endif //DOXYGEN + +DEAL_II_NAMESPACE_CLOSE + +#endif diff --git a/include/deal.II/matrix_free/fe_evaluation.h b/include/deal.II/matrix_free/fe_evaluation.h index bfd8d3b42a..eca7223d3a 100644 --- a/include/deal.II/matrix_free/fe_evaluation.h +++ b/include/deal.II/matrix_free/fe_evaluation.h @@ -30,6 +30,7 @@ #include #include #include +#include DEAL_II_NAMESPACE_OPEN @@ -5338,66 +5339,10 @@ FEEvaluation Assert(this->matrix_info != nullptr || this->mapped_geometry->is_initialized(), ExcNotInitialized()); - // Run time selection of algorithm matching the element type. Since some - // template combinations do not work for fe_degree==-1, create safe template - // values for the calls below. - const unsigned int fe_degree_nonnegative = fe_degree != -1 ? fe_degree : 0; - const unsigned int n_q_points_1d_positive = n_q_points_1d > 0 ? n_q_points_1d : 1; - const unsigned int n_q_points_1d_adjusted = fe_degree == -1 ? 0 : n_q_points_1d; - if (fe_degree >= 0 && - fe_degree+1 == n_q_points_1d && - this->data->element_type == internal::MatrixFreeFunctions::tensor_symmetric_collocation) - { - internal::FEEvaluationImplCollocation - ::evaluate(*this->data, &this->values_dofs[0], this->values_quad, - this->gradients_quad, this->hessians_quad, this->scratch_data, - evaluate_values, evaluate_gradients, evaluate_hessians); - } - else if (fe_degree >= 0 && - fe_degree+1 == n_q_points_1d && - this->data->element_type == internal::MatrixFreeFunctions::tensor_symmetric) - { - internal::FEEvaluationImplTransformToCollocation - ::evaluate(*this->data, &this->values_dofs[0], this->values_quad, - this->gradients_quad, this->hessians_quad, this->scratch_data, - evaluate_values, evaluate_gradients, evaluate_hessians); - } - else if (fe_degree >= 0 && - this->data->element_type == internal::MatrixFreeFunctions::tensor_symmetric) - { - internal::FEEvaluationImpl - ::evaluate(*this->data, &this->values_dofs[0], this->values_quad, - this->gradients_quad, this->hessians_quad, this->scratch_data, - evaluate_values, evaluate_gradients, evaluate_hessians); - } - else if (this->data->element_type == internal::MatrixFreeFunctions::tensor_symmetric_plus_dg0) - { - internal::FEEvaluationImpl - ::evaluate(*this->data, &this->values_dofs[0], this->values_quad, - this->gradients_quad, this->hessians_quad, this->scratch_data, - evaluate_values, evaluate_gradients, evaluate_hessians); - } - else if (this->data->element_type == internal::MatrixFreeFunctions::truncated_tensor) - { - internal::FEEvaluationImpl - ::evaluate(*this->data, &this->values_dofs[0], this->values_quad, - this->gradients_quad, this->hessians_quad, this->scratch_data, - evaluate_values, evaluate_gradients, evaluate_hessians); - } - else if (fe_degree == -1 || - this->data->element_type == internal::MatrixFreeFunctions::tensor_general) - { - internal::FEEvaluationImpl - ::evaluate(*this->data, &this->values_dofs[0], this->values_quad, - this->gradients_quad, this->hessians_quad, this->scratch_data, - evaluate_values, evaluate_gradients, evaluate_hessians); - } - else - AssertThrow(false, ExcNotImplemented()); + SelectEvaluator + ::evaluate (*this->data, &this->values_dofs[0], this->values_quad, + this->gradients_quad, this->hessians_quad, this->scratch_data, + evaluate_values, evaluate_gradients, evaluate_hessians); #ifdef DEBUG if (evaluate_values == true) @@ -5428,66 +5373,10 @@ FEEvaluation Assert(this->matrix_info != nullptr || this->mapped_geometry->is_initialized(), ExcNotInitialized()); - // Run time selection of algorithm matching the element type. Since some - // template combinations do not work for fe_degree==-1, create safe template - // values for the calls below. - const unsigned int fe_degree_nonnegative = fe_degree != -1 ? fe_degree : 0; - const unsigned int n_q_points_1d_positive = n_q_points_1d > 0 ? n_q_points_1d : 1; - const unsigned int n_q_points_1d_adjusted = fe_degree == -1 ? 0 : n_q_points_1d; - if (fe_degree >= 0 && - fe_degree+1 == n_q_points_1d && - this->data->element_type == internal::MatrixFreeFunctions::tensor_symmetric_collocation) - { - internal::FEEvaluationImplCollocation - ::integrate(*this->data, &this->values_dofs[0], this->values_quad, - this->gradients_quad, this->scratch_data, - integrate_values, integrate_gradients); - } - else if (fe_degree >= 0 && - fe_degree+1 == n_q_points_1d && - this->data->element_type == internal::MatrixFreeFunctions::tensor_symmetric) - { - internal::FEEvaluationImplTransformToCollocation - ::integrate(*this->data, &this->values_dofs[0], this->values_quad, - this->gradients_quad, this->scratch_data, - integrate_values, integrate_gradients); - } - else if (fe_degree >= 0 && - this->data->element_type == internal::MatrixFreeFunctions::tensor_symmetric) - { - internal::FEEvaluationImpl - ::integrate(*this->data, &this->values_dofs[0], this->values_quad, - this->gradients_quad, this->scratch_data, - integrate_values, integrate_gradients); - } - else if (this->data->element_type == internal::MatrixFreeFunctions::tensor_symmetric_plus_dg0) - { - internal::FEEvaluationImpl - ::integrate(*this->data, &this->values_dofs[0], this->values_quad, - this->gradients_quad, this->scratch_data, - integrate_values, integrate_gradients); - } - else if (this->data->element_type == internal::MatrixFreeFunctions::truncated_tensor) - { - internal::FEEvaluationImpl - ::integrate(*this->data, &this->values_dofs[0], this->values_quad, - this->gradients_quad, this->scratch_data, - integrate_values, integrate_gradients); - } - else if (fe_degree == -1 || - this->data->element_type == internal::MatrixFreeFunctions::tensor_general) - { - internal::FEEvaluationImpl - ::integrate(*this->data, &this->values_dofs[0], this->values_quad, - this->gradients_quad, this->scratch_data, - integrate_values, integrate_gradients); - } - else - AssertThrow(false, ExcNotImplemented()); + SelectEvaluator + ::integrate (*this->data, &this->values_dofs[0], this->values_quad, + this->gradients_quad, this->scratch_data, + integrate_values, integrate_gradients); #ifdef DEBUG this->dof_values_initialized = true; -- 2.39.5