From b7f9a01abbacdc3243f3c71d82cd187f5d0eb1c8 Mon Sep 17 00:00:00 2001 From: Peter Munch Date: Sat, 6 Feb 2021 22:13:49 +0100 Subject: [PATCH] Add utility functions to create polynomial coarsening sequences --- .../multigrid/mg_transfer_global_coarsening.h | 54 +++++++++++++++++++ .../mg_transfer_global_coarsening.templates.h | 43 +++++++++++++++ ...reate_polynomial_coarsening_sequence_01.cc | 52 ++++++++++++++++++ ...e_polynomial_coarsening_sequence_01.output | 49 +++++++++++++++++ .../multigrid_p_01.cc | 8 +-- .../multigrid_util.h | 51 ------------------ 6 files changed, 203 insertions(+), 54 deletions(-) create mode 100644 tests/multigrid-global-coarsening/create_polynomial_coarsening_sequence_01.cc create mode 100644 tests/multigrid-global-coarsening/create_polynomial_coarsening_sequence_01.output diff --git a/include/deal.II/multigrid/mg_transfer_global_coarsening.h b/include/deal.II/multigrid/mg_transfer_global_coarsening.h index dc88c7e8fa..c640e407c8 100644 --- a/include/deal.II/multigrid/mg_transfer_global_coarsening.h +++ b/include/deal.II/multigrid/mg_transfer_global_coarsening.h @@ -37,6 +37,60 @@ namespace internal +/** + * Global coarsening utility functions. + */ +namespace MGTransferGlobalCoarseningTools +{ + /** + * Common polynomial coarsening sequences. + * + * @note These polynomial coarsening sequences up to a degree of 9 are + * precompiled in MGTwoLevelTransfer. See also: + * MGTwoLevelTransfer::fast_polynomial_transfer_supported() + */ + enum class PolynomialCoarseningSequenceType + { + /** + * Half polynomial degree by integer division. For example, for degree=7 + * the following sequence would be obtained:: 7 -> 3 -> 1 + */ + bisect, + /** + * Decrease the polynomial degree by one. E.g., for degree=7 following + * sequence would result: 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 + */ + decrease_by_one, + /** + * Decrease the polynomial degree to one. E.g., for degree=7 following + * sequence would result: 7 -> 1 + */ + go_to_one + }; + + /** + * For a given @p degree and polynomial coarsening sequence @p p_sequence, + * determine the next coarser degree. + */ + unsigned int + create_next_polynomial_coarsening_degree( + const unsigned int degree, + const PolynomialCoarseningSequenceType &p_sequence); + + /** + * For a given @p max_degree and polynomial coarsening sequence @p p_sequence, + * determine the full sequence of polynomial degrees, sorted in ascending + * order. + */ + std::vector + create_polynomial_coarsening_sequence( + const unsigned int max_degree, + const PolynomialCoarseningSequenceType &p_sequence); + +} // namespace MGTransferGlobalCoarseningTools + + + /** * Class for transfer between two multigrid levels for p- or global coarsening. */ 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 4985e28000..104f9784a6 100644 --- a/include/deal.II/multigrid/mg_transfer_global_coarsening.templates.h +++ b/include/deal.II/multigrid/mg_transfer_global_coarsening.templates.h @@ -1620,6 +1620,49 @@ namespace internal } // namespace internal + +namespace MGTransferGlobalCoarseningTools +{ + unsigned int + create_next_polynomial_coarsening_degree( + const unsigned int previous_fe_degree, + const PolynomialCoarseningSequenceType &p_sequence) + { + switch (p_sequence) + { + case PolynomialCoarseningSequenceType::bisect: + return std::max(previous_fe_degree / 2, 1u); + case PolynomialCoarseningSequenceType::decrease_by_one: + return std::max(previous_fe_degree - 1, 1u); + case PolynomialCoarseningSequenceType::go_to_one: + return 1u; + default: + Assert(false, StandardExceptions::ExcNotImplemented()); + return 1u; + } + } + + + + std::vector + create_polynomial_coarsening_sequence( + const unsigned int max_degree, + const PolynomialCoarseningSequenceType &p_sequence) + { + std::vector degrees{max_degree}; + + while (degrees.back() > 1) + degrees.push_back( + create_next_polynomial_coarsening_degree(degrees.back(), p_sequence)); + + std::reverse(degrees.begin(), degrees.end()); + + return degrees; + } +} // namespace MGTransferGlobalCoarseningTools + + + template void MGTwoLevelTransfer>::prolongate( diff --git a/tests/multigrid-global-coarsening/create_polynomial_coarsening_sequence_01.cc b/tests/multigrid-global-coarsening/create_polynomial_coarsening_sequence_01.cc new file mode 100644 index 0000000000..60289e4161 --- /dev/null +++ b/tests/multigrid-global-coarsening/create_polynomial_coarsening_sequence_01.cc @@ -0,0 +1,52 @@ +// --------------------------------------------------------------------- +// +// 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. +// +// --------------------------------------------------------------------- + +// Print all polynomial coarsening sequences up to degree 15. + +#include + +#include "../tests.h" + +using namespace dealii; + +void +test( + const MGTransferGlobalCoarseningTools::PolynomialCoarseningSequenceType type) +{ + for (unsigned int i = 1; i <= 15; i++) + { + const auto sequence = + MGTransferGlobalCoarseningTools::create_polynomial_coarsening_sequence( + i, type); + + for (const auto i : sequence) + deallog << i << " "; + deallog << std::endl; + } + deallog << std::endl; +} + +int +main() +{ + initlog(); + + test( + MGTransferGlobalCoarseningTools::PolynomialCoarseningSequenceType::bisect); + test(MGTransferGlobalCoarseningTools::PolynomialCoarseningSequenceType:: + decrease_by_one); + test(MGTransferGlobalCoarseningTools::PolynomialCoarseningSequenceType:: + go_to_one); +} diff --git a/tests/multigrid-global-coarsening/create_polynomial_coarsening_sequence_01.output b/tests/multigrid-global-coarsening/create_polynomial_coarsening_sequence_01.output new file mode 100644 index 0000000000..b8394d2ed5 --- /dev/null +++ b/tests/multigrid-global-coarsening/create_polynomial_coarsening_sequence_01.output @@ -0,0 +1,49 @@ + +DEAL::1 +DEAL::1 2 +DEAL::1 3 +DEAL::1 2 4 +DEAL::1 2 5 +DEAL::1 3 6 +DEAL::1 3 7 +DEAL::1 2 4 8 +DEAL::1 2 4 9 +DEAL::1 2 5 10 +DEAL::1 2 5 11 +DEAL::1 3 6 12 +DEAL::1 3 6 13 +DEAL::1 3 7 14 +DEAL::1 3 7 15 +DEAL:: +DEAL::1 +DEAL::1 2 +DEAL::1 2 3 +DEAL::1 2 3 4 +DEAL::1 2 3 4 5 +DEAL::1 2 3 4 5 6 +DEAL::1 2 3 4 5 6 7 +DEAL::1 2 3 4 5 6 7 8 +DEAL::1 2 3 4 5 6 7 8 9 +DEAL::1 2 3 4 5 6 7 8 9 10 +DEAL::1 2 3 4 5 6 7 8 9 10 11 +DEAL::1 2 3 4 5 6 7 8 9 10 11 12 +DEAL::1 2 3 4 5 6 7 8 9 10 11 12 13 +DEAL::1 2 3 4 5 6 7 8 9 10 11 12 13 14 +DEAL::1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +DEAL:: +DEAL::1 +DEAL::1 2 +DEAL::1 3 +DEAL::1 4 +DEAL::1 5 +DEAL::1 6 +DEAL::1 7 +DEAL::1 8 +DEAL::1 9 +DEAL::1 10 +DEAL::1 11 +DEAL::1 12 +DEAL::1 13 +DEAL::1 14 +DEAL::1 15 +DEAL:: diff --git a/tests/multigrid-global-coarsening/multigrid_p_01.cc b/tests/multigrid-global-coarsening/multigrid_p_01.cc index 623d35b62d..1f1e6a23d2 100644 --- a/tests/multigrid-global-coarsening/multigrid_p_01.cc +++ b/tests/multigrid-global-coarsening/multigrid_p_01.cc @@ -36,9 +36,11 @@ test(const unsigned int n_refinements, GridGenerator::subdivided_hyper_cube(tria, 2); tria.refine_global(n_refinements); - const auto level_degrees = MGTransferGlobalCoarseningTools::create_p_sequence( - fe_degree_fine, - MGTransferGlobalCoarseningTools::PolynomialSequenceType::bisect); + const auto level_degrees = + MGTransferGlobalCoarseningTools::create_polynomial_coarsening_sequence( + fe_degree_fine, + MGTransferGlobalCoarseningTools::PolynomialCoarseningSequenceType:: + bisect); const unsigned int min_level = 0; const unsigned int max_level = level_degrees.size() - 1; diff --git a/tests/multigrid-global-coarsening/multigrid_util.h b/tests/multigrid-global-coarsening/multigrid_util.h index e3176b616c..d52957f3bb 100644 --- a/tests/multigrid-global-coarsening/multigrid_util.h +++ b/tests/multigrid-global-coarsening/multigrid_util.h @@ -60,57 +60,6 @@ #include "../tests.h" -namespace MGTransferGlobalCoarseningTools -{ - enum class PolynomialSequenceType - { - bisect, - decrease_by_one, - go_to_one - }; - - unsigned int - generate_level_degree(const unsigned int previous_fe_degree, - const PolynomialSequenceType &p_sequence) - { - switch (p_sequence) - { - case PolynomialSequenceType::bisect: - return std::max(previous_fe_degree / 2, 1u); - case PolynomialSequenceType::decrease_by_one: - return std::max(previous_fe_degree - 1, 1u); - case PolynomialSequenceType::go_to_one: - return 1u; - default: - Assert(false, StandardExceptions::ExcNotImplemented()); - return 1u; - } - } - - std::vector - create_p_sequence(const unsigned int degree, - const PolynomialSequenceType &p_sequence) - { - std::vector degrees; - degrees.push_back(degree); - - unsigned int previous_fe_degree = degree; - while (previous_fe_degree > 1) - { - const unsigned int level_degree = - generate_level_degree(previous_fe_degree, p_sequence); - - degrees.push_back(level_degree); - previous_fe_degree = level_degree; - } - - std::reverse(degrees.begin(), degrees.end()); - - return degrees; - } - -} // namespace MGTransferGlobalCoarseningTools - template class Operator : public Subscriptor { -- 2.39.5