]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Add utility functions to create geometric coarsening sequences 11707/head
authorPeter Munch <peterrmuench@gmail.com>
Sat, 6 Feb 2021 21:54:05 +0000 (22:54 +0100)
committerPeter Munch <peterrmuench@gmail.com>
Tue, 9 Feb 2021 13:52:21 +0000 (14:52 +0100)
include/deal.II/multigrid/mg_transfer_global_coarsening.h
include/deal.II/multigrid/mg_transfer_global_coarsening.templates.h
source/multigrid/mg_transfer_global_coarsening.inst.in
tests/multigrid-global-coarsening/create_geometric_coarsening_sequence_01.cc [new file with mode: 0644]
tests/multigrid-global-coarsening/create_geometric_coarsening_sequence_01.with_p4est=true.mpirun=1.output [new file with mode: 0644]
tests/multigrid-global-coarsening/create_geometric_coarsening_sequence_01.with_p4est=true.mpirun=2.output [new file with mode: 0644]

index c640e407c87fe33cbd522c95723d7f3b9a7119a5..5d4fe9b1e8af323694b00ed592b2ec48781193bd 100644 (file)
@@ -87,6 +87,19 @@ namespace MGTransferGlobalCoarseningTools
     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
 
 
index 104f9784a68f82dfa76ad1023c4f159579f18055..d04c194afab15426487867b82b4fb0391c74d591 100644 (file)
@@ -27,6 +27,8 @@
 
 #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>
@@ -1659,6 +1661,80 @@ namespace MGTransferGlobalCoarseningTools
 
     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
 
 
index 80cb0daca46d8ef0cab6c2d84d5e7ab1c508ad49..458227c55ba13c033e89fb526687b9cb36c49958 100644 (file)
@@ -20,3 +20,14 @@ for (deal_II_dimension : DIMENSIONS; S1 : REAL_SCALARS)
     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
+  }
diff --git a/tests/multigrid-global-coarsening/create_geometric_coarsening_sequence_01.cc b/tests/multigrid-global-coarsening/create_geometric_coarsening_sequence_01.cc
new file mode 100644 (file)
index 0000000..c0fa232
--- /dev/null
@@ -0,0 +1,77 @@
+// ---------------------------------------------------------------------
+//
+// 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>();
+}
diff --git a/tests/multigrid-global-coarsening/create_geometric_coarsening_sequence_01.with_p4est=true.mpirun=1.output b/tests/multigrid-global-coarsening/create_geometric_coarsening_sequence_01.with_p4est=true.mpirun=1.output
new file mode 100644 (file)
index 0000000..c5c52a2
--- /dev/null
@@ -0,0 +1,45 @@
+
+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::
diff --git a/tests/multigrid-global-coarsening/create_geometric_coarsening_sequence_01.with_p4est=true.mpirun=2.output b/tests/multigrid-global-coarsening/create_geometric_coarsening_sequence_01.with_p4est=true.mpirun=2.output
new file mode 100644 (file)
index 0000000..d3b4999
--- /dev/null
@@ -0,0 +1,51 @@
+
+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::
+

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.