From 44ee1b2b51677d0c2da797037096741f7454a496 Mon Sep 17 00:00:00 2001 From: Timo Heister Date: Tue, 26 May 2020 12:12:43 -0400 Subject: [PATCH] matrix-free: do not use bool args - replace evaluate*, integrate* calls in FEEvaluation --- examples/step-37/step-37.cc | 4 +- include/deal.II/matrix_free/fe_evaluation.h | 675 ++++++++++++++++++-- 2 files changed, 621 insertions(+), 58 deletions(-) diff --git a/examples/step-37/step-37.cc b/examples/step-37/step-37.cc index e7ecb56bad..3bbabfad07 100644 --- a/examples/step-37/step-37.cc +++ b/examples/step-37/step-37.cc @@ -403,10 +403,10 @@ namespace Step37 phi.reinit(cell); phi.read_dof_values(src); - phi.evaluate(false, true); + phi.evaluate(EvaluationFlags::gradients); for (unsigned int q = 0; q < phi.n_q_points; ++q) phi.submit_gradient(coefficient(cell, q) * phi.get_gradient(q), q); - phi.integrate(false, true); + phi.integrate(EvaluationFlags::gradients); phi.distribute_local_to_global(dst); } } diff --git a/include/deal.II/matrix_free/fe_evaluation.h b/include/deal.II/matrix_free/fe_evaluation.h index a3a2684c26..28f7561ba9 100644 --- a/include/deal.II/matrix_free/fe_evaluation.h +++ b/include/deal.II/matrix_free/fe_evaluation.h @@ -57,6 +57,99 @@ template operator | would be an + * integer which would in turn trigger a compiler warning when we tried to + * assign it to an object of type UpdateFlags. + * + * @ref type + */ + inline EvaluationFlags + operator|(const EvaluationFlags f1, const EvaluationFlags f2) + { + return static_cast(static_cast(f1) | + static_cast(f2)); + } + + + + /** + * Global operator which sets the bits from the second argument also in the + * first one. + * + * @ref type + */ + inline EvaluationFlags & + operator|=(EvaluationFlags &f1, const EvaluationFlags f2) + { + f1 = f1 | f2; + return f1; + } + + + /** + * Global operator which returns an object in which all bits are set which are + * set in the first as well as the second argument. This operator exists since + * if it did not then the result of the bit-and operator & would be + * an integer which would in turn trigger a compiler warning when we tried to + * assign it to an object of type UpdateFlags. + * + * @ref UpdateFlags + */ + inline EvaluationFlags operator&(const EvaluationFlags f1, + const EvaluationFlags f2) + { + return static_cast(static_cast(f1) & + static_cast(f2)); + } + + + /** + * Global operator which clears all the bits in the first argument if they are + * not also set in the second argument. + * + * @ref UpdateFlags + */ + inline EvaluationFlags & + operator&=(EvaluationFlags &f1, const EvaluationFlags f2) + { + f1 = f1 & f2; + return f1; + } + +} // namespace EvaluationFlags + /** * This is the base class for the FEEvaluation classes. This class is a base * class and needs usually not be called in user code. It does not have any @@ -2509,6 +2602,14 @@ public: * manually). */ void + evaluate(const EvaluationFlags::EvaluationFlags evaluation_flag); + + /** + * Like above but with separate bool flags. + * @deprecated use evaluate() with the EvaluationFlags argument. + */ + DEAL_II_DEPRECATED + void evaluate(const bool evaluate_values, const bool evaluate_gradients, const bool evaluate_hessians = false); @@ -2526,6 +2627,15 @@ public: * useful information (unless these values have been set manually). */ void + evaluate(const VectorizedArrayType * values_array, + const EvaluationFlags::EvaluationFlags evaluation_flag); + + /** + * Like above but using separate bool flags. + * @deprecated use evaluate() with the EvaluationFlags argument. + */ + DEAL_II_DEPRECATED + void evaluate(const VectorizedArrayType *values_array, const bool evaluate_values, const bool evaluate_gradients, @@ -2546,6 +2656,14 @@ public: */ template void + gather_evaluate(const VectorType & input_vector, + const EvaluationFlags::EvaluationFlags evaluation_flag); + + /** + * @deprecated Please use the gather_evaluate() function with the EvaluationFlags argument. + */ + template + DEAL_II_DEPRECATED void gather_evaluate(const VectorType &input_vector, const bool evaluate_values, const bool evaluate_gradients, @@ -2562,6 +2680,13 @@ public: * distribute_local_to_global() or set_dof_values() methods). */ void + integrate(const EvaluationFlags::EvaluationFlags integration_flag); + + + /** + * @deprecated Please use the integrate() function with the EvaluationFlags argument. + */ + DEAL_II_DEPRECATED void integrate(const bool integrate_values, const bool integrate_gradients); /** @@ -2576,6 +2701,14 @@ public: * internal data structures behind begin_dof_values(). */ void + integrate(const EvaluationFlags::EvaluationFlags integration_flag, + VectorizedArrayType * values_array); + + /** + * @deprecated Please use the integrate() function with the EvaluationFlags argument. + */ + DEAL_II_DEPRECATED + void integrate(const bool integrate_values, const bool integrate_gradients, VectorizedArrayType *values_array); @@ -2595,6 +2728,14 @@ public: */ template void + integrate_scatter(const EvaluationFlags::EvaluationFlags evaluation_flag, + VectorType & output_vector); + + /** + * @deprecated Please use the integrate_scatter() function with the EvaluationFlags argument. + */ + template + DEAL_II_DEPRECATED void integrate_scatter(const bool integrate_values, const bool integrate_gradients, VectorType &output_vector); @@ -2849,6 +2990,13 @@ public: * accessing the internal data pointers). */ void + evaluate(const EvaluationFlags::EvaluationFlags evaluation_flag); + + /** + * @deprecated Please use the evaluate() function with the EvaluationFlags argument. + */ + DEAL_II_DEPRECATED + void evaluate(const bool evaluate_values, const bool evaluate_gradients); /** @@ -2864,6 +3012,14 @@ public: * been set manually). */ void + evaluate(const VectorizedArrayType * values_array, + const EvaluationFlags::EvaluationFlags evaluation_flag); + + /** + * @deprecated Please use the evaluate() function with the EvaluationFlags argument. + */ + DEAL_II_DEPRECATED + void evaluate(const VectorizedArrayType *values_array, const bool evaluate_values, const bool evaluate_gradients); @@ -2881,6 +3037,14 @@ public: */ template void + gather_evaluate(const VectorType & input_vector, + const EvaluationFlags::EvaluationFlags evaluation_flag); + + /** + * @deprecated Please use the gather_evaluate() function with the EvaluationFlags argument. + */ + template + DEAL_II_DEPRECATED void gather_evaluate(const VectorType &input_vector, const bool evaluate_values, const bool evaluate_gradients); @@ -2895,6 +3059,13 @@ public: * distribute_local_to_global() or set_dof_values() methods). */ void + integrate(const EvaluationFlags::EvaluationFlags evaluation_flag); + + /** + * @deprecated Please use the integrate() function with the EvaluationFlags argument. + */ + DEAL_II_DEPRECATED + void integrate(const bool integrate_values, const bool integrate_gradients); /** @@ -2906,6 +3077,14 @@ public: * call stores the result of the testing in the given array `values_array`. */ void + integrate(const EvaluationFlags::EvaluationFlags evaluation_flag, + VectorizedArrayType * values_array); + + /** + * @deprecated Please use the integrate() function with the EvaluationFlags argument. + */ + DEAL_II_DEPRECATED + void integrate(const bool integrate_values, const bool integrate_gradients, VectorizedArrayType *values_array); @@ -2923,6 +3102,14 @@ public: */ template void + integrate_scatter(const EvaluationFlags::EvaluationFlags evaluation_flag, + VectorType & output_vector); + + /** + * @deprecated Please use the integrate_scatter() function with the EvaluationFlags argument. + */ + template + DEAL_II_DEPRECATED void integrate_scatter(const bool integrate_values, const bool integrate_gradients, VectorType &output_vector); @@ -6971,6 +7158,29 @@ FEEvaluation +inline void +FEEvaluation:: + evaluate(const EvaluationFlags::EvaluationFlags evaluation_flags) +{ +# ifdef DEBUG + Assert(this->dof_values_initialized == true, + internal::ExcAccessToUninitializedField()); +# endif + evaluate(this->values_dofs[0], evaluation_flags); +} + + template +inline void +FEEvaluation:: + evaluate(const VectorizedArrayType * values_array, + const EvaluationFlags::EvaluationFlags evaluation_flags) +{ + SelectEvaluator:: + evaluate(*this->data, + const_cast(values_array), + this->values_quad[0], + this->gradients_quad[0][0], + this->hessians_quad[0][0], + this->scratch_data, + evaluation_flags & EvaluationFlags::values, + evaluation_flags & EvaluationFlags::gradients, + evaluation_flags & EvaluationFlags::hessians); + +# ifdef DEBUG + if (evaluation_flags & EvaluationFlags::values) + this->values_quad_initialized = true; + if (evaluation_flags & EvaluationFlags::gradients) + this->gradients_quad_initialized = true; + if (evaluation_flags & EvaluationFlags::hessians) + this->hessians_quad_initialized = true; +# endif +} + + + template ::gather_evaluate(const VectorType &input_vector, - const bool evaluate_values, - const bool evaluate_gradients, - const bool evaluate_hessians) + + const bool evaluate_values, + const bool evaluate_gradients, + const bool evaluate_hessians) +{ + const EvaluationFlags::EvaluationFlags flag = + ((evaluate_values) ? EvaluationFlags::values : EvaluationFlags::nothing) | + ((evaluate_gradients) ? EvaluationFlags::gradients : + EvaluationFlags::nothing) | + ((evaluate_hessians) ? EvaluationFlags::hessians : + EvaluationFlags::nothing); + + gather_evaluate(input_vector, flag); +} + +template +template +inline void +FEEvaluation:: + gather_evaluate(const VectorType & input_vector, + const EvaluationFlags::EvaluationFlags evaluation_flag) { // If the index storage is interleaved and contiguous and the vector storage // has the correct alignment, we can directly pass the pointer into the @@ -7066,17 +7347,17 @@ FEEvaluation< VectorizedArrayType::size()); evaluate(vec_values, - evaluate_values, - evaluate_gradients, - evaluate_hessians); + evaluation_flag & EvaluationFlags::values, + evaluation_flag & EvaluationFlags::gradients, + evaluation_flag & EvaluationFlags::hessians); } else { this->read_dof_values(input_vector); evaluate(this->begin_dof_values(), - evaluate_values, - evaluate_gradients, - evaluate_hessians); + evaluation_flag & EvaluationFlags::values, + evaluation_flag & EvaluationFlags::gradients, + evaluation_flag & EvaluationFlags::hessians); } } @@ -7106,6 +7387,30 @@ FEEvaluation +inline void +FEEvaluation:: + integrate(const EvaluationFlags::EvaluationFlags integration_flag) +{ + integrate(integration_flag, this->values_dofs[0]); + +# ifdef DEBUG + this->dof_values_initialized = true; +# endif +} + + + template +inline void +FEEvaluation:: + integrate(const EvaluationFlags::EvaluationFlags integration_flag, + VectorizedArrayType * values_array) +{ +# ifdef DEBUG + if (integration_flag & EvaluationFlags::values) + Assert(this->values_quad_submitted == true, + internal::ExcAccessToUninitializedField()); + if (integration_flag & EvaluationFlags::gradients) + Assert(this->gradients_quad_submitted == true, + internal::ExcAccessToUninitializedField()); +# endif + Assert(this->matrix_info != nullptr || + this->mapped_geometry->is_initialized(), + ExcNotInitialized()); + + Assert( + (integration_flag & + ~(EvaluationFlags::values | EvaluationFlags::gradients)) == 0, + ExcMessage( + "Only EvaluationFlags::values and EvaluationFlags::gradients are supported.")); + + SelectEvaluator::integrate(*this->data, + values_array, + this->values_quad[0], + this->gradients_quad[0][0], + this->scratch_data, + integration_flag & + EvaluationFlags::values, + integration_flag & + EvaluationFlags::gradients, + false); + +# ifdef DEBUG + this->dof_values_initialized = true; +# endif +} + + + template ::integrate_scatter(const bool integrate_values, const bool integrate_gradients, VectorType &destination) +{ + const EvaluationFlags::EvaluationFlags flag = + ((integrate_values) ? EvaluationFlags::values : EvaluationFlags::nothing) | + ((integrate_gradients) ? EvaluationFlags::gradients : + EvaluationFlags::nothing); + + integrate_scatter(flag, destination); +} + + + +template +template +inline void +FEEvaluation:: + integrate_scatter(const EvaluationFlags::EvaluationFlags evaluation_flag, + VectorType & destination) { // If the index storage is interleaved and contiguous and the vector storage // has the correct alignment, we can directly pass the pointer into the @@ -7199,24 +7587,26 @@ FEEvaluation< ->component_dof_indices_offset[this->active_fe_index] [this->first_selected_component] * VectorizedArrayType::size()); - SelectEvaluator::integrate(*this->data, - vec_values, - this->values_quad[0], - this - ->gradients_quad[0][0], - this->scratch_data, - integrate_values, - integrate_gradients, - true); + SelectEvaluator< + dim, + fe_degree, + n_q_points_1d, + n_components, + VectorizedArrayType>::integrate(*this->data, + vec_values, + this->values_quad[0], + this->gradients_quad[0][0], + this->scratch_data, + evaluation_flag & + EvaluationFlags::values, + evaluation_flag & + EvaluationFlags::gradients, + true); } else { - integrate(integrate_values, - integrate_gradients, + integrate(evaluation_flag & EvaluationFlags::values, + evaluation_flag & EvaluationFlags::gradients, this->begin_dof_values()); this->distribute_local_to_global(destination); } @@ -7431,6 +7821,30 @@ FEFaceEvaluation +inline void +FEFaceEvaluation:: + evaluate(const EvaluationFlags::EvaluationFlags evaluation_flag) +{ +# ifdef DEBUG + Assert(this->dof_values_initialized, ExcNotInitialized()); +# endif + + evaluate(this->values_dofs[0], evaluation_flag); +} + + + template +inline void +FEFaceEvaluation:: + evaluate(const VectorizedArrayType * values_array, + const EvaluationFlags::EvaluationFlags evaluation_flag) +{ + Assert( + (evaluation_flag & + ~(EvaluationFlags::values | EvaluationFlags::gradients)) == 0, + ExcMessage( + "Only EvaluationFlags::values and EvaluationFlags::gradients are supported.")); + + if (!(evaluation_flag & EvaluationFlags::values) && + !(evaluation_flag & EvaluationFlags::gradients)) return; internal::FEFaceEvaluationSelector< @@ -7462,8 +7909,8 @@ FEFaceEvaluationbegin_values(), this->begin_gradients(), this->scratch_data, - evaluate_values, - evaluate_gradients, + evaluation_flag & EvaluationFlags::values, + evaluation_flag & EvaluationFlags::gradients, this->face_no, this->subface_index, this->face_orientation, @@ -7472,15 +7919,39 @@ FEFaceEvaluationvalues_quad_initialized = true; - if (evaluate_gradients == true) + if (evaluation_flag & EvaluationFlags::gradients) this->gradients_quad_initialized = true; # endif } +template +inline void +FEFaceEvaluation:: + integrate(const EvaluationFlags::EvaluationFlags evaluation_flag) +{ + integrate(evaluation_flag, this->values_dofs[0]); + +# ifdef DEBUG + this->dof_values_initialized = true; +# endif +} + + + template +inline void +FEFaceEvaluation:: + integrate(const EvaluationFlags::EvaluationFlags evaluation_flag, + VectorizedArrayType * values_array) +{ + Assert( + (evaluation_flag & + ~(EvaluationFlags::values | EvaluationFlags::gradients)) == 0, + ExcMessage( + "Only EvaluationFlags::values and EvaluationFlags::gradients are supported.")); + + if (!(evaluation_flag & EvaluationFlags::values) && + !(evaluation_flag & EvaluationFlags::gradients)) return; - internal::FEFaceEvaluationSelector< - dim, - fe_degree, - n_q_points_1d, - n_components, - Number, - VectorizedArrayType>::integrate(*this->data, - values_array, - this->begin_values(), - this->begin_gradients(), - this->scratch_data, - integrate_values, - integrate_gradients, - this->face_no, - this->subface_index, - this->face_orientation, - this->mapping_data - ->descriptor[this->active_fe_index] - .face_orientations); + internal::FEFaceEvaluationSelector:: + integrate( + *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); } @@ -7565,6 +8068,33 @@ FEFaceEvaluation< VectorizedArrayType>::gather_evaluate(const VectorType &input_vector, const bool evaluate_values, const bool evaluate_gradients) +{ + const EvaluationFlags::EvaluationFlags flag = + ((evaluate_values) ? EvaluationFlags::values : EvaluationFlags::nothing) | + ((evaluate_gradients) ? EvaluationFlags::gradients : + EvaluationFlags::nothing); + + gather_evaluate(input_vector, flag); +} + + + +template +template +inline void +FEFaceEvaluation:: + gather_evaluate(const VectorType & input_vector, + const EvaluationFlags::EvaluationFlags evaluation_flag) { static_assert(internal::has_begin::value && (std::is_same().begin()), @@ -7575,6 +8105,12 @@ FEFaceEvaluation< "evaluating to a pointer to basic number (float,double). " "Use read_dof_values() followed by evaluate() instead."); + Assert( + (evaluation_flag & + ~(EvaluationFlags::values | EvaluationFlags::gradients)) == 0, + ExcMessage( + "Only EvaluationFlags::values and EvaluationFlags::gradients are supported.")); + if (!internal::FEFaceEvaluationSelectorbegin_values(), this->begin_gradients(), this->scratch_data, - evaluate_values, - evaluate_gradients, + evaluation_flag & EvaluationFlags::values, + evaluation_flag & EvaluationFlags::gradients, this->active_fe_index, this->first_selected_component, this->cell, @@ -7600,13 +8136,13 @@ FEFaceEvaluation< .face_orientations)) { this->read_dof_values(input_vector); - this->evaluate(evaluate_values, evaluate_gradients); + this->evaluate(evaluation_flag); } # ifdef DEBUG - if (evaluate_values == true) + if (evaluation_flag & EvaluationFlags::values) this->values_quad_initialized = true; - if (evaluate_gradients == true) + if (evaluation_flag & EvaluationFlags::gradients) this->gradients_quad_initialized = true; # endif } @@ -7630,6 +8166,33 @@ FEFaceEvaluation< VectorizedArrayType>::integrate_scatter(const bool integrate_values, const bool integrate_gradients, VectorType &destination) +{ + const EvaluationFlags::EvaluationFlags flag = + ((integrate_values) ? EvaluationFlags::values : EvaluationFlags::nothing) | + ((integrate_gradients) ? EvaluationFlags::gradients : + EvaluationFlags::nothing); + + integrate_scatter(flag, destination); +} + + + +template +template +inline void +FEFaceEvaluation:: + integrate_scatter(const EvaluationFlags::EvaluationFlags evaluation_flag, + VectorType & destination) { static_assert(internal::has_begin::value && (std::is_same().begin()), @@ -7654,8 +8217,8 @@ FEFaceEvaluation< this->begin_values(), this->begin_gradients(), this->scratch_data, - integrate_values, - integrate_gradients, + evaluation_flag & EvaluationFlags::values, + evaluation_flag & EvaluationFlags::gradients, this->active_fe_index, this->first_selected_component, this->cell, -- 2.39.5