22#ifndef OPERATOR_CONSTRAINTS_H
23#define OPERATOR_CONSTRAINTS_H
25#include <deal.II/multigrid/mg_constrained_dofs.h>
29namespace ConstraintUtil
33template<
int dim,
typename Number>
35add_periodicity_constraints(
unsigned int const level,
36 unsigned int const target_level,
37 typename dealii::DoFHandler<dim>::face_iterator
const face1,
38 typename dealii::DoFHandler<dim>::face_iterator
const face2,
39 dealii::AffineConstraints<Number> & constraints)
44 unsigned int const dofs_per_face = face1->get_fe(0).dofs_per_face;
46 std::vector<dealii::types::global_dof_index> dofs_1(dofs_per_face);
47 std::vector<dealii::types::global_dof_index> dofs_2(dofs_per_face);
49 face1->get_mg_dof_indices(target_level, dofs_1, 0);
50 face2->get_mg_dof_indices(target_level, dofs_2, 0);
52 for(
unsigned int i = 0; i < dofs_per_face; ++i)
54 if(constraints.can_store_line(dofs_2[i]) and constraints.can_store_line(dofs_1[i]) and
55 not(constraints.is_constrained(dofs_2[i])))
58 constraints.add_line(dofs_2[i]);
60 constraints.add_entry(dofs_2[i], dofs_1[i], 1.);
64 else if(face1->has_children() and face2->has_children())
67 for(
unsigned int c = 0; c < face1->n_children(); ++c)
69 add_periodicity_constraints<dim>(
70 level - 1, target_level, face1->child(c), face2->child(c), constraints);
76template<
int dim,
typename Number>
78add_periodicity_constraints(
79 dealii::DoFHandler<dim>
const & dof_handler,
80 unsigned int const level,
81 std::vector<
typename dealii::GridTools::PeriodicFacePair<
82 typename dealii::Triangulation<dim>::cell_iterator>>
const & periodic_face_pairs_level0,
83 dealii::AffineConstraints<Number> & affine_constraints_own)
86 for(
auto & it : periodic_face_pairs_level0)
89 typename dealii::DoFHandler<dim>::cell_iterator cell1(&dof_handler.get_triangulation(),
93 typename dealii::DoFHandler<dim>::cell_iterator cell0(&dof_handler.get_triangulation(),
100 add_periodicity_constraints<dim, Number>(level,
102 cell1->face(it.face_idx[1]),
103 cell0->face(it.face_idx[0]),
104 affine_constraints_own);
108template<
int dim,
typename Number>
110add_constraints(
bool is_dg,
111 bool operator_is_singular,
112 dealii::DoFHandler<dim>
const & dof_handler,
113 dealii::AffineConstraints<Number> & affine_constraints_own,
114 dealii::MGConstrainedDoFs
const & mg_constrained_dofs,
115 std::vector<dealii::GridTools::PeriodicFacePair<
116 typename dealii::Triangulation<dim>::cell_iterator>>
const & periodic_face_pairs,
117 unsigned int const level)
122 affine_constraints_own.close();
126 affine_constraints_own.clear();
129 dealii::IndexSet relevant_dofs;
130 if(level != dealii::numbers::invalid_unsigned_int)
131 dealii::DoFTools::extract_locally_relevant_level_dofs(dof_handler, level, relevant_dofs);
133 dealii::DoFTools::extract_locally_relevant_dofs(dof_handler, relevant_dofs);
134 affine_constraints_own.reinit(relevant_dofs);
137 add_periodicity_constraints<dim, Number>(dof_handler,
140 affine_constraints_own);
143 if(mg_constrained_dofs.have_boundary_indices())
144 affine_constraints_own.add_lines(mg_constrained_dofs.get_boundary_indices(level));
150 if(operator_is_singular and affine_constraints_own.can_store_line(0))
154 dealii::types::global_dof_index line_index = 0;
157 auto const * lines = affine_constraints_own.get_constraint_entries(line_index);
161 affine_constraints_own.add_line(line_index);
164 if(mg_constrained_dofs.have_boundary_indices() &&
165 level != dealii::numbers::invalid_unsigned_int)
167 if(mg_constrained_dofs.get_boundary_indices(level).size() != dof_handler.n_dofs(level))
168 const_cast<dealii::IndexSet &
>(mg_constrained_dofs.get_boundary_indices(level))
169 .set_size(dof_handler.n_dofs(level));
170 const_cast<dealii::IndexSet &
>(mg_constrained_dofs.get_boundary_indices(level))
171 .add_index(line_index);
178 Assert(lines->size() == 1 and std::abs((*lines)[0].second - 1.) < 1e-15,
179 dealii::ExcMessage(
"Periodic index expected, bailing out"));
181 line_index = (*lines)[0].first;
186 affine_constraints_own.close();