--- /dev/null
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 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_distributed_repartitioning_policy_tools_h
+#define dealii_distributed_repartitioning_policy_tools_h
+
+#include <deal.II/grid/tria.h>
+
+#include <deal.II/lac/la_parallel_vector.h>
+
+DEAL_II_NAMESPACE_OPEN
+
+/**
+ * A namespace with repartitioning policies. These classes return vectors of
+ * of the new owners of the active locally owned and ghost cells of a
+ * Triangulation object. The returned vectors can be used, e.g., in
+ * TriangulationDescription::Utilities::create_description_from_triangulation()
+ * to create a TriangulationDescription::Description based on a given
+ * Triangulation and the predescribed partition, which can be used to
+ * set up a parallel::fullydistributed::Triangulation objects.
+ *
+ * These policies can be also used in context of
+ * MGTransferGlobalCoarseningTools::create_geometric_coarsening_sequence() to
+ * prescribe arbitrary partitioning in multgrid levels of global coarsening
+ * multigrid schmeme.
+ */
+namespace RepartitioningPolicyTools
+{
+ /**
+ * A base class of a repartitioning policy.
+ */
+ template <int dim, int spacedim = dim>
+ class Base
+ {
+ public:
+ /**
+ * Return a vector of the new owners of the active locally owned and ghost
+ * cells.
+ */
+ virtual LinearAlgebra::distributed::Vector<double>
+ partition(const Triangulation<dim, spacedim> &tria_coarse_in) const = 0;
+ };
+
+ /**
+ * A dummy policy that simply returns an empty vector, which is interpreted
+ * in MGTransferGlobalCoarseningTools::create_geometric_coarsening_sequence()
+ * in a way that the triangulation is not repartitioned.
+ */
+ template <int dim, int spacedim = dim>
+ class DefaultPolicy : public Base<dim, spacedim>
+ {
+ public:
+ virtual LinearAlgebra::distributed::Vector<double>
+ partition(
+ const Triangulation<dim, spacedim> &tria_coarse_in) const override;
+ };
+
+ /**
+ * A policy that partitions coarse grids based on a base triangulation
+ * according to a first-child policy. The triangulation to be partitioned
+ * should be able to be obtained by a sequence of (global) coarsening steps.
+ */
+ template <int dim, int spacedim = dim>
+ class FirstChildPolicy : public Base<dim, spacedim>
+ {
+ public:
+ /**
+ * Constructor taking the base (fine) triangulation.
+ */
+ FirstChildPolicy(const Triangulation<dim, spacedim> &tria_fine);
+
+ virtual LinearAlgebra::distributed::Vector<double>
+ partition(
+ const Triangulation<dim, spacedim> &tria_coarse_in) const override;
+
+ private:
+ /**
+ * Number of coarse cells.
+ */
+ const unsigned int n_coarse_cells;
+
+ /**
+ * Number of global levels.
+ */
+ const unsigned int n_global_levels;
+
+ /**
+ * Index set constructed from the triangulation passed to the constructor.
+ * It contains all the cells that would be owned by the current process
+ * if the levels would be partitioned according to a first-child policy.
+ */
+ IndexSet is_level_partitions;
+ };
+
+ /**
+ * A policy that allows to specify a minimal number of cells per process. If
+ * a threshold is reached, processes might be left without cells.
+ */
+ template <int dim, int spacedim = dim>
+ class MinimalGranularityPolicy : public Base<dim, spacedim>
+ {
+ public:
+ /**
+ * Constructor taking the minimum number of cells per process.
+ */
+ MinimalGranularityPolicy(const unsigned int n_min_cells);
+
+ virtual LinearAlgebra::distributed::Vector<double>
+ partition(const Triangulation<dim, spacedim> &tria_in) const override;
+
+ private:
+ /**
+ * Minimum number of cells per process.
+ */
+ const unsigned int n_min_cells;
+ };
+
+} // namespace RepartitioningPolicyTools
+
+DEAL_II_NAMESPACE_CLOSE
+
+#endif
cell_weights.cc
cell_data_transfer.cc
fully_distributed_tria.cc
+ repartitioning_policy_tools.cc
solution_transfer.cc
tria.cc
tria_base.cc
cell_weights.inst.in
cell_data_transfer.inst.in
fully_distributed_tria.inst.in
+ repartitioning_policy_tools.inst.in
solution_transfer.inst.in
tria.inst.in
shared_tria.inst.in
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 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.
+//
+// ---------------------------------------------------------------------
+
+
+#include <deal.II/base/mpi_compute_index_owner_internal.h>
+#include <deal.II/base/mpi_consensus_algorithms.h>
+
+#include <deal.II/distributed/repartitioning_policy_tools.h>
+
+#include <deal.II/multigrid/mg_transfer_global_coarsening.templates.h>
+
+DEAL_II_NAMESPACE_OPEN
+
+
+namespace RepartitioningPolicyTools
+{
+ namespace
+ {
+ template <typename MeshType>
+ unsigned int
+ compute_n_coarse_cells(const MeshType &mesh)
+ {
+ types::coarse_cell_id n_coarse_cells = 0;
+
+ for (const auto &cell :
+ mesh.get_triangulation().cell_iterators_on_level(0))
+ n_coarse_cells =
+ std::max(n_coarse_cells, cell->id().get_coarse_cell_id());
+
+ return Utilities::MPI::max(n_coarse_cells, mesh.get_communicator()) + 1;
+ }
+
+
+
+ template <typename MeshType>
+ unsigned int
+ compute_n_global_levels(const MeshType &mesh)
+ {
+ return mesh.get_triangulation().n_global_levels();
+ }
+
+
+
+ template <int dim, int spacedim>
+ void
+ add_indices_recursevly_for_first_child_policy(
+ const TriaIterator<CellAccessor<dim, spacedim>> &cell,
+ const internal::CellIDTranslator<dim> & cell_id_translator,
+ IndexSet & is_fine)
+ {
+ is_fine.add_index(cell_id_translator.translate(cell));
+
+ if (cell->level() > 0 &&
+ (cell->index() % GeometryInfo<dim>::max_children_per_cell) == 0)
+ add_indices_recursevly_for_first_child_policy(cell->parent(),
+ cell_id_translator,
+ is_fine);
+ }
+ } // namespace
+
+ template <int dim, int spacedim>
+ LinearAlgebra::distributed::Vector<double>
+ DefaultPolicy<dim, spacedim>::partition(
+ const Triangulation<dim, spacedim> &) const
+ {
+ return {}; // nothing to do
+ }
+
+
+
+ template <int dim, int spacedim>
+ FirstChildPolicy<dim, spacedim>::FirstChildPolicy(
+ const Triangulation<dim, spacedim> &tria_fine)
+ : n_coarse_cells(compute_n_coarse_cells(tria_fine))
+ , n_global_levels(compute_n_global_levels(tria_fine))
+ {
+ Assert(
+ tria_fine.all_reference_cells_are_hyper_cube(),
+ ExcMessage(
+ "FirstChildPolicy is only working for pure hex meshes at the moment."))
+
+ const internal::CellIDTranslator<dim>
+ cell_id_translator(n_coarse_cells, n_global_levels);
+ is_level_partitions.set_size(cell_id_translator.size());
+
+ for (const auto &cell : tria_fine.active_cell_iterators())
+ if (cell->is_locally_owned())
+ add_indices_recursevly_for_first_child_policy(cell,
+ cell_id_translator,
+ is_level_partitions);
+ }
+
+
+
+ template <int dim, int spacedim>
+ LinearAlgebra::distributed::Vector<double>
+ FirstChildPolicy<dim, spacedim>::partition(
+ const Triangulation<dim, spacedim> &tria_coarse_in) const
+ {
+ const auto communicator = tria_coarse_in.get_communicator();
+
+ const internal::CellIDTranslator<dim> cell_id_translator(n_coarse_cells,
+ n_global_levels);
+
+ IndexSet is_coarse(cell_id_translator.size());
+
+ for (const auto &cell : tria_coarse_in.active_cell_iterators())
+ if (cell->is_locally_owned())
+ is_coarse.add_index(cell_id_translator.translate(cell));
+
+ std::vector<unsigned int> owning_ranks_of_coarse_cells(
+ is_coarse.n_elements());
+ {
+ Utilities::MPI::internal::ComputeIndexOwner::ConsensusAlgorithmsPayload
+ process(is_level_partitions,
+ is_coarse,
+ communicator,
+ owning_ranks_of_coarse_cells,
+ false);
+
+ Utilities::MPI::ConsensusAlgorithms::Selector<
+ std::pair<types::global_cell_index, types::global_cell_index>,
+ unsigned int>
+ consensus_algorithm(process, communicator);
+ consensus_algorithm.run();
+ }
+
+ const auto tria =
+ dynamic_cast<const parallel::TriangulationBase<dim, spacedim> *>(
+ &tria_coarse_in);
+
+ Assert(tria, ExcNotImplemented());
+
+ LinearAlgebra::distributed::Vector<double> partition(
+ tria->global_active_cell_index_partitioner().lock());
+
+ for (const auto &cell : tria_coarse_in.active_cell_iterators())
+ if (cell->is_locally_owned())
+ partition[cell->global_active_cell_index()] =
+ owning_ranks_of_coarse_cells[is_coarse.index_within_set(
+ cell_id_translator.translate(cell))];
+
+ partition.update_ghost_values();
+
+ return partition;
+ }
+
+
+ template <int dim, int spacedim>
+ MinimalGranularityPolicy<dim, spacedim>::MinimalGranularityPolicy(
+ const unsigned int n_min_cells)
+ : n_min_cells(n_min_cells)
+ {}
+
+
+
+ template <int dim, int spacedim>
+ LinearAlgebra::distributed::Vector<double>
+ MinimalGranularityPolicy<dim, spacedim>::partition(
+ const Triangulation<dim, spacedim> &tria_in) const
+ {
+ const auto tria =
+ dynamic_cast<const parallel::TriangulationBase<dim, spacedim> *>(
+ &tria_in);
+
+ Assert(tria, ExcNotImplemented());
+
+ LinearAlgebra::distributed::Vector<double> partition(
+ tria->global_active_cell_index_partitioner().lock());
+
+ // step 1) check if all processes have enough cells
+
+ unsigned int n_locally_owned_active_cells = 0;
+ for (const auto &cell : tria_in.active_cell_iterators())
+ if (cell->is_locally_owned())
+ ++n_locally_owned_active_cells;
+
+ const auto comm = tria_in.get_communicator();
+
+ if (Utilities::MPI::min(n_locally_owned_active_cells, comm) >= n_min_cells)
+ return {}; // all processes have enough cells
+
+ // step 2) there are processes which do not have enough cells so that
+ // a repartitioning kicks in with the aim that all processes that own
+ // cells have at least the specified number of cells
+
+ const unsigned int n_global_active_cells = tria_in.n_global_active_cells();
+
+ const unsigned int n_partitions =
+ std::max<unsigned int>(1,
+ std::min(n_global_active_cells / n_min_cells,
+ Utilities::MPI::n_mpi_processes(comm)));
+
+ const unsigned int min_cells = n_global_active_cells / n_partitions;
+
+ const auto convert = [&](const unsigned int i) {
+ // determine the owner of a given index: we try to assign each process
+ // the same number of cells; if there is a remainder, we assign the
+ // first processes an additional cell (so that the difference of number of
+ // locally owned cells is never larger than one between processes).
+ if (i < (i / min_cells) * min_cells + (n_global_active_cells % min_cells))
+ return i / (min_cells + 1);
+ else
+ return (i - (n_global_active_cells % min_cells)) / min_cells;
+ };
+
+ for (const auto i : partition.locally_owned_elements())
+ partition[i] = convert(i);
+
+ partition.update_ghost_values();
+
+ return partition;
+ }
+
+
+} // namespace RepartitioningPolicyTools
+
+
+
+/*-------------- Explicit Instantiations -------------------------------*/
+#include "repartitioning_policy_tools.inst"
+
+DEAL_II_NAMESPACE_CLOSE
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : SPACE_DIMENSIONS)
+ {
+#if deal_II_dimension <= deal_II_space_dimension
+ template class RepartitioningPolicyTools::
+ DefaultPolicy<deal_II_dimension, deal_II_space_dimension>;
+
+ template class RepartitioningPolicyTools::
+ FirstChildPolicy<deal_II_dimension, deal_II_space_dimension>;
+
+ template class RepartitioningPolicyTools::
+ MinimalGranularityPolicy<deal_II_dimension, deal_II_space_dimension>;
+
+#endif
+ }
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 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.
+//
+// ---------------------------------------------------------------------
+
+
+// Test different partitioning policies from RepartitioningPolicyTools.
+
+
+#include <deal.II/base/mpi_consensus_algorithms.h>
+
+#include <deal.II/distributed/fully_distributed_tria.h>
+#include <deal.II/distributed/repartitioning_policy_tools.h>
+#include <deal.II/distributed/tria.h>
+
+#include <deal.II/fe/fe_q.h>
+
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/grid/grid_out.h>
+#include <deal.II/grid/grid_tools.h>
+#include <deal.II/grid/tria_description.h>
+
+#include <deal.II/lac/la_parallel_vector.h>
+
+#include <deal.II/numerics/data_out.h>
+
+#include "tests.h"
+
+using namespace dealii;
+
+template <int dim, int spacedim>
+void
+create_triangulation(Triangulation<dim, spacedim> &tria)
+{
+ const unsigned int n_ref_global = 3;
+ const unsigned int n_ref_local = 3;
+ GridGenerator::hyper_cube(tria, -1.0, +1.0);
+ tria.refine_global(n_ref_global);
+
+ for (unsigned int i = 0; i < n_ref_local; ++i)
+ {
+ for (auto cell : tria.active_cell_iterators())
+ if (cell->is_locally_owned())
+ {
+ bool flag = true;
+ for (unsigned int d = 0; d < dim; d++)
+ if (cell->center()[d] > 0.0)
+ flag = false;
+ if (flag)
+ cell->set_refine_flag();
+ }
+ tria.execute_coarsening_and_refinement();
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ Utilities::MPI::MPI_InitFinalize mpi(argc, argv, 1);
+ MPILogInitAll all;
+
+ const unsigned int dim = 2;
+ const MPI_Comm comm = MPI_COMM_WORLD;
+
+ parallel::distributed::Triangulation<dim> tria(comm);
+ create_triangulation(tria);
+
+ const auto test = [&](const auto &policy, const std::string &label) {
+ const auto partition_new = policy.partition(tria);
+ partition_new.update_ghost_values();
+
+ // repartition triangulation so that it has strided partitioning
+ const auto construction_data =
+ partition_new.size() == 0 ?
+ TriangulationDescription::Utilities::
+ create_description_from_triangulation(tria, comm) :
+ TriangulationDescription::Utilities::
+ create_description_from_triangulation(tria, partition_new);
+
+ parallel::fullydistributed::Triangulation<dim> tria_pft(comm);
+ tria_pft.create_triangulation(construction_data);
+
+ FE_Q<dim> fe(2);
+ DoFHandler<dim> dof_handler(tria_pft);
+ dof_handler.distribute_dofs(fe);
+
+ // print statistics
+ deallog.push(label);
+ print_statistics(tria_pft);
+ print_statistics(dof_handler);
+ deallog.pop();
+ };
+
+ // default policy (simply copy p:d:T)
+ test(RepartitioningPolicyTools::DefaultPolicy<dim>(), "grid_policy_default");
+
+ // first-child policy
+ test(RepartitioningPolicyTools::FirstChildPolicy<dim>(tria),
+ "grid_policy_first");
+
+ // first-child policy
+ test(RepartitioningPolicyTools::MinimalGranularityPolicy<dim>(4),
+ "grid_policy_minimal_4");
+ test(RepartitioningPolicyTools::MinimalGranularityPolicy<dim>(100),
+ "grid_policy_minimal_100");
+ test(RepartitioningPolicyTools::MinimalGranularityPolicy<dim>(500),
+ "grid_policy_minimal_500");
+}
--- /dev/null
+
+DEAL:0:grid_policy_default::n_levels: 7
+DEAL:0:grid_policy_default::n_cells: 465
+DEAL:0:grid_policy_default::n_active_cells: 349
+DEAL:0:grid_policy_default::
+DEAL:0:grid_policy_default::n_dofs: 4813
+DEAL:0:grid_policy_default::n_locally_owned_dofs: 993
+DEAL:0:grid_policy_default::
+DEAL:0:grid_policy_first::n_levels: 7
+DEAL:0:grid_policy_first::n_cells: 465
+DEAL:0:grid_policy_first::n_active_cells: 349
+DEAL:0:grid_policy_first::
+DEAL:0:grid_policy_first::n_dofs: 4813
+DEAL:0:grid_policy_first::n_locally_owned_dofs: 993
+DEAL:0:grid_policy_first::
+DEAL:0:grid_policy_minimal_4::n_levels: 7
+DEAL:0:grid_policy_minimal_4::n_cells: 465
+DEAL:0:grid_policy_minimal_4::n_active_cells: 349
+DEAL:0:grid_policy_minimal_4::
+DEAL:0:grid_policy_minimal_4::n_dofs: 4813
+DEAL:0:grid_policy_minimal_4::n_locally_owned_dofs: 993
+DEAL:0:grid_policy_minimal_4::
+DEAL:0:grid_policy_minimal_100::n_levels: 7
+DEAL:0:grid_policy_minimal_100::n_cells: 465
+DEAL:0:grid_policy_minimal_100::n_active_cells: 349
+DEAL:0:grid_policy_minimal_100::
+DEAL:0:grid_policy_minimal_100::n_dofs: 4813
+DEAL:0:grid_policy_minimal_100::n_locally_owned_dofs: 993
+DEAL:0:grid_policy_minimal_100::
+DEAL:0:grid_policy_minimal_500::n_levels: 7
+DEAL:0:grid_policy_minimal_500::n_cells: 1001
+DEAL:0:grid_policy_minimal_500::n_active_cells: 751
+DEAL:0:grid_policy_minimal_500::
+DEAL:0:grid_policy_minimal_500::n_dofs: 4813
+DEAL:0:grid_policy_minimal_500::n_locally_owned_dofs: 2417
+DEAL:0:grid_policy_minimal_500::
+
+DEAL:1:grid_policy_default::n_levels: 7
+DEAL:1:grid_policy_default::n_cells: 577
+DEAL:1:grid_policy_default::n_active_cells: 433
+DEAL:1:grid_policy_default::
+DEAL:1:grid_policy_default::n_dofs: 4813
+DEAL:1:grid_policy_default::n_locally_owned_dofs: 944
+DEAL:1:grid_policy_default::
+DEAL:1:grid_policy_first::n_levels: 7
+DEAL:1:grid_policy_first::n_cells: 577
+DEAL:1:grid_policy_first::n_active_cells: 433
+DEAL:1:grid_policy_first::
+DEAL:1:grid_policy_first::n_dofs: 4813
+DEAL:1:grid_policy_first::n_locally_owned_dofs: 944
+DEAL:1:grid_policy_first::
+DEAL:1:grid_policy_minimal_4::n_levels: 7
+DEAL:1:grid_policy_minimal_4::n_cells: 577
+DEAL:1:grid_policy_minimal_4::n_active_cells: 433
+DEAL:1:grid_policy_minimal_4::
+DEAL:1:grid_policy_minimal_4::n_dofs: 4813
+DEAL:1:grid_policy_minimal_4::n_locally_owned_dofs: 944
+DEAL:1:grid_policy_minimal_4::
+DEAL:1:grid_policy_minimal_100::n_levels: 7
+DEAL:1:grid_policy_minimal_100::n_cells: 577
+DEAL:1:grid_policy_minimal_100::n_active_cells: 433
+DEAL:1:grid_policy_minimal_100::
+DEAL:1:grid_policy_minimal_100::n_dofs: 4813
+DEAL:1:grid_policy_minimal_100::n_locally_owned_dofs: 944
+DEAL:1:grid_policy_minimal_100::
+DEAL:1:grid_policy_minimal_500::n_levels: 7
+DEAL:1:grid_policy_minimal_500::n_cells: 977
+DEAL:1:grid_policy_minimal_500::n_active_cells: 733
+DEAL:1:grid_policy_minimal_500::
+DEAL:1:grid_policy_minimal_500::n_dofs: 4813
+DEAL:1:grid_policy_minimal_500::n_locally_owned_dofs: 2396
+DEAL:1:grid_policy_minimal_500::
+
+
+DEAL:2:grid_policy_default::n_levels: 7
+DEAL:2:grid_policy_default::n_cells: 665
+DEAL:2:grid_policy_default::n_active_cells: 499
+DEAL:2:grid_policy_default::
+DEAL:2:grid_policy_default::n_dofs: 4813
+DEAL:2:grid_policy_default::n_locally_owned_dofs: 960
+DEAL:2:grid_policy_default::
+DEAL:2:grid_policy_first::n_levels: 7
+DEAL:2:grid_policy_first::n_cells: 665
+DEAL:2:grid_policy_first::n_active_cells: 499
+DEAL:2:grid_policy_first::
+DEAL:2:grid_policy_first::n_dofs: 4813
+DEAL:2:grid_policy_first::n_locally_owned_dofs: 960
+DEAL:2:grid_policy_first::
+DEAL:2:grid_policy_minimal_4::n_levels: 7
+DEAL:2:grid_policy_minimal_4::n_cells: 665
+DEAL:2:grid_policy_minimal_4::n_active_cells: 499
+DEAL:2:grid_policy_minimal_4::
+DEAL:2:grid_policy_minimal_4::n_dofs: 4813
+DEAL:2:grid_policy_minimal_4::n_locally_owned_dofs: 960
+DEAL:2:grid_policy_minimal_4::
+DEAL:2:grid_policy_minimal_100::n_levels: 7
+DEAL:2:grid_policy_minimal_100::n_cells: 665
+DEAL:2:grid_policy_minimal_100::n_active_cells: 499
+DEAL:2:grid_policy_minimal_100::
+DEAL:2:grid_policy_minimal_100::n_dofs: 4813
+DEAL:2:grid_policy_minimal_100::n_locally_owned_dofs: 960
+DEAL:2:grid_policy_minimal_100::
+DEAL:2:grid_policy_minimal_500::n_levels: 1
+DEAL:2:grid_policy_minimal_500::n_cells: 1
+DEAL:2:grid_policy_minimal_500::n_active_cells: 1
+DEAL:2:grid_policy_minimal_500::
+DEAL:2:grid_policy_minimal_500::n_dofs: 4813
+DEAL:2:grid_policy_minimal_500::n_locally_owned_dofs: 0
+DEAL:2:grid_policy_minimal_500::
+
+
+DEAL:3:grid_policy_default::n_levels: 7
+DEAL:3:grid_policy_default::n_cells: 657
+DEAL:3:grid_policy_default::n_active_cells: 493
+DEAL:3:grid_policy_default::
+DEAL:3:grid_policy_default::n_dofs: 4813
+DEAL:3:grid_policy_default::n_locally_owned_dofs: 912
+DEAL:3:grid_policy_default::
+DEAL:3:grid_policy_first::n_levels: 7
+DEAL:3:grid_policy_first::n_cells: 657
+DEAL:3:grid_policy_first::n_active_cells: 493
+DEAL:3:grid_policy_first::
+DEAL:3:grid_policy_first::n_dofs: 4813
+DEAL:3:grid_policy_first::n_locally_owned_dofs: 912
+DEAL:3:grid_policy_first::
+DEAL:3:grid_policy_minimal_4::n_levels: 7
+DEAL:3:grid_policy_minimal_4::n_cells: 657
+DEAL:3:grid_policy_minimal_4::n_active_cells: 493
+DEAL:3:grid_policy_minimal_4::
+DEAL:3:grid_policy_minimal_4::n_dofs: 4813
+DEAL:3:grid_policy_minimal_4::n_locally_owned_dofs: 912
+DEAL:3:grid_policy_minimal_4::
+DEAL:3:grid_policy_minimal_100::n_levels: 7
+DEAL:3:grid_policy_minimal_100::n_cells: 657
+DEAL:3:grid_policy_minimal_100::n_active_cells: 493
+DEAL:3:grid_policy_minimal_100::
+DEAL:3:grid_policy_minimal_100::n_dofs: 4813
+DEAL:3:grid_policy_minimal_100::n_locally_owned_dofs: 912
+DEAL:3:grid_policy_minimal_100::
+DEAL:3:grid_policy_minimal_500::n_levels: 1
+DEAL:3:grid_policy_minimal_500::n_cells: 1
+DEAL:3:grid_policy_minimal_500::n_active_cells: 1
+DEAL:3:grid_policy_minimal_500::
+DEAL:3:grid_policy_minimal_500::n_dofs: 4813
+DEAL:3:grid_policy_minimal_500::n_locally_owned_dofs: 0
+DEAL:3:grid_policy_minimal_500::
+
+
+DEAL:4:grid_policy_default::n_levels: 7
+DEAL:4:grid_policy_default::n_cells: 541
+DEAL:4:grid_policy_default::n_active_cells: 406
+DEAL:4:grid_policy_default::
+DEAL:4:grid_policy_default::n_dofs: 4813
+DEAL:4:grid_policy_default::n_locally_owned_dofs: 1004
+DEAL:4:grid_policy_default::
+DEAL:4:grid_policy_first::n_levels: 7
+DEAL:4:grid_policy_first::n_cells: 541
+DEAL:4:grid_policy_first::n_active_cells: 406
+DEAL:4:grid_policy_first::
+DEAL:4:grid_policy_first::n_dofs: 4813
+DEAL:4:grid_policy_first::n_locally_owned_dofs: 1004
+DEAL:4:grid_policy_first::
+DEAL:4:grid_policy_minimal_4::n_levels: 7
+DEAL:4:grid_policy_minimal_4::n_cells: 541
+DEAL:4:grid_policy_minimal_4::n_active_cells: 406
+DEAL:4:grid_policy_minimal_4::
+DEAL:4:grid_policy_minimal_4::n_dofs: 4813
+DEAL:4:grid_policy_minimal_4::n_locally_owned_dofs: 1004
+DEAL:4:grid_policy_minimal_4::
+DEAL:4:grid_policy_minimal_100::n_levels: 7
+DEAL:4:grid_policy_minimal_100::n_cells: 541
+DEAL:4:grid_policy_minimal_100::n_active_cells: 406
+DEAL:4:grid_policy_minimal_100::
+DEAL:4:grid_policy_minimal_100::n_dofs: 4813
+DEAL:4:grid_policy_minimal_100::n_locally_owned_dofs: 1004
+DEAL:4:grid_policy_minimal_100::
+DEAL:4:grid_policy_minimal_500::n_levels: 1
+DEAL:4:grid_policy_minimal_500::n_cells: 1
+DEAL:4:grid_policy_minimal_500::n_active_cells: 1
+DEAL:4:grid_policy_minimal_500::
+DEAL:4:grid_policy_minimal_500::n_dofs: 4813
+DEAL:4:grid_policy_minimal_500::n_locally_owned_dofs: 0
+DEAL:4:grid_policy_minimal_500::
+