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.
}
+template <class Object>
+const Object &
+MGLevelObject<Object>::back() const
+{
+ return this->operator[](this->max_level());
+}
+
+
template <class Object>
template <class... Args>
void
#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
+/**
+ * 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 --------------------------------- */
#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
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
: 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
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;
};
*/
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;
};
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 "
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];
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);
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);
}
}
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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
{
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)
#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>
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);
}
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);
}
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();
}
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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);
+}
--- /dev/null
+
+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