From: Martin Kronbichler Date: Thu, 17 Sep 2020 14:19:49 +0000 (+0200) Subject: Implement factory class for FEEvaluation and FEFaceEvaluation X-Git-Tag: v9.3.0-rc1~1087^2~8 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dc4efca4a50a7469397028295cdea8e4d5db5b49;p=dealii.git Implement factory class for FEEvaluation and FEFaceEvaluation --- diff --git a/include/deal.II/matrix_free/evaluation_kernels.h b/include/deal.II/matrix_free/evaluation_kernels.h index 8f40cb85d3..cbe9fe3b4f 100644 --- a/include/deal.II/matrix_free/evaluation_kernels.h +++ b/include/deal.II/matrix_free/evaluation_kernels.h @@ -1500,8 +1500,7 @@ namespace internal hessians_quad, scratch_data); } - else if (shape_info.element_type == - internal::MatrixFreeFunctions::tensor_general) + else { internal::FEEvaluationImpl< internal::MatrixFreeFunctions::tensor_general, @@ -1517,8 +1516,6 @@ namespace internal hessians_quad, scratch_data); } - else - AssertThrow(false, ExcNotImplemented()); return false; } @@ -1649,8 +1646,7 @@ namespace internal scratch_data, sum_into_values_array); } - else if (shape_info.element_type == - internal::MatrixFreeFunctions::tensor_general) + else { internal::FEEvaluationImpl< internal::MatrixFreeFunctions::tensor_general, @@ -1666,8 +1662,6 @@ namespace internal scratch_data, sum_into_values_array); } - else - AssertThrow(false, ExcNotImplemented()); return false; } diff --git a/include/deal.II/matrix_free/evaluation_template_factory.h b/include/deal.II/matrix_free/evaluation_template_factory.h new file mode 100644 index 0000000000..a7484b2f25 --- /dev/null +++ b/include/deal.II/matrix_free/evaluation_template_factory.h @@ -0,0 +1,180 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2020 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.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +#ifndef dealii_matrix_free_evaluation_template_factory_h +#define dealii_matrix_free_evaluation_template_factory_h + + +#include + +#include +#include +#include + + +DEAL_II_NAMESPACE_OPEN + + +template +class FEEvaluationBaseData; + + +namespace internal +{ + template > + struct FEEvaluationFactory + { + static void + evaluate( + const unsigned int n_components, + const EvaluationFlags::EvaluationFlags evaluation_flag, + const MatrixFreeFunctions::ShapeInfo &shape_info, + VectorizedArrayType *values_dofs_actual, + VectorizedArrayType *values_quad, + VectorizedArrayType *gradients_quad, + VectorizedArrayType *hessians_quad, + VectorizedArrayType *scratch_data); + + static void + integrate( + const unsigned int n_components, + const EvaluationFlags::EvaluationFlags integration_flag, + const MatrixFreeFunctions::ShapeInfo &shape_info, + VectorizedArrayType *values_dofs_actual, + VectorizedArrayType *values_quad, + VectorizedArrayType *gradients_quad, + VectorizedArrayType *scratch_data, + const bool sum_into_values_array); + }; + + + + template > + struct FEFaceEvaluationFactory + { + static void + evaluate(const unsigned int n_components, + const MatrixFreeFunctions::ShapeInfo &data, + const VectorizedArrayType * values_array, + VectorizedArrayType * values_quad, + VectorizedArrayType * gradients_quad, + VectorizedArrayType * scratch_data, + const bool evaluate_values, + const bool evaluate_gradients, + const unsigned int face_no, + const unsigned int subface_index, + const unsigned int face_orientation, + const Table<2, unsigned int> &orientation_map); + + static void + integrate(const unsigned int n_components, + const MatrixFreeFunctions::ShapeInfo &data, + VectorizedArrayType * values_array, + VectorizedArrayType * values_quad, + VectorizedArrayType * gradients_quad, + VectorizedArrayType * scratch_data, + const bool integrate_values, + const bool integrate_gradients, + const unsigned int face_no, + const unsigned int subface_index, + const unsigned int face_orientation, + const Table<2, unsigned int> &orientation_map); + + template + static bool + gather_evaluate( + const unsigned int n_components, + const Number * src_ptr, + const MatrixFreeFunctions::ShapeInfo &data, + const MatrixFreeFunctions::DoFInfo & dof_info, + VectorizedArrayType * values_quad, + VectorizedArrayType * gradients_quad, + VectorizedArrayType * scratch_data, + const bool evaluate_values, + const bool evaluate_gradients, + const unsigned int active_fe_index, + const unsigned int first_selected_component, + const std::array cells, + const std::array face_nos, + const unsigned int subface_index, + const MatrixFreeFunctions::DoFInfo::DoFAccessIndex dof_access_index, + const std::array face_orientations, + const Table<2, unsigned int> & orientation_map); + + template + static bool + integrate_scatter( + const unsigned int n_components, + Number * dst_ptr, + const MatrixFreeFunctions::ShapeInfo &data, + const MatrixFreeFunctions::DoFInfo & dof_info, + VectorizedArrayType * values_array, + VectorizedArrayType * values_quad, + VectorizedArrayType * gradients_quad, + VectorizedArrayType * scratch_data, + const bool integrate_values, + const bool integrate_gradients, + const unsigned int active_fe_index, + const unsigned int first_selected_component, + const std::array cells, + const std::array face_nos, + const unsigned int subface_index, + const MatrixFreeFunctions::DoFInfo::DoFAccessIndex dof_access_index, + const std::array face_orientations, + const Table<2, unsigned int> & orientation_map); + }; + + + + template > + struct CellwiseInverseMassFactory + { + static void + apply(const unsigned int n_components, + const unsigned int fe_degree, + const FEEvaluationBaseData + & fe_eval, + const VectorizedArrayType *in_array, + VectorizedArrayType * out_array); + + static void + apply(const unsigned int n_components, + const unsigned int fe_degree, + const AlignedVector &inverse_shape, + const AlignedVector &inverse_coefficients, + const VectorizedArrayType * in_array, + VectorizedArrayType * out_array); + + static void + transform_from_q_points_to_basis( + const unsigned int n_components, + const unsigned int fe_degree, + const AlignedVector &inverse_shape, + const VectorizedArrayType * in_array, + VectorizedArrayType * out_array); + }; + +} // end of namespace internal + +DEAL_II_NAMESPACE_CLOSE + +#endif diff --git a/include/deal.II/matrix_free/evaluation_template_factory.templates.h b/include/deal.II/matrix_free/evaluation_template_factory.templates.h new file mode 100644 index 0000000000..f89eee257d --- /dev/null +++ b/include/deal.II/matrix_free/evaluation_template_factory.templates.h @@ -0,0 +1,367 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2020 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.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +#ifndef dealii_matrix_free_evaluation_template_factory_templates_h +#define dealii_matrix_free_evaluation_template_factory_templates_h + + +#include + +#include +#include +#include +#include + +#ifndef FE_EVAL_FACTORY_DEGREE_MAX +# define FE_EVAL_FACTORY_DEGREE_MAX 6 +#endif + +DEAL_II_NAMESPACE_OPEN + +namespace internal +{ + template + bool + instantiation_helper_run(const unsigned int given_degree, + const unsigned int n_q_points_1d, + Args &... args) + { + if (given_degree == degree) + { + if (n_q_points_1d == degree + 1) + return EvaluatorType::template run(args...); + else if (n_q_points_1d == degree + 2) + return EvaluatorType::template run(args...); + else if (n_q_points_1d == degree) + return EvaluatorType::template run(args...); + else + // slow path + return EvaluatorType::template run<-1, 0>(args...); + } + else if (degree < FE_EVAL_FACTORY_DEGREE_MAX) + return instantiation_helper_run< + (degree < FE_EVAL_FACTORY_DEGREE_MAX ? degree + 1 : degree), + EvaluatorType>(given_degree, n_q_points_1d, args...); + else + // slow path + return EvaluatorType::template run<-1, 0>(args...); + } + + + + template + void + FEEvaluationFactory::evaluate( + const unsigned int n_components, + const EvaluationFlags::EvaluationFlags evaluation_flag, + const MatrixFreeFunctions::ShapeInfo &shape_info, + VectorizedArrayType *values_dofs_actual, + VectorizedArrayType *values_quad, + VectorizedArrayType *gradients_quad, + VectorizedArrayType *hessians_quad, + VectorizedArrayType *scratch_data) + { + instantiation_helper_run< + 1, + FEEvaluationImplEvaluateSelector>( + shape_info.data[0].fe_degree, + shape_info.data[0].n_q_points_1d, + n_components, + evaluation_flag, + shape_info, + values_dofs_actual, + values_quad, + gradients_quad, + hessians_quad, + scratch_data); + } + + + + template + void + FEEvaluationFactory::integrate( + const unsigned int n_components, + const EvaluationFlags::EvaluationFlags integration_flag, + const MatrixFreeFunctions::ShapeInfo &shape_info, + VectorizedArrayType *values_dofs_actual, + VectorizedArrayType *values_quad, + VectorizedArrayType *gradients_quad, + VectorizedArrayType *scratch_data, + const bool sum_into_values_array) + { + instantiation_helper_run< + 1, + FEEvaluationImplIntegrateSelector>( + shape_info.data[0].fe_degree, + shape_info.data[0].n_q_points_1d, + n_components, + integration_flag, + shape_info, + values_dofs_actual, + values_quad, + gradients_quad, + scratch_data, + sum_into_values_array); + } + + + + template + void + FEFaceEvaluationFactory::evaluate( + const unsigned int n_components, + const MatrixFreeFunctions::ShapeInfo &data, + const VectorizedArrayType * values_array, + VectorizedArrayType * values_quad, + VectorizedArrayType * gradients_quad, + VectorizedArrayType * scratch_data, + const bool evaluate_values, + const bool evaluate_gradients, + const unsigned int face_no, + const unsigned int subface_index, + const unsigned int face_orientation, + const Table<2, unsigned int> &orientation_map) + { + instantiation_helper_run< + 1, + FEFaceEvaluationImplEvaluateSelector>( + data.data[0].fe_degree, + data.data[0].n_q_points_1d, + n_components, + data, + values_array, + values_quad, + gradients_quad, + scratch_data, + evaluate_values, + evaluate_gradients, + face_no, + subface_index, + face_orientation, + orientation_map); + } + + + + template + void + FEFaceEvaluationFactory::integrate( + const unsigned int n_components, + const MatrixFreeFunctions::ShapeInfo &data, + VectorizedArrayType * values_array, + VectorizedArrayType * values_quad, + VectorizedArrayType * gradients_quad, + VectorizedArrayType * scratch_data, + const bool integrate_values, + const bool integrate_gradients, + const unsigned int face_no, + const unsigned int subface_index, + const unsigned int face_orientation, + const Table<2, unsigned int> &orientation_map) + { + instantiation_helper_run< + 1, + FEFaceEvaluationImplIntegrateSelector>( + data.data[0].fe_degree, + data.data[0].n_q_points_1d, + n_components, + data, + values_array, + values_quad, + gradients_quad, + scratch_data, + integrate_values, + integrate_gradients, + face_no, + subface_index, + face_orientation, + orientation_map); + } + + + + template + template + bool + FEFaceEvaluationFactory::gather_evaluate( + const unsigned int n_components, + const Number * src_ptr, + const MatrixFreeFunctions::ShapeInfo &data, + const MatrixFreeFunctions::DoFInfo & dof_info, + VectorizedArrayType * values_quad, + VectorizedArrayType * gradients_quad, + VectorizedArrayType * scratch_data, + const bool evaluate_values, + const bool evaluate_gradients, + const unsigned int active_fe_index, + const unsigned int first_selected_component, + const std::array cells, + const std::array face_nos, + const unsigned int subface_index, + const MatrixFreeFunctions::DoFInfo::DoFAccessIndex dof_access_index, + const std::array face_orientations, + const Table<2, unsigned int> & orientation_map) + { + return instantiation_helper_run< + 1, + FEFaceEvaluationImplGatherEvaluateSelector>( + data.data[0].fe_degree, + data.data[0].n_q_points_1d, + n_components, + src_ptr, + data, + dof_info, + values_quad, + gradients_quad, + scratch_data, + evaluate_values, + evaluate_gradients, + active_fe_index, + first_selected_component, + cells, + face_nos, + subface_index, + dof_access_index, + face_orientations, + orientation_map); + } + + + + template + template + bool + FEFaceEvaluationFactory::integrate_scatter( + const unsigned int n_components, + Number * dst_ptr, + const MatrixFreeFunctions::ShapeInfo &data, + const MatrixFreeFunctions::DoFInfo & dof_info, + VectorizedArrayType * values_array, + VectorizedArrayType * values_quad, + VectorizedArrayType * gradients_quad, + VectorizedArrayType * scratch_data, + const bool integrate_values, + const bool integrate_gradients, + const unsigned int active_fe_index, + const unsigned int first_selected_component, + const std::array cells, + const std::array face_nos, + const unsigned int subface_index, + const MatrixFreeFunctions::DoFInfo::DoFAccessIndex dof_access_index, + const std::array face_orientations, + const Table<2, unsigned int> & orientation_map) + { + return instantiation_helper_run< + 1, + FEFaceEvaluationImplIntegrateScatterSelector>( + data.data[0].fe_degree, + data.data[0].n_q_points_1d, + n_components, + dst_ptr, + data, + dof_info, + values_array, + values_quad, + gradients_quad, + scratch_data, + integrate_values, + integrate_gradients, + active_fe_index, + first_selected_component, + cells, + face_nos, + subface_index, + dof_access_index, + face_orientations, + orientation_map); + } + + + + template + void + CellwiseInverseMassFactory::apply( + const unsigned int n_components, + const unsigned int fe_degree, + const FEEvaluationBaseData + & fe_eval, + const VectorizedArrayType *in_array, + VectorizedArrayType * out_array) + { + instantiation_helper_run< + 1, + CellwiseInverseMassMatrixImplBasic>( + fe_degree, fe_degree + 1, n_components, fe_eval, in_array, out_array); + } + + + + template + void + CellwiseInverseMassFactory::apply( + const unsigned int n_components, + const unsigned int fe_degree, + const AlignedVector &inverse_shape, + const AlignedVector &inverse_coefficients, + const VectorizedArrayType * in_array, + VectorizedArrayType * out_array) + { + instantiation_helper_run< + 1, + CellwiseInverseMassMatrixImplFlexible>( + fe_degree, + fe_degree + 1, + n_components, + inverse_shape, + inverse_coefficients, + in_array, + out_array); + } + + + + template + void + CellwiseInverseMassFactory:: + transform_from_q_points_to_basis( + const unsigned int n_components, + const unsigned int fe_degree, + const AlignedVector &inverse_shape, + const VectorizedArrayType * in_array, + VectorizedArrayType * out_array) + { + instantiation_helper_run< + 1, + CellwiseInverseMassMatrixImplTransformFromQPoints>( + fe_degree, + fe_degree + 1, + n_components, + inverse_shape, + in_array, + out_array); + } + +} // end of namespace internal + +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 49dce2fa12..17c444436e 100644 --- a/include/deal.II/matrix_free/fe_evaluation.h +++ b/include/deal.II/matrix_free/fe_evaluation.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -85,10 +86,7 @@ class FEEvaluation; * * @ingroup matrixfree */ -template > +template class FEEvaluationBaseData { static_assert( @@ -7405,15 +7403,26 @@ FEEvaluation::evaluate( - n_components, - evaluation_flags, - *this->data, - const_cast(values_array), - this->values_quad, - this->gradients_quad, - this->hessians_quad, - this->scratch_data); + if (fe_degree > -1) + SelectEvaluator:: + evaluate(n_components, + evaluation_flags, + *this->data, + const_cast(values_array), + this->values_quad, + this->gradients_quad, + this->hessians_quad, + this->scratch_data); + else + internal::FEEvaluationFactory::evaluate( + n_components, + evaluation_flags, + *this->data, + const_cast(values_array), + this->values_quad, + this->gradients_quad, + this->hessians_quad, + this->scratch_data); # ifdef DEBUG if (evaluation_flags & EvaluationFlags::values) @@ -7595,15 +7604,27 @@ namespace internal dof_info->component_dof_indices_offset[active_fe_index] [first_selected_component] * VectorizedArrayType::size()); - SelectEvaluator:: - integrate(n_components, - integration_flag, - *data, - vec_values, - values_quad, - gradients_quad, - scratch_data, - true); + if (fe_degree > -1) + SelectEvaluator:: + integrate(n_components, + integration_flag, + *data, + vec_values, + values_quad, + gradients_quad, + scratch_data, + true); + else + FEEvaluationFactory::integrate( + n_components, + integration_flag, + *data, + vec_values, + values_quad, + gradients_quad, + scratch_data, + true); + return true; } @@ -7680,6 +7701,8 @@ namespace internal } } // namespace internal + + template :: - integrate(n_components, - integration_flag, - *this->data, - values_array, - this->values_quad, - this->gradients_quad, - this->scratch_data, - false); + if (fe_degree > -1) + SelectEvaluator:: + integrate(n_components, + integration_flag, + *this->data, + values_array, + this->values_quad, + this->gradients_quad, + this->scratch_data, + false); + else + internal::FEEvaluationFactory::integrate( + n_components, + integration_flag, + *this->data, + values_array, + this->values_quad, + this->gradients_quad, + this->scratch_data, + false); # ifdef DEBUG this->dof_values_initialized = true; @@ -8187,20 +8221,37 @@ FEFaceEvaluation:: - template run( - n_components, - *this->data, - values_array, - this->begin_values(), - this->begin_gradients(), - this->scratch_data, - evaluation_flag & EvaluationFlags::values, - evaluation_flag & EvaluationFlags::gradients, - this->face_no, - this->subface_index, - this->face_orientation, - this->mapping_data->descriptor[this->active_fe_index].face_orientations); + if (fe_degree > -1) + internal::FEFaceEvaluationImplEvaluateSelector:: + template run( + n_components, + *this->data, + values_array, + this->begin_values(), + this->begin_gradients(), + this->scratch_data, + evaluation_flag & EvaluationFlags::values, + evaluation_flag & EvaluationFlags::gradients, + this->face_no, + this->subface_index, + this->face_orientation, + this->mapping_data->descriptor[this->active_fe_index] + .face_orientations); + else + internal::FEFaceEvaluationFactory:: + evaluate(n_components, + *this->data, + values_array, + this->begin_values(), + this->begin_gradients(), + this->scratch_data, + evaluation_flag & EvaluationFlags::values, + evaluation_flag & EvaluationFlags::gradients, + this->face_no, + this->subface_index, + this->face_orientation, + this->mapping_data->descriptor[this->active_fe_index] + .face_orientations); # ifdef DEBUG if (evaluation_flag & EvaluationFlags::values) @@ -8313,20 +8364,37 @@ FEFaceEvaluation:: - template run( - n_components, - *this->data, - values_array, - this->begin_values(), - this->begin_gradients(), - this->scratch_data, - evaluation_flag & EvaluationFlags::values, - evaluation_flag & EvaluationFlags::gradients, - this->face_no, - this->subface_index, - this->face_orientation, - this->mapping_data->descriptor[this->active_fe_index].face_orientations); + if (fe_degree > -1) + internal::FEFaceEvaluationImplIntegrateSelector:: + template run( + n_components, + *this->data, + values_array, + this->begin_values(), + this->begin_gradients(), + this->scratch_data, + evaluation_flag & EvaluationFlags::values, + evaluation_flag & EvaluationFlags::gradients, + this->face_no, + this->subface_index, + this->face_orientation, + this->mapping_data->descriptor[this->active_fe_index] + .face_orientations); + else + internal::FEFaceEvaluationFactory:: + integrate(n_components, + *this->data, + values_array, + this->begin_values(), + this->begin_gradients(), + this->scratch_data, + evaluation_flag & EvaluationFlags::values, + evaluation_flag & EvaluationFlags::gradients, + this->face_no, + this->subface_index, + this->face_orientation, + this->mapping_data->descriptor[this->active_fe_index] + .face_orientations); } @@ -8417,29 +8485,52 @@ FEFaceEvaluation:: - template run( - n_components, - internal::get_beginning(input_vector), - *this->data, - *this->dof_info, - this->begin_values(), - this->begin_gradients(), - this->scratch_data, - evaluation_flag & EvaluationFlags::values, - evaluation_flag & EvaluationFlags::gradients, - this->active_fe_index, - this->first_selected_component, - std::array{{this->cell}}, - std::array{{this->face_no}}, - this->subface_index, - this->dof_access_index, - std::array{{this->face_orientation}}, - this->mapping_data->descriptor[this->active_fe_index] - .face_orientations); + if (fe_degree > -1) + return internal::FEFaceEvaluationImplGatherEvaluateSelector< + dim, + Number, + VectorizedArrayType>:: + template run( + n_components, + internal::get_beginning(input_vector), + *this->data, + *this->dof_info, + this->begin_values(), + this->begin_gradients(), + this->scratch_data, + evaluation_flag & EvaluationFlags::values, + evaluation_flag & EvaluationFlags::gradients, + this->active_fe_index, + this->first_selected_component, + std::array{{this->cell}}, + std::array{{this->face_no}}, + this->subface_index, + this->dof_access_index, + std::array{{this->face_orientation}}, + this->mapping_data->descriptor[this->active_fe_index] + .face_orientations); + else + return internal:: + FEFaceEvaluationFactory:: + gather_evaluate( + n_components, + internal::get_beginning(input_vector), + *this->data, + *this->dof_info, + this->begin_values(), + this->begin_gradients(), + this->scratch_data, + evaluation_flag & EvaluationFlags::values, + evaluation_flag & EvaluationFlags::gradients, + this->active_fe_index, + this->first_selected_component, + std::array{{this->cell}}, + std::array{{this->face_no}}, + this->subface_index, + this->dof_access_index, + std::array{{this->face_orientation}}, + this->mapping_data->descriptor[this->active_fe_index] + .face_orientations); } }; @@ -8509,36 +8600,66 @@ FEFaceEvaluationis_interior_face == false) == false, ExcNotImplemented()); - if (!internal::FEFaceEvaluationImplIntegrateScatterSelector< - dim, - Number, - VectorizedArrayType>:: - template run( - n_components, - internal::get_beginning(destination), - *this->data, - *this->dof_info, - this->begin_dof_values(), - this->begin_values(), - this->begin_gradients(), - this->scratch_data, - evaluation_flag & EvaluationFlags::values, - evaluation_flag & EvaluationFlags::gradients, - this->active_fe_index, - this->first_selected_component, - std::array{{this->cell}}, - std::array{{this->face_no}}, - this->subface_index, - this->dof_access_index, - std::array{{this->face_orientation}}, - this->mapping_data->descriptor[this->active_fe_index] - .face_orientations)) + if (fe_degree > -1) { - // if we arrive here, writing into the destination vector did not succeed - // because some of the assumptions in integrate_scatter were not - // fulfilled (e.g. an element or degree that does not support direct - // writing), so we must do it here - this->distribute_local_to_global(destination); + if (!internal::FEFaceEvaluationImplIntegrateScatterSelector< + dim, + Number, + VectorizedArrayType>:: + template run( + n_components, + internal::get_beginning(destination), + *this->data, + *this->dof_info, + this->begin_dof_values(), + this->begin_values(), + this->begin_gradients(), + this->scratch_data, + evaluation_flag & EvaluationFlags::values, + evaluation_flag & EvaluationFlags::gradients, + this->active_fe_index, + this->first_selected_component, + std::array{{this->cell}}, + std::array{{this->face_no}}, + this->subface_index, + this->dof_access_index, + std::array{{this->face_orientation}}, + this->mapping_data->descriptor[this->active_fe_index] + .face_orientations)) + { + // if we arrive here, writing into the destination vector did not + // succeed because some of the assumptions in integrate_scatter were + // not fulfilled (e.g. an element or degree that does not support + // direct writing), so we must do it here + this->distribute_local_to_global(destination); + } + } + else + { + if (!internal::FEFaceEvaluationFactory:: + integrate_scatter( + n_components, + internal::get_beginning(destination), + *this->data, + *this->dof_info, + this->begin_dof_values(), + this->begin_values(), + this->begin_gradients(), + this->scratch_data, + evaluation_flag & EvaluationFlags::values, + evaluation_flag & EvaluationFlags::gradients, + this->active_fe_index, + this->first_selected_component, + std::array{{this->cell}}, + std::array{{this->face_no}}, + this->subface_index, + this->dof_access_index, + std::array{{this->face_orientation}}, + this->mapping_data->descriptor[this->active_fe_index] + .face_orientations)) + { + this->distribute_local_to_global(destination); + } } } diff --git a/source/matrix_free/CMakeLists.txt b/source/matrix_free/CMakeLists.txt index 348e4cf6c7..9249b5dd6f 100644 --- a/source/matrix_free/CMakeLists.txt +++ b/source/matrix_free/CMakeLists.txt @@ -18,6 +18,12 @@ INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR}) SET(_src dof_info.cc evaluation_selector.cc + evaluation_template_factory.cc + evaluation_template_factory_inst2.cc + evaluation_template_factory_inst3.cc + evaluation_template_factory_inst4.cc + evaluation_template_factory_inst5.cc + evaluation_template_factory_inst6.cc mapping_info.cc mapping_info_inst2.cc mapping_info_inst3.cc @@ -28,6 +34,7 @@ SET(_src SET(_inst evaluation_selector.inst.in + evaluation_template_factory.inst.in mapping_info.inst.in matrix_free.inst.in shape_info.inst.in diff --git a/source/matrix_free/evaluation_template_factory.cc b/source/matrix_free/evaluation_template_factory.cc new file mode 100644 index 0000000000..6bad4875e2 --- /dev/null +++ b/source/matrix_free/evaluation_template_factory.cc @@ -0,0 +1,30 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2020 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.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +#define FE_EVAL_FACTORY_DEGREE_MAX 6 + +#include + +DEAL_II_NAMESPACE_OPEN + +#define SPLIT_INSTANTIATIONS_COUNT 6 +#ifndef SPLIT_INSTANTIATIONS_INDEX +# define SPLIT_INSTANTIATIONS_INDEX 0 +#endif + +#include "evaluation_template_factory.inst" + +DEAL_II_NAMESPACE_CLOSE diff --git a/source/matrix_free/evaluation_template_factory.inst.in b/source/matrix_free/evaluation_template_factory.inst.in new file mode 100644 index 0000000000..a0019c9c57 --- /dev/null +++ b/source/matrix_free/evaluation_template_factory.inst.in @@ -0,0 +1,82 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2020 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.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +for (deal_II_dimension : DIMENSIONS; + deal_II_scalar_vectorized : REAL_SCALARS_VECTORIZED) + { + template struct dealii::internal::FEEvaluationFactory< + deal_II_dimension, + deal_II_scalar_vectorized::value_type, + deal_II_scalar_vectorized>; + + template struct dealii::internal::FEFaceEvaluationFactory< + deal_II_dimension, + deal_II_scalar_vectorized::value_type, + deal_II_scalar_vectorized>; + + // inverse mass + template struct dealii::internal::CellwiseInverseMassFactory< + deal_II_dimension, + deal_II_scalar_vectorized::value_type, + deal_II_scalar_vectorized>; + + template bool dealii::internal::FEFaceEvaluationFactory< + deal_II_dimension, + deal_II_scalar_vectorized::value_type, + deal_II_scalar_vectorized>:: + gather_evaluate<1>( + const unsigned int, + const deal_II_scalar_vectorized::value_type *, + const MatrixFreeFunctions::ShapeInfo &, + const MatrixFreeFunctions::DoFInfo &, + deal_II_scalar_vectorized *, + deal_II_scalar_vectorized *, + deal_II_scalar_vectorized *, + const bool, + const bool, + const unsigned int, + const unsigned int, + const std::array, + const std::array, + const unsigned int, + const MatrixFreeFunctions::DoFInfo::DoFAccessIndex, + const std::array, + const Table<2, unsigned int> &); + + template bool dealii::internal::FEFaceEvaluationFactory< + deal_II_dimension, + deal_II_scalar_vectorized::value_type, + deal_II_scalar_vectorized>:: + integrate_scatter<1>( + const unsigned int, + deal_II_scalar_vectorized::value_type *, + const MatrixFreeFunctions::ShapeInfo &, + const MatrixFreeFunctions::DoFInfo &, + deal_II_scalar_vectorized *, + deal_II_scalar_vectorized *, + deal_II_scalar_vectorized *, + deal_II_scalar_vectorized *, + const bool, + const bool, + const unsigned int, + const unsigned int, + const std::array, + const std::array, + const unsigned int, + const MatrixFreeFunctions::DoFInfo::DoFAccessIndex, + const std::array, + const Table<2, unsigned int> &); + } diff --git a/source/matrix_free/evaluation_template_factory_inst2.cc b/source/matrix_free/evaluation_template_factory_inst2.cc new file mode 100644 index 0000000000..3c6c193da3 --- /dev/null +++ b/source/matrix_free/evaluation_template_factory_inst2.cc @@ -0,0 +1,17 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2020 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.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + +#define SPLIT_INSTANTIATIONS_INDEX 1 +#include "evaluation_template_factory.cc" diff --git a/source/matrix_free/evaluation_template_factory_inst3.cc b/source/matrix_free/evaluation_template_factory_inst3.cc new file mode 100644 index 0000000000..ddf1b77a72 --- /dev/null +++ b/source/matrix_free/evaluation_template_factory_inst3.cc @@ -0,0 +1,17 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2020 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.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + +#define SPLIT_INSTANTIATIONS_INDEX 2 +#include "evaluation_template_factory.cc" diff --git a/source/matrix_free/evaluation_template_factory_inst4.cc b/source/matrix_free/evaluation_template_factory_inst4.cc new file mode 100644 index 0000000000..5f76e3a956 --- /dev/null +++ b/source/matrix_free/evaluation_template_factory_inst4.cc @@ -0,0 +1,17 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2020 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.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + +#define SPLIT_INSTANTIATIONS_INDEX 3 +#include "evaluation_template_factory.cc" diff --git a/source/matrix_free/evaluation_template_factory_inst5.cc b/source/matrix_free/evaluation_template_factory_inst5.cc new file mode 100644 index 0000000000..af122d3e7d --- /dev/null +++ b/source/matrix_free/evaluation_template_factory_inst5.cc @@ -0,0 +1,17 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2020 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.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + +#define SPLIT_INSTANTIATIONS_INDEX 4 +#include "evaluation_template_factory.cc" diff --git a/source/matrix_free/evaluation_template_factory_inst6.cc b/source/matrix_free/evaluation_template_factory_inst6.cc new file mode 100644 index 0000000000..8cc50063b0 --- /dev/null +++ b/source/matrix_free/evaluation_template_factory_inst6.cc @@ -0,0 +1,17 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2020 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.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + +#define SPLIT_INSTANTIATIONS_INDEX 5 +#include "evaluation_template_factory.cc"