]> https://gitweb.dealii.org/ - dealii.git/commitdiff
MGConstrainedDoFs: move implementation into new file 16216/head
authorPeter Munch <peterrmuench@gmail.com>
Mon, 30 Oct 2023 12:20:52 +0000 (13:20 +0100)
committerPeter Munch <peterrmuench@gmail.com>
Fri, 24 Nov 2023 15:28:55 +0000 (16:28 +0100)
48 files changed:
doc/news/changes/incompatibilities/20231031Munch [new file with mode: 0644]
examples/step-87/step-87.cc
include/deal.II/multigrid/mg_constrained_dofs.h
include/deal.II/numerics/vector_tools_project.templates.h
source/multigrid/CMakeLists.txt
source/multigrid/mg_constrained_dofs.cc [new file with mode: 0644]
source/multigrid/mg_constrained_dofs.inst.in [new file with mode: 0644]
tests/grid/grid_generator_marching_cube_algorithm_02.cc
tests/integrators/assembler_simple_matrix_03.cc
tests/integrators/assembler_simple_matrix_03m.cc
tests/integrators/assembler_simple_matrix_03tri.cc
tests/integrators/assembler_simple_matrix_04.cc
tests/matrix_free/mass_operator_04.cc
tests/matrix_free/matrix_vector_stokes_base.cc
tests/multigrid-global-coarsening/block_01.cc
tests/multigrid-global-coarsening/fe_nothing_01.cc
tests/multigrid-global-coarsening/interpolate_01.cc
tests/multigrid-global-coarsening/interpolate_to_mg_01.cc
tests/multigrid-global-coarsening/mg_transfer_a_01.cc
tests/multigrid-global-coarsening/mg_transfer_a_02.cc
tests/multigrid-global-coarsening/mg_transfer_a_03.cc
tests/multigrid-global-coarsening/mg_transfer_a_04.cc
tests/multigrid-global-coarsening/mg_transfer_a_05.cc
tests/multigrid-global-coarsening/mg_transfer_p_01.cc
tests/multigrid-global-coarsening/mg_transfer_p_02.cc
tests/multigrid-global-coarsening/mg_transfer_p_03.cc
tests/multigrid-global-coarsening/mg_transfer_p_04.cc
tests/multigrid-global-coarsening/mg_transfer_p_05.cc
tests/multigrid-global-coarsening/mg_transfer_p_06.cc
tests/multigrid-global-coarsening/mg_transfer_p_07.cc
tests/multigrid-global-coarsening/non_nested_transfer_01.cc
tests/multigrid-global-coarsening/non_nested_transfer_02.cc
tests/multigrid-global-coarsening/non_nested_transfer_03.cc
tests/multigrid-global-coarsening/non_nested_transfer_04.cc
tests/multigrid-global-coarsening/non_nested_transfer_05.cc
tests/multigrid-global-coarsening/transfer_matrix_free_04.cc
tests/multigrid/constrained_dofs_04.cc
tests/multigrid/constrained_dofs_07.cc
tests/multigrid/flux_sparsity_pattern_constraints.cc
tests/multigrid/interface_matrix_entry_01.cc
tests/multigrid/interpolate_to_mg_01.cc
tests/multigrid/max_level_for_coarse_mesh.cc
tests/multigrid/mg_stats_01.cc
tests/multigrid/transfer_matrix_free_04.cc
tests/multigrid/transfer_matrix_free_13.cc
tests/multigrid/transfer_prebuilt_05.cc
tests/multigrid/workload_imbalance.cc
tests/simplex/step-67.cc

diff --git a/doc/news/changes/incompatibilities/20231031Munch b/doc/news/changes/incompatibilities/20231031Munch
new file mode 100644 (file)
index 0000000..8d5ccbf
--- /dev/null
@@ -0,0 +1,5 @@
+Removed: The file `include/deal.II/multigrid/mg_constrained_dofs.h`
+used to include `deal.II/dofs/dof_tools.h` and 
+`deal.II/multigrid/mg_tools.h`. This is not the case any more.
+<br>
+(Peter Munch, 2023/10/31)
index d47034a54de0e859355d33b5c67a04ee533e5b21..66feef4eb65580dbae58c7a154cdf2b6eb389a9a 100644 (file)
@@ -31,6 +31,7 @@
 #include <deal.II/distributed/tria.h>
 
 #include <deal.II/dofs/dof_renumbering.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_nothing.h>
 #include <deal.II/fe/fe_q.h>
index fbb3d7f7ec3dbd3df42b3a48eeb9ff90852be7e6..d28f92bd414eff72da54396449d2a198e453af01 100644 (file)
 #include <deal.II/base/mg_level_object.h>
 #include <deal.II/base/subscriptor.h>
 
-#include <deal.II/dofs/dof_tools.h>
-
 #include <deal.II/lac/affine_constraints.h>
 
-#include <deal.II/multigrid/mg_tools.h>
-
 #include <set>
 #include <vector>
 
@@ -274,227 +270,6 @@ private:
 
 
 
