From d02f5ccff2ad1df1e14014496bf1736e1adb8cea Mon Sep 17 00:00:00 2001 From: Peter Munch Date: Mon, 22 Feb 2021 18:31:12 +0100 Subject: [PATCH] Add MGTransferBase::prolongate_and_add --- .../changes/minor/2020222MartinKronbichler | 4 ++ include/deal.II/multigrid/mg_base.h | 15 +++++++ .../multigrid/mg_transfer_matrix_free.h | 12 ++++++ source/multigrid/mg_base.cc | 16 +++++++ source/multigrid/mg_transfer_matrix_free.cc | 42 +++++++++++++++++-- 5 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 doc/news/changes/minor/2020222MartinKronbichler diff --git a/doc/news/changes/minor/2020222MartinKronbichler b/doc/news/changes/minor/2020222MartinKronbichler new file mode 100644 index 0000000000..f86e2afd1c --- /dev/null +++ b/doc/news/changes/minor/2020222MartinKronbichler @@ -0,0 +1,4 @@ +New: The new MGTransferBase::prolongate_and_add() performs a prolongation +without zeroing out the destination vector. +
+(Martin Kronbichler, 2020/02/22) diff --git a/include/deal.II/multigrid/mg_base.h b/include/deal.II/multigrid/mg_base.h index f688d11b1e..2073b33b74 100644 --- a/include/deal.II/multigrid/mg_base.h +++ b/include/deal.II/multigrid/mg_base.h @@ -191,6 +191,21 @@ public: VectorType & dst, const VectorType & src) const = 0; + /** + * Prolongate a vector from level to_level-1 to level + * to_level, summing into the previous content of dst. + * + * @arg src is a vector with as many elements as there are degrees of + * freedom on the coarser level involved. + * + * @arg dst has as many elements as there are degrees of freedom on the + * finer level. + */ + virtual void + prolongate_and_add(const unsigned int to_level, + VectorType & dst, + const VectorType & src) const; + /** * Restrict a vector from level from_level to level * from_level-1 and add this restriction to dst. If the diff --git a/include/deal.II/multigrid/mg_transfer_matrix_free.h b/include/deal.II/multigrid/mg_transfer_matrix_free.h index 8c71361164..210aa36a1b 100644 --- a/include/deal.II/multigrid/mg_transfer_matrix_free.h +++ b/include/deal.II/multigrid/mg_transfer_matrix_free.h @@ -125,6 +125,12 @@ public: LinearAlgebra::distributed::Vector & dst, const LinearAlgebra::distributed::Vector &src) const override; + virtual void + prolongate_and_add( + const unsigned int to_level, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const override; + /** * Restrict a vector from level from_level to level * from_level-1 using the transpose operation of the prolongate() @@ -382,6 +388,12 @@ public: LinearAlgebra::distributed::BlockVector & dst, const LinearAlgebra::distributed::BlockVector &src) const override; + virtual void + prolongate_and_add( + const unsigned int to_level, + LinearAlgebra::distributed::BlockVector & dst, + const LinearAlgebra::distributed::BlockVector &src) const override; + /** * Restrict a vector from level from_level to level * from_level-1 using the transpose operation of the prolongate() diff --git a/source/multigrid/mg_base.cc b/source/multigrid/mg_base.cc index 7ac5d611fb..1750407279 100644 --- a/source/multigrid/mg_base.cc +++ b/source/multigrid/mg_base.cc @@ -41,6 +41,22 @@ MGSmootherBase::apply(const unsigned int level, } + +template +void +MGTransferBase::prolongate_and_add(const unsigned int to_level, + VectorType & dst, + const VectorType & src) const +{ + VectorType temp; + temp.reinit(dst, true); + + this->prolongate(to_level, temp, src); + + dst += temp; +} + + // Explicit instantiations #include "mg_base.inst" diff --git a/source/multigrid/mg_transfer_matrix_free.cc b/source/multigrid/mg_transfer_matrix_free.cc index d1cc31f16d..48a7986303 100644 --- a/source/multigrid/mg_transfer_matrix_free.cc +++ b/source/multigrid/mg_transfer_matrix_free.cc @@ -184,6 +184,19 @@ MGTransferMatrixFree::prolongate( const unsigned int to_level, LinearAlgebra::distributed::Vector & dst, const LinearAlgebra::distributed::Vector &src) const +{ + dst = 0; + prolongate_and_add(to_level, dst, src); +} + + + +template +void +MGTransferMatrixFree::prolongate_and_add( + const unsigned int to_level, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const { Assert((to_level >= 1) && (to_level <= level_dof_indices.size()), ExcIndexRange(to_level, 1, level_dof_indices.size() + 1)); @@ -210,6 +223,7 @@ MGTransferMatrixFree::prolongate( this->vector_partitioners[to_level]); AssertDimension(this->ghosted_level_vector[to_level].locally_owned_size(), dst.locally_owned_size()); + this->ghosted_level_vector[to_level] = 0.; } const LinearAlgebra::distributed::Vector &src_vec = @@ -217,8 +231,6 @@ MGTransferMatrixFree::prolongate( LinearAlgebra::distributed::Vector &dst_vec = dst_inplace ? dst : this->ghosted_level_vector[to_level]; - dst_vec = 0.; - src_vec.update_ghost_values(); // the implementation in do_prolongate_add is templated in the degree of the // element (for efficiency reasons), so we need to find the appropriate @@ -250,7 +262,7 @@ MGTransferMatrixFree::prolongate( dst_vec.compress(VectorOperation::add); if (dst_inplace == false) - dst.copy_locally_owned_data_from(this->ghosted_level_vector[to_level]); + dst += dst_vec; if (src_inplace == true) src.zero_out_ghost_values(); @@ -777,6 +789,30 @@ MGTransferBlockMatrixFree::prolongate( +template +void +MGTransferBlockMatrixFree::prolongate_and_add( + const unsigned int to_level, + LinearAlgebra::distributed::BlockVector & dst, + const LinearAlgebra::distributed::BlockVector &src) const +{ + const unsigned int n_blocks = src.n_blocks(); + AssertDimension(dst.n_blocks(), n_blocks); + + if (!same_for_all) + AssertDimension(matrix_free_transfer_vector.size(), n_blocks); + + for (unsigned int b = 0; b < n_blocks; ++b) + { + const unsigned int data_block = same_for_all ? 0 : b; + matrix_free_transfer_vector[data_block].prolongate_and_add(to_level, + dst.block(b), + src.block(b)); + } +} + + + template void MGTransferBlockMatrixFree::restrict_and_add( -- 2.39.5