38#ifdef DEAL_II_WITH_MPI
59 check_primary_dof_list(
61 const std::vector<types::global_dof_index> &primary_dof_list)
63 const unsigned int N = primary_dof_list.size();
66 for (
unsigned int i = 0; i <
N; ++i)
67 for (
unsigned int j = 0; j <
N; ++j)
68 tmp(i, j) = face_interpolation_matrix(primary_dof_list[i], j);
79 double diagonal_sum = 0;
80 for (
unsigned int i = 0; i <
N; ++i)
81 diagonal_sum += std::fabs(tmp(i, i));
82 const double typical_diagonal_element = diagonal_sum /
N;
86 std::vector<unsigned int> p(N);
87 for (
unsigned int i = 0; i <
N; ++i)
90 for (
unsigned int j = 0; j <
N; ++j)
94 double max = std::fabs(tmp(j, j));
96 for (
unsigned int i = j + 1; i <
N; ++i)
98 if (std::fabs(tmp(i, j)) > max)
100 max = std::fabs(tmp(i, j));
107 if (max < 1.e-12 * typical_diagonal_element)
113 for (
unsigned int k = 0; k <
N; ++k)
114 std::swap(tmp(j, k), tmp(r, k));
116 std::swap(p[j], p[r]);
120 const double hr = 1. / tmp(j, j);
122 for (
unsigned int k = 0; k <
N; ++k)
126 for (
unsigned int i = 0; i <
N; ++i)
130 tmp(i, k) -= tmp(i, j) * tmp(j, k) * hr;
133 for (
unsigned int i = 0; i <
N; ++i)
169 template <
int dim,
int spacedim>
171 select_primary_dofs_for_face_restriction(
175 std::vector<bool> &primary_dof_mask)
181 const unsigned int face_no = 0;
216 std::vector<types::global_dof_index> primary_dof_list;
217 unsigned int index = 0;
222 unsigned int dofs_added = 0;
231 primary_dof_list.push_back(index + i);
234 if (check_primary_dof_list(face_interpolation_matrix,
235 primary_dof_list) ==
true)
240 primary_dof_list.pop_back();
253 unsigned int dofs_added = 0;
259 primary_dof_list.push_back(index + i);
260 if (check_primary_dof_list(face_interpolation_matrix,
261 primary_dof_list) ==
true)
264 primary_dof_list.pop_back();
276 unsigned int dofs_added = 0;
282 primary_dof_list.push_back(index + i);
283 if (check_primary_dof_list(face_interpolation_matrix,
284 primary_dof_list) ==
true)
287 primary_dof_list.pop_back();
298 std::fill(primary_dof_mask.begin(), primary_dof_mask.end(),
false);
299 for (
const auto dof : primary_dof_list)
300 primary_dof_mask[dof] = true;
309 template <
int dim,
int spacedim>
311 ensure_existence_of_primary_dof_mask(
315 std::unique_ptr<std::vector<bool>> &primary_dof_mask)
321 const unsigned int face_no = 0;
323 if (primary_dof_mask ==
nullptr)
327 select_primary_dofs_for_face_restriction(fe1,
329 face_interpolation_matrix,
341 template <
int dim,
int spacedim>
343 ensure_existence_of_face_matrix(
352 const unsigned int face_no = 0;
354 if (matrix ==
nullptr)
356 matrix = std::make_unique<FullMatrix<double>>(
367 template <
int dim,
int spacedim>
369 ensure_existence_of_subface_matrix(
372 const unsigned int subface,
379 const unsigned int face_no = 0;
381 if (matrix ==
nullptr)
383 matrix = std::make_unique<FullMatrix<double>>(
400 ensure_existence_of_split_face_matrix(
402 const std::vector<bool> &primary_dof_mask,
407 Assert(std::count(primary_dof_mask.begin(),
408 primary_dof_mask.end(),
410 static_cast<signed int>(face_interpolation_matrix.
n()),
413 if (split_matrix ==
nullptr)
415 split_matrix = std::make_unique<
418 const unsigned int n_primary_dofs = face_interpolation_matrix.
n();
419 const unsigned int n_dofs = face_interpolation_matrix.
m();
425 split_matrix->first.reinit(n_primary_dofs, n_primary_dofs);
426 split_matrix->second.reinit(n_dofs - n_primary_dofs,
429 unsigned int nth_primary_dof = 0, nth_dependent_dof = 0;
431 for (
unsigned int i = 0; i < n_dofs; ++i)
432 if (primary_dof_mask[i] ==
true)
434 for (
unsigned int j = 0; j < n_primary_dofs; ++j)
435 split_matrix->first(nth_primary_dof, j) =
436 face_interpolation_matrix(i, j);
441 for (
unsigned int j = 0; j < n_primary_dofs; ++j)
442 split_matrix->second(nth_dependent_dof, j) =
443 face_interpolation_matrix(i, j);
452 split_matrix->first.gauss_jordan();
462 template <
int dim,
int spacedim>
484 template <
typename number1,
typename number2>
487 const std::vector<types::global_dof_index> &primary_dofs,
488 const std::vector<types::global_dof_index> &dependent_dofs,
492 Assert(face_constraints.
n() == primary_dofs.size(),
494 Assert(face_constraints.
m() == dependent_dofs.size(),
496 face_constraints.
m()));
498 const unsigned int n_primary_dofs = primary_dofs.size();
499 const unsigned int n_dependent_dofs = dependent_dofs.size();
503 for (
unsigned int row = 0; row != n_dependent_dofs; ++row)
506 for (
unsigned int col = 0; col != n_primary_dofs; ++col)
517 boost::container::small_vector<std::pair<size_type, size_type>, 25>
519 sorted_primary_dofs.reserve(n_primary_dofs);
520 for (
unsigned int i = 0; i < n_primary_dofs; ++i)
521 sorted_primary_dofs.emplace_back(primary_dofs[i], i);
522 std::sort(sorted_primary_dofs.begin(), sorted_primary_dofs.end());
524 boost::container::small_vector<std::pair<size_type, number2>, 25>
526 entries.reserve(n_primary_dofs);
527 for (
unsigned int row = 0; row != n_dependent_dofs; ++row)
547 bool is_trivial_constraint =
false;
549 for (
unsigned int i = 0; i < n_primary_dofs; ++i)
550 if (face_constraints(row, i) == 1.0)
551 if (dependent_dofs[row] == primary_dofs[i])
553 is_trivial_constraint =
true;
555 for (
unsigned int ii = 0; ii < n_primary_dofs; ++ii)
557 Assert(face_constraints(row, ii) == 0.0,
563 if (is_trivial_constraint ==
true)
578 for (
const auto &[dof_index, unsorted_index] :
580 if (
std::
fabs(face_constraints(row, unsorted_index)) >= 1
e-14)
581 entries.emplace_back(dof_index,
582 face_constraints(row, unsorted_index));
593 template <
typename number,
int spacedim>
604 template <
typename number,
int spacedim>
607 const ::DoFHandler<1, spacedim> & ,
609 std::integral_constant<int, 1>)
616 template <
typename number,
int spacedim>
621 std::integral_constant<int, 1>)
628 template <
int dim_,
int spacedim,
typename number>
633 std::integral_constant<int, 2>)
635 const unsigned int dim = 2;
637 std::vector<types::global_dof_index> dofs_on_mother;
638 std::vector<types::global_dof_index> dofs_on_children;
645 boost::container::small_vector<
646 std::pair<typename AffineConstraints<number>::size_type, number>,
662 if (cell->is_artificial())
665 for (
const unsigned int face : cell->face_indices())
666 if (cell->face(face)->has_children())
672 Assert(cell->face(face)->n_active_fe_indices() == 1,
674 Assert(cell->face(face)->fe_index_is_active(
675 cell->active_fe_index()) ==
true,
677 for (
unsigned int c = 0; c < cell->face(face)->n_children();
679 if (!cell->neighbor_child_on_subface(face, c)
681 Assert(cell->face(face)->child(c)->n_active_fe_indices() ==
687 for (
unsigned int c = 0; c < cell->face(face)->n_children();
689 if (!cell->neighbor_child_on_subface(face, c)
691 Assert(cell->face(face)->child(c)->fe_index_is_active(
692 cell->active_fe_index()) ==
true,
699 const unsigned int n_dofs_on_mother =
706 dofs_on_mother.resize(n_dofs_on_mother);
709 dofs_on_children.clear();
710 dofs_on_children.reserve(n_dofs_on_children);
720 this_face = cell->face(face);
724 unsigned int next_index = 0;
725 for (
unsigned int vertex = 0; vertex < 2; ++vertex)
728 dofs_on_mother[next_index++] =
729 this_face->vertex_dof_index(vertex, dof, fe_index);
731 dofs_on_mother[next_index++] =
732 this_face->dof_index(dof, fe_index);
736 dofs_on_children.push_back(
737 this_face->child(0)->vertex_dof_index(1, dof, fe_index));
738 for (
unsigned int child = 0; child < 2; ++child)
741 if (cell->neighbor_child_on_subface(face, child)
746 dofs_on_children.push_back(
747 this_face->child(child)->dof_index(dof, fe_index));
750 Assert(dofs_on_children.size() <= n_dofs_on_children,
754 for (
unsigned int row = 0; row != dofs_on_children.size();
757 constraint_entries.clear();
758 constraint_entries.reserve(dofs_on_mother.size());
759 for (
unsigned int i = 0; i != dofs_on_mother.size(); ++i)
760 constraint_entries.emplace_back(dofs_on_mother[i],
774 if (!cell->at_boundary(face) &&
775 !cell->neighbor(face)->is_artificial())
777 Assert(cell->face(face)->n_active_fe_indices() == 1,
779 Assert(cell->face(face)->fe_index_is_active(
780 cell->active_fe_index()) ==
true,
789 template <
int dim_,
int spacedim,
typename number>
794 std::integral_constant<int, 3>)
796 const unsigned int dim = 3;
798 std::vector<types::global_dof_index> dofs_on_mother;
799 std::vector<types::global_dof_index> dofs_on_children;
806 boost::container::small_vector<
807 std::pair<typename AffineConstraints<number>::size_type, number>,
823 if (cell->is_artificial())
826 for (
const unsigned int face : cell->face_indices())
827 if (cell->face(face)->has_children())
832 if (cell->get_fe().n_dofs_per_face(face) == 0)
835 Assert(cell->face(face)->refinement_case() ==
844 Assert(cell->face(face)->fe_index_is_active(
845 cell->active_fe_index()) ==
true,
847 for (
unsigned int c = 0; c < cell->face(face)->n_children();
849 if (!cell->neighbor_child_on_subface(face, c)
852 cell->face(face)->child(c)->n_active_fe_indices(), 1);
857 for (
unsigned int c = 0; c < cell->face(face)->n_children();
859 if (!cell->neighbor_child_on_subface(face, c)
862 Assert(cell->face(face)->child(c)->fe_index_is_active(
863 cell->active_fe_index()) ==
true,
865 for (
unsigned int e = 0; e < 4; ++e)
870 ->n_active_fe_indices() == 1,
875 ->fe_index_is_active(
876 cell->active_fe_index()) ==
true,
880 for (
unsigned int e = 0; e < 4; ++e)
882 Assert(cell->face(face)->line(e)->n_active_fe_indices() ==
885 Assert(cell->face(face)->line(e)->fe_index_is_active(
886 cell->active_fe_index()) ==
true,
895 const unsigned int n_dofs_on_children =
902 dofs_on_mother.resize(n_dofs_on_mother);
905 dofs_on_children.clear();
906 dofs_on_children.reserve(n_dofs_on_children);
916 this_face = cell->face(face);
920 unsigned int next_index = 0;
921 for (
unsigned int vertex = 0; vertex < 4; ++vertex)
924 dofs_on_mother[next_index++] =
925 this_face->vertex_dof_index(vertex, dof, fe_index);
926 for (
unsigned int line = 0; line < 4; ++line)
928 dofs_on_mother[next_index++] =
929 this_face->line(line)->dof_index(dof, fe_index);
932 dofs_on_mother[next_index++] =
933 this_face->dof_index(dof, fe_index);
942 ((this_face->child(0)->vertex_index(3) ==
943 this_face->child(1)->vertex_index(2)) &&
944 (this_face->child(0)->vertex_index(3) ==
945 this_face->child(2)->vertex_index(1)) &&
946 (this_face->child(0)->vertex_index(3) ==
947 this_face->child(3)->vertex_index(0))),
951 dofs_on_children.push_back(
952 this_face->child(0)->vertex_dof_index(3, dof));
955 for (
unsigned int line = 0; line < 4; ++line)
958 dofs_on_children.push_back(
959 this_face->line(line)->child(0)->vertex_dof_index(
966 dofs_on_children.push_back(
967 this_face->child(0)->line(1)->dof_index(dof, fe_index));
969 dofs_on_children.push_back(
970 this_face->child(2)->line(1)->dof_index(dof, fe_index));
972 dofs_on_children.push_back(
973 this_face->child(0)->line(3)->dof_index(dof, fe_index));
975 dofs_on_children.push_back(
976 this_face->child(1)->line(3)->dof_index(dof, fe_index));
979 for (
unsigned int line = 0; line < 4; ++line)
980 for (
unsigned int child = 0; child < 2; ++child)
984 dofs_on_children.push_back(
985 this_face->line(line)->child(child)->dof_index(
990 for (
unsigned int child = 0; child < 4; ++child)
993 if (cell->neighbor_child_on_subface(face, child)
998 dofs_on_children.push_back(
999 this_face->child(child)->dof_index(dof, fe_index));
1003 Assert(dofs_on_children.size() <= n_dofs_on_children,
1011 for (
unsigned int row = 0; row != dofs_on_children.size();
1016 constraint_entries.clear();
1017 constraint_entries.reserve(dofs_on_mother.size());
1018 for (
unsigned int i = 0; i != dofs_on_mother.size(); ++i)
1019 constraint_entries.emplace_back(dofs_on_mother[i],
1034 if (!cell->at_boundary(face) &&
1035 !cell->neighbor(face)->is_artificial())
1037 Assert(cell->face(face)->n_active_fe_indices() == 1,
1039 Assert(cell->face(face)->fe_index_is_active(
1040 cell->active_fe_index()) ==
true,
1049 template <
int dim_,
int spacedim,
typename number>
1054 std::integral_constant<int, 2>)
1061 const unsigned int dim = 2;
1063 std::vector<types::global_dof_index> face_dof_indices;
1064 std::map<types::global_dof_index, std::set<types::global_dof_index>>
1071 if (cell->is_artificial())
1075 for (
const unsigned int f : cell->face_indices())
1079 if (!cell->face(f)->has_children())
1082 Assert(cell->face(f)->n_active_fe_indices() == 1,
1084 Assert(cell->face(f)->fe_index_is_active(
1085 cell->active_fe_index()) ==
true,
1090 for (
unsigned int c = 0; c < cell->face(f)->n_children(); ++c)
1092 if (cell->neighbor_child_on_subface(f, c)
1096 Assert(cell->face(f)->child(c)->n_active_fe_indices() ==
1100 Assert(cell->face(f)->child(c)->fe_index_is_active(
1101 cell->active_fe_index()) ==
true,
1110 face_dof_indices.resize(n_dofs);
1112 cell->face(f)->get_dof_indices(face_dof_indices);
1113 const std::vector<types::global_dof_index> dof_on_mother_face =
1116 cell->face(f)->child(0)->get_dof_indices(face_dof_indices);
1117 const std::vector<types::global_dof_index> dof_on_child_face_0 =
1120 cell->face(f)->child(1)->get_dof_indices(face_dof_indices);
1121 const std::vector<types::global_dof_index> dof_on_child_face_1 =
1130 const bool direction_mother = (cell->face(f)->vertex_index(0) >
1131 cell->face(f)->vertex_index(1)) ?
1134 const bool direction_child_0 =
1135 (cell->face(f)->child(0)->vertex_index(0) >
1136 cell->face(f)->child(0)->vertex_index(1)) ?
1139 const bool direction_child_1 =
1140 (cell->face(f)->child(1)->vertex_index(0) >
1141 cell->face(f)->child(1)->vertex_index(1)) ?
1145 for (
unsigned int row = 0; row < n_dofs; ++row)
1147 constraints.
add_line(dof_on_child_face_0[row]);
1148 constraints.
add_line(dof_on_child_face_1[row]);
1151 for (
unsigned int row = 0; row < n_dofs; ++row)
1153 for (
unsigned int dof_i_on_mother = 0;
1154 dof_i_on_mother < n_dofs;
1161 unsigned int shift_0 =
1162 (direction_mother == direction_child_0) ? 0 : n_dofs;
1163 constraints.
add_entry(dof_on_child_face_0[row],
1164 dof_on_mother_face[dof_i_on_mother],
1168 unsigned int shift_1 =
1169 (direction_mother == direction_child_1) ? 0 : n_dofs;
1170 constraints.
add_entry(dof_on_child_face_1[row],
1171 dof_on_mother_face[dof_i_on_mother],
1181 template <
int dim_,
int spacedim,
typename number>
1186 std::integral_constant<int, 3>)
1193 const unsigned int dim = 3;
1204 std::vector<types::global_dof_index> dofs_on_mother;
1205 std::vector<types::global_dof_index> dofs_on_children;
1211 if (cell->is_artificial())
1215 for (
const unsigned int face : cell->face_indices())
1218 if (cell->face(face)->has_children() ==
false)
1221 if (cell->get_fe().n_dofs_per_face(face) == 0)
1224 Assert(cell->face(face)->refinement_case() ==
1230 Assert(cell->face(face)->fe_index_is_active(
1231 cell->active_fe_index()) ==
true,
1236 for (
unsigned int c = 0; c < cell->face(face)->n_children();
1239 if (cell->neighbor_child_on_subface(face, c)
1244 cell->face(face)->child(c)->n_active_fe_indices(), 1);
1246 Assert(cell->face(face)->child(c)->fe_index_is_active(
1247 cell->active_fe_index()) ==
true,
1250 for (
unsigned int e = 0;
1251 e < GeometryInfo<dim>::vertices_per_face;
1257 ->n_active_fe_indices() == 1,
1263 ->fe_index_is_active(
1264 cell->active_fe_index()) ==
true,
1269 for (
unsigned int e = 0;
1270 e < GeometryInfo<dim>::vertices_per_face;
1273 Assert(cell->face(face)->line(e)->n_active_fe_indices() ==
1277 Assert(cell->face(face)->line(e)->fe_index_is_active(
1278 cell->active_fe_index()) ==
true,
1285 const unsigned int fe_index = cell->active_fe_index();
1288 unsigned int degree(fe.
degree);
1293 dofs_on_mother.resize(n_dofs_on_mother);
1295 const unsigned int n_lines_on_mother =
1310 const unsigned int n_internal_lines_on_children = 4;
1322 const unsigned int n_external_lines_on_children = 8;
1324 const unsigned int n_lines_on_children =
1325 n_internal_lines_on_children + n_external_lines_on_children;
1328 const unsigned int n_children_per_face =
1330 const unsigned int n_children_per_line =
1336 const unsigned int n_dofs_on_children =
1340 dofs_on_children.clear();
1341 dofs_on_children.reserve(n_dofs_on_children);
1351 unsigned int next_index = 0;
1357 for (
unsigned int line = 0;
1358 line < GeometryInfo<dim>::lines_per_face;
1361 dofs_on_mother[next_index++] =
1362 this_face->line(line)->dof_index(dof, fe_index);
1366 dofs_on_mother[next_index++] =
1367 this_face->dof_index(dof, fe_index);
1386 dofs_on_children.push_back(
1387 this_face->child(0)->line(1)->dof_index(dof, fe_index));
1390 dofs_on_children.push_back(
1391 this_face->child(2)->line(1)->dof_index(dof, fe_index));
1394 dofs_on_children.push_back(
1395 this_face->child(0)->line(3)->dof_index(dof, fe_index));
1398 dofs_on_children.push_back(
1399 this_face->child(1)->line(3)->dof_index(dof, fe_index));
1404 for (
unsigned int line = 0;
1405 line < GeometryInfo<dim>::lines_per_face;
1407 for (
unsigned int child = 0; child < n_children_per_line;
1410 dofs_on_children.push_back(
1411 this_face->line(line)->child(child)->dof_index(dof,
1415 for (
unsigned int child = 0; child < n_children_per_face; ++child)
1418 if (cell->neighbor_child_on_subface(face, child)
1424 dofs_on_children.push_back(
1425 this_face->child(child)->dof_index(dof, fe_index));
1430 Assert(dofs_on_children.size() <= n_dofs_on_children,
1440 std::vector<bool> direction_mother(
1442 for (
unsigned int line = 0;
1443 line < GeometryInfo<dim>::lines_per_face;
1445 if (this_face->line(line)->vertex_index(0) >
1446 this_face->line(line)->vertex_index(1))
1447 direction_mother[line] =
true;
1450 std::vector<bool> direction_child_intern(
1451 n_internal_lines_on_children,
false);
1456 unsigned int center = this_face->child(0)->vertex_index(3);
1459 for (
unsigned int line = 0; line < n_internal_lines_on_children;
1463 direction_child_intern[line] =
1464 this_face->line(line)->child(0)->vertex_index(1) <
1471 direction_child_intern[line] =
1472 this_face->line(line)->child(0)->vertex_index(1) >
1479 std::vector<bool> direction_child(n_external_lines_on_children,
1481 for (
unsigned int line = 0;
1482 line < GeometryInfo<dim>::lines_per_face;
1485 if (this_face->line(line)->child(0)->vertex_index(0) >
1486 this_face->line(line)->child(0)->vertex_index(1))
1487 direction_child[2 * line] =
true;
1488 if (this_face->line(line)->child(1)->vertex_index(0) >
1489 this_face->line(line)->child(1)->vertex_index(1))
1490 direction_child[2 * line + 1] =
true;
1495 bool mother_flip_x =
false;
1496 bool mother_flip_y =
false;
1497 bool mother_flip_xy =
false;
1498 std::vector<bool> child_flip_x(n_children_per_face,
false);
1499 std::vector<bool> child_flip_y(n_children_per_face,
false);
1500 std::vector<bool> child_flip_xy(n_children_per_face,
false);
1503 [2] = {{1, 2}, {0, 3}, {3, 0}, {2, 1}};
1508 unsigned int current_glob = cell->face(face)->vertex_index(0);
1509 unsigned int current_max = 0;
1510 for (
unsigned int v = 1;
1511 v < GeometryInfo<dim>::vertices_per_face;
1513 if (current_glob < this_face->vertex_index(v))
1516 current_glob = this_face->vertex_index(v);
1521 if (current_max < 2)
1522 mother_flip_y =
true;
1526 if (current_max % 2 == 0)
1527 mother_flip_x =
true;
1530 if (this_face->vertex_index(
1531 vertices_adjacent_on_face[current_max][0]) <
1532 this_face->vertex_index(
1533 vertices_adjacent_on_face[current_max][1]))
1534 mother_flip_xy =
true;
1539 for (
unsigned int child = 0; child < n_children_per_face; ++child)
1541 unsigned int current_max = 0;
1542 unsigned int current_glob =
1543 this_face->child(child)->vertex_index(0);
1545 for (
unsigned int v = 1;
1546 v < GeometryInfo<dim>::vertices_per_face;
1548 if (current_glob < this_face->child(child)->vertex_index(v))
1551 current_glob = this_face->child(child)->vertex_index(v);
1554 if (current_max < 2)
1555 child_flip_y[child] =
true;
1557 if (current_max % 2 == 0)
1558 child_flip_x[child] =
true;
1560 if (this_face->child(child)->vertex_index(
1561 vertices_adjacent_on_face[current_max][0]) <
1562 this_face->child(child)->vertex_index(
1563 vertices_adjacent_on_face[current_max][1]))
1564 child_flip_xy[child] =
true;
1566 child_flip_xy[child] = mother_flip_xy;
1570 std::vector<std::vector<double>> constraints_matrix(
1573 std::vector<double>(dofs_on_mother.size(), 0));
1578 for (
unsigned int line = 0; line < n_internal_lines_on_children;
1582 unsigned int line_mother = line / 2;
1583 unsigned int row_mother =
1587 for (
unsigned int i = 0;
1590 constraints_matrix[row + row_start][i] =
1594 for (
unsigned int line = 0; line < n_internal_lines_on_children;
1598 unsigned int line_mother = line / 2;
1599 unsigned int row_mother =
1603 for (
unsigned int i =
1605 i < dofs_on_mother.size();
1607 constraints_matrix[row + row_start][i] =
1612 unsigned int row_offset =
1614 for (
unsigned int line = 0; line < n_external_lines_on_children;
1618 unsigned int line_mother = line / 2;
1619 unsigned int row_mother =
1621 for (
unsigned int row = row_offset;
1624 for (
unsigned int i = 0; i < dofs_on_mother.size(); ++i)
1625 constraints_matrix[row + row_start][i] =
1631 for (
unsigned int face = 0; face < n_children_per_face; ++face)
1634 for (
unsigned int row = row_offset;
1637 for (
unsigned int i = 0; i < dofs_on_mother.size(); ++i)
1638 constraints_matrix[row + row_start][i] =
1647 for (
unsigned int i = 0;
1652 unsigned int tmp_i = i % degree;
1655 for (
unsigned int j = 0;
1660 unsigned int tmp_j = j % degree;
1662 if ((line_i < 2 && line_j < 2) ||
1663 (line_i >= 2 && line_j >= 2))
1665 if (direction_child_intern[line_i] !=
1666 direction_mother[line_j])
1668 if ((tmp_i + tmp_j) % 2 == 1)
1670 constraints_matrix[i][j] *= -1.0;
1676 if (direction_mother[line_i])
1678 if ((tmp_i + tmp_j) % 2 == 1)
1680 constraints_matrix[i][j] *= -1.0;
1688 for (
unsigned int i =
1694 unsigned int tmp_i = i % degree;
1697 for (
unsigned int j = 0;
1702 unsigned int tmp_j = j % degree;
1704 if (direction_child[line_i] != direction_mother[line_j])
1706 if ((tmp_i + tmp_j) % 2 == 1)
1708 constraints_matrix[i][j] *= -1.0;
1726 unsigned int tmp_i = i % degree;
1728 unsigned int start_j =
1731 for (
unsigned int block = 0; block < n_blocks; ++block)
1734 for (
unsigned int jy = 0; jy < degree - 1; ++jy)
1735 for (
unsigned int jx = 0; jx < degree - 1; ++jx)
1737 unsigned int j = start_j + jx + (jy * (degree - 1));
1738 if (direction_child_intern[line_i] != mother_flip_y)
1740 if ((jy + tmp_i) % 2 == 0)
1742 constraints_matrix[i][j] *= -1.0;
1747 start_j += (degree - 1) * (degree - 1);
1750 for (
unsigned int jy = 0; jy < degree - 1; ++jy)
1751 for (
unsigned int jx = 0; jx < degree - 1; ++jx)
1753 unsigned int j = start_j + jx + (jy * (degree - 1));
1755 if (direction_child_intern[line_i] != mother_flip_y)
1757 if ((jy + tmp_i) % 2 == 0)
1759 constraints_matrix[i][j] *= -1.0;
1763 start_j += (degree - 1) * (degree - 1);
1767 start_j += degree - 1;
1771 start_j += degree - 1;
1781 unsigned int tmp_i = i % degree;
1783 unsigned int start_j =
1786 for (
unsigned int block = 0; block < n_blocks; block++)
1789 for (
unsigned int jy = 0; jy < degree - 1; ++jy)
1790 for (
unsigned int jx = 0; jx < degree - 1; ++jx)
1792 unsigned int j = start_j + jx + (jy * (degree - 1));
1793 if (direction_child_intern[line_i] != mother_flip_x)
1795 if ((jx + tmp_i) % 2 == 0)
1797 constraints_matrix[i][j] *= -1.0;
1802 start_j += (degree - 1) * (degree - 1);
1805 for (
unsigned int jy = 0; jy < degree - 1; ++jy)
1806 for (
unsigned int jx = 0; jx < degree - 1; ++jx)
1808 unsigned int j = start_j + jx + (jy * (degree - 1));
1809 if (direction_child_intern[line_i] != mother_flip_x)
1811 if ((jx + tmp_i) % 2 == 0)
1813 constraints_matrix[i][j] *= -1.0;
1817 start_j += (degree - 1) * (degree - 1);
1821 start_j += degree - 1;
1825 start_j += degree - 1;
1830 unsigned int degree_square = (degree - 1) * (degree - 1);
1834 for (
unsigned int child_face = 0;
1835 child_face < n_children_per_face;
1837 for (
unsigned int block = 0; block < n_blocks; ++block)
1849 for (
unsigned int iy = 0; iy < degree - 1; ++iy)
1850 for (
unsigned int ix = 0; ix < degree - 1; ++ix)
1856 for (
unsigned int jy = 0; jy < degree - 1; ++jy)
1857 for (
unsigned int jx = 0; jx < degree - 1; ++jx)
1859 if (child_flip_x[child_face] !=
1862 if ((ix + jx) % 2 == 1)
1864 constraints_matrix[i][j] *= -1.0;
1868 if (child_flip_y[child_face] !=
1871 if ((iy + jy) % 2 == 1)
1873 constraints_matrix[i][j] *= -1.0;
1883 for (
unsigned int iy = 0; iy < degree - 1; ++iy)
1884 for (
unsigned int ix = 0; ix < degree - 1; ++ix)
1889 degree_square + block * block_size;
1890 for (
unsigned int jy = 0; jy < degree - 1; ++jy)
1891 for (
unsigned int jx = 0; jx < degree - 1; ++jx)
1893 if (child_flip_x[child_face] !=
1896 if ((ix + jx) % 2 == 1)
1898 constraints_matrix[i][j] *= -1.0;
1902 if (child_flip_y[child_face] !=
1905 if ((iy + jy) % 2 == 1)
1907 constraints_matrix[i][j] *= -1.0;
1919 for (
unsigned int iy = 0; iy < degree - 1; ++iy)
1924 degree_square + block * block_size;
1925 for (
unsigned int jy = 0; jy < degree - 1; ++jy)
1926 for (
unsigned int jx = 0; jx < degree - 1; ++jx)
1928 if (child_flip_x[child_face] !=
1933 constraints_matrix[i][j] *= -1.0;
1937 if (child_flip_y[child_face] !=
1940 if ((iy + jy) % 2 == 1)
1942 constraints_matrix[i][j] *= -1.0;
1951 2 * degree_square + block * block_size;
1952 for (
unsigned int jy = 0; jy < degree - 1; ++jy)
1954 if (child_flip_y[child_face] !=
1957 if ((iy + jy) % 2 == 1)
1959 constraints_matrix[i][j] *= -1.0;
1969 for (
unsigned int ix = 0; ix < degree - 1; ++ix)
1974 degree_square + block * block_size;
1975 for (
unsigned int jy = 0; jy < degree - 1; ++jy)
1976 for (
unsigned int jx = 0; jx < degree - 1; ++jx)
1978 if (child_flip_x[child_face] !=
1981 if ((ix + jx) % 2 == 1)
1983 constraints_matrix[i][j] *= -1.0;
1987 if (child_flip_y[child_face] !=
1992 constraints_matrix[i][j] *= -1.0;
2001 2 * degree_square + (degree - 1) +
2003 for (
unsigned int jx = 0; jx < degree - 1; ++jx)
2005 if (child_flip_x[child_face] !=
2008 if ((ix + jx) % 2 == 1)
2010 constraints_matrix[i][j] *= -1.0;
2027 for (
unsigned int i = 0;
2035 std::vector<double> constraints_matrix_old(
2036 dofs_on_mother.size(), 0);
2037 for (
unsigned int j = 0; j < dofs_on_mother.size(); ++j)
2039 constraints_matrix_old[j] = constraints_matrix[i][j];
2042 unsigned int j_start =
2044 for (
unsigned block = 0; block < n_blocks; block++)
2047 for (
unsigned int jy = 0; jy < degree - 1; ++jy)
2048 for (
unsigned int jx = 0; jx < degree - 1; ++jx)
2050 unsigned int j_old =
2051 j_start + jx + (jy * (degree - 1));
2052 unsigned int j_new =
2053 j_start + jy + (jx * (degree - 1));
2054 constraints_matrix[i][j_new] =
2055 constraints_matrix_old[j_old];
2057 j_start += degree_square;
2060 for (
unsigned int jy = 0; jy < degree - 1; ++jy)
2061 for (
unsigned int jx = 0; jx < degree - 1; ++jx)
2063 unsigned int j_old =
2064 j_start + jx + (jy * (degree - 1));
2065 unsigned int j_new =
2066 j_start + jy + (jx * (degree - 1));
2067 constraints_matrix[i][j_new] =
2068 -constraints_matrix_old[j_old];
2070 j_start += degree_square;
2073 for (
unsigned int j = j_start;
2074 j < j_start + (degree - 1);
2077 constraints_matrix[i][j] =
2078 constraints_matrix_old[j + (degree - 1)];
2079 constraints_matrix[i][j + (degree - 1)] =
2080 constraints_matrix_old[j];
2082 j_start += 2 * (degree - 1);
2089 const unsigned int deg = degree - 1;
2092 std::vector<std::vector<double>> constraints_matrix_old(
2095 for (
unsigned int i = 0;
2099 constraints_matrix_old[i][j] = constraints_matrix
2104 for (
unsigned int child = 0; child < n_children_per_face;
2107 if (!child_flip_xy[child])
2110 unsigned int i_start_new =
2115 unsigned int j_start =
2118 for (
unsigned int block = 0; block < n_blocks; block++)
2121 for (
unsigned int ix = 0; ix < deg; ++ix)
2123 for (
unsigned int iy = 0; iy < deg; ++iy)
2125 for (
unsigned int j = 0;
2128 constraints_matrix[i_start_new + iy +
2129 (ix * deg)][j + j_start] =
2130 constraints_matrix_old[i_start_old + ix +
2134 i_start_new += deg * deg;
2135 i_start_old += deg * deg;
2138 for (
unsigned int ix = 0; ix < deg; ++ix)
2140 for (
unsigned int iy = 0; iy < deg; ++iy)
2142 for (
unsigned int j = 0;
2145 constraints_matrix[i_start_new + iy +
2146 (ix * deg)][j + j_start] =
2147 -constraints_matrix_old[i_start_old + ix +
2151 i_start_new += deg * deg;
2152 i_start_old += deg * deg;
2155 for (
unsigned int ix = 0; ix < deg; ++ix)
2159 constraints_matrix[i_start_new + ix][j +
2161 constraints_matrix_old[i_start_old + ix + deg]
2165 constraints_matrix[i_start_new + ix +
2167 constraints_matrix_old[i_start_old + ix][j];
2170 i_start_new += 2 * deg;
2171 i_start_old += 2 * deg;
2176 for (
unsigned int i = 0;
2180 constraints_matrix_old[i][j] = constraints_matrix
2187 unsigned int i_start =
2190 unsigned int j_start_new =
2192 unsigned int j_start_old = 0;
2194 for (
unsigned int block = 0; block < n_blocks; ++block)
2197 for (
unsigned int jx = 0; jx < deg; ++jx)
2199 for (
unsigned int jy = 0; jy < deg; ++jy)
2201 for (
unsigned int i = 0;
2205 constraints_matrix[i + i_start][j_start_new +
2208 constraints_matrix_old[i][j_start_old + jx +
2212 j_start_new += deg * deg;
2213 j_start_old += deg * deg;
2216 for (
unsigned int jx = 0; jx < deg; ++jx)
2218 for (
unsigned int jy = 0; jy < deg; ++jy)
2220 for (
unsigned int i = 0;
2224 constraints_matrix[i + i_start][j_start_new +
2227 -constraints_matrix_old[i][j_start_old +
2231 j_start_new += deg * deg;
2232 j_start_old += deg * deg;
2235 for (
unsigned int jx = 0; jx < deg; ++jx)
2237 for (
unsigned int i = 0;
2241 constraints_matrix[i + i_start][j_start_new +
2243 constraints_matrix_old[i][j_start_old + jx +
2245 constraints_matrix[i + i_start][j_start_new +
2247 constraints_matrix_old[i][j_start_old + jx];
2250 j_start_new += 2 * deg;
2251 j_start_old += 2 * deg;
2261 for (
unsigned int line = 0; line < n_internal_lines_on_children;
2268 constraints.
add_line(dofs_on_children[row_start + row]);
2269 for (
unsigned int i = 0; i < dofs_on_mother.size(); ++i)
2272 dofs_on_children[row_start + row],
2274 constraints_matrix[row_start + row][i]);
2277 dofs_on_children[row_start + row], 0.);
2282 for (
unsigned int line = 0; line < n_external_lines_on_children;
2285 unsigned int row_start =
2290 constraints.
add_line(dofs_on_children[row_start + row]);
2291 for (
unsigned int i = 0; i < dofs_on_mother.size(); ++i)
2294 dofs_on_children[row_start + row],
2296 constraints_matrix[row_start + row][i]);
2299 dofs_on_children[row_start + row], 0.);
2304 for (
unsigned int f = 0; f < n_children_per_face; ++f)
2306 unsigned int row_start =
2312 constraints.
add_line(dofs_on_children[row_start + row]);
2314 for (
unsigned int i = 0; i < dofs_on_mother.size(); ++i)
2317 dofs_on_children[row_start + row],
2319 constraints_matrix[row_start + row][i]);
2323 dofs_on_children[row_start + row], 0.);
2331 template <
int dim,
int spacedim,
typename number>
2349 std::vector<types::global_dof_index> primary_dofs;
2350 std::vector<types::global_dof_index> dependent_dofs;
2351 std::vector<types::global_dof_index> scratch_dofs;
2357 n_finite_elements(dof_handler), n_finite_elements(dof_handler));
2359 subface_interpolation_matrices(
2360 n_finite_elements(dof_handler),
2361 n_finite_elements(dof_handler),
2371 split_face_interpolation_matrices(n_finite_elements(dof_handler),
2372 n_finite_elements(dof_handler));
2378 n_finite_elements(dof_handler), n_finite_elements(dof_handler));
2389 if (cell->is_artificial())
2392 for (
const unsigned int face : cell->face_indices())
2393 if (cell->face(face)->has_children())
2398 if (cell->get_fe().n_dofs_per_face(face) == 0)
2401 Assert(cell->face(face)->refinement_case() ==
2412 Assert(cell->face(face)->n_active_fe_indices() == 1,
2414 Assert(cell->face(face)->fe_index_is_active(
2415 cell->active_fe_index()) ==
true,
2417 for (
unsigned int c = 0; c < cell->face(face)->n_children();
2419 if (!cell->neighbor_child_on_subface(face, c)
2421 Assert(cell->face(face)->child(c)->n_active_fe_indices() ==
2437 std::set<unsigned int> fe_ind_face_subface;
2441 fe_ind_face_subface.insert(cell->active_fe_index());
2442 for (
unsigned int c = 0;
2443 c < cell->face(face)->n_active_descendants();
2446 const auto subcell =
2447 cell->neighbor_child_on_subface(face, c);
2448 if (!subcell->is_artificial())
2450 mother_face_dominates =
2451 mother_face_dominates &
2452 (cell->get_fe().compare_for_domination(
2453 subcell->get_fe(), 1));
2454 fe_ind_face_subface.insert(
2455 subcell->active_fe_index());
2460 switch (mother_face_dominates)
2472 primary_dofs.resize(
2473 cell->get_fe().n_dofs_per_face(face));
2475 cell->face(face)->get_dof_indices(
2476 primary_dofs, cell->active_fe_index());
2482 for (
unsigned int c = 0;
2483 c < cell->face(face)->n_children();
2486 if (cell->neighbor_child_on_subface(face, c)
2491 active_face_iterator subface =
2492 cell->face(face)->child(c);
2494 Assert(subface->n_active_fe_indices() == 1,
2498 subface->nth_active_fe_index(0);
2509 if (cell->get_fe().compare_for_domination(
2510 subface->
get_fe(subface_fe_index),
2517 dependent_dofs.resize(
2518 subface->
get_fe(subface_fe_index)
2520 subface->get_dof_indices(dependent_dofs,
2526 (void)dependent_dof;
2554 ensure_existence_of_subface_matrix(
2556 subface->
get_fe(subface_fe_index),
2558 subface_interpolation_matrices
2559 [cell->active_fe_index()][subface_fe_index][c]);
2563 filter_constraints(primary_dofs,
2565 *(subface_interpolation_matrices
2566 [cell->active_fe_index()]
2567 [subface_fe_index][c]),
2587 const ::hp::FECollection<dim, spacedim>
2616 Assert(fe_ind_face_subface.size() > 0,
2619 fe_collection.find_dominating_fe_extended(
2620 fe_ind_face_subface,
2626 "Could not find a least face dominating FE."));
2629 dof_handler.
get_fe(dominating_fe_index);
2634 cell->get_fe().n_dofs_per_face(face),
2637 ensure_existence_of_face_matrix(
2640 face_interpolation_matrices[dominating_fe_index]
2641 [cell->active_fe_index()]);
2645 ensure_existence_of_primary_dof_mask(
2648 (*face_interpolation_matrices
2649 [dominating_fe_index][cell->active_fe_index()]),
2650 primary_dof_masks[dominating_fe_index]
2651 [cell->active_fe_index()]);
2653 ensure_existence_of_split_face_matrix(
2654 *face_interpolation_matrices[dominating_fe_index]
2655 [cell->active_fe_index()],
2656 (*primary_dof_masks[dominating_fe_index]
2657 [cell->active_fe_index()]),
2658 split_face_interpolation_matrices
2659 [dominating_fe_index][cell->active_fe_index()]);
2662 &restrict_mother_to_virtual_primary_inv =
2663 (split_face_interpolation_matrices
2664 [dominating_fe_index][cell->active_fe_index()]
2668 &restrict_mother_to_virtual_dependent =
2669 (split_face_interpolation_matrices
2670 [dominating_fe_index][cell->active_fe_index()]
2675 constraint_matrix.reinit(
2676 cell->get_fe().n_dofs_per_face(face) -
2679 restrict_mother_to_virtual_dependent.
mmult(
2681 restrict_mother_to_virtual_primary_inv);
2685 scratch_dofs.resize(
2686 cell->get_fe().n_dofs_per_face(face));
2687 cell->face(face)->get_dof_indices(
2688 scratch_dofs, cell->active_fe_index());
2691 primary_dofs.clear();
2692 dependent_dofs.clear();
2693 for (
unsigned int i = 0;
2694 i < cell->get_fe().n_dofs_per_face(face);
2696 if ((*primary_dof_masks[dominating_fe_index]
2698 ->active_fe_index()])[i] ==
2700 primary_dofs.push_back(scratch_dofs[i]);
2702 dependent_dofs.push_back(scratch_dofs[i]);
2707 cell->get_fe().n_dofs_per_face(face) -
2710 filter_constraints(primary_dofs,
2719 for (
unsigned int sf = 0;
2720 sf < cell->face(face)->n_children();
2725 if (cell->neighbor_child_on_subface(face, sf)
2726 ->is_artificial() ||
2727 (dim == 2 && cell->is_ghost() &&
2728 cell->neighbor_child_on_subface(face, sf)
2734 ->n_active_fe_indices() == 1,
2738 cell->face(face)->child(sf)->nth_active_fe_index(
2741 dof_handler.
get_fe(subface_fe_index);
2748 ensure_existence_of_subface_matrix(
2752 subface_interpolation_matrices
2753 [dominating_fe_index][subface_fe_index][sf]);
2756 &restrict_subface_to_virtual = *(
2757 subface_interpolation_matrices
2758 [dominating_fe_index][subface_fe_index][sf]);
2760 constraint_matrix.reinit(
2764 restrict_subface_to_virtual.
mmult(
2766 restrict_mother_to_virtual_primary_inv);
2768 dependent_dofs.resize(
2770 cell->face(face)->child(sf)->get_dof_indices(
2771 dependent_dofs, subface_fe_index);
2773 filter_constraints(primary_dofs,
2796 Assert(cell->face(face)->fe_index_is_active(
2797 cell->active_fe_index()) ==
true,
2804 if (!cell->at_boundary(face) &&
2805 cell->neighbor(face)->is_artificial())
2811 !cell->face(face)->at_boundary() &&
2812 (cell->neighbor(face)->active_fe_index() !=
2813 cell->active_fe_index()) &&
2814 (!cell->face(face)->has_children() &&
2815 !cell->neighbor_is_coarser(face)))
2818 spacedim>::level_cell_iterator
2819 neighbor = cell->neighbor(face);
2823 cell->get_fe().compare_for_domination(neighbor->get_fe(),
2830 primary_dofs.resize(
2831 cell->get_fe().n_dofs_per_face(face));
2832 cell->face(face)->get_dof_indices(
2833 primary_dofs, cell->active_fe_index());
2838 if (primary_dofs.empty())
2841 dependent_dofs.resize(
2842 neighbor->get_fe().n_dofs_per_face(face));
2843 cell->face(face)->get_dof_indices(
2844 dependent_dofs, neighbor->active_fe_index());
2848 ensure_existence_of_face_matrix(
2851 face_interpolation_matrices
2852 [cell->active_fe_index()]
2853 [neighbor->active_fe_index()]);
2859 *(face_interpolation_matrices
2860 [cell->active_fe_index()]
2861 [neighbor->active_fe_index()]),
2904 if (cell < neighbor)
2919 cell->active_fe_index();
2921 neighbor->active_fe_index();
2922 std::set<types::fe_index> fes;
2923 fes.insert(this_fe_index);
2924 fes.insert(neighbor_fe_index);
2925 const ::hp::FECollection<dim, spacedim>
2931 {fes.begin(), fes.end()}, 1);
2936 "Could not find the dominating FE for " +
2937 cell->get_fe().get_name() +
" and " +
2938 neighbor->get_fe().get_name() +
2939 " inside FECollection."));
2942 fe_collection[dominating_fe_index];
2950 cell->get_fe().n_dofs_per_face(face),
2953 ensure_existence_of_face_matrix(
2956 face_interpolation_matrices
2957 [dominating_fe_index][cell->active_fe_index()]);
2961 ensure_existence_of_primary_dof_mask(
2964 (*face_interpolation_matrices
2965 [dominating_fe_index]
2966 [cell->active_fe_index()]),
2967 primary_dof_masks[dominating_fe_index]
2968 [cell->active_fe_index()]);
2970 ensure_existence_of_split_face_matrix(
2971 *face_interpolation_matrices
2972 [dominating_fe_index][cell->active_fe_index()],
2973 (*primary_dof_masks[dominating_fe_index]
2974 [cell->active_fe_index()]),
2975 split_face_interpolation_matrices
2976 [dominating_fe_index][cell->active_fe_index()]);
2979 double> &restrict_mother_to_virtual_primary_inv =
2980 (split_face_interpolation_matrices
2981 [dominating_fe_index][cell->active_fe_index()]
2985 double> &restrict_mother_to_virtual_dependent =
2986 (split_face_interpolation_matrices
2987 [dominating_fe_index][cell->active_fe_index()]
2992 constraint_matrix.reinit(
2993 cell->get_fe().n_dofs_per_face(face) -
2996 restrict_mother_to_virtual_dependent.
mmult(
2998 restrict_mother_to_virtual_primary_inv);
3002 scratch_dofs.resize(
3003 cell->get_fe().n_dofs_per_face(face));
3004 cell->face(face)->get_dof_indices(
3005 scratch_dofs, cell->active_fe_index());
3008 primary_dofs.clear();
3009 dependent_dofs.clear();
3010 for (
unsigned int i = 0;
3011 i < cell->get_fe().n_dofs_per_face(face);
3013 if ((*primary_dof_masks[dominating_fe_index]
3014 [cell->active_fe_index()])
3016 primary_dofs.push_back(scratch_dofs[i]);
3018 dependent_dofs.push_back(scratch_dofs[i]);
3024 dependent_dofs.size(),
3025 cell->get_fe().n_dofs_per_face(face) -
3028 filter_constraints(primary_dofs,
3037 neighbor->get_fe().n_dofs_per_face(face),
3040 ensure_existence_of_face_matrix(
3043 face_interpolation_matrices
3044 [dominating_fe_index]
3045 [neighbor->active_fe_index()]);
3048 &restrict_secondface_to_virtual =
3049 *(face_interpolation_matrices
3050 [dominating_fe_index]
3051 [neighbor->active_fe_index()]);
3053 constraint_matrix.reinit(
3054 neighbor->get_fe().n_dofs_per_face(face),
3057 restrict_secondface_to_virtual.
mmult(
3059 restrict_mother_to_virtual_primary_inv);
3061 dependent_dofs.resize(
3062 neighbor->get_fe().n_dofs_per_face(face));
3063 cell->face(face)->get_dof_indices(
3064 dependent_dofs, neighbor->active_fe_index());
3066 filter_constraints(primary_dofs,
3092 template <
int dim,
int spacedim,
typename number>
3099 "The given DoFHandler does not have any DoFs. Did you forget to "
3100 "call dof_handler.distribute_dofs()?"));
3110 dof_handler, constraints, std::integral_constant<int, dim>());
3115 dof_handler, constraints, std::integral_constant<int, dim>());
3122 template <
typename FaceIterator,
typename number>
3125 const FaceIterator &face_1,
3131 const number periodicity_factor,
3132 const unsigned int level)
3134 static const int dim = FaceIterator::AccessorType::dimension;
3135 static const int spacedim = FaceIterator::AccessorType::space_dimension;
3140 const unsigned int face_no = 0;
3151 face_1->get_fe(face_1->nth_active_fe_index(0)).n_unique_faces(), 1);
3153 face_2->get_fe(face_2->nth_active_fe_index(0)).n_unique_faces(), 1);
3158 Assert(face_1->get_fe(face_1_index) == face_2->get_fe(face_2_index),
3160 "Matching periodic cells need to use the same finite element"));
3163 "The number of components in the mask has to be either "
3164 "zero or equal to the number of components in the finite "
3174 if ((!use_mg) && face_2->has_children())
3176 Assert(face_2->n_children() == face_2->reference_cell().n_children(),
3181 std::vector<types::global_dof_index> dofs_1(dofs_per_face);
3182 face_1->get_dof_indices(dofs_1, face_1->nth_active_fe_index(0));
3183 for (
unsigned int i = 0; i < dofs_per_face; ++i)
3193 for (
unsigned int c = 0; c < face_2->n_children(); ++c)
3198 const auto &fe = face_1->get_fe(face_1->nth_active_fe_index(0));
3201 subface_interpolation,
3203 subface_interpolation.
mmult(child_transformation, transformation);
3207 child_transformation,
3210 combined_orientation,
3211 periodicity_factor);
3221 std::vector<types::global_dof_index> dofs_1(dofs_per_face);
3222 std::vector<types::global_dof_index> dofs_2(dofs_per_face);
3228 face_1->get_mg_dof_indices(
level, dofs_1, face_1_index);
3230 face_1->get_dof_indices(dofs_1, face_1_index);
3233 face_2->get_mg_dof_indices(
level, dofs_2, face_2_index);
3235 face_2->get_dof_indices(dofs_2, face_2_index);
3253 for (
unsigned int i = 0; i < dofs_per_face; ++i)
3262 if (
const auto tria =
dynamic_cast<
3264 &face_1->get_triangulation()))
3265 if (tria->with_artificial_cells() &&
3267 for (
unsigned int i = 0; i < dofs_per_face; ++i)
3282 std::vector<unsigned int> cell_to_face_index(
3285 for (
unsigned int face_dof = 0; face_dof < dofs_per_face; ++face_dof)
3295 boost::container::small_vector<
3296 std::pair<typename AffineConstraints<number>::size_type, number>,
3304 for (
unsigned int i = 0; i < dofs_per_face; ++i)
3325 bool is_identity_constrained =
false;
3327 number constraint_factor = periodicity_factor;
3329 constexpr double eps = 1.e-13;
3330 for (
unsigned int jj = 0; jj < dofs_per_face; ++jj)
3332 const auto entry = transformation(i, jj);
3335 if (is_identity_constrained)
3340 is_identity_constrained =
false;
3343 is_identity_constrained =
true;
3345 constraint_factor = entry * periodicity_factor;
3354 if (!is_identity_constrained)
3361 constraint_entries.clear();
3362 constraint_entries.reserve(dofs_per_face);
3364 for (
unsigned int jj = 0; jj < dofs_per_face; ++jj)
3368 const unsigned int j =
3370 jj, face_no, combined_orientation)];
3374 if (
std::abs(transformation(i, jj)) > eps)
3375 constraint_entries.emplace_back(dofs_1[j],
3376 transformation(i, jj));
3394 target, face_no, combined_orientation)];
3397 auto dof_left = dofs_1[j];
3398 auto dof_right = dofs_2[i];
3404 (dof_left < dof_right &&
3407 std::swap(dof_left, dof_right);
3408 constraint_factor = 1. / constraint_factor;
3424 bool constraints_are_cyclic =
true;
3425 number cycle_constraint_factor = constraint_factor;
3427 for (
auto test_dof = dof_right; test_dof != dof_left;)
3431 constraints_are_cyclic =
false;
3435 const auto &constraint_entries =
3437 if (constraint_entries.size() == 1)
3439 test_dof = constraint_entries[0].first;
3440 cycle_constraint_factor *= constraint_entries[0].second;
3444 constraints_are_cyclic =
false;
3459 if (constraints_are_cyclic)
3461 if (
std::abs(cycle_constraint_factor - number(1.)) > eps)
3467 dof_left, {{dof_right, constraint_factor}}, 0.);
3489 ExcMessage(
"The periodicity constraint is too large. "
3490 "The parameter periodicity_factor might "
3491 "be too large or too small."));
3505 template <
int dim,
int spacedim>
3507 compute_transformation(
3510 const std::vector<unsigned int> &first_vector_components)
3515 const unsigned int face_no = 0;
3521 if (matrix.m() == n_dofs_per_face)
3528 if (first_vector_components.empty() &&
matrix.m() == 0)
3545 using DoFTuple = std::array<unsigned int, spacedim>;
3550 for (
unsigned int i = 0; i < n_dofs_per_face; ++i)
3552 std::vector<unsigned int>::const_iterator comp_it =
3553 std::find(first_vector_components.begin(),
3554 first_vector_components.end(),
3556 if (comp_it != first_vector_components.end())
3558 const unsigned int first_vector_component = *comp_it;
3561 DoFTuple vector_dofs;
3563 unsigned int n_found = 1;
3568 "Error: the finite element does not have enough components "
3569 "to define rotated periodic boundaries."));
3571 for (
unsigned int k = 0; k < n_dofs_per_face; ++k)
3572 if ((k != i) && (quadrature.point(k) == quadrature.point(i)) &&
3574 first_vector_component) &&
3576 first_vector_component + spacedim))
3580 first_vector_component] = k;
3588 for (
unsigned int i = 0; i < spacedim; ++i)
3590 transformation[vector_dofs[i]][vector_dofs[i]] = 0.;
3591 for (
unsigned int j = 0; j < spacedim; ++j)
3592 transformation[vector_dofs[i]][vector_dofs[j]] =
3597 return transformation;
3605 template <
typename FaceIterator,
typename number>
3608 const FaceIterator &face_1,
3614 const std::vector<unsigned int> &first_vector_components,
3615 const number periodicity_factor)
3617 static const int dim = FaceIterator::AccessorType::dimension;
3618 static const int spacedim = FaceIterator::AccessorType::space_dimension;
3622 const auto [orientation, rotation, flip] =
3626 (orientation ==
true && flip ==
false && rotation ==
false),
3628 "The supplied orientation (orientation, rotation, flip) "
3629 "is invalid for 1d"));
3631 Assert((dim != 2) || (flip ==
false && rotation ==
false),
3633 "The supplied orientation (orientation, rotation, flip) "
3634 "is invalid for 2d"));
3637 ExcMessage(
"face_1 and face_2 are equal! Cannot constrain DoFs "
3638 "on the very same face"));
3640 Assert(face_1->at_boundary() && face_2->at_boundary(),
3641 ExcMessage(
"Faces for periodicity constraints must be on the "
3644 Assert(matrix.m() == matrix.n(),
3646 "The supplied (rotation or interpolation) matrix must "
3647 "be a square matrix"));
3649 Assert(first_vector_components.empty() || matrix.m() == spacedim,
3650 ExcMessage(
"first_vector_components is nonempty, so matrix must "
3651 "be a rotation matrix exactly of size spacedim"));
3653 if (!face_1->has_children())
3658 face_1->get_fe(face_1->nth_active_fe_index(0)).n_unique_faces(),
3660 const unsigned int face_no = 0;
3663 const unsigned int n_dofs_per_face =
3664 face_1->get_fe(face_1->nth_active_fe_index(0))
3665 .n_dofs_per_face(face_no);
3667 Assert(matrix.m() == 0 ||
3668 (first_vector_components.empty() &&
3669 matrix.m() == n_dofs_per_face) ||
3670 (!first_vector_components.empty() &&
3671 matrix.m() == spacedim),
3673 "The matrix must have either size 0 or spacedim "
3674 "(if first_vector_components is nonempty) "
3675 "or the size must be equal to the # of DoFs on the face "
3676 "(if first_vector_components is empty)."));
3679 if (!face_2->has_children())
3684 face_2->get_fe(face_2->nth_active_fe_index(0)).n_unique_faces(),
3686 const unsigned int face_no = 0;
3689 const unsigned int n_dofs_per_face =
3690 face_2->get_fe(face_2->nth_active_fe_index(0))
3691 .n_dofs_per_face(face_no);
3693 Assert(matrix.m() == 0 ||
3694 (first_vector_components.empty() &&
3695 matrix.m() == n_dofs_per_face) ||
3696 (!first_vector_components.empty() &&
3697 matrix.m() == spacedim),
3699 "The matrix must have either size 0 or spacedim "
3700 "(if first_vector_components is nonempty) "
3701 "or the size must be equal to the # of DoFs on the face "
3702 "(if first_vector_components is empty)."));
3706 if (face_1->has_children() && face_2->has_children())
3711 Assert(face_1->n_children() ==
3717 for (
unsigned int i = 0; i < GeometryInfo<dim>::max_children_per_face;
3723 const unsigned int face_no = dim == 2 ? 2 : 4;
3727 const auto reference_cell = ReferenceCells::get_hypercube<dim>();
3728 const unsigned int j =
3729 reference_cell.child_cell_on_face(face_no,
3731 combined_orientation);
3737 combined_orientation,
3739 first_vector_components,
3740 periodicity_factor);
3750 face_1->has_children() ?
3751 face_2->get_fe(face_2->nth_active_fe_index(0)) :
3752 face_1->get_fe(face_1->nth_active_fe_index(0));
3757 const unsigned int face_no = 0;
3763 if (n_dofs_per_face == 0)
3767 compute_transformation(fe, matrix, first_vector_components);
3769 if (!face_2->has_children())
3773 if (first_vector_components.empty() && matrix.m() == 0)
3780 combined_orientation,
3781 periodicity_factor);
3786 inverse.
invert(transformation);
3793 combined_orientation,
3794 periodicity_factor);
3804 const auto face_reference_cell = face_1->reference_cell();
3811 face_reference_cell.get_inverse_combined_orientation(
3812 combined_orientation),
3813 periodicity_factor);
3820 template <
typename FaceIterator,
typename number>
3823 const FaceIterator &face_1,
3825 const unsigned int level,
3830 const std::vector<unsigned int> &first_vector_components,
3831 const number periodicity_factor)
3833 static const int dim = FaceIterator::AccessorType::dimension;
3834 static const int spacedim = FaceIterator::AccessorType::space_dimension;
3838 const auto [orientation, rotation, flip] =
3841 (orientation ==
true && flip ==
false && rotation ==
false),
3842 ExcMessage(
"The supplied face orientation is invalid for 1d."));
3843 Assert((dim != 2) || (flip ==
false && rotation ==
false),
3844 ExcMessage(
"The supplied face orientation is invalid for 2d."));
3848 ExcMessage(
"face_1 and face_2 are equal! Cannot constrain DoFs "
3849 "on the very same face"));
3850 Assert(face_1->at_boundary() && face_2->at_boundary(),
3851 ExcMessage(
"Faces for periodicity constraints must be on the "
3853 Assert(&face_1->get_dof_handler() == &face_2->get_dof_handler(),
3854 ExcMessage(
"The two faces must belong to the same DoFHandler."));
3856 level, face_1->get_dof_handler().get_triangulation().n_global_levels());
3857 Assert(face_1->get_dof_handler().has_hp_capabilities() ==
false,
3859 Assert(matrix.m() == matrix.n(),
3860 ExcMessage(
"The supplied rotation or interpolation matrix must "
3862 Assert(first_vector_components.empty() || matrix.m() == spacedim,
3863 ExcMessage(
"If first_vector_components is nonempty, matrix must "
3864 "be a rotation matrix of size spacedim."));
3868 compute_transformation(fe, matrix, first_vector_components);
3870 if (first_vector_components.empty() && matrix.m() == 0)
3876 combined_orientation,
3882 inverse.
invert(transformation);
3889 combined_orientation,
3897 template <
int dim,
int spacedim,
typename number>
3904 const std::vector<unsigned int> &first_vector_components,
3905 const number periodicity_factor)
3908 for (
auto &pair : periodic_faces)
3911 const FaceIterator face_1 = pair.cell[0]->face(pair.face_idx[0]);
3912 const FaceIterator face_2 = pair.cell[1]->face(pair.face_idx[1]);
3914 Assert(face_1->at_boundary() && face_2->at_boundary(),
3927 first_vector_components,
3928 periodicity_factor);
3936 template <
int dim,
int spacedim,
typename number>
3941 const unsigned int direction,
3944 const number periodicity_factor)
3949 ExcMessage(
"The boundary indicators b_id1 and b_id2 must be "
3950 "different to denote different boundaries."));
3958 dof_handler, b_id1, b_id2, direction, matched_faces);
3960 make_periodicity_constraints<dim, spacedim>(matched_faces,
3963 std::vector<unsigned int>(),
3964 periodicity_factor);
3969 template <
int dim,
int spacedim,
typename number>
3973 const unsigned int direction,
3976 const number periodicity_factor)
3992 make_periodicity_constraints<dim, spacedim>(matched_faces,
3995 std::vector<unsigned int>(),
3996 periodicity_factor);
4010 template <
int dim,
int spacedim>
4015#ifdef DEAL_II_WITH_MPI
4016 std::vector<::LinearAlgebra::distributed::Vector<double>>
4031 template <
int dim,
int spacedim>
4033 compute_intergrid_weights_3(
4036 const unsigned int coarse_component,
4095 for (
unsigned int local_dof = 0; local_dof < copy_data.
dofs_per_cell;
4101 const unsigned int local_parameter_dof =
4110 coarse_to_fine_grid_map[cell]->set_dof_values_by_interpolation(
4111 parameter_dofs[local_parameter_dof],
4123 template <
int dim,
int spacedim>
4125 copy_intergrid_weights_3(
4126 const Assembler::CopyData<dim, spacedim> ©_data,
4127 const unsigned int coarse_component,
4129 const std::vector<types::global_dof_index> &weight_mapping,
4130 const bool is_called_in_parallel,
4131 std::vector<std::map<types::global_dof_index, float>> &weights)
4133 unsigned int pos = 0;
4134 for (
unsigned int local_dof = 0; local_dof < copy_data.dofs_per_cell;
4161 i < copy_data.global_parameter_representation[pos].size();
4167 if (copy_data.global_parameter_representation[pos](i) != 0)
4170 wi = copy_data.parameter_dof_indices[local_dof],
4171 wj = weight_mapping[i];
4173 copy_data.global_parameter_representation[pos](i);
4176 else if (!is_called_in_parallel)
4181 Assert(copy_data.global_parameter_representation[pos](i) ==
4197 template <
int dim,
int spacedim>
4199 compute_intergrid_weights_2(
4201 const unsigned int coarse_component,
4204 const std::vector<types::global_dof_index> &weight_mapping,
4205 std::vector<std::map<types::global_dof_index, float>> &weights)
4207 Assembler::CopyData<dim, spacedim> copy_data;
4209 unsigned int n_interesting_dofs = 0;
4210 for (
unsigned int local_dof = 0;
4211 local_dof < coarse_grid.
get_fe().n_dofs_per_cell();
4215 ++n_interesting_dofs;
4217 copy_data.global_parameter_representation.resize(n_interesting_dofs);
4219 bool is_called_in_parallel =
false;
4220 for (std::size_t i = 0;
4221 i < copy_data.global_parameter_representation.size();
4224#ifdef DEAL_II_WITH_MPI
4225 MPI_Comm communicator = MPI_COMM_SELF;
4228 const typename ::parallel::TriangulationBase<dim,
4230 &tria =
dynamic_cast<const typename ::parallel::
4231 TriangulationBase<dim, spacedim> &
>(
4232 coarse_to_fine_grid_map.get_destination_grid()
4233 .get_triangulation());
4234 communicator = tria.get_mpi_communicator();
4235 is_called_in_parallel =
true;
4237 catch (std::bad_cast &)
4243 const IndexSet locally_relevant_dofs =
4245 coarse_to_fine_grid_map.get_destination_grid());
4247 copy_data.global_parameter_representation[i].reinit(
4248 coarse_to_fine_grid_map.get_destination_grid()
4249 .locally_owned_dofs(),
4250 locally_relevant_dofs,
4254 copy_data.global_parameter_representation[i].reinit(n_fine_dofs);
4261 &coarse_to_fine_grid_map,
4265 const Assembler::Scratch &,
4266 Assembler::CopyData<dim, spacedim> ©_data) {
4267 compute_intergrid_weights_3<dim, spacedim>(cell,
4270 coarse_grid.get_fe(),
4271 coarse_to_fine_grid_map,
4279 is_called_in_parallel,
4280 &weights](
const Assembler::CopyData<dim, spacedim> ©_data) {
4281 copy_intergrid_weights_3<dim, spacedim>(copy_data,
4283 coarse_grid.get_fe(),
4285 is_called_in_parallel,
4293 Assembler::Scratch(),
4296#ifdef DEAL_II_WITH_MPI
4297 for (std::size_t i = 0;
4298 i < copy_data.global_parameter_representation.size();
4300 copy_data.global_parameter_representation[i].update_ghost_values();
4311 template <
int dim,
int spacedim>
4313 compute_intergrid_weights_1(
4315 const unsigned int coarse_component,
4317 const unsigned int fine_component,
4319 std::vector<std::map<types::global_dof_index, float>> &weights,
4320 std::vector<types::global_dof_index> &weight_mapping)
4324 &fine_fe = fine_grid.
get_fe();
4328 n_fine_dofs = fine_grid.
n_dofs();
4331 const unsigned int fine_dofs_per_cell = fine_fe.n_dofs_per_cell();
4335 const unsigned int coarse_dofs_per_cell_component =
4349 Assert(&coarse_to_fine_grid_map.get_source_grid() == &coarse_grid,
4351 Assert(&coarse_to_fine_grid_map.get_destination_grid() == &fine_grid,
4363 fine_fe.component_to_base_index(fine_component).first),
4370 for (
const auto &cell : coarse_grid.active_cell_iterators())
4396 std::vector<::Vector<double>> parameter_dofs(
4397 coarse_dofs_per_cell_component,
4402 for (
unsigned int local_coarse_dof = 0;
4403 local_coarse_dof < coarse_dofs_per_cell_component;
4405 for (
unsigned int fine_dof = 0; fine_dof < fine_fe.n_dofs_per_cell();
4407 if (fine_fe.system_to_component_index(fine_dof) ==
4408 std::make_pair(fine_component, local_coarse_dof))
4410 parameter_dofs[local_coarse_dof](fine_dof) = 1.;
4417 unsigned int n_parameters_on_fine_grid = 0;
4421 std::vector<bool> dof_is_interesting(fine_grid.
n_dofs(),
false);
4422 std::vector<types::global_dof_index> local_dof_indices(
4423 fine_fe.n_dofs_per_cell());
4425 for (
const auto &cell : fine_grid.active_cell_iterators() |
4428 cell->get_dof_indices(local_dof_indices);
4429 for (
unsigned int i = 0; i < fine_fe.n_dofs_per_cell(); ++i)
4430 if (fine_fe.system_to_component_index(i).first ==
4432 dof_is_interesting[local_dof_indices[i]] =
true;
4435 n_parameters_on_fine_grid = std::count(dof_is_interesting.begin(),
4436 dof_is_interesting.end(),
4443 weights.resize(n_coarse_dofs);
4445 weight_mapping.clear();
4449 std::vector<types::global_dof_index> local_dof_indices(
4450 fine_fe.n_dofs_per_cell());
4451 unsigned int next_free_index = 0;
4452 for (
const auto &cell : fine_grid.active_cell_iterators() |
4455 cell->get_dof_indices(local_dof_indices);
4456 for (
unsigned int i = 0; i < fine_fe.n_dofs_per_cell(); ++i)
4459 if ((fine_fe.system_to_component_index(i).first ==
4461 (weight_mapping[local_dof_indices[i]] ==
4464 weight_mapping[local_dof_indices[i]] = next_free_index;
4469 Assert(next_free_index == n_parameters_on_fine_grid,
4481 compute_intergrid_weights_2(coarse_grid,
4483 coarse_to_fine_grid_map,
4504 for (
unsigned int col = 0; col < n_parameters_on_fine_grid; ++col)
4509 if (weights[row].find(col) != weights[row].end())
4510 sum += weights[row][col];
4511 Assert((std::fabs(sum - 1) < 1.e-12) ||
4518 return n_parameters_on_fine_grid;
4527 template <
int dim,
int spacedim>
4531 const unsigned int coarse_component,
4533 const unsigned int fine_component,
4539 ExcMessage(
"This function is not yet implemented for DoFHandlers "
4540 "using hp-capabilities."));
4561 std::vector<std::map<types::global_dof_index, float>> weights;
4567 std::vector<types::global_dof_index> weight_mapping;
4569 const unsigned int n_parameters_on_fine_grid =
4570 internal::compute_intergrid_weights_1(coarse_grid,
4574 coarse_to_fine_grid_map,
4577 (void)n_parameters_on_fine_grid;
4581 n_fine_dofs = fine_grid.
n_dofs();
4589 mask[coarse_component] =
true;
4591 coarse_dof_is_parameter =
4592 extract_dofs<dim, spacedim>(coarse_grid,
ComponentMask(mask));
4604 std::vector<types::global_dof_index> representants(
4607 parameter_dof < n_coarse_dofs;
4609 if (coarse_dof_is_parameter.
is_element(parameter_dof))
4616 std::map<types::global_dof_index, float>::const_iterator i =
4617 weights[parameter_dof].begin();
4618 for (; i != weights[parameter_dof].end(); ++i)
4628 for (; global_dof < weight_mapping.size(); ++global_dof)
4629 if (weight_mapping[global_dof] ==
4635 representants[parameter_dof] = global_dof;
4651 std::vector<std::pair<types::global_dof_index, double>> constraint_line;
4670 std::map<types::global_dof_index, float>::const_iterator col_entry =
4672 for (; first_used_row < n_coarse_dofs; ++first_used_row)
4674 col_entry = weights[first_used_row].find(col);
4675 if (col_entry != weights[first_used_row].
end())
4679 Assert(col_entry != weights[first_used_row].
end(),
4682 if ((col_entry->second == 1) &&
4683 (representants[first_used_row] == global_dof))
4691 constraint_line.clear();
4693 row < n_coarse_dofs;
4696 const std::map<types::global_dof_index, float>::const_iterator j =
4697 weights[row].find(col);
4698 if ((j != weights[row].
end()) && (j->second != 0))
4699 constraint_line.emplace_back(representants[row], j->second);
4708 template <
int dim,
int spacedim>
4712 const unsigned int coarse_component,
4714 const unsigned int fine_component,
4716 std::vector<std::map<types::global_dof_index, float>>
4717 &transfer_representation)
4721 ExcMessage(
"This function is not yet implemented for DoFHandlers "
4722 "using hp-capabilities."));
4743 std::vector<std::map<types::global_dof_index, float>> weights;
4749 std::vector<types::global_dof_index> weight_mapping;
4751 internal::compute_intergrid_weights_1(coarse_grid,
4755 coarse_to_fine_grid_map,
4761 std::count_if(weight_mapping.begin(),
4762 weight_mapping.end(),
4764 return dof != numbers::invalid_dof_index;
4768 std::vector<types::global_dof_index> inverse_weight_mapping(
4777 Assert((inverse_weight_mapping[parameter_dof] ==
4781 inverse_weight_mapping[parameter_dof] = i;
4788 transfer_representation.clear();
4789 transfer_representation.resize(n_rows);
4794 std::map<types::global_dof_index, float>::const_iterator j =
4796 for (; j != weights[i].end(); ++j)
4801 transfer_representation[p][i] = j->second;
4808 template <
int dim,
int spacedim,
typename number>
4817 ExcMessage(
"The number of components in the mask has to be either "
4818 "zero or equal to the number of components in the finite "
4827 std::vector<types::global_dof_index> face_dofs;
4830 std::vector<types::global_dof_index> cell_dofs;
4838 std::set<types::global_dof_index> dofs_already_treated;
4841 if (!cell->is_artificial() && cell->at_boundary())
4847 cell->get_dof_indices(cell_dofs);
4849 for (
const auto face_no : cell->face_indices())
4852 cell->face(face_no);
4856 if (face->at_boundary() &&
4858 (face->boundary_id() == boundary_id)))
4862 face->get_dof_indices(face_dofs, cell->active_fe_index());
4867 if (dofs_already_treated.find(face_dof) ==
4868 dofs_already_treated.end())
4872 const std::vector<types::global_dof_index>::iterator
4873 it_index_on_cell = std::find(cell_dofs.begin(),
4876 Assert(it_index_on_cell != cell_dofs.end(),
4878 const unsigned int index_on_cell =
4879 std::distance(cell_dofs.begin(), it_index_on_cell);
4881 cell->get_fe().get_nonzero_components(index_on_cell);
4884 for (
unsigned int c = 0; c < n_components; ++c)
4885 if (nonzero_component_array[c] && component_mask[c])
4901 Assert(zero_boundary_constraints
4902 .is_inhomogeneously_constrained(
4909 dofs_already_treated.insert(face_dof);
4918 template <
int dim,
int spacedim,
typename number>
4927 zero_boundary_constraints,
4938#include "dofs/dof_tools_constraints.inst"
void add_line(const size_type line_n)
void add_constraint(const size_type constrained_dof, const ArrayView< const std::pair< size_type, number > > &dependencies, const number inhomogeneity=0)
void add_entry(const size_type constrained_dof_index, const size_type column, const number weight)
const IndexSet & get_local_lines() const
void set_inhomogeneity(const size_type constrained_dof_index, const number value)
bool is_constrained(const size_type line_n) const
const std::vector< std::pair< size_type, number > > * get_constraint_entries(const size_type line_n) const
void constrain_dof_to_zero(const size_type constrained_dof)
bool represents_n_components(const unsigned int n) const
unsigned int n_selected_components(const unsigned int overall_number_of_components=numbers::invalid_unsigned_int) const
const hp::FECollection< dim, spacedim > & get_fe_collection() const
bool has_active_dofs() const
const FiniteElement< dim, spacedim > & get_fe(const types::fe_index index=0) const
const Triangulation< dim, spacedim > & get_triangulation() const
bool has_hp_capabilities() const
types::global_dof_index n_dofs() const
unsigned int n_dofs_per_vertex() const
const unsigned int degree
unsigned int n_dofs_per_cell() const
unsigned int n_dofs_per_line() const
unsigned int n_dofs_per_face(unsigned int face_no=0, unsigned int child=0) const
unsigned int n_components() const
unsigned int n_unique_faces() const
unsigned int n_dofs_per_quad(unsigned int face_no=0) const
const unsigned int dofs_per_cell
virtual std::string get_name() const =0
virtual const FiniteElement< dim, spacedim > & base_element(const unsigned int index) const
std::pair< unsigned int, unsigned int > component_to_base_index(const unsigned int component) const
const std::vector< Point< dim - 1 > > & get_unit_face_support_points(const unsigned int face_no=0) const
virtual void get_subface_interpolation_matrix(const FiniteElement< dim, spacedim > &source, const unsigned int subface, FullMatrix< double > &matrix, const unsigned int face_no=0) const
std::pair< unsigned int, unsigned int > system_to_component_index(const unsigned int index) const
const FullMatrix< double > & constraints(const ::internal::SubfaceCase< dim > &subface_case=::internal::SubfaceCase< dim >::case_isotropic) const
virtual unsigned int face_to_cell_index(const unsigned int face_dof_index, const unsigned int face, const types::geometric_orientation combined_orientation=numbers::default_geometric_orientation) const
virtual void get_face_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix, const unsigned int face_no=0) const
std::pair< unsigned int, unsigned int > face_system_to_component_index(const unsigned int index, const unsigned int face_no=0) const
void mmult(FullMatrix< number2 > &C, const FullMatrix< number2 > &B, const bool adding=false) const
void invert(const FullMatrix< number2 > &M)
bool is_element(const size_type index) const
bool get_anisotropic_refinement_flag() const
unsigned int n_cells() const
void compute_line_to_adjacent_cells_map()
unsigned int size() const
unsigned int find_dominating_fe_extended(const std::set< unsigned int > &fes, const unsigned int codim=0) const
bool hp_constraints_are_implemented() const
unsigned int max_dofs_per_face() const
unsigned int n_components() const
unsigned int max_dofs_per_cell() const
#define DEAL_II_NAMESPACE_OPEN
constexpr bool running_in_debug_mode()
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_ASSERT_UNREACHABLE()
IteratorRange< active_cell_iterator > active_cell_iterators() const
static ::ExceptionBase & ExcInvalidIterator()
static ::ExceptionBase & ExcGridNotCoarser()
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcFiniteElementsDontMatch()
static ::ExceptionBase & ExcNoComponentSelected()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcGridsDontMatch()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
typename ActiveSelector::cell_iterator cell_iterator
typename ActiveSelector::line_iterator line_iterator
typename ActiveSelector::face_iterator face_iterator
typename ActiveSelector::active_cell_iterator active_cell_iterator
void compute_intergrid_transfer_representation(const DoFHandler< dim, spacedim > &coarse_grid, const unsigned int coarse_component, const DoFHandler< dim, spacedim > &fine_grid, const unsigned int fine_component, const InterGridMap< DoFHandler< dim, spacedim > > &coarse_to_fine_grid_map, std::vector< std::map< types::global_dof_index, float > > &transfer_representation)
void make_hanging_node_constraints(const DoFHandler< dim, spacedim > &dof_handler, AffineConstraints< number > &constraints)
void compute_intergrid_constraints(const DoFHandler< dim, spacedim > &coarse_grid, const unsigned int coarse_component, const DoFHandler< dim, spacedim > &fine_grid, const unsigned int fine_component, const InterGridMap< DoFHandler< dim, spacedim > > &coarse_to_fine_grid_map, AffineConstraints< double > &constraints)
void make_zero_boundary_constraints(const DoFHandler< dim, spacedim > &dof, const types::boundary_id boundary_id, AffineConstraints< number > &zero_boundary_constraints, const ComponentMask &component_mask={})
Expression fabs(const Expression &x)
types::global_dof_index size_type
@ either_element_can_dominate
@ other_element_dominates
@ neither_element_dominates
@ matrix
Contents is actually a matrix.
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
* * if(update_pressure &update_flags) * compute_pressure(constitutive_request
T sum(const T &t, const MPI_Comm mpi_communicator)
void run(const std::vector< std::vector< Iterator > > &colored_iterators, Worker worker, Copier copier, const ScratchData &sample_scratch_data, const CopyData &sample_copy_data, const unsigned int queue_length=2 *MultithreadInfo::n_threads(), const unsigned int chunk_size=8)
std::tuple< bool, bool, bool > split_face_orientation(const types::geometric_orientation combined_orientation)
constexpr types::global_dof_index invalid_dof_index
constexpr unsigned int invalid_unsigned_int
constexpr types::boundary_id invalid_boundary_id
constexpr types::geometric_orientation default_geometric_orientation
constexpr types::fe_index invalid_fe_index
typename type_identity< T >::type type_identity_t
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
unsigned short int fe_index
std::uint8_t geometric_orientation
static unsigned int n_children(const RefinementCase< dim > &refinement_case)