-template <int dim, int spacedim>
-inline void
-MGConstrainedDoFs::initialize(
-  const DoFHandler<dim, spacedim> &dof,
-  const MGLevelObject<IndexSet>   &level_relevant_dofs)
-{
-  boundary_indices.clear();
-  refinement_edge_indices.clear();
-  level_constraints.clear();
-  user_constraints.clear();
-
-  const unsigned int nlevels   = dof.get_triangulation().n_global_levels();
-  const unsigned int min_level = level_relevant_dofs.min_level();
-  const unsigned int max_level = (level_relevant_dofs.max_level() == 0) ?
-                                   nlevels - 1 :
-                                   level_relevant_dofs.max_level();
-  const bool         use_provided_level_relevant_dofs =
-    (level_relevant_dofs.max_level() > 0);
-
-  // At this point level_constraint and refinement_edge_indices are empty.
-  refinement_edge_indices.resize(nlevels);
-  level_constraints.resize(nlevels);
-  user_constraints.resize(nlevels);
-  for (unsigned int l = min_level; l <= max_level; ++l)
-    {
-      if (use_provided_level_relevant_dofs)
-        {
-          level_constraints[l].reinit(dof.locally_owned_mg_dofs(l),
-                                      level_relevant_dofs[l]);
-        }
-      else
-        {
-          const IndexSet relevant_dofs =
-            DoFTools::extract_locally_relevant_level_dofs(dof, l);
-          level_constraints[l].reinit(dof.locally_owned_mg_dofs(l),
-                                      relevant_dofs);
-        }
-    }
-
-  // TODO: currently we only consider very basic periodic constraints
-  const IdentityMatrix transformation(dof.get_fe().n_dofs_per_face());
-  const ComponentMask  component_mask;
-  const double         periodicity_factor = 1.0;
-
-  for (const auto &[first_cell, second_cell] :
-       dof.get_triangulation().get_periodic_face_map())
-    {
-      // only consider non-artificial cells
-      if (first_cell.first->is_artificial_on_level())
-        continue;
-      if (second_cell.first.first->is_artificial_on_level())
-        continue;
-
-      // consider cell pairs with the same level
-      if (first_cell.first->level() != second_cell.first.first->level())
-        continue;
-
-      DoFTools::internal::set_periodicity_constraints(
-        first_cell.first->as_dof_handler_level_iterator(dof)->face(
-          first_cell.second),
-        second_cell.first.first->as_dof_handler_level_iterator(dof)->face(
-          second_cell.first.second),
-        transformation,
-        level_constraints[first_cell.first->level()],
-        component_mask,
-        second_cell.second[0],
-        second_cell.second[1],
-        second_cell.second[2],
-        periodicity_factor,
-        first_cell.first->level());
-    }
-
-  for (unsigned int l = min_level; l <= max_level; ++l)
-    {
-      level_constraints[l].close();
-
-      // Initialize with empty IndexSet of correct size
-      refinement_edge_indices[l] = IndexSet(dof.n_dofs(l));
-    }
-
-  MGTools::extract_inner_interface_dofs(dof, refinement_edge_indices);
-}
-
-
-
-template <int dim, int spacedim>
-inline void
-MGConstrainedDoFs::make_zero_boundary_constraints(
-  const DoFHandler<dim, spacedim>    &dof,
-  const std::set<types::boundary_id> &boundary_ids,
-  const ComponentMask                &component_mask)
-{
-  // allocate an IndexSet for each global level. Contents will be
-  // overwritten inside make_boundary_list.
-  const unsigned int n_levels = dof.get_triangulation().n_global_levels();
-  Assert(boundary_indices.empty() || boundary_indices.size() == n_levels,
-         ExcInternalError());
-  boundary_indices.resize(n_levels);
-
-  MGTools::make_boundary_list(dof,
-                              boundary_ids,
-                              boundary_indices,
-                              component_mask);
-}
-
-
-
-template <int dim, int spacedim>
-inline void
-MGConstrainedDoFs::add_boundary_indices(const DoFHandler<dim, spacedim> &dof,
-                                        const unsigned int               level,
-                                        const IndexSet &level_boundary_indices)
-{
-  const unsigned int n_levels = dof.get_triangulation().n_global_levels();
-  if (boundary_indices.empty())
-    {
-      boundary_indices.resize(n_levels);
-      for (unsigned int i = 0; i < n_levels; ++i)
-        boundary_indices[i] = IndexSet(dof.n_dofs(i));
-    }
-  AssertDimension(boundary_indices.size(), n_levels);
-  boundary_indices[level].add_indices(level_boundary_indices);
-}
-
-
-
-template <int dim, int spacedim>
-inline void
-MGConstrainedDoFs::make_no_normal_flux_constraints(
-  const DoFHandler<dim, spacedim> &dof,
-  const types::boundary_id         bid,
-  const unsigned int               first_vector_component)
-{
-  // For a given boundary id, find which vector component is on the boundary
-  // and set a zero boundary constraint for those degrees of freedom.
-  const unsigned int n_components = dof.get_fe_collection().n_components();
-  AssertIndexRange(first_vector_component + dim - 1, n_components);
-
-  ComponentMask comp_mask(n_components, false);
-
-
-  typename Triangulation<dim>::face_iterator
-    face = dof.get_triangulation().begin_face(),
-    endf = dof.get_triangulation().end_face();
-  for (; face != endf; ++face)
-    if (face->at_boundary() && face->boundary_id() == bid)
-      for (unsigned int d = 0; d < dim; ++d)
-        {
-          Tensor<1, dim, double> unit_vec;
-          unit_vec[d] = 1.0;
-
-          const Tensor<1, dim> normal_vec =
-            face->get_manifold().normal_vector(face, face->center());
-
-          if (std::abs(std::abs(unit_vec * normal_vec) - 1.0) < 1e-10)
-            comp_mask.set(d + first_vector_component, true);
-          else
-            Assert(
-              std::abs(unit_vec * normal_vec) < 1e-10,
-              ExcMessage(
-                "We can currently only support no normal flux conditions "
-                "for a specific boundary id if all faces are normal to the "
-                "x, y, or z axis."));
-        }
-
-  Assert(comp_mask.n_selected_components() == 1,
-         ExcMessage(
-           "We can currently only support no normal flux conditions "
-           "for a specific boundary id if all faces are facing in the "
-           "same direction, i.e., a boundary normal to the x-axis must "
-           "have a different boundary id than a boundary normal to the "
-           "y- or z-axis and so on. If the mesh here was produced using "
-           "GridGenerator::..., setting colorize=true during mesh generation "
-           "and calling make_no_normal_flux_constraints() for each no normal "
-           "flux boundary will fulfill the condition."));
-
-  this->make_zero_boundary_constraints(dof, {bid}, comp_mask);
-}
-
-
-
-inline void
-MGConstrainedDoFs::add_user_constraints(
-  const unsigned int               level,
-  const AffineConstraints<double> &constraints_on_level)
-{
-  AssertIndexRange(level, user_constraints.size());
-
-  // Get the relevant DoFs from level_constraints if
-  // the user constraint matrix has not been initialized
-  if (user_constraints[level].get_local_lines().size() == 0)
-    user_constraints[level].reinit(
-      level_constraints[level].get_locally_owned_indices(),
-      level_constraints[level].get_local_lines());
-
-  user_constraints[level].merge(
-    constraints_on_level,
-    AffineConstraints<double>::MergeConflictBehavior::right_object_wins);
-  user_constraints[level].close();
-}
-
-
-
-inline void
-MGConstrainedDoFs::clear_user_constraints()
-{
-  for (auto &constraint : user_constraints)
-    constraint.clear();
-}
-
-
-
-inline void
-MGConstrainedDoFs::clear()
-{
-  boundary_indices.clear();
-  refinement_edge_indices.clear();
-  user_constraints.clear();
-}
-
-
 inline bool
 MGConstrainedDoFs::is_boundary_index(const unsigned int            level,
                                      const types::global_dof_index index) const
@@ -580,61 +355,6 @@ MGConstrainedDoFs::get_user_constraint_matrix(const unsigned int level) const
 
 
 
-template <typename Number>
-inline void
-MGConstrainedDoFs::merge_constraints(AffineConstraints<Number> &constraints,
-                                     const unsigned int         level,
-                                     const bool add_boundary_indices,
-                                     const bool add_refinement_edge_indices,
-                                     const bool add_level_constraints,
-                                     const bool add_user_constraints) const
-{
-  constraints.clear();
-
-  // determine local lines
-  IndexSet index_set(this->get_refinement_edge_indices(level).size());
-
-  if (add_boundary_indices && this->have_boundary_indices())
-    index_set.add_indices(this->get_boundary_indices(level));
-
-  if (add_refinement_edge_indices)
-    index_set.add_indices(this->get_refinement_edge_indices(level));
-
-  if (add_level_constraints)
-    index_set.add_indices(this->get_level_constraints(level).get_local_lines());
-
-  if (add_user_constraints)
-    index_set.add_indices(
-      this->get_user_constraint_matrix(level).get_local_lines());
-
-  constraints.reinit(level_constraints[level].get_locally_owned_indices(),
-                     index_set);
-
-  // merge constraints
-  if (add_boundary_indices && this->have_boundary_indices())
-    for (const auto i : this->get_boundary_indices(level))
-      constraints.constrain_dof_to_zero(i);
-
-  if (add_refinement_edge_indices)
-    for (const auto i : this->get_refinement_edge_indices(level))
-      constraints.constrain_dof_to_zero(i);
-
-  if (add_level_constraints)
-    constraints.merge(this->get_level_constraints(level),
-                      AffineConstraints<Number>::left_object_wins,
-                      true);
-
-  if (add_user_constraints)
-    constraints.merge(this->get_user_constraint_matrix(level),
-                      AffineConstraints<Number>::left_object_wins,
-                      true);
-
-  // finalize setup
-  constraints.close();
-}
-
-
-
 DEAL_II_NAMESPACE_CLOSE
 
 #endif
index dfaefee818f5ac4019b4ce4d294c52efb3a5d43e..43fa6e6b93718f769b200462f027ba920a47261f 100644 (file)
@@ -16,6 +16,8 @@
 #ifndef dealii_vector_tools_project_templates_h
 #define dealii_vector_tools_project_templates_h
 
+#include <deal.II/dofs/dof_tools.h>
+
 #include <deal.II/fe/fe_dgq.h>
 #include <deal.II/fe/fe_q.h>
 #include <deal.II/fe/fe_simplex_p_bubbles.h>
index 03bbd16756a92b7c711ea0344c873a51aa04e129..285f91a924791c6a18015024ab274bba3ed95292 100644 (file)
@@ -15,6 +15,7 @@
 
 set(_unity_include_src
   mg_base.cc
+  mg_constrained_dofs.cc
   mg_level_global_transfer.cc
   mg_transfer_block.cc
   mg_transfer_component.cc
@@ -40,6 +41,7 @@ setup_source_list("${_unity_include_src}"
 
 set(_inst
   mg_base.inst.in
+  mg_constrained_dofs.inst.in
   mg_level_global_transfer.inst.in
   mg_tools.inst.in
   mg_transfer_block.inst.in
diff --git a/source/multigrid/mg_constrained_dofs.cc b/source/multigrid/mg_constrained_dofs.cc
new file mode 100644 (file)
index 0000000..27da1a2
--- /dev/null
@@ -0,0 +1,305 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2010 - 2023 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.
+//
+// ---------------------------------------------------------------------
+
+
+#include <deal.II/dofs/dof_tools.h>
+
+#include <deal.II/grid/manifold.h>
+
+#include <deal.II/multigrid/mg_constrained_dofs.h>
+#include <deal.II/multigrid/mg_tools.h>
+
+DEAL_II_NAMESPACE_OPEN
+
+
+template <int dim, int spacedim>
+void
+MGConstrainedDoFs::initialize(
+  const DoFHandler<dim, spacedim> &dof,
+  const MGLevelObject<IndexSet>   &level_relevant_dofs)
+{
+  boundary_indices.clear();
+  refinement_edge_indices.clear();
+  level_constraints.clear();
+  user_constraints.clear();
+
+  const unsigned int nlevels   = dof.get_triangulation().n_global_levels();
+  const unsigned int min_level = level_relevant_dofs.min_level();
+  const unsigned int max_level = (level_relevant_dofs.max_level() == 0) ?
+                                   nlevels - 1 :
+                                   level_relevant_dofs.max_level();
+  const bool         use_provided_level_relevant_dofs =
+    (level_relevant_dofs.max_level() > 0);
+
+  // At this point level_constraint and refinement_edge_indices are empty.
+  refinement_edge_indices.resize(nlevels);
+  level_constraints.resize(nlevels);
+  user_constraints.resize(nlevels);
+  for (unsigned int l = min_level; l <= max_level; ++l)
+    {
+      if (use_provided_level_relevant_dofs)
+        {
+          level_constraints[l].reinit(dof.locally_owned_mg_dofs(l),
+                                      level_relevant_dofs[l]);
+        }
+      else
+        {
+          const IndexSet relevant_dofs =
+            DoFTools::extract_locally_relevant_level_dofs(dof, l);
+          level_constraints[l].reinit(dof.locally_owned_mg_dofs(l),
+                                      relevant_dofs);
+        }
+    }
+
+  // TODO: currently we only consider very basic periodic constraints
+  const IdentityMatrix transformation(dof.get_fe().n_dofs_per_face());
+  const ComponentMask  component_mask;
+  const double         periodicity_factor = 1.0;
+
+  for (const auto &[first_cell, second_cell] :
+       dof.get_triangulation().get_periodic_face_map())
+    {
+      // only consider non-artificial cells
+      if (first_cell.first->is_artificial_on_level())
+        continue;
+      if (second_cell.first.first->is_artificial_on_level())
+        continue;
+
+      // consider cell pairs with the same level
+      if (first_cell.first->level() != second_cell.first.first->level())
+        continue;
+
+      DoFTools::internal::set_periodicity_constraints(
+        first_cell.first->as_dof_handler_level_iterator(dof)->face(
+          first_cell.second),
+        second_cell.first.first->as_dof_handler_level_iterator(dof)->face(
+          second_cell.first.second),
+        transformation,
+        level_constraints[first_cell.first->level()],
+        component_mask,
+        second_cell.second[0],
+        second_cell.second[1],
+        second_cell.second[2],
+        periodicity_factor,
+        first_cell.first->level());
+    }
+
+  for (unsigned int l = min_level; l <= max_level; ++l)
+    {
+      level_constraints[l].close();
+
+      // Initialize with empty IndexSet of correct size
+      refinement_edge_indices[l] = IndexSet(dof.n_dofs(l));
+    }
+
+  MGTools::extract_inner_interface_dofs(dof, refinement_edge_indices);
+}
+
+
+
+template <int dim, int spacedim>
+void
+MGConstrainedDoFs::make_zero_boundary_constraints(
+  const DoFHandler<dim, spacedim>    &dof,
+  const std::set<types::boundary_id> &boundary_ids,
+  const ComponentMask                &component_mask)
+{
+  // allocate an IndexSet for each global level. Contents will be
+  // overwritten inside make_boundary_list.
+  const unsigned int n_levels = dof.get_triangulation().n_global_levels();
+  Assert(boundary_indices.empty() || boundary_indices.size() == n_levels,
+         ExcInternalError());
+  boundary_indices.resize(n_levels);
+
+  MGTools::make_boundary_list(dof,
+                              boundary_ids,
+                              boundary_indices,
+                              component_mask);
+}
+
+
+
+template <int dim, int spacedim>
+void
+MGConstrainedDoFs::add_boundary_indices(const DoFHandler<dim, spacedim> &dof,
+                                        const unsigned int               level,
+                                        const IndexSet &level_boundary_indices)
+{
+  const unsigned int n_levels = dof.get_triangulation().n_global_levels();
+  if (boundary_indices.empty())
+    {
+      boundary_indices.resize(n_levels);
+      for (unsigned int i = 0; i < n_levels; ++i)
+        boundary_indices[i] = IndexSet(dof.n_dofs(i));
+    }
+  AssertDimension(boundary_indices.size(), n_levels);
+  boundary_indices[level].add_indices(level_boundary_indices);
+}
+
+
+
+template <int dim, int spacedim>
+void
+MGConstrainedDoFs::make_no_normal_flux_constraints(
+  const DoFHandler<dim, spacedim> &dof,
+  const types::boundary_id         bid,
+  const unsigned int               first_vector_component)
+{
+  // For a given boundary id, find which vector component is on the boundary
+  // and set a zero boundary constraint for those degrees of freedom.
+  const unsigned int n_components = dof.get_fe_collection().n_components();
+  AssertIndexRange(first_vector_component + dim - 1, n_components);
+
+  ComponentMask comp_mask(n_components, false);
+
+
+  typename Triangulation<dim>::face_iterator
+    face = dof.get_triangulation().begin_face(),
+    endf = dof.get_triangulation().end_face();
+  for (; face != endf; ++face)
+    if (face->at_boundary() && face->boundary_id() == bid)
+      for (unsigned int d = 0; d < dim; ++d)
+        {
+          Tensor<1, dim, double> unit_vec;
+          unit_vec[d] = 1.0;
+
+          const Tensor<1, dim> normal_vec =
+            face->get_manifold().normal_vector(face, face->center());
+
+          if (std::abs(std::abs(unit_vec * normal_vec) - 1.0) < 1e-10)
+            comp_mask.set(d + first_vector_component, true);
+          else
+            Assert(
+              std::abs(unit_vec * normal_vec) < 1e-10,
+              ExcMessage(
+                "We can currently only support no normal flux conditions "
+                "for a specific boundary id if all faces are normal to the "
+                "x, y, or z axis."));
+        }
+
+  Assert(comp_mask.n_selected_components() == 1,
+         ExcMessage(
+           "We can currently only support no normal flux conditions "
+           "for a specific boundary id if all faces are facing in the "
+           "same direction, i.e., a boundary normal to the x-axis must "
+           "have a different boundary id than a boundary normal to the "
+           "y- or z-axis and so on. If the mesh here was produced using "
+           "GridGenerator::..., setting colorize=true during mesh generation "
+           "and calling make_no_normal_flux_constraints() for each no normal "
+           "flux boundary will fulfill the condition."));
+
+  this->make_zero_boundary_constraints(dof, {bid}, comp_mask);
+}
+
+
+
+void
+MGConstrainedDoFs::add_user_constraints(
+  const unsigned int               level,
+  const AffineConstraints<double> &constraints_on_level)
+{
+  AssertIndexRange(level, user_constraints.size());
+
+  // Get the relevant DoFs from level_constraints if
+  // the user constraint matrix has not been initialized
+  if (user_constraints[level].get_local_lines().size() == 0)
+    user_constraints[level].reinit(
+      level_constraints[level].get_locally_owned_indices(),
+      level_constraints[level].get_local_lines());
+
+  user_constraints[level].merge(
+    constraints_on_level,
+    AffineConstraints<double>::MergeConflictBehavior::right_object_wins);
+  user_constraints[level].close();
+}
+
+
+
+void
+MGConstrainedDoFs::clear_user_constraints()
+{
+  for (auto &constraint : user_constraints)
+    constraint.clear();
+}
+
+
+
+void
+MGConstrainedDoFs::clear()
+{
+  boundary_indices.clear();
+  refinement_edge_indices.clear();
+  user_constraints.clear();
+}
+
+
+
+template <typename Number>
+void
+MGConstrainedDoFs::merge_constraints(AffineConstraints<Number> &constraints,
+                                     const unsigned int         level,
+                                     const bool add_boundary_indices,
+                                     const bool add_refinement_edge_indices,
+                                     const bool add_level_constraints,
+                                     const bool add_user_constraints) const
+{
+  constraints.clear();
+
+  // determine local lines
+  IndexSet index_set(this->get_refinement_edge_indices(level).size());
+
+  if (add_boundary_indices && this->have_boundary_indices())
+    index_set.add_indices(this->get_boundary_indices(level));
+
+  if (add_refinement_edge_indices)
+    index_set.add_indices(this->get_refinement_edge_indices(level));
+
+  if (add_level_constraints)
+    index_set.add_indices(this->get_level_constraints(level).get_local_lines());
+
+  if (add_user_constraints)
+    index_set.add_indices(
+      this->get_user_constraint_matrix(level).get_local_lines());
+
+  constraints.reinit(level_constraints[level].get_locally_owned_indices(),
+                     index_set);
+
+  // merge constraints
+  if (add_boundary_indices && this->have_boundary_indices())
+    for (const auto i : this->get_boundary_indices(level))
+      constraints.constrain_dof_to_zero(i);
+
+  if (add_refinement_edge_indices)
+    for (const auto i : this->get_refinement_edge_indices(level))
+      constraints.constrain_dof_to_zero(i);
+
+  if (add_level_constraints)
+    constraints.merge(this->get_level_constraints(level),
+                      AffineConstraints<Number>::left_object_wins,
+                      true);
+
+  if (add_user_constraints)
+    constraints.merge(this->get_user_constraint_matrix(level),
+                      AffineConstraints<Number>::left_object_wins,
+                      true);
+
+  // finalize setup
+  constraints.close();
+}
+
+#include "mg_constrained_dofs.inst"
+
+
+DEAL_II_NAMESPACE_CLOSE
diff --git a/source/multigrid/mg_constrained_dofs.inst.in b/source/multigrid/mg_constrained_dofs.inst.in
new file mode 100644 (file)
index 0000000..571e037
--- /dev/null
@@ -0,0 +1,49 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2010 - 2023 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+for (deal_II_dimension : DIMENSIONS)
+  {
+    template void MGConstrainedDoFs::initialize(
+      const DoFHandler<deal_II_dimension, deal_II_dimension> &dof,
+      const MGLevelObject<IndexSet> &level_relevant_dofs);
+
+    template void MGConstrainedDoFs::make_zero_boundary_constraints(
+      const DoFHandler<deal_II_dimension, deal_II_dimension> &dof,
+      const std::set<types::boundary_id>                     &boundary_ids,
+      const ComponentMask                                    &component_mask);
+
+    template void MGConstrainedDoFs::add_boundary_indices(
+      const DoFHandler<deal_II_dimension, deal_II_dimension> &dof,
+      const unsigned int                                      level,
+      const IndexSet                                         &boundary_indices);
+
+    template void MGConstrainedDoFs::make_no_normal_flux_constraints(
+      const DoFHandler<deal_II_dimension, deal_II_dimension> &dof,
+      const types::boundary_id                                bid,
+      const unsigned int first_vector_component);
+  }
+
+for (S1 : REAL_SCALARS)
+  {
+    template void MGConstrainedDoFs::merge_constraints(
+      AffineConstraints<S1> & constraints,
+      const unsigned int level,
+      const bool         add_boundary_indices,
+      const bool         add_refinement_edge_indices,
+      const bool         add_level_constraints,
+      const bool         add_user_constraints) const;
+  }
index 3aa1458c9821c766472f8680fc387070e590230b..c342684b1ccd14651379d6b909465a0d65911454 100644 (file)
@@ -20,6 +20,7 @@
 #include <deal.II/distributed/tria.h>
 
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_q.h>
 #include <deal.II/fe/mapping_q1.h>
index c8bd6f11ceb237ce649bd74a4ab74a86aae7e61f..c8bd42be62438323e2a569e0eb30631b184798a1 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <deal.II/dofs/dof_handler.h>
 #include <deal.II/dofs/dof_renumbering.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgp.h>
 #include <deal.II/fe/fe_q.h>
index 3d9aae1c4a2c71827f370d8c148482db9d8ab7a5..c38b62f73c9fb79a55f1b22c8f445f48c31cb780 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <deal.II/dofs/dof_handler.h>
 #include <deal.II/dofs/dof_renumbering.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgp.h>
 #include <deal.II/fe/fe_q.h>
index f4ff982902fd2885f3937ca0d63e2c90003b8962..9308cb056ef04d2db0d3d5fec455b27fd3ad442f 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <deal.II/dofs/dof_handler.h>
 #include <deal.II/dofs/dof_renumbering.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgp.h>
 #include <deal.II/fe/fe_q.h>
index 2cbfdee2c8b116d82e77f2a68583a855066ace00..ba1f2e64e02f2ab0476d91ef2ef3f944b52a8b88 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <deal.II/dofs/dof_handler.h>
 #include <deal.II/dofs/dof_renumbering.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgp.h>
 #include <deal.II/fe/fe_q.h>
index f3a5dd15b4bf387a9f113e1bf66c3f90a6b5aec4..1023d16c3890154852610965b0174a02118f2138 100644 (file)
@@ -24,6 +24,7 @@
 #include <deal.II/distributed/tria.h>
 
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_q.h>
 #include <deal.II/fe/fe_values.h>
index f4e39338b7ca6713e9e865588c24dacff933ce47..5c23da762c47823b085c4bc4dca6061f6f9f7eaa 100644 (file)
@@ -20,6 +20,7 @@
 #include <deal.II/base/multithread_info.h>
 
 #include <deal.II/dofs/dof_renumbering.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_q.h>
 #include <deal.II/fe/fe_system.h>
index 32316620a4e43c197a428fbb6b670d874d2cdf75..62e6a5d822778827640a0ef9d63b35124258f3bc 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <deal.II/dofs/dof_handler.h>
 #include <deal.II/dofs/dof_renumbering.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgq.h>
 #include <deal.II/fe/fe_q.h>
index d64f59ea31978eb1a036743e983ea972817b1ed2..0e0fa8ae3d8795cf92d9d3dc0d90d3fdd72bb2f4 100644 (file)
@@ -27,6 +27,7 @@
 #include <deal.II/distributed/tria.h>
 
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgq.h>
 #include <deal.II/fe/fe_nothing.h>
index 0ceb8a9169850616301ab7b3b885db6e0c3902fa..238871a2dea55cda82322214e2ea970284f6332d 100644 (file)
@@ -26,6 +26,7 @@
 #include <deal.II/distributed/tria.h>
 
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgq.h>
 #include <deal.II/fe/fe_q.h>
index a30f5b954e6b7d4b5bfcd8c61f8c5b640217e03e..cf6d45c6fcb9a73e96ffa5f2324ae663ca8f6e1f 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <deal.II/distributed/tria.h>
 
+#include <deal.II/dofs/dof_tools.h>
+
 #include <deal.II/fe/fe_q.h>
 #include <deal.II/fe/fe_system.h>
 #include <deal.II/fe/mapping_q1.h>
index 13d3e73c9b58d6b6c28790c461aefea98e1509c6..69122d21e0ed9464f2d5958bcf6224c6875e61ec 100644 (file)
@@ -40,6 +40,7 @@
 #include <deal.II/distributed/tria.h>
 
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgq.h>
 #include <deal.II/fe/fe_q.h>
index abede4c9326e16ae458d8de041832b862803e6ea..0ad3689f034a92cd0579e06db048fdd749c68f9d 100644 (file)
@@ -26,6 +26,7 @@
 #include <deal.II/distributed/tria.h>
 
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgq.h>
 #include <deal.II/fe/fe_q.h>
index ca0f35f4e1175f32a750683406f28b5674e7be01..9bbcc29c5a09e64101f7756f95eb8be4af426bfd 100644 (file)
@@ -27,6 +27,7 @@
 #include <deal.II/distributed/tria.h>
 
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgq.h>
 #include <deal.II/fe/fe_q.h>
index 4fd335c5f6095c730ab4e3309ecdeab3be95ebc3..fd3fe9d2f638e3eb9353990943f95f8622546fb8 100644 (file)
@@ -24,6 +24,7 @@
 #include <deal.II/base/quadrature_lib.h>
 
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgq.h>
 #include <deal.II/fe/fe_q.h>
index 3bba3c378f5b31a8e7cd9e1d07acb308f6745d02..85e73951e23dcede68832eec44868ed5abfbce54 100644 (file)
@@ -29,6 +29,7 @@
 #include <deal.II/distributed/tria.h>
 
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgq.h>
 #include <deal.II/fe/fe_q.h>
index 11b68190a6227fdc8ef36b679e75f7df72eb8340..36bb1f901e50be15630bcceb19d7b1308c12255f 100644 (file)
@@ -40,6 +40,7 @@
 #include <deal.II/distributed/tria.h>
 
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgq.h>
 #include <deal.II/fe/fe_q.h>
index 297c4ae96437665da4d7a3584583461365c9d753..3880b0adb747e9dc61d65ae09062f15798de0104 100644 (file)
@@ -40,6 +40,7 @@
 #include <deal.II/distributed/tria.h>
 
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgq.h>
 #include <deal.II/fe/fe_q.h>
index 73ae1ceaa28733981298ae37cd7d07163f6bc9cc..bc6fe62924eb1385d78d8dc5d005a3ae3d3b508d 100644 (file)
@@ -26,6 +26,7 @@
 #include <deal.II/distributed/tria.h>
 
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgq.h>
 #include <deal.II/fe/fe_q.h>
index ad3ef0182d35102d4d8e1d47955d223d8cbb3ef8..73a0a79cc700b58635357fbb39e72107501bf365 100644 (file)
@@ -41,6 +41,7 @@
 #include <deal.II/distributed/tria.h>
 
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgq.h>
 #include <deal.II/fe/fe_q.h>
index b85f8237b92919d5c02f441853530d04c0dd12f0..8e280099795fa3adc61af131262364f7cb3e1ff2 100644 (file)
@@ -40,6 +40,7 @@
 #include <deal.II/distributed/tria.h>
 
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgq.h>
 #include <deal.II/fe/fe_q.h>
index a636a89627f775008eafdcbd8c6272b8e77d66ab..fa1473643990e25438e6094eb998242116451773 100644 (file)
@@ -38,6 +38,7 @@
 #include <deal.II/distributed/tria.h>
 
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgq.h>
 #include <deal.II/fe/fe_q.h>
index 4fbc8eeb1712fdbfff529659a4d248d05d2eaa47..5545ce996b6c9c0890093c1ca877e2a4ccee9c4d 100644 (file)
@@ -24,6 +24,7 @@
 #include <deal.II/base/quadrature_lib.h>
 
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgq.h>
 #include <deal.II/fe/fe_q.h>
index d31ebd8335d36c3680ebfbfe34ab771524ef6701..36ffc8d7619268a4b18f1cc266fdc0ab6a220b09 100644 (file)
@@ -41,6 +41,7 @@
 #include <deal.II/distributed/tria.h>
 
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgq.h>
 #include <deal.II/fe/fe_q.h>
index 5a78d7d4837dbe36f3b02d0830444a0feaaceb6b..dc74b2d2310c4d204bc43e47581a48a01d588b9a 100644 (file)
@@ -27,6 +27,7 @@
 #include <deal.II/distributed/tria.h>
 
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgq.h>
 #include <deal.II/fe/fe_q.h>
index c320fca471fcb9efd855c0bc9c1c5673689f6d3d..0d502c23fc9a9e3a7ae9a96eb89ae9aeac325510 100644 (file)
@@ -28,6 +28,7 @@
 #include <deal.II/distributed/tria.h>
 
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgq.h>
 #include <deal.II/fe/fe_q.h>
index 76b063ea5a63088586add0580bece28a64e39f0b..b4ca3029a9538af1361e9feb0c04643f7e15ed7e 100644 (file)
@@ -24,6 +24,7 @@
 #include <deal.II/distributed/tria.h>
 
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_q.h>
 #include <deal.II/fe/fe_system.h>
index 97e0313f48a973a89a7c0592045c78ceace9f340..3cc8135451b19412e7d1a9f4a27be680b615341e 100644 (file)
@@ -30,6 +30,7 @@
 #include <deal.II/distributed/tria.h>
 
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgq.h>
 #include <deal.II/fe/fe_q.h>
index 665c50ad71740e40019eb705f2714d09c52165a0..41f110bbe9febc6986b427f3ccfb5a78a03a7ffa 100644 (file)
@@ -20,6 +20,8 @@
 
 #include <deal.II/distributed/tria.h>
 
+#include <deal.II/dofs/dof_tools.h>
+
 #include <deal.II/fe/fe_dgq.h>
 
 #include <deal.II/grid/grid_generator.h>
index 22646c3411e9900b502194f39a351627c98959b2..b4a45c9d765aec81bc97a5d6b2eddc4bfa2bfa47 100644 (file)
@@ -17,6 +17,8 @@
 // check that we get a reasonable error message when trying to call
 // MGConstrainedDofs::initialize() with distributing level dofs.
 
+#include <deal.II/dofs/dof_handler.h>
+
 #include <deal.II/fe/fe_q.h>
 
 #include <deal.II/grid/grid_generator.h>
index e6aa5afc55c69d6347ee5bb7f808158a4d7d3840..507eed838c8dfa8320131b024f01edc963c2bb33 100644 (file)
@@ -17,6 +17,8 @@
 // Check clear_user_constraints()
 #include <deal.II/distributed/tria.h>
 
+#include <deal.II/dofs/dof_tools.h>
+
 #include <deal.II/fe/fe_q.h>
 
 #include <deal.II/grid/grid_generator.h>
index d3283f9ad737d1bc1c1c86e9f947bb7e319fde3c..6054ced002c191fe0c9a6bff15cf21f45cf2a82b 100644 (file)
@@ -38,6 +38,7 @@
 #include <deal.II/lac/sparsity_pattern.h>
 
 #include <deal.II/multigrid/mg_constrained_dofs.h>
+#include <deal.II/multigrid/mg_tools.h>
 
 #include "../tests.h"
 
index e808c12f89028016ec498da4ba905188a8acda1d..458329582a89d03bd81c96bca4dabb7588f6b9a7 100644 (file)
@@ -41,6 +41,7 @@
 #include <deal.II/lac/sparse_matrix.h>
 
 #include <deal.II/multigrid/mg_constrained_dofs.h>
+#include <deal.II/multigrid/mg_tools.h>
 #include <deal.II/multigrid/multigrid.h>
 
 #include <deal.II/numerics/vector_tools.h>
index a5cd8ff9fda25786e572382651772a2fb798a753..a77b49aca6563df37148e572bf5acb04dd158696 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <deal.II/distributed/tria.h>
 
+#include <deal.II/dofs/dof_tools.h>
+
 #include <deal.II/fe/fe_q.h>
 #include <deal.II/fe/fe_system.h>
 #include <deal.II/fe/mapping_q1.h>
index 558853b49b2a5dfce46ff436039abe7cfc5c1c72..ec251fe81c1de95ee45d2ad2838fef7ee91e740a 100644 (file)
@@ -29,6 +29,7 @@
 #include <deal.II/grid/tria_iterator.h>
 
 #include <deal.II/multigrid/mg_constrained_dofs.h>
+#include <deal.II/multigrid/mg_tools.h>
 #include <deal.II/multigrid/multigrid.h>
 
 #include <deal.II/numerics/vector_tools.h>
index 65de32e0df9ca34fbd5f7f0a210ebd4b77a13a15..58737f2bb9a333e4bcfae837db36a5e3a32f63ed 100644 (file)
@@ -28,6 +28,7 @@
 #include <deal.II/grid/tria_iterator.h>
 
 #include <deal.II/multigrid/mg_constrained_dofs.h>
+#include <deal.II/multigrid/mg_tools.h>
 #include <deal.II/multigrid/mg_transfer_global_coarsening.h>
 #include <deal.II/multigrid/multigrid.h>
 
index ae3a5c32fe1e49aa2b36e1e09fc3448ba9dfb0b0..13481d0bc281bb3a8deefd8934749c2c33139f46 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <deal.II/lac/la_parallel_vector.h>
 
+#include <deal.II/multigrid/mg_tools.h>
 #include <deal.II/multigrid/mg_transfer.h>
 #include <deal.II/multigrid/mg_transfer_matrix_free.h>
 
index 197fa2106b83d7974b8a97193a64f6e3172984fe..3f364bf4c72a6cadc457c6e8e0b1d0b49c2486cb 100644 (file)
@@ -18,6 +18,8 @@
 
 #include <deal.II/distributed/tria.h>
 
+#include <deal.II/dofs/dof_tools.h>
+
 #include <deal.II/fe/fe_q.h>
 
 #include <deal.II/grid/grid_generator.h>
index 7a0239ef6f880b3b4d848049acac1fe2af0d61b0..45345de78f003f18229d55468d1ca2135ccb1d7c 100644 (file)
@@ -18,6 +18,8 @@
 
 #include <deal.II/distributed/tria.h>
 
+#include <deal.II/dofs/dof_tools.h>
+
 #include <deal.II/fe/fe_q.h>
 
 #include <deal.II/grid/grid_generator.h>
index e52294f7415f0cd5fc2463e8b72a8c4cba3ab007..84667507f68a26c0ef45409bf6ca953efdf1803a 100644 (file)
@@ -27,6 +27,7 @@
 #include <deal.II/grid/tria_iterator.h>
 
 #include <deal.II/multigrid/mg_constrained_dofs.h>
+#include <deal.II/multigrid/mg_tools.h>
 #include <deal.II/multigrid/multigrid.h>
 
 #include <deal.II/numerics/vector_tools.h>
index 75be730e4c7d952a6362bb37ea96ab48faba72c9..e6f7dd8fd8018c3a279602a3fbf75fc5fb10d240 100644 (file)
@@ -61,6 +61,7 @@
 #endif
 
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_tools.h>
 
 #include <deal.II/fe/fe_dgq.h>
 #include <deal.II/fe/fe_system.h>

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.