+/**
+ * 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<unsigned int>
+ 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.
*/
} // 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<unsigned int>
+ create_polynomial_coarsening_sequence(
+ const unsigned int max_degree,
+ const PolynomialCoarseningSequenceType &p_sequence)
+ {
+ std::vector<unsigned int> 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 <int dim, typename Number>
void
MGTwoLevelTransfer<dim, LinearAlgebra::distributed::Vector<Number>>::prolongate(
--- /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.
+//
+// ---------------------------------------------------------------------
+
+// Print all polynomial coarsening sequences up to degree 15.
+
+#include <deal.II/multigrid/mg_transfer_global_coarsening.h>
+
+#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);
+}
--- /dev/null
+
+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::
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;
#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<unsigned int>
- create_p_sequence(const unsigned int degree,
- const PolynomialSequenceType &p_sequence)
- {
- std::vector<unsigned int> 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 <int dim_, typename Number>
class Operator : public Subscriptor
{