]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Introduce MGTransferBlockGlobalCoarsening 13637/head
authorPeter Munch <peterrmuench@gmail.com>
Sun, 24 Apr 2022 20:46:03 +0000 (22:46 +0200)
committerPeter Munch <peterrmuench@gmail.com>
Mon, 25 Apr 2022 07:16:33 +0000 (09:16 +0200)
include/deal.II/base/mg_level_object.h
include/deal.II/multigrid/mg_transfer_global_coarsening.h
include/deal.II/multigrid/mg_transfer_global_coarsening.templates.h
include/deal.II/multigrid/mg_transfer_matrix_free.h
include/deal.II/multigrid/mg_transfer_matrix_free.templates.h [new file with mode: 0644]
source/multigrid/mg_transfer_global_coarsening.inst.in
source/multigrid/mg_transfer_matrix_free.cc
tests/multigrid-global-coarsening/block_01.cc [new file with mode: 0644]
tests/multigrid-global-coarsening/block_01.with_p4est=true.mpirun=1.output [new file with mode: 0644]

index 88a9e3ae47f5021286015df5b473e35bc5c16393..fd10610f5dcdcf7af6fdd854de250505730e0872 100644 (file)
@@ -97,6 +97,12 @@ public:
   const Object &
   operator[](const unsigned int level) const;
 
+  /**
+   * Return object on level max.
+   */
+  const Object &
+  back() const;
+
   /**
    * Delete all previous contents of this object and reset its size according
    * to the values of @p new_minlevel and @p new_maxlevel.
@@ -230,6 +236,14 @@ MGLevelObject<Object>::operator[](const unsigned int i) const
 }
 
 
+template <class Object>
+const Object &
+MGLevelObject<Object>::back() const
+{
+  return this->operator[](this->max_level());
+}
+
+
 template <class Object>
 template <class... Args>
 void
index 7b93d0e367f4c311a47926970b15fe5b4a120c00..8948f5ba39c74d173d0fd30ec1d50114524b987f 100644 (file)
@@ -28,6 +28,7 @@
 #include <deal.II/matrix_free/shape_info.h>
 
 #include <deal.II/multigrid/mg_base.h>
+#include <deal.II/multigrid/mg_transfer_matrix_free.h>
 
 DEAL_II_NAMESPACE_OPEN
 
@@ -616,6 +617,38 @@ private:
 
 
 
+/**
+ * This class works with LinearAlgebra::distributed::BlockVector and
+ * performs exactly the same transfer operations for each block as
+ * MGTransferGlobalCoarsening.
+ */
+template <int dim, typename VectorType>
+class MGTransferBlockGlobalCoarsening
+  : public MGTransferBlockMatrixFreeBase<
+      dim,
+      typename VectorType::value_type,
+      MGTransferGlobalCoarsening<dim, VectorType>>
+{
+public:
+  /**
+   * Constructor.
+   */
+  MGTransferBlockGlobalCoarsening(
+    const MGTransferGlobalCoarsening<dim, VectorType> &transfer_operator);
+
+protected:
+  const MGTransferGlobalCoarsening<dim, VectorType> &
+  get_matrix_free_transfer(const unsigned int b) const override;
+
+private:
+  /**
+   * Non-block version of transfer operation.
+   */
+  const MGTransferGlobalCoarsening<dim, VectorType> &transfer_operator;
+};
+
+
+
 #ifndef DOXYGEN
 
 /* ----------------------- Inline functions --------------------------------- */
index 3a1465860967f70e92a282dd73ff13746d50e55a..70ab1f48b45b3bf44801a17e89db6edfbe3d0eb6 100644 (file)
@@ -45,6 +45,7 @@
 
 #include <deal.II/multigrid/mg_tools.h>
 #include <deal.II/multigrid/mg_transfer_global_coarsening.h>
+#include <deal.II/multigrid/mg_transfer_matrix_free.templates.h>
 
 DEAL_II_NAMESPACE_OPEN
 
@@ -3163,6 +3164,32 @@ MGTwoLevelTransfer<dim, LinearAlgebra::distributed::Vector<Number>>::
   return size;
 }
 
+
+
+template <int dim, typename VectorType>
+MGTransferBlockGlobalCoarsening<dim, VectorType>::
+  MGTransferBlockGlobalCoarsening(
+    const MGTransferGlobalCoarsening<dim, VectorType> &transfer_operator)
+  : MGTransferBlockMatrixFreeBase<dim,
+                                  typename VectorType::value_type,
+                                  MGTransferGlobalCoarsening<dim, VectorType>>(
+      true)
+  , transfer_operator(transfer_operator)
+{}
+
+
+
+template <int dim, typename VectorType>
+const MGTransferGlobalCoarsening<dim, VectorType> &
+MGTransferBlockGlobalCoarsening<dim, VectorType>::get_matrix_free_transfer(
+  const unsigned int b) const
+{
+  (void)b;
+  AssertDimension(b, 0);
+  return transfer_operator;
+}
+
+
 DEAL_II_NAMESPACE_CLOSE
 
 #endif
index 336832606675bc55d827ac4b0204a1f28105a86e..df6a6b9cc1b40f8cc6092c6e2abbb16ae8302ec2 100644 (file)
@@ -321,6 +321,10 @@ class MGTransferBlockMatrixFreeBase
   : public MGTransferBase<LinearAlgebra::distributed::BlockVector<Number>>
 {
 public:
+  MGTransferBlockMatrixFreeBase(const bool same_for_all)
+    : same_for_all(same_for_all)
+  {}
+
   /**
    * Prolongate a vector from level <tt>to_level-1</tt> to level
    * <tt>to_level</tt> using the embedding matrices of the underlying finite
@@ -428,15 +432,17 @@ public:
 
 protected:
   /**
-   * Non-block matrix-free versions of transfer operation.
+   * Return the right non-block transfer operator. Has to be implemented by
+   * the derived class.
    */
-  std::vector<TransferType> matrix_free_transfer_vector;
+  virtual const TransferType &
+  get_matrix_free_transfer(const unsigned int b) const = 0;
 
   /**
    * A flag to indicate whether the same DoFHandler is used for all
    * the components or if each block has its own DoFHandler.
    */
-  bool same_for_all;
+  const bool same_for_all;
 };
 
 
@@ -520,6 +526,16 @@ public:
    */
   std::size_t
   memory_consumption() const;
+
+protected:
+  const MGTransferMatrixFree<dim, Number> &
+  get_matrix_free_transfer(const unsigned int b) const override;
+
+private:
+  /**
+   * Non-block matrix-free versions of transfer operation.
+   */
+  std::vector<MGTransferMatrixFree<dim, Number>> matrix_free_transfer_vector;
 };
 
 
@@ -631,7 +647,6 @@ MGTransferBlockMatrixFreeBase<dim, Number, TransferType>::copy_to_mg(
   MGLevelObject<LinearAlgebra::distributed::BlockVector<Number>> &dst,
   const LinearAlgebra::distributed::BlockVector<Number2> &        src) const
 {
-  AssertDimension(matrix_free_transfer_vector.size(), 1);
   Assert(same_for_all,
          ExcMessage(
            "This object was initialized with support for usage with one "
@@ -673,9 +688,8 @@ MGTransferBlockMatrixFreeBase<dim, Number, TransferType>::copy_to_mg(
   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].copy_to_mg(*dof_handler[b],
-                                                         dst_non_block,
-                                                         src.block(b));
+      get_matrix_free_transfer(data_block)
+        .copy_to_mg(*dof_handler[b], dst_non_block, src.block(b));
 
       for (unsigned int l = min_level; l <= max_level; ++l)
         dst[l].block(b) = dst_non_block[l];
@@ -694,7 +708,11 @@ MGTransferBlockMatrixFreeBase<dim, Number, TransferType>::copy_from_mg(
   const MGLevelObject<LinearAlgebra::distributed::BlockVector<Number>> &src)
   const
 {
-  AssertDimension(matrix_free_transfer_vector.size(), 1);
+  Assert(same_for_all,
+         ExcMessage(
+           "This object was initialized with support for usage with one "
+           "DoFHandler for each block, but this method assumes that "
+           "the same DoFHandler is used for all the blocks!"));
   const std::vector<const DoFHandler<dim, spacedim> *> mg_dofs(dst.n_blocks(),
                                                                &dof_handler);
 
@@ -734,9 +752,8 @@ MGTransferBlockMatrixFreeBase<dim, Number, TransferType>::copy_from_mg(
           src_non_block[l] = src[l].block(b);
         }
       const unsigned int data_block = same_for_all ? 0 : b;
-      matrix_free_transfer_vector[data_block].copy_from_mg(*dof_handler[b],
-                                                           dst.block(b),
-                                                           src_non_block);
+      get_matrix_free_transfer(data_block)
+        .copy_from_mg(*dof_handler[b], dst.block(b), src_non_block);
     }
 }
 
diff --git a/include/deal.II/multigrid/mg_transfer_matrix_free.templates.h b/include/deal.II/multigrid/mg_transfer_matrix_free.templates.h
new file mode 100644 (file)
index 0000000..e45d295
--- /dev/null
@@ -0,0 +1,86 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2016 - 2021 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_mg_transfer_matrix_free_templates_h
+#define dealii_mg_transfer_matrix_free_templates_h
+
+#include <deal.II/base/config.h>
+
+#include <deal.II/multigrid/mg_transfer_matrix_free.h>
+
+
+DEAL_II_NAMESPACE_OPEN
+
+template <int dim, typename Number, typename TransferType>
+void
+MGTransferBlockMatrixFreeBase<dim, Number, TransferType>::prolongate(
+  const unsigned int                                     to_level,
+  LinearAlgebra::distributed::BlockVector<Number> &      dst,
+  const LinearAlgebra::distributed::BlockVector<Number> &src) const
+{
+  const unsigned int n_blocks = src.n_blocks();
+  AssertDimension(dst.n_blocks(), n_blocks);
+
+  for (unsigned int b = 0; b < n_blocks; ++b)
+    {
+      const unsigned int data_block = same_for_all ? 0 : b;
+      get_matrix_free_transfer(data_block)
+        .prolongate(to_level, dst.block(b), src.block(b));
+    }
+}
+
+
+
+template <int dim, typename Number, typename TransferType>
+void
+MGTransferBlockMatrixFreeBase<dim, Number, TransferType>::prolongate_and_add(
+  const unsigned int                                     to_level,
+  LinearAlgebra::distributed::BlockVector<Number> &      dst,
+  const LinearAlgebra::distributed::BlockVector<Number> &src) const
+{
+  const unsigned int n_blocks = src.n_blocks();
+  AssertDimension(dst.n_blocks(), n_blocks);
+
+  for (unsigned int b = 0; b < n_blocks; ++b)
+    {
+      const unsigned int data_block = same_for_all ? 0 : b;
+      get_matrix_free_transfer(data_block)
+        .prolongate_and_add(to_level, dst.block(b), src.block(b));
+    }
+}
+
+
+
+template <int dim, typename Number, typename TransferType>
+void
+MGTransferBlockMatrixFreeBase<dim, Number, TransferType>::restrict_and_add(
+  const unsigned int                                     from_level,
+  LinearAlgebra::distributed::BlockVector<Number> &      dst,
+  const LinearAlgebra::distributed::BlockVector<Number> &src) const
+{
+  const unsigned int n_blocks = src.n_blocks();
+  AssertDimension(dst.n_blocks(), n_blocks);
+
+  for (unsigned int b = 0; b < n_blocks; ++b)
+    {
+      const unsigned int data_block = same_for_all ? 0 : b;
+      get_matrix_free_transfer(data_block)
+        .restrict_and_add(from_level, dst.block(b), src.block(b));
+    }
+}
+
+DEAL_II_NAMESPACE_CLOSE
+
+#endif
index e9a9eb71d709415e621d9994353a1fde1559909f..209a7ee8c14222bf20a6f029fb6e73ee9bbfc647 100644 (file)
@@ -19,6 +19,14 @@ for (deal_II_dimension : DIMENSIONS; S1 : REAL_SCALARS)
   {
     template class MGTwoLevelTransfer<deal_II_dimension,
                                       LinearAlgebra::distributed::Vector<S1>>;
+    template class MGTransferBlockMatrixFreeBase<
+      deal_II_dimension,
+      S1,
+      MGTransferGlobalCoarsening<deal_II_dimension,
+                                 LinearAlgebra::distributed::Vector<S1>>>;
+    template class MGTransferBlockGlobalCoarsening<
+      deal_II_dimension,
+      LinearAlgebra::distributed::Vector<S1>>;
   }
 
 for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : SPACE_DIMENSIONS)
index 19fcb4295fadcd9491ebcfaf58adc6b4ca81962e..af000da93f9e5b29da865e4e067d88b05e425f37 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <deal.II/multigrid/mg_tools.h>
 #include <deal.II/multigrid/mg_transfer_internal.h>
-#include <deal.II/multigrid/mg_transfer_matrix_free.h>
+#include <deal.II/multigrid/mg_transfer_matrix_free.templates.h>
 
 #include <algorithm>
 
@@ -707,8 +707,10 @@ MGTransferMatrixFree<dim, Number>::memory_consumption() const
 template <int dim, typename Number>
 MGTransferBlockMatrixFree<dim, Number>::MGTransferBlockMatrixFree(
   const MGConstrainedDoFs &mg_c)
+  : MGTransferBlockMatrixFreeBase<dim,
+                                  Number,
+                                  MGTransferMatrixFree<dim, Number>>(true)
 {
-  this->same_for_all = true;
   this->matrix_free_transfer_vector.emplace_back(mg_c);
 }
 
@@ -717,8 +719,10 @@ MGTransferBlockMatrixFree<dim, Number>::MGTransferBlockMatrixFree(
 template <int dim, typename Number>
 MGTransferBlockMatrixFree<dim, Number>::MGTransferBlockMatrixFree(
   const std::vector<MGConstrainedDoFs> &mg_c)
+  : MGTransferBlockMatrixFreeBase<dim,
+                                  Number,
+                                  MGTransferMatrixFree<dim, Number>>(false)
 {
-  this->same_for_all = false;
   for (const auto &constrained_block_dofs : mg_c)
     this->matrix_free_transfer_vector.emplace_back(constrained_block_dofs);
 }
@@ -795,82 +799,20 @@ MGTransferBlockMatrixFree<dim, Number>::memory_consumption() const
 
 
 template <int dim, typename Number>
-void
-MGTransferBlockMatrixFree<dim, Number>::clear()
-{
-  this->matrix_free_transfer_vector.clear();
-}
-
-
-
-template <int dim, typename Number, typename TransferType>
-void
-MGTransferBlockMatrixFreeBase<dim, Number, TransferType>::prolongate(
-  const unsigned int                                     to_level,
-  LinearAlgebra::distributed::BlockVector<Number> &      dst,
-  const LinearAlgebra::distributed::BlockVector<Number> &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(to_level,
-                                                         dst.block(b),
-                                                         src.block(b));
-    }
-}
-
-
-
-template <int dim, typename Number, typename TransferType>
-void
-MGTransferBlockMatrixFreeBase<dim, Number, TransferType>::prolongate_and_add(
-  const unsigned int                                     to_level,
-  LinearAlgebra::distributed::BlockVector<Number> &      dst,
-  const LinearAlgebra::distributed::BlockVector<Number> &src) const
+const MGTransferMatrixFree<dim, Number> &
+MGTransferBlockMatrixFree<dim, Number>::get_matrix_free_transfer(
+  const unsigned int b) 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));
-    }
+  return matrix_free_transfer_vector[b];
 }
 
 
 
-template <int dim, typename Number, typename TransferType>
+template <int dim, typename Number>
 void
-MGTransferBlockMatrixFreeBase<dim, Number, TransferType>::restrict_and_add(
-  const unsigned int                                     from_level,
-  LinearAlgebra::distributed::BlockVector<Number> &      dst,
-  const LinearAlgebra::distributed::BlockVector<Number> &src) const
+MGTransferBlockMatrixFree<dim, Number>::clear()
 {
-  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].restrict_and_add(from_level,
-                                                               dst.block(b),
-                                                               src.block(b));
-    }
+  this->matrix_free_transfer_vector.clear();
 }
 
 
diff --git a/tests/multigrid-global-coarsening/block_01.cc b/tests/multigrid-global-coarsening/block_01.cc
new file mode 100644 (file)
index 0000000..3231662
--- /dev/null
@@ -0,0 +1,190 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2022 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.
+//
+// ---------------------------------------------------------------------
+
+
+/**
+ * Test global-coarsening multigrid for block vectors.
+ */
+
+#include <deal.II/base/conditional_ostream.h>
+#include <deal.II/base/logstream.h>
+#include <deal.II/base/mpi.h>
+#include <deal.II/base/quadrature_lib.h>
+
+#include <deal.II/distributed/tria.h>
+
+#include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_renumbering.h>
+
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/fe/fe_q.h>
+#include <deal.II/fe/fe_system.h>
+#include <deal.II/fe/fe_tools.h>
+#include <deal.II/fe/mapping_q.h>
+
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/grid/grid_out.h>
+
+#include <deal.II/matrix_free/fe_evaluation.h>
+#include <deal.II/matrix_free/matrix_free.h>
+
+#include <deal.II/multigrid/mg_constrained_dofs.h>
+#include <deal.II/multigrid/mg_transfer_global_coarsening.h>
+
+#include "../tests.h"
+
+template <int dim, typename Number = double>
+void
+test(const unsigned int n_refinements, const unsigned int fe_degree)
+{
+  using VectorType = LinearAlgebra::distributed::Vector<Number>;
+
+  const unsigned int min_level = 0;
+  const unsigned int max_level = n_refinements;
+
+  parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD);
+
+  GridGenerator::hyper_cube(tria);
+  tria.refine_global(n_refinements);
+
+  const auto trias =
+    MGTransferGlobalCoarseningTools::create_geometric_coarsening_sequence(tria);
+
+  MGLevelObject<DoFHandler<dim>> dof_handlers(min_level, max_level);
+  MGLevelObject<DoFHandler<dim>> dof_handlers_system(min_level, max_level);
+  MGLevelObject<std::shared_ptr<const Utilities::MPI::Partitioner>>
+    partitioners(min_level, max_level);
+  MGLevelObject<std::shared_ptr<const Utilities::MPI::Partitioner>>
+    partitioners_system(min_level, max_level);
+  MGLevelObject<MGTwoLevelTransfer<dim, VectorType>> transfers(min_level,
+                                                               max_level);
+  MGLevelObject<MGTwoLevelTransfer<dim, VectorType>> transfers_system(
+    min_level, max_level);
+
+  for (auto l = min_level; l <= max_level; ++l)
+    {
+      dof_handlers[l].reinit(*trias[l]);
+      dof_handlers[l].distribute_dofs(FE_Q<dim>(fe_degree));
+      partitioners[l] = std::make_shared<const Utilities::MPI::Partitioner>(
+        dof_handlers[l].locally_owned_dofs(),
+        DoFTools::extract_locally_relevant_dofs(dof_handlers[l]),
+        MPI_COMM_WORLD);
+
+
+      dof_handlers_system[l].reinit(*trias[l]);
+      dof_handlers_system[l].distribute_dofs(
+        FESystem<dim>(FE_Q<dim>(fe_degree), dim));
+      DoFRenumbering::block_wise(dof_handlers_system[l]);
+      partitioners_system[l] =
+        std::make_shared<const Utilities::MPI::Partitioner>(
+          dof_handlers_system[l].locally_owned_dofs(),
+          DoFTools::extract_locally_relevant_dofs(dof_handlers_system[l]),
+          MPI_COMM_WORLD);
+    }
+
+  for (unsigned int l = min_level; l < max_level; ++l)
+    {
+      transfers[l + 1].reinit(dof_handlers[l + 1], dof_handlers[l]);
+      transfers_system[l + 1].reinit(dof_handlers_system[l + 1],
+                                     dof_handlers_system[l]);
+    }
+
+
+
+  MGTransferGlobalCoarsening<dim, VectorType> transfer(
+    transfers, [&](const auto l, auto &vec) { vec.reinit(partitioners[l]); });
+
+  MGTransferGlobalCoarsening<dim, VectorType> transfer_system(
+    transfers_system,
+    [&](const auto l, auto &vec) { vec.reinit(partitioners_system[l]); });
+
+  MGTransferBlockGlobalCoarsening<dim, VectorType> transfer_block(transfer);
+
+  LinearAlgebra::distributed::BlockVector<Number> vec_block(dim);
+  for (unsigned int d = 0; d < dim; ++d)
+    vec_block.block(d).reinit(partitioners.back());
+  MGLevelObject<LinearAlgebra::distributed::BlockVector<Number>>
+    vec_levels_block(min_level, max_level);
+
+  LinearAlgebra::distributed::Vector<Number> vec_system(
+    partitioners_system.back());
+  MGLevelObject<LinearAlgebra::distributed::Vector<Number>> vec_levels_system(
+    min_level, max_level);
+
+  for (unsigned int b = 0, c = 0; b < dim; ++b)
+    for (unsigned int i = 0; i < dof_handlers.back().n_dofs(); ++i, ++c)
+      {
+        vec_block.block(b)[i] = c;
+        vec_system[c]         = c;
+      }
+
+  // test copy_to_mg()
+  transfer_block.copy_to_mg(dof_handlers.back(), vec_levels_block, vec_block);
+  transfer_system.copy_to_mg(dof_handlers_system.back(),
+                             vec_levels_system,
+                             vec_system);
+
+  vec_levels_block.back().print(deallog.get_file_stream());
+  vec_levels_system.back().print(deallog.get_file_stream());
+
+  // test copy_from_mg()
+  transfer_block.copy_from_mg(dof_handlers.back(), vec_block, vec_levels_block);
+  transfer_system.copy_from_mg(dof_handlers_system.back(),
+                               vec_system,
+                               vec_levels_system);
+
+  vec_block.print(deallog.get_file_stream());
+  vec_system.print(deallog.get_file_stream());
+
+
+  // test restrict_and_add()
+  for (unsigned int l = max_level; l > min_level; --l)
+    {
+      transfer_block.restrict_and_add(l,
+                                      vec_levels_block[l - 1],
+                                      vec_levels_block[l]);
+      transfer_system.restrict_and_add(l,
+                                       vec_levels_system[l - 1],
+                                       vec_levels_system[l]);
+
+      vec_levels_block[l - 1].print(deallog.get_file_stream());
+      vec_levels_system[l - 1].print(deallog.get_file_stream());
+    }
+
+  // test prolongate()
+  for (unsigned int l = min_level; l < max_level; ++l)
+    {
+      transfer_block.prolongate(l + 1,
+                                vec_levels_block[l + 1],
+                                vec_levels_block[l]);
+      transfer_system.prolongate(l + 1,
+                                 vec_levels_system[l + 1],
+                                 vec_levels_system[l]);
+
+      vec_levels_block[l + 1].print(deallog.get_file_stream());
+      vec_levels_system[l + 1].print(deallog.get_file_stream());
+    }
+}
+
+int
+main(int argc, char **argv)
+{
+  Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1);
+  MPILogInitAll                    all;
+
+  deallog.precision(8);
+
+  test<2>(2, 1);
+}
diff --git a/tests/multigrid-global-coarsening/block_01.with_p4est=true.mpirun=1.output b/tests/multigrid-global-coarsening/block_01.with_p4est=true.mpirun=1.output
new file mode 100644 (file)
index 0000000..29dae0a
--- /dev/null
@@ -0,0 +1,73 @@
+
+Process #0
+Local range: [0, 25), global size: 25
+Vector data:
+0.000e+00 1.000e+00 2.000e+00 3.000e+00 4.000e+00 5.000e+00 6.000e+00 7.000e+00 8.000e+00 9.000e+00 1.000e+01 1.100e+01 1.200e+01 1.300e+01 1.400e+01 1.500e+01 1.600e+01 1.700e+01 1.800e+01 1.900e+01 2.000e+01 2.100e+01 2.200e+01 2.300e+01 2.400e+01 
+Process #0
+Local range: [0, 25), global size: 25
+Vector data:
+2.500e+01 2.600e+01 2.700e+01 2.800e+01 2.900e+01 3.000e+01 3.100e+01 3.200e+01 3.300e+01 3.400e+01 3.500e+01 3.600e+01 3.700e+01 3.800e+01 3.900e+01 4.000e+01 4.100e+01 4.200e+01 4.300e+01 4.400e+01 4.500e+01 4.600e+01 4.700e+01 4.800e+01 4.900e+01 
+Process #0
+Local range: [0, 50), global size: 50
+Vector data:
+0.000e+00 1.000e+00 2.000e+00 3.000e+00 4.000e+00 5.000e+00 6.000e+00 7.000e+00 8.000e+00 9.000e+00 1.000e+01 1.100e+01 1.200e+01 1.300e+01 1.400e+01 1.500e+01 1.600e+01 1.700e+01 1.800e+01 1.900e+01 2.000e+01 2.100e+01 2.200e+01 2.300e+01 2.400e+01 2.500e+01 2.600e+01 2.700e+01 2.800e+01 2.900e+01 3.000e+01 3.100e+01 3.200e+01 3.300e+01 3.400e+01 3.500e+01 3.600e+01 3.700e+01 3.800e+01 3.900e+01 4.000e+01 4.100e+01 4.200e+01 4.300e+01 4.400e+01 4.500e+01 4.600e+01 4.700e+01 4.800e+01 4.900e+01 
+Process #0
+Local range: [0, 25), global size: 25
+Vector data:
+0.000e+00 1.000e+00 2.000e+00 3.000e+00 4.000e+00 5.000e+00 6.000e+00 7.000e+00 8.000e+00 9.000e+00 1.000e+01 1.100e+01 1.200e+01 1.300e+01 1.400e+01 1.500e+01 1.600e+01 1.700e+01 1.800e+01 1.900e+01 2.000e+01 2.100e+01 2.200e+01 2.300e+01 2.400e+01 
+Process #0
+Local range: [0, 25), global size: 25
+Vector data:
+2.500e+01 2.600e+01 2.700e+01 2.800e+01 2.900e+01 3.000e+01 3.100e+01 3.200e+01 3.300e+01 3.400e+01 3.500e+01 3.600e+01 3.700e+01 3.800e+01 3.900e+01 4.000e+01 4.100e+01 4.200e+01 4.300e+01 4.400e+01 4.500e+01 4.600e+01 4.700e+01 4.800e+01 4.900e+01 
+Process #0
+Local range: [0, 50), global size: 50
+Vector data:
+0.000e+00 1.000e+00 2.000e+00 3.000e+00 4.000e+00 5.000e+00 6.000e+00 7.000e+00 8.000e+00 9.000e+00 1.000e+01 1.100e+01 1.200e+01 1.300e+01 1.400e+01 1.500e+01 1.600e+01 1.700e+01 1.800e+01 1.900e+01 2.000e+01 2.100e+01 2.200e+01 2.300e+01 2.400e+01 2.500e+01 2.600e+01 2.700e+01 2.800e+01 2.900e+01 3.000e+01 3.100e+01 3.200e+01 3.300e+01 3.400e+01 3.500e+01 3.600e+01 3.700e+01 3.800e+01 3.900e+01 4.000e+01 4.100e+01 4.200e+01 4.300e+01 4.400e+01 4.500e+01 4.600e+01 4.700e+01 4.800e+01 4.900e+01 
+Process #0
+Local range: [0, 9), global size: 9
+Vector data:
+2.250e+00 1.475e+01 2.275e+01 4.150e+01 2.400e+01 4.525e+01 3.900e+01 5.875e+01 5.175e+01 
+Process #0
+Local range: [0, 9), global size: 9
+Vector data:
+5.850e+01 8.975e+01 9.775e+01 1.415e+02 8.025e+01 1.202e+02 9.525e+01 1.338e+02 1.080e+02 
+Process #0
+Local range: [0, 18), global size: 18
+Vector data:
+2.250e+00 1.475e+01 2.275e+01 4.150e+01 2.400e+01 4.525e+01 3.900e+01 5.875e+01 5.175e+01 5.850e+01 8.975e+01 9.775e+01 1.415e+02 8.025e+01 1.202e+02 9.525e+01 1.338e+02 1.080e+02 
+Process #0
+Local range: [0, 4), global size: 4
+Vector data:
+3.138e+01 6.438e+01 9.012e+01 1.141e+02 
+Process #0
+Local range: [0, 4), global size: 4
+Vector data:
+1.876e+02 2.206e+02 2.464e+02 2.704e+02 
+Process #0
+Local range: [0, 8), global size: 8
+Vector data:
+3.138e+01 6.438e+01 9.012e+01 1.141e+02 1.876e+02 2.206e+02 2.464e+02 2.704e+02 
+Process #0
+Local range: [0, 9), global size: 9
+Vector data:
+3.138e+01 4.788e+01 6.075e+01 7.500e+01 6.438e+01 8.925e+01 9.012e+01 1.021e+02 1.141e+02 
+Process #0
+Local range: [0, 9), global size: 9
+Vector data:
+1.876e+02 2.041e+02 2.170e+02 2.312e+02 2.206e+02 2.455e+02 2.464e+02 2.584e+02 2.704e+02 
+Process #0
+Local range: [0, 18), global size: 18
+Vector data:
+3.138e+01 4.788e+01 6.075e+01 7.500e+01 6.438e+01 8.925e+01 9.012e+01 1.021e+02 1.141e+02 1.876e+02 2.041e+02 2.170e+02 2.312e+02 2.206e+02 2.455e+02 2.464e+02 2.584e+02 2.704e+02 
+Process #0
+Local range: [0, 25), global size: 25
+Vector data:
+3.138e+01 3.962e+01 4.606e+01 5.375e+01 4.788e+01 6.144e+01 6.075e+01 6.788e+01 7.500e+01 5.612e+01 6.912e+01 6.438e+01 7.681e+01 8.212e+01 8.925e+01 7.544e+01 8.200e+01 8.856e+01 9.012e+01 9.612e+01 1.021e+02 9.512e+01 1.017e+02 1.081e+02 1.141e+02 
+Process #0
+Local range: [0, 25), global size: 25
+Vector data:
+1.876e+02 1.959e+02 2.023e+02 2.100e+02 2.041e+02 2.177e+02 2.170e+02 2.241e+02 2.312e+02 2.124e+02 2.254e+02 2.206e+02 2.331e+02 2.384e+02 2.455e+02 2.317e+02 2.382e+02 2.448e+02 2.464e+02 2.524e+02 2.584e+02 2.514e+02 2.579e+02 2.644e+02 2.704e+02 
+Process #0
+Local range: [0, 50), global size: 50
+Vector data:
+3.138e+01 3.962e+01 4.606e+01 5.375e+01 4.788e+01 6.144e+01 6.075e+01 6.788e+01 7.500e+01 5.612e+01 6.912e+01 6.438e+01 7.681e+01 8.212e+01 8.925e+01 7.544e+01 8.200e+01 8.856e+01 9.012e+01 9.612e+01 1.021e+02 9.512e+01 1.017e+02 1.081e+02 1.141e+02 1.876e+02 1.959e+02 2.023e+02 2.100e+02 2.041e+02 2.177e+02 2.170e+02 2.241e+02 2.312e+02 2.124e+02 2.254e+02 2.206e+02 2.331e+02 2.384e+02 2.455e+02 2.317e+02 2.382e+02 2.448e+02 2.464e+02 2.524e+02 2.584e+02 2.514e+02 2.579e+02 2.644e+02 2.704e+02 

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.