From: Peter Munch Date: Sun, 23 Jan 2022 17:50:59 +0000 (+0100) Subject: Introduce FEEval::*_face_data() X-Git-Tag: v9.4.0-rc1~546^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F13281%2Fhead;p=dealii.git Introduce FEEval::*_face_data() --- diff --git a/include/deal.II/matrix_free/fe_evaluation.h b/include/deal.II/matrix_free/fe_evaluation.h index 1e2c7760a2..030932d6c6 100644 --- a/include/deal.II/matrix_free/fe_evaluation.h +++ b/include/deal.II/matrix_free/fe_evaluation.h @@ -579,44 +579,6 @@ public: //@} - /** - * Provides a unified interface to access data in a vector of - * VectorizedArray fields of length MatrixFree::n_cell_batches() + - * MatrixFree::n_ghost_cell_batches() for both cells (plain read) and faces - * (indirect addressing). - */ - VectorizedArrayType - read_cell_data(const AlignedVector &array) const; - - /** - * Provides a unified interface to set data in a vector of - * VectorizedArray fields of length MatrixFree::n_cell_batches() + - * MatrixFree::n_ghost_cell_batches() for both cells (plain read) and faces - * (indirect addressing). - */ - void - set_cell_data(AlignedVector &array, - const VectorizedArrayType & value) const; - - /** - * The same as above, just for std::array of length of VectorizedArrayType for - * arbitrary data type. - */ - template - std::array - read_cell_data(const AlignedVector> - &array) const; - - /** - * The same as above, just for std::array of length of VectorizedArrayType for - * arbitrary data type. - */ - template - void - set_cell_data( - AlignedVector> &array, - const std::array & value) const; - /** * Return the underlying MatrixFree object. */ @@ -3144,124 +3106,6 @@ FEEvaluationBase:: } -namespace internal -{ - template - inline void - process_cell_data( - const FEEvaluationBase & fe_eval, - const MatrixFree *matrix_free, - GlobalVectorType & array, - VectorizedArrayType2 & out, - const FU & fu) - { - (void)matrix_free; - Assert(matrix_free != nullptr, ExcNotImplemented()); - AssertDimension(array.size(), - matrix_free->get_task_info().cell_partition_data.back()); - - // 1) collect ids of cell - const auto cells = fe_eval.get_cell_ids(); - - // 2) actually gather values - for (unsigned int i = 0; i < VectorizedArrayType::size(); ++i) - if (cells[i] != numbers::invalid_unsigned_int) - fu(out[i], - array[cells[i] / VectorizedArrayType::size()] - [cells[i] % VectorizedArrayType::size()]); - } -} // namespace internal - - - -template -inline VectorizedArrayType -FEEvaluationBase:: - read_cell_data(const AlignedVector &array) const -{ - VectorizedArrayType out = Number(1.); - internal::process_cell_data( - *this, this->matrix_free, array, out, [](auto &local, const auto &global) { - local = global; - }); - return out; -} - - - -template -inline void -FEEvaluationBase:: - set_cell_data(AlignedVector &array, - const VectorizedArrayType & in) const -{ - internal::process_cell_data( - *this, this->matrix_free, array, in, [](const auto &local, auto &global) { - global = local; - }); -} - - - -template -template -inline std::array -FEEvaluationBase:: - read_cell_data(const AlignedVector> - &array) const -{ - std::array out; - internal::process_cell_data( - *this, this->matrix_free, array, out, [](auto &local, const auto &global) { - local = global; - }); - return out; -} - - - -template -template -inline void -FEEvaluationBase:: - set_cell_data( - AlignedVector> &array, - const std::array & in) const -{ - internal::process_cell_data( - *this, this->matrix_free, array, in, [](const auto &local, auto &global) { - global = local; - }); -} - - namespace internal { @@ -7583,9 +7427,9 @@ FEFaceEvaluationmatrix_free->n_active_entries_per_face_batch(this->cell); ++i) - this->cell_or_face_ids[i] = face_index * VectorizedArrayType::size() + i; + this->face_ids[i] = face_index * VectorizedArrayType::size() + i; for (; i < VectorizedArrayType::size(); ++i) - this->cell_or_face_ids[i] = numbers::invalid_unsigned_int; + this->face_ids[i] = numbers::invalid_unsigned_int; this->cell_type = this->matrix_free->get_mapping_info().face_type[face_index]; const unsigned int offsets = @@ -7674,6 +7518,8 @@ FEFaceEvaluationface_ids[i] = face_index; + if (face_index == numbers::invalid_unsigned_int) { this->cell_ids[i] = numbers::invalid_unsigned_int; @@ -7722,6 +7568,11 @@ FEFaceEvaluationface_numbers[0] = face_number; for (unsigned int i = 0; i < n_lanes; ++i) this->cell_ids[i] = cell_index * n_lanes + i; + for (unsigned int i = 0; i < n_lanes; ++i) + this->face_ids[i] = + this->matrix_free->get_cell_and_face_to_plain_faces()(cell_index, + face_number, + i); } const unsigned int offsets = diff --git a/include/deal.II/matrix_free/fe_evaluation_data.h b/include/deal.II/matrix_free/fe_evaluation_data.h index 7de101a44f..2661c074d5 100644 --- a/include/deal.II/matrix_free/fe_evaluation_data.h +++ b/include/deal.II/matrix_free/fe_evaluation_data.h @@ -485,6 +485,20 @@ public: return cell_ids; } + /** + * Return the id of the faces this FEFaceEvaluation is + * associated with. + */ + const std::array & + get_face_ids() const + { +// implemented inline to avoid compilation problems on Windows +#ifdef DEBUG + Assert(is_reinitialized && is_face, ExcNotInitialized()); +#endif + return face_ids; + } + /** * Return the id of the cell/face batch this FEEvaluation/FEFaceEvaluation is * associated with. @@ -516,11 +530,94 @@ public: internal::MatrixFreeFunctions::DoFInfo::dof_access_cell) return cell_ids; else - return cell_or_face_ids; + return face_ids; } //@} + /** + * @name 3: Functions to access cell- and face-data vectors. + */ + //@{ + + /** + * Provides a unified interface to access data in a vector of + * VectorizedArray fields of length MatrixFree::n_cell_batches() + + * MatrixFree::n_ghost_cell_batches() for cell data. It is implemented + * both for cells and faces (access data to the associated cell). + */ + Number + read_cell_data(const AlignedVector &array) const; + + /** + * Provides a unified interface to set data in a vector of + * VectorizedArray fields of length MatrixFree::n_cell_batches() + + * MatrixFree::n_ghost_cell_batches() for cell data. It is implemented + * both for cells and faces (access data to the associated cell). + */ + void + set_cell_data(AlignedVector &array, const Number &value) const; + + /** + * The same as above, just for std::array of length of Number for + * arbitrary data type. + */ + template + std::array + read_cell_data( + const AlignedVector> &array) const; + + /** + * The same as above, just for std::array of length of Number for + * arbitrary data type. + */ + template + void + set_cell_data(AlignedVector> &array, + const std::array & value) const; + + /** + * Provides a unified interface to access data in a vector of + * VectorizedArray fields of length MatrixFree::n_inner_face_batches() + + * MatrixFree::n_boundary_face_batches() + + * MatrixFree::n_ghost_inner_face_batches() for face data. + * + * @note Only implemented for faces. + */ + Number + read_face_data(const AlignedVector &array) const; + + /** + * Provides a unified interface to set data in a vector of + * VectorizedArray fields of length MatrixFree::n_inner_face_batches() + + * MatrixFree::n_boundary_face_batches() + + * MatrixFree::n_ghost_inner_face_batches() for face data. + * + * @note Only implemented for faces. + */ + void + set_face_data(AlignedVector &array, const Number &value) const; + + /** + * The same as above, just for std::array of length of Number for + * arbitrary data type. + */ + template + std::array + read_face_data( + const AlignedVector> &array) const; + + /** + * The same as above, just for std::array of length of Number for + * arbitrary data type. + */ + template + void + set_face_data(AlignedVector> &array, + const std::array & value) const; + + //@} + /** * This data structure is used for the initialization by the derived * FEEvaluation classes. @@ -855,7 +952,7 @@ protected: * Stores the (non-vectorized) id of the cells or faces this object is * initialized to. Relevant for ECL. */ - std::array cell_or_face_ids; + std::array face_ids; /** * Geometry data that can be generated FEValues on the fly with the @@ -1485,6 +1582,165 @@ FEEvaluationData::get_is_interior_face() const +namespace internal +{ + template + inline void + process_cell_or_face_data(const std::array indices, + GlobalVectorType & array, + VectorizedArrayType2 & out, + const FU & fu) + { + for (unsigned int i = 0; i < N; ++i) + if (indices[i] != numbers::invalid_unsigned_int) + { + AssertIndexRange(indices[i] / N, array.size()); + fu(out[i], array[indices[i] / N][indices[i] % N]); + } + } +} // namespace internal + + + +template +inline Number +FEEvaluationData::read_cell_data( + const AlignedVector &array) const +{ + Number out = Number(1.); + internal::process_cell_or_face_data(this->get_cell_ids(), + array, + out, + [](auto &local, const auto &global) { + local = global; + }); + return out; +} + + + +template +inline void +FEEvaluationData::set_cell_data( + AlignedVector &array, + const Number & in) const +{ + internal::process_cell_or_face_data(this->get_cell_ids(), + array, + in, + [](const auto &local, auto &global) { + global = local; + }); +} + + + +template +template +inline std::array +FEEvaluationData::read_cell_data( + const AlignedVector> &array) const +{ + std::array out; + internal::process_cell_or_face_data(this->get_cell_ids(), + array, + out, + [](auto &local, const auto &global) { + local = global; + }); + return out; +} + + + +template +template +inline void +FEEvaluationData::set_cell_data( + AlignedVector> &array, + const std::array & in) const +{ + internal::process_cell_or_face_data(this->get_cell_ids(), + array, + in, + [](const auto &local, auto &global) { + global = local; + }); +} + + + +template +inline Number +FEEvaluationData::read_face_data( + const AlignedVector &array) const +{ + Number out = Number(1.); + internal::process_cell_or_face_data(this->get_face_ids(), + array, + out, + [](auto &local, const auto &global) { + local = global; + }); + return out; +} + + + +template +inline void +FEEvaluationData::set_face_data( + AlignedVector &array, + const Number & in) const +{ + internal::process_cell_or_face_data(this->get_face_ids(), + array, + in, + [](const auto &local, auto &global) { + global = local; + }); +} + + + +template +template +inline std::array +FEEvaluationData::read_face_data( + const AlignedVector> &array) const +{ + std::array out; + internal::process_cell_or_face_data(this->get_face_ids(), + array, + out, + [](auto &local, const auto &global) { + local = global; + }); + return out; +} + + + +template +template +inline void +FEEvaluationData::set_face_data( + AlignedVector> &array, + const std::array & in) const +{ + internal::process_cell_or_face_data(this->get_face_ids(), + array, + in, + [](const auto &local, auto &global) { + global = local; + }); +} + + + #endif // ifndef DOXYGEN