From: Peter Munch Date: Sat, 6 Feb 2021 21:54:05 +0000 (+0100) Subject: Add utility functions to create geometric coarsening sequences X-Git-Tag: v9.3.0-rc1~477^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d58cf6b05b80a12e0fc58139017114ef1385b946;p=dealii.git Add utility functions to create geometric coarsening sequences --- diff --git a/include/deal.II/multigrid/mg_transfer_global_coarsening.h b/include/deal.II/multigrid/mg_transfer_global_coarsening.h index c640e407c8..5d4fe9b1e8 100644 --- a/include/deal.II/multigrid/mg_transfer_global_coarsening.h +++ b/include/deal.II/multigrid/mg_transfer_global_coarsening.h @@ -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 + std::vector>> + create_geometric_coarsening_sequence( + const Triangulation &tria); + } // namespace MGTransferGlobalCoarseningTools diff --git a/include/deal.II/multigrid/mg_transfer_global_coarsening.templates.h b/include/deal.II/multigrid/mg_transfer_global_coarsening.templates.h index 104f9784a6..d04c194afa 100644 --- a/include/deal.II/multigrid/mg_transfer_global_coarsening.templates.h +++ b/include/deal.II/multigrid/mg_transfer_global_coarsening.templates.h @@ -27,6 +27,8 @@ #include +#include + #include #include @@ -1659,6 +1661,80 @@ namespace MGTransferGlobalCoarseningTools return degrees; } + + + + template + std::vector>> + create_geometric_coarsening_sequence( + const Triangulation &fine_triangulation_in) + { + std::vector>> + coarse_grid_triangulations; + +#ifndef DEAL_II_WITH_P4EST + (void)fine_triangulation_in; + Assert(false, ExcNotImplemented()); +#else + const auto fine_triangulation = + dynamic_cast *>( + &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 *>(&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 *>( + coarse_grid_triangulations[l].get()) + ->save("mesh"); + MPI_Barrier(fine_triangulation->get_communicator()); + + // create empty triangulation + auto new_tria = + std::make_shared>( + 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 diff --git a/source/multigrid/mg_transfer_global_coarsening.inst.in b/source/multigrid/mg_transfer_global_coarsening.inst.in index 80cb0daca4..458227c55b 100644 --- a/source/multigrid/mg_transfer_global_coarsening.inst.in +++ b/source/multigrid/mg_transfer_global_coarsening.inst.in @@ -20,3 +20,14 @@ for (deal_II_dimension : DIMENSIONS; S1 : REAL_SCALARS) template class MGTwoLevelTransfer>; } + +for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : SPACE_DIMENSIONS) + { +#if deal_II_dimension <= deal_II_space_dimension + template std::vector>> + MGTransferGlobalCoarseningTools::create_geometric_coarsening_sequence( + const Triangulation + &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 index 0000000000..c0fa232c67 --- /dev/null +++ b/tests/multigrid-global-coarsening/create_geometric_coarsening_sequence_01.cc @@ -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 + +#include + +#include + +#include "../tests.h" + +using namespace dealii; + +template +void +test() +{ + parallel::distributed::Triangulation 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 index 0000000000..c5c52a2b4b --- /dev/null +++ b/tests/multigrid-global-coarsening/create_geometric_coarsening_sequence_01.with_p4est=true.mpirun=1.output @@ -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 index 0000000000..d3b4999d73 --- /dev/null +++ b/tests/multigrid-global-coarsening/create_geometric_coarsening_sequence_01.with_p4est=true.mpirun=2.output @@ -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:: +