From 93b0e10bcb91a8c9b5384d5226cad0264d192706 Mon Sep 17 00:00:00 2001 From: Denis Davydov Date: Tue, 12 Jun 2018 15:30:33 +0200 Subject: [PATCH] fixed a bug where exchanger.ghosts_were_set was not set for vectors with large number of blocks. Update the test to make sure this is being checked. --- doc/news/changes/minor/20180612DenisDavydov | 4 ++++ include/deal.II/matrix_free/matrix_free.h | 13 ++++++++++--- tests/matrix_free/matrix_vector_blocks.cc | 13 ++++++++++++- 3 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 doc/news/changes/minor/20180612DenisDavydov diff --git a/doc/news/changes/minor/20180612DenisDavydov b/doc/news/changes/minor/20180612DenisDavydov new file mode 100644 index 0000000000..8219f343e9 --- /dev/null +++ b/doc/news/changes/minor/20180612DenisDavydov @@ -0,0 +1,4 @@ +Bugfix: Fixed a bug where VectorDataExchange::ghosts_were_set was +not set inside MatrixFree::cell_loop() for block vectors +with many blocks. +(Denis Davydov 2018/06/12) diff --git a/include/deal.II/matrix_free/matrix_free.h b/include/deal.II/matrix_free/matrix_free.h index ce79cd6dfd..337069426b 100644 --- a/include/deal.II/matrix_free/matrix_free.h +++ b/include/deal.II/matrix_free/matrix_free.h @@ -3271,10 +3271,17 @@ namespace internal VectorDataExchange &exchanger) { if (get_communication_block_size(vec) < vec.n_blocks()) - vec.update_ghost_values(); + { + // don't forget to set ghosts_were_set, that otherwise happens + // inside VectorDataExchange::update_ghost_values_start() + exchanger.ghosts_were_set = vec.has_ghost_elements(); + vec.update_ghost_values(); + } else - for (unsigned int i = 0; i < vec.n_blocks(); ++i) - update_ghost_values_start(vec.block(i), exchanger, channel + i); + { + for (unsigned int i = 0; i < vec.n_blocks(); ++i) + update_ghost_values_start(vec.block(i), exchanger, channel + i); + } } diff --git a/tests/matrix_free/matrix_vector_blocks.cc b/tests/matrix_free/matrix_vector_blocks.cc index 46d71eaa1b..93c42c4d92 100644 --- a/tests/matrix_free/matrix_vector_blocks.cc +++ b/tests/matrix_free/matrix_vector_blocks.cc @@ -100,7 +100,6 @@ test() tria.refine_global(1); typename Triangulation::active_cell_iterator cell = tria.begin_active(), endc = tria.end(); - cell = tria.begin_active(); for (; cell != endc; ++cell) if (cell->is_locally_owned()) if (cell->center().norm() < 0.2) @@ -172,6 +171,10 @@ test() out.reinit(in); ref.reinit(in); + // after initialization via MatrixFree we are in the write state for + // ghosts + AssertThrow(in.has_ghost_elements() == false, ExcInternalError()); + // fill each block with random numbers and do the block-wise // matrix-vector product for reference for (unsigned int block = 0; block < n_blocks; ++block) @@ -186,6 +189,10 @@ test() mf_ref.vmult(ref.block(block), in.block(block)); } + // explicitly update ghosts so that we can read them: + in.update_ghost_values(); + AssertThrow(in.has_ghost_elements(), ExcInternalError()); + deallog << "Norm of difference with " << n_blocks << " blocks:"; // run 10 times to make a possible error more @@ -193,6 +200,10 @@ test() for (unsigned int run = 0; run < 10; ++run) { mf.vmult(out, in); + + // since we made "in" ghosted, make sure it is still ghosted + AssertThrow(in.has_ghost_elements(), ExcInternalError()); + out -= ref; const double diff_norm = out.linfty_norm(); deallog << " " << diff_norm; -- 2.39.5