const unsigned int max_degree,
const PolynomialCoarseningSequenceType &p_sequence);
+ /**
+ * For a given triangulation @p tria, determine the geometric coarsening
+ * sequence by repeated global coarsening of the provided triangulation.
+ *
+ * @note For convenience, a reference to the input triangulation is stored in
+ * the last entry of the return vector.
+ * @note Currently, only implemented for parallel::distributed::Triangulation.
+ */
+ template <int dim, int spacedim>
+ std::vector<std::shared_ptr<Triangulation<dim, spacedim>>>
+ create_geometric_coarsening_sequence(
+ const Triangulation<dim, spacedim> &tria);
+
} // namespace MGTransferGlobalCoarseningTools
#include <deal.II/fe/fe_tools.h>
+#include <deal.II/grid/grid_tools.h>
+
#include <deal.II/hp/dof_handler.h>
#include <deal.II/matrix_free/evaluation_kernels.h>
return degrees;
}
+
+
+
+ template <int dim, int spacedim>
+ std::vector<std::shared_ptr<Triangulation<dim, spacedim>>>
+ create_geometric_coarsening_sequence(
+ const Triangulation<dim, spacedim> &fine_triangulation_in)
+ {
+ std::vector<std::shared_ptr<Triangulation<dim, spacedim>>>
+ coarse_grid_triangulations;
+
+#ifndef DEAL_II_WITH_P4EST
+ (void)fine_triangulation_in;
+ Assert(false, ExcNotImplemented());
+#else
+ const auto fine_triangulation =
+ dynamic_cast<const parallel::distributed::Triangulation<dim, spacedim> *>(
+ &fine_triangulation_in);
+
+ Assert(fine_triangulation, ExcNotImplemented());
+
+ const unsigned int max_level = fine_triangulation->n_global_levels() - 1;
+
+ const auto coarse_mesh_description =
+ GridTools::get_coarse_mesh_description(*fine_triangulation);
+
+ coarse_grid_triangulations.resize(fine_triangulation->n_global_levels());
+
+ coarse_grid_triangulations[max_level].reset(
+ const_cast<Triangulation<dim, spacedim> *>(&fine_triangulation_in),
+ [](auto &) {
+ // empty deleter, since fine_triangulation_in is an external field
+ // and its destructor is called somewhere else
+ });
+
+ // create coarse meshes
+ for (unsigned int l = max_level; l > 0; --l)
+ {
+ // store finer mesh to file
+ dynamic_cast<
+ const parallel::distributed::Triangulation<dim, spacedim> *>(
+ coarse_grid_triangulations[l].get())
+ ->save("mesh");
+ MPI_Barrier(fine_triangulation->get_communicator());
+
+ // create empty triangulation
+ auto new_tria =
+ std::make_shared<parallel::distributed::Triangulation<dim, spacedim>>(
+ fine_triangulation->get_communicator(),
+ fine_triangulation->get_mesh_smoothing());
+
+ // create coarse grid
+ new_tria->create_triangulation(std::get<0>(coarse_mesh_description),
+ std::get<1>(coarse_mesh_description),
+ std::get<2>(coarse_mesh_description));
+
+ for (const auto i : fine_triangulation->get_manifold_ids())
+ if (i != numbers::flat_manifold_id)
+ new_tria->set_manifold(i, fine_triangulation->get_manifold(i));
+
+ // create refinement hierarchy (by loading stored mesh)
+ new_tria->load("mesh", false);
+ MPI_Barrier(fine_triangulation->get_communicator());
+
+ // coarsen mesh
+ new_tria->coarsen_global();
+
+ // save mesh
+ coarse_grid_triangulations[l - 1] = new_tria;
+ }
+#endif
+
+ return coarse_grid_triangulations;
+ }
} // namespace MGTransferGlobalCoarseningTools
template class MGTwoLevelTransfer<deal_II_dimension,
LinearAlgebra::distributed::Vector<S1>>;
}
+
+for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : SPACE_DIMENSIONS)
+ {
+#if deal_II_dimension <= deal_II_space_dimension
+ template std::vector<std::shared_ptr<
+ Triangulation<deal_II_dimension, deal_II_space_dimension>>>
+ MGTransferGlobalCoarseningTools::create_geometric_coarsening_sequence(
+ const Triangulation<deal_II_dimension, deal_II_space_dimension>
+ &fine_triangulation_in);
+#endif
+ }
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2020 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 MGTransferGlobalCoarseningTools::create_geometric_coarsening_sequence.
+ */
+
+#include <deal.II/distributed/tria.h>
+
+#include <deal.II/grid/grid_generator.h>
+
+#include <deal.II/multigrid/mg_transfer_global_coarsening.h>
+
+#include "../tests.h"
+
+using namespace dealii;
+
+template <int dim>
+void
+test()
+{
+ parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD);
+ GridGenerator::hyper_cube(tria, -1.0, +1.0);
+
+ tria.refine_global(1);
+
+ // refine cells in the first quadrant
+ for (unsigned int i = 1; i < 3; i++)
+ {
+ for (auto cell : tria.active_cell_iterators())
+ if (cell->is_locally_owned())
+ {
+ bool flag = true;
+ for (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();
+ }
+
+ const auto trias =
+ MGTransferGlobalCoarseningTools::create_geometric_coarsening_sequence(tria);
+
+ for (const auto &tria : trias)
+ {
+ for (const auto &cell : tria->active_cell_iterators())
+ if (cell->is_locally_owned())
+ deallog << cell->id() << std::endl;
+ deallog << std::endl;
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1);
+ MPILogInitAll all;
+
+ deallog.precision(8);
+
+ test<2>();
+}
--- /dev/null
+
+DEAL:0::0_0:
+DEAL:0::
+DEAL:0::0_1:0
+DEAL:0::0_1:1
+DEAL:0::0_1:2
+DEAL:0::0_1:3
+DEAL:0::
+DEAL:0::0_1:1
+DEAL:0::0_1:2
+DEAL:0::0_1:3
+DEAL:0::0_2:00
+DEAL:0::0_2:01
+DEAL:0::0_2:02
+DEAL:0::0_2:03
+DEAL:0::
+DEAL:0::0_2:10
+DEAL:0::0_2:11
+DEAL:0::0_2:12
+DEAL:0::0_2:13
+DEAL:0::0_2:20
+DEAL:0::0_2:21
+DEAL:0::0_2:22
+DEAL:0::0_2:23
+DEAL:0::0_2:30
+DEAL:0::0_2:31
+DEAL:0::0_2:32
+DEAL:0::0_2:33
+DEAL:0::0_3:000
+DEAL:0::0_3:001
+DEAL:0::0_3:002
+DEAL:0::0_3:003
+DEAL:0::0_3:010
+DEAL:0::0_3:011
+DEAL:0::0_3:012
+DEAL:0::0_3:013
+DEAL:0::0_3:020
+DEAL:0::0_3:021
+DEAL:0::0_3:022
+DEAL:0::0_3:023
+DEAL:0::0_3:030
+DEAL:0::0_3:031
+DEAL:0::0_3:032
+DEAL:0::0_3:033
+DEAL:0::
--- /dev/null
+
+DEAL:0::
+DEAL:0::0_1:0
+DEAL:0::0_1:1
+DEAL:0::0_1:2
+DEAL:0::0_1:3
+DEAL:0::
+DEAL:0::0_2:00
+DEAL:0::0_2:01
+DEAL:0::0_2:02
+DEAL:0::0_2:03
+DEAL:0::
+DEAL:0::0_3:000
+DEAL:0::0_3:001
+DEAL:0::0_3:002
+DEAL:0::0_3:003
+DEAL:0::0_3:010
+DEAL:0::0_3:011
+DEAL:0::0_3:012
+DEAL:0::0_3:013
+DEAL:0::0_3:020
+DEAL:0::0_3:021
+DEAL:0::0_3:022
+DEAL:0::0_3:023
+DEAL:0::0_3:030
+DEAL:0::0_3:031
+DEAL:0::0_3:032
+DEAL:0::0_3:033
+DEAL:0::
+
+DEAL:1::0_0:
+DEAL:1::
+DEAL:1::
+DEAL:1::0_1:1
+DEAL:1::0_1:2
+DEAL:1::0_1:3
+DEAL:1::
+DEAL:1::0_2:10
+DEAL:1::0_2:11
+DEAL:1::0_2:12
+DEAL:1::0_2:13
+DEAL:1::0_2:20
+DEAL:1::0_2:21
+DEAL:1::0_2:22
+DEAL:1::0_2:23
+DEAL:1::0_2:30
+DEAL:1::0_2:31
+DEAL:1::0_2:32
+DEAL:1::0_2:33
+DEAL:1::
+