41#ifdef DEAL_II_WITH_MPI
61 check_primary_dof_list(
63 const std::vector<types::global_dof_index> &primary_dof_list)
65 const unsigned int N = primary_dof_list.size();
68 for (
unsigned int i = 0; i < N; ++i)
69 for (
unsigned int j = 0; j < N; ++j)
70 tmp(i, j) = face_interpolation_matrix(primary_dof_list[i], j);
81 double diagonal_sum = 0;
82 for (
unsigned int i = 0; i < N; ++i)
83 diagonal_sum += std::fabs(tmp(i, i));
84 const double typical_diagonal_element = diagonal_sum / N;
88 std::vector<unsigned int> p(N);
89 for (
unsigned int i = 0; i < N; ++i)
92 for (
unsigned int j = 0; j < N; ++j)
96 double max = std::fabs(tmp(j, j));
98 for (
unsigned int i = j + 1; i < N; ++i)
100 if (std::fabs(tmp(i, j)) > max)
102 max = std::fabs(tmp(i, j));
109 if (max < 1.e-12 * typical_diagonal_element)
115 for (
unsigned int k = 0; k < N; ++k)
116 std::swap(tmp(j, k), tmp(r, k));
118 std::swap(p[j], p[r]);
122 const double hr = 1. / tmp(j, j);
124 for (
unsigned int k = 0; k < N; ++k)
128 for (
unsigned int i = 0; i < N; ++i)
132 tmp(i, k) -= tmp(i, j) * tmp(j, k) * hr;
135 for (
unsigned int i = 0; i < N; ++i)
171 template <
int dim,
int spacedim>
173 select_primary_dofs_for_face_restriction(
177 std::vector<bool> & primary_dof_mask)
183 const unsigned int face_no = 0;
218 std::vector<types::global_dof_index> primary_dof_list;
219 unsigned int index = 0;
224 unsigned int dofs_added = 0;
233 primary_dof_list.push_back(index + i);
236 if (check_primary_dof_list(face_interpolation_matrix,
237 primary_dof_list) ==
true)
242 primary_dof_list.pop_back();
255 unsigned int dofs_added = 0;
261 primary_dof_list.push_back(index + i);
262 if (check_primary_dof_list(face_interpolation_matrix,
263 primary_dof_list) ==
true)
266 primary_dof_list.pop_back();
278 unsigned int dofs_added = 0;
284 primary_dof_list.push_back(index + i);
285 if (check_primary_dof_list(face_interpolation_matrix,
286 primary_dof_list) ==
true)
289 primary_dof_list.pop_back();
300 std::fill(primary_dof_mask.begin(), primary_dof_mask.end(),
false);
301 for (
const auto dof : primary_dof_list)
302 primary_dof_mask[dof] =
true;
311 template <
int dim,
int spacedim>
313 ensure_existence_of_primary_dof_mask(
317 std::unique_ptr<std::vector<bool>> &primary_dof_mask)
323 const unsigned int face_no = 0;
325 if (primary_dof_mask ==
nullptr)
329 select_primary_dofs_for_face_restriction(fe1,
331 face_interpolation_matrix,
343 template <
int dim,
int spacedim>
345 ensure_existence_of_face_matrix(
354 const unsigned int face_no = 0;
356 if (matrix ==
nullptr)
358 matrix = std::make_unique<FullMatrix<double>>(
369 template <
int dim,
int spacedim>
371 ensure_existence_of_subface_matrix(
374 const unsigned int subface,
381 const unsigned int face_no = 0;
383 if (matrix ==
nullptr)
385 matrix = std::make_unique<FullMatrix<double>>(
402 ensure_existence_of_split_face_matrix(
404 const std::vector<bool> & primary_dof_mask,
409 Assert(std::count(primary_dof_mask.begin(),
410 primary_dof_mask.end(),
412 static_cast<signed int>(face_interpolation_matrix.
n()),
415 if (split_matrix ==
nullptr)
417 split_matrix = std::make_unique<
420 const unsigned int n_primary_dofs = face_interpolation_matrix.
n();
421 const unsigned int n_dofs = face_interpolation_matrix.
m();
427 split_matrix->first.reinit(n_primary_dofs, n_primary_dofs);
428 split_matrix->second.reinit(n_dofs - n_primary_dofs,
431 unsigned int nth_primary_dof = 0, nth_dependent_dof = 0;
433 for (
unsigned int i = 0; i < n_dofs; ++i)
434 if (primary_dof_mask[i] ==
true)
436 for (
unsigned int j = 0; j < n_primary_dofs; ++j)
437 split_matrix->first(nth_primary_dof, j) =
438 face_interpolation_matrix(i, j);
443 for (
unsigned int j = 0; j < n_primary_dofs; ++j)
444 split_matrix->second(nth_dependent_dof, j) =
445 face_interpolation_matrix(i, j);
454 split_matrix->first.gauss_jordan();
464 template <
int dim,
int spacedim>
486 template <
typename number1,
typename number2>
489 const std::vector<types::global_dof_index> &primary_dofs,
490 const std::vector<types::global_dof_index> &dependent_dofs,
494 Assert(face_constraints.
n() == primary_dofs.size(),
496 Assert(face_constraints.
m() == dependent_dofs.size(),
498 face_constraints.
m()));
500 const unsigned int n_primary_dofs = primary_dofs.size();
501 const unsigned int n_dependent_dofs = dependent_dofs.size();
505 for (
unsigned int row = 0; row != n_dependent_dofs; ++row)
508 for (
unsigned int col = 0; col != n_primary_dofs; ++col)
513 for (
unsigned int row = 0; row != n_dependent_dofs; ++row)
533 bool is_trivial_constraint =
false;
535 for (
unsigned int i = 0; i < n_primary_dofs; ++i)
536 if (face_constraints(row, i) == 1.0)
537 if (dependent_dofs[row] == primary_dofs[i])
539 is_trivial_constraint =
true;
541 for (
unsigned int ii = 0; ii < n_primary_dofs; ++ii)
543 Assert(face_constraints(row, ii) == 0.0,
549 if (is_trivial_constraint ==
true)
555 for (
unsigned int i = 0; i < n_primary_dofs; ++i)
556 abs_sum +=
std::abs(face_constraints(row, i));
564 constraints.
add_line(dependent_dofs[row]);
565 for (
unsigned int i = 0; i < n_primary_dofs; ++i)
566 if ((face_constraints(row, i) != 0) &&
567 (std::fabs(face_constraints(row, i)) >= 1e-14 * abs_sum))
568 constraints.
add_entry(dependent_dofs[row],
570 face_constraints(row, i));
578 template <
typename number>
587 template <
typename number>
591 std::integral_constant<int, 1>)
597 template <
typename number>
606 template <
typename number>
610 std::integral_constant<int, 1>)
616 template <
typename number,
int spacedim>
619 const ::DoFHandler<1, spacedim> & ,
626 template <
typename number,
int spacedim>
629 const ::DoFHandler<1, spacedim> & ,
631 std::integral_constant<int, 1>)
636 template <
int dim_,
int spacedim,
typename number>
641 std::integral_constant<int, 2>)
643 const unsigned int dim = 2;
645 std::vector<types::global_dof_index> dofs_on_mother;
646 std::vector<types::global_dof_index> dofs_on_children;
658 endc = dof_handler.
end();
659 for (; cell != endc; ++cell)
663 if (cell->is_artificial())
666 for (
const unsigned int face : cell->face_indices())
667 if (cell->face(face)->has_children())
673 Assert(cell->face(face)->n_active_fe_indices() == 1,
675 Assert(cell->face(face)->fe_index_is_active(
676 cell->active_fe_index()) ==
true,
678 for (
unsigned int c = 0; c < cell->face(face)->n_children();
680 if (!cell->neighbor_child_on_subface(face, c)
682 Assert(cell->face(face)->child(c)->n_active_fe_indices() ==
688 for (
unsigned int c = 0; c < cell->face(face)->n_children();
690 if (!cell->neighbor_child_on_subface(face, c)
692 Assert(cell->face(face)->child(c)->fe_index_is_active(
693 cell->active_fe_index()) ==
true,
698 const unsigned int fe_index = cell->active_fe_index();
700 const unsigned int n_dofs_on_mother =
707 dofs_on_mother.resize(n_dofs_on_mother);
710 dofs_on_children.clear();
711 dofs_on_children.reserve(n_dofs_on_children);
721 this_face = cell->face(face);
725 unsigned int next_index = 0;
726 for (
unsigned int vertex = 0; vertex < 2; ++vertex)
729 dofs_on_mother[next_index++] =
730 this_face->vertex_dof_index(vertex, dof, fe_index);
732 dofs_on_mother[next_index++] =
733 this_face->dof_index(dof, fe_index);
737 dofs_on_children.push_back(
738 this_face->child(0)->vertex_dof_index(1, dof, fe_index));
739 for (
unsigned int child = 0; child < 2; ++child)
742 if (cell->neighbor_child_on_subface(face, child)
747 dofs_on_children.push_back(
748 this_face->child(child)->dof_index(dof, fe_index));
751 Assert(dofs_on_children.size() <= n_dofs_on_children,
755 for (
unsigned int row = 0; row != dofs_on_children.size();
758 constraints.
add_line(dofs_on_children[row]);
759 for (
unsigned int i = 0; i != dofs_on_mother.size(); ++i)
760 constraints.
add_entry(dofs_on_children[row],
773 if (!cell->at_boundary(face) &&
774 !cell->neighbor(face)->is_artificial())
776 Assert(cell->face(face)->n_active_fe_indices() == 1,
778 Assert(cell->face(face)->fe_index_is_active(
779 cell->active_fe_index()) ==
true,
788 template <
int dim_,
int spacedim,
typename number>
793 std::integral_constant<int, 3>)
795 const unsigned int dim = 3;
797 std::vector<types::global_dof_index> dofs_on_mother;
798 std::vector<types::global_dof_index> dofs_on_children;
810 endc = dof_handler.
end();
811 for (; cell != endc; ++cell)
815 if (cell->is_artificial())
818 for (
const unsigned int face : cell->face_indices())
819 if (cell->face(face)->has_children())
827 Assert(cell->face(face)->refinement_case() ==
836 Assert(cell->face(face)->fe_index_is_active(
837 cell->active_fe_index()) ==
true,
839 for (
unsigned int c = 0; c < cell->face(face)->n_children();
841 if (!cell->neighbor_child_on_subface(face, c)
844 cell->face(face)->child(c)->n_active_fe_indices(), 1);
849 for (
unsigned int c = 0; c < cell->face(face)->n_children();
851 if (!cell->neighbor_child_on_subface(face, c)
854 Assert(cell->face(face)->child(c)->fe_index_is_active(
855 cell->active_fe_index()) ==
true,
857 for (
unsigned int e = 0; e < 4; ++e)
862 ->n_active_fe_indices() == 1,
867 ->fe_index_is_active(
868 cell->active_fe_index()) ==
true,
872 for (
unsigned int e = 0; e < 4; ++e)
874 Assert(cell->face(face)->line(e)->n_active_fe_indices() ==
877 Assert(cell->face(face)->line(e)->fe_index_is_active(
878 cell->active_fe_index()) ==
true,
884 const unsigned int fe_index = cell->active_fe_index();
887 const unsigned int n_dofs_on_children =
894 dofs_on_mother.resize(n_dofs_on_mother);
897 dofs_on_children.clear();
898 dofs_on_children.reserve(n_dofs_on_children);
908 this_face = cell->face(face);
912 unsigned int next_index = 0;
913 for (
unsigned int vertex = 0; vertex < 4; ++vertex)
916 dofs_on_mother[next_index++] =
917 this_face->vertex_dof_index(vertex, dof, fe_index);
918 for (
unsigned int line = 0; line < 4; ++line)
920 dofs_on_mother[next_index++] =
921 this_face->line(line)->dof_index(dof, fe_index);
924 dofs_on_mother[next_index++] =
925 this_face->dof_index(dof, fe_index);
934 ((this_face->child(0)->vertex_index(3) ==
935 this_face->child(1)->vertex_index(2)) &&
936 (this_face->child(0)->vertex_index(3) ==
937 this_face->child(2)->vertex_index(1)) &&
938 (this_face->child(0)->vertex_index(3) ==
939 this_face->child(3)->vertex_index(0))),
943 dofs_on_children.push_back(
944 this_face->child(0)->vertex_dof_index(3, dof));
947 for (
unsigned int line = 0; line < 4; ++line)
950 dofs_on_children.push_back(
951 this_face->line(line)->child(0)->vertex_dof_index(
958 dofs_on_children.push_back(
959 this_face->child(0)->line(1)->dof_index(dof, fe_index));
961 dofs_on_children.push_back(
962 this_face->child(2)->line(1)->dof_index(dof, fe_index));
964 dofs_on_children.push_back(
965 this_face->child(0)->line(3)->dof_index(dof, fe_index));
967 dofs_on_children.push_back(
968 this_face->child(1)->line(3)->dof_index(dof, fe_index));
971 for (
unsigned int line = 0; line < 4; ++line)
972 for (
unsigned int child = 0; child < 2; ++child)
976 dofs_on_children.push_back(
977 this_face->line(line)->child(child)->dof_index(
982 for (
unsigned int child = 0; child < 4; ++child)
985 if (cell->neighbor_child_on_subface(face, child)
990 dofs_on_children.push_back(
991 this_face->child(child)->dof_index(dof, fe_index));
995 Assert(dofs_on_children.size() <= n_dofs_on_children,
999 for (
unsigned int row = 0; row != dofs_on_children.size();
1002 constraints.
add_line(dofs_on_children[row]);
1003 for (
unsigned int i = 0; i != dofs_on_mother.size(); ++i)
1004 constraints.
add_entry(dofs_on_children[row],
1017 if (!cell->at_boundary(face) &&
1018 !cell->neighbor(face)->is_artificial())
1020 Assert(cell->face(face)->n_active_fe_indices() == 1,
1022 Assert(cell->face(face)->fe_index_is_active(
1023 cell->active_fe_index()) ==
true,
1032 template <
int dim,
int spacedim,
typename number>
1050 std::vector<types::global_dof_index> primary_dofs;
1051 std::vector<types::global_dof_index> dependent_dofs;
1052 std::vector<types::global_dof_index> scratch_dofs;
1058 n_finite_elements(dof_handler), n_finite_elements(dof_handler));
1060 subface_interpolation_matrices(
1061 n_finite_elements(dof_handler),
1062 n_finite_elements(dof_handler),
1072 split_face_interpolation_matrices(n_finite_elements(dof_handler),
1073 n_finite_elements(dof_handler));
1079 n_finite_elements(dof_handler), n_finite_elements(dof_handler));
1090 if (cell->is_artificial())
1093 for (
const unsigned int face : cell->face_indices())
1094 if (cell->face(face)->has_children())
1099 if (cell->get_fe().n_dofs_per_face(face) == 0)
1102 Assert(cell->face(face)->refinement_case() ==
1113 Assert(cell->face(face)->n_active_fe_indices() == 1,
1115 Assert(cell->face(face)->fe_index_is_active(
1116 cell->active_fe_index()) ==
true,
1118 for (
unsigned int c = 0; c < cell->face(face)->n_children();
1120 if (!cell->neighbor_child_on_subface(face, c)
1122 Assert(cell->face(face)->child(c)->n_active_fe_indices() ==
1138 std::set<unsigned int> fe_ind_face_subface;
1139 fe_ind_face_subface.insert(cell->active_fe_index());
1142 for (
unsigned int c = 0;
1143 c < cell->face(face)->n_active_descendants();
1146 const auto subcell =
1147 cell->neighbor_child_on_subface(face, c);
1148 if (!subcell->is_artificial())
1150 mother_face_dominates =
1151 mother_face_dominates &
1152 (cell->get_fe().compare_for_domination(
1153 subcell->get_fe(), 1));
1154 fe_ind_face_subface.insert(
1155 subcell->active_fe_index());
1159 switch (mother_face_dominates)
1171 primary_dofs.resize(
1172 cell->get_fe().n_dofs_per_face(face));
1174 cell->face(face)->get_dof_indices(
1175 primary_dofs, cell->active_fe_index());
1181 for (
unsigned int c = 0;
1182 c < cell->face(face)->n_children();
1185 if (cell->neighbor_child_on_subface(face, c)
1190 active_face_iterator subface =
1191 cell->face(face)->child(c);
1193 Assert(subface->n_active_fe_indices() == 1,
1196 const unsigned int subface_fe_index =
1197 subface->nth_active_fe_index(0);
1208 if (cell->get_fe().compare_for_domination(
1209 subface->
get_fe(subface_fe_index),
1216 dependent_dofs.resize(
1217 subface->
get_fe(subface_fe_index)
1219 subface->get_dof_indices(dependent_dofs,
1225 (void)dependent_dof;
1253 ensure_existence_of_subface_matrix(
1255 subface->
get_fe(subface_fe_index),
1257 subface_interpolation_matrices
1258 [cell->active_fe_index()][subface_fe_index][c]);
1262 filter_constraints(primary_dofs,
1264 *(subface_interpolation_matrices
1265 [cell->active_fe_index()]
1266 [subface_fe_index][c]),
1286 const ::hp::FECollection<dim, spacedim>
1313 const unsigned int dominating_fe_index =
1315 fe_ind_face_subface, 1);
1320 "Could not find a least face dominating FE."));
1323 dof_handler.
get_fe(dominating_fe_index);
1328 cell->get_fe().n_dofs_per_face(face),
1331 ensure_existence_of_face_matrix(
1334 face_interpolation_matrices[dominating_fe_index]
1335 [cell->active_fe_index()]);
1339 ensure_existence_of_primary_dof_mask(
1342 (*face_interpolation_matrices
1343 [dominating_fe_index][cell->active_fe_index()]),
1344 primary_dof_masks[dominating_fe_index]
1345 [cell->active_fe_index()]);
1347 ensure_existence_of_split_face_matrix(
1348 *face_interpolation_matrices[dominating_fe_index]
1349 [cell->active_fe_index()],
1350 (*primary_dof_masks[dominating_fe_index]
1351 [cell->active_fe_index()]),
1352 split_face_interpolation_matrices
1353 [dominating_fe_index][cell->active_fe_index()]);
1356 &restrict_mother_to_virtual_primary_inv =
1357 (split_face_interpolation_matrices
1358 [dominating_fe_index][cell->active_fe_index()]
1362 &restrict_mother_to_virtual_dependent =
1363 (split_face_interpolation_matrices
1364 [dominating_fe_index][cell->active_fe_index()]
1369 constraint_matrix.reinit(
1370 cell->get_fe().n_dofs_per_face(face) -
1373 restrict_mother_to_virtual_dependent.
mmult(
1375 restrict_mother_to_virtual_primary_inv);
1379 scratch_dofs.resize(
1380 cell->get_fe().n_dofs_per_face(face));
1381 cell->face(face)->get_dof_indices(
1382 scratch_dofs, cell->active_fe_index());
1385 primary_dofs.clear();
1386 dependent_dofs.clear();
1387 for (
unsigned int i = 0;
1388 i < cell->get_fe().n_dofs_per_face(face);
1390 if ((*primary_dof_masks[dominating_fe_index]
1392 ->active_fe_index()])[i] ==
1394 primary_dofs.push_back(scratch_dofs[i]);
1396 dependent_dofs.push_back(scratch_dofs[i]);
1401 cell->get_fe().n_dofs_per_face(face) -
1404 filter_constraints(primary_dofs,
1413 for (
unsigned int sf = 0;
1414 sf < cell->face(face)->n_children();
1419 if (cell->neighbor_child_on_subface(face, sf)
1420 ->is_artificial() ||
1421 (dim == 2 && cell->is_ghost() &&
1422 cell->neighbor_child_on_subface(face, sf)
1428 ->n_active_fe_indices() == 1,
1431 const unsigned int subface_fe_index =
1432 cell->face(face)->child(sf)->nth_active_fe_index(
1435 dof_handler.
get_fe(subface_fe_index);
1442 ensure_existence_of_subface_matrix(
1446 subface_interpolation_matrices
1447 [dominating_fe_index][subface_fe_index][sf]);
1450 &restrict_subface_to_virtual = *(
1451 subface_interpolation_matrices
1452 [dominating_fe_index][subface_fe_index][sf]);
1454 constraint_matrix.reinit(
1458 restrict_subface_to_virtual.
mmult(
1460 restrict_mother_to_virtual_primary_inv);
1462 dependent_dofs.resize(
1464 cell->face(face)->child(sf)->get_dof_indices(
1465 dependent_dofs, subface_fe_index);
1467 filter_constraints(primary_dofs,
1490 Assert(cell->face(face)->fe_index_is_active(
1491 cell->active_fe_index()) ==
true,
1498 if (!cell->at_boundary(face) &&
1499 cell->neighbor(face)->is_artificial())
1505 !cell->face(face)->at_boundary() &&
1506 (cell->neighbor(face)->active_fe_index() !=
1507 cell->active_fe_index()) &&
1508 (!cell->face(face)->has_children() &&
1509 !cell->neighbor_is_coarser(face)))
1512 spacedim>::level_cell_iterator
1513 neighbor = cell->neighbor(face);
1517 cell->get_fe().compare_for_domination(neighbor->get_fe(),
1524 primary_dofs.resize(
1525 cell->get_fe().n_dofs_per_face(face));
1526 cell->face(face)->get_dof_indices(
1527 primary_dofs, cell->active_fe_index());
1532 if (primary_dofs.size() == 0)
1535 dependent_dofs.resize(
1536 neighbor->get_fe().n_dofs_per_face(face));
1537 cell->face(face)->get_dof_indices(
1538 dependent_dofs, neighbor->active_fe_index());
1542 ensure_existence_of_face_matrix(
1545 face_interpolation_matrices
1546 [cell->active_fe_index()]
1547 [neighbor->active_fe_index()]);
1553 *(face_interpolation_matrices
1554 [cell->active_fe_index()]
1555 [neighbor->active_fe_index()]),
1598 if (cell < neighbor)
1612 const unsigned int this_fe_index =
1613 cell->active_fe_index();
1614 const unsigned int neighbor_fe_index =
1615 neighbor->active_fe_index();
1616 std::set<unsigned int> fes;
1617 fes.insert(this_fe_index);
1618 fes.insert(neighbor_fe_index);
1619 const ::hp::FECollection<dim, spacedim>
1622 const unsigned int dominating_fe_index =
1627 dominating_fe_index !=
1630 "Could not find the dominating FE for " +
1631 cell->get_fe().get_name() +
" and " +
1632 neighbor->get_fe().get_name() +
1633 " inside FECollection."));
1636 fe_collection[dominating_fe_index];
1644 cell->get_fe().n_dofs_per_face(face),
1647 ensure_existence_of_face_matrix(
1650 face_interpolation_matrices
1651 [dominating_fe_index][cell->active_fe_index()]);
1655 ensure_existence_of_primary_dof_mask(
1658 (*face_interpolation_matrices
1659 [dominating_fe_index]
1660 [cell->active_fe_index()]),
1661 primary_dof_masks[dominating_fe_index]
1662 [cell->active_fe_index()]);
1664 ensure_existence_of_split_face_matrix(
1665 *face_interpolation_matrices
1666 [dominating_fe_index][cell->active_fe_index()],
1667 (*primary_dof_masks[dominating_fe_index]
1668 [cell->active_fe_index()]),
1669 split_face_interpolation_matrices
1670 [dominating_fe_index][cell->active_fe_index()]);
1673 double> &restrict_mother_to_virtual_primary_inv =
1674 (split_face_interpolation_matrices
1675 [dominating_fe_index][cell->active_fe_index()]
1679 double> &restrict_mother_to_virtual_dependent =
1680 (split_face_interpolation_matrices
1681 [dominating_fe_index][cell->active_fe_index()]
1686 constraint_matrix.reinit(
1687 cell->get_fe().n_dofs_per_face(face) -
1690 restrict_mother_to_virtual_dependent.
mmult(
1692 restrict_mother_to_virtual_primary_inv);
1696 scratch_dofs.resize(
1697 cell->get_fe().n_dofs_per_face(face));
1698 cell->face(face)->get_dof_indices(
1699 scratch_dofs, cell->active_fe_index());
1702 primary_dofs.clear();
1703 dependent_dofs.clear();
1704 for (
unsigned int i = 0;
1705 i < cell->get_fe().n_dofs_per_face(face);
1707 if ((*primary_dof_masks[dominating_fe_index]
1708 [cell->active_fe_index()])
1710 primary_dofs.push_back(scratch_dofs[i]);
1712 dependent_dofs.push_back(scratch_dofs[i]);
1718 dependent_dofs.size(),
1719 cell->get_fe().n_dofs_per_face(face) -
1722 filter_constraints(primary_dofs,
1731 neighbor->get_fe().n_dofs_per_face(face),
1734 ensure_existence_of_face_matrix(
1737 face_interpolation_matrices
1738 [dominating_fe_index]
1739 [neighbor->active_fe_index()]);
1742 &restrict_secondface_to_virtual =
1743 *(face_interpolation_matrices
1744 [dominating_fe_index]
1745 [neighbor->active_fe_index()]);
1747 constraint_matrix.reinit(
1748 neighbor->get_fe().n_dofs_per_face(face),
1751 restrict_secondface_to_virtual.
mmult(
1753 restrict_mother_to_virtual_primary_inv);
1755 dependent_dofs.resize(
1756 neighbor->get_fe().n_dofs_per_face(face));
1757 cell->face(face)->get_dof_indices(
1758 dependent_dofs, neighbor->active_fe_index());
1760 filter_constraints(primary_dofs,
1786 template <
int dim,
int spacedim,
typename number>
1793 "The given DoFHandler does not have any DoFs. Did you forget to "
1794 "call dof_handler.distribute_dofs()?"));
1804 dof_handler, constraints, std::integral_constant<int, dim>());
1836 template <
typename FaceIterator,
typename number>
1838 set_periodicity_constraints(
1839 const FaceIterator & face_1,
1844 const bool face_orientation,
1845 const bool face_flip,
1846 const bool face_rotation,
1847 const number periodicity_factor)
1849 static const int dim = FaceIterator::AccessorType::dimension;
1850 static const int spacedim = FaceIterator::AccessorType::space_dimension;
1860 face_1->get_fe(face_1->nth_active_fe_index(0)).n_unique_faces(), 1);
1862 face_2->get_fe(face_2->nth_active_fe_index(0)).n_unique_faces(), 1);
1863 const unsigned int face_no = 0;
1868 if (face_2->has_children())
1870 Assert(face_2->n_children() ==
1874 const unsigned int dofs_per_face =
1875 face_1->get_fe(face_1->nth_active_fe_index(0))
1876 .n_dofs_per_face(face_no);
1881 for (
unsigned int c = 0; c < face_2->n_children(); ++c)
1886 const auto &fe = face_1->get_fe(face_1->nth_active_fe_index(0));
1887 fe.get_subface_interpolation_matrix(fe,
1889 subface_interpolation,
1891 subface_interpolation.mmult(child_transformation, transformation);
1893 set_periodicity_constraints(face_1,
1895 child_transformation,
1901 periodicity_factor);
1911 const unsigned int face_1_index = face_1->nth_active_fe_index(0);
1912 const unsigned int face_2_index = face_2->nth_active_fe_index(0);
1913 Assert(face_1->get_fe(face_1_index) == face_2->get_fe(face_2_index),
1915 "Matching periodic cells need to use the same finite element"));
1921 "The number of components in the mask has to be either "
1922 "zero or equal to the number of components in the finite "
1927 std::vector<types::global_dof_index> dofs_1(dofs_per_face);
1928 std::vector<types::global_dof_index> dofs_2(dofs_per_face);
1930 face_1->get_dof_indices(dofs_1, face_1_index);
1931 face_2->get_dof_indices(dofs_2, face_2_index);
1949 for (
unsigned int i = 0; i < dofs_per_face; ++i)
1971 std::map<unsigned int, unsigned int> cell_to_rotated_face_index;
1974 for (
unsigned int i = 0; i < dofs_per_face; ++i)
1993 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2014 bool is_identity_constrained =
false;
2016 number constraint_factor = periodicity_factor;
2018 constexpr double eps = 1.e-13;
2019 for (
unsigned int jj = 0; jj < dofs_per_face; ++jj)
2021 const auto entry = transformation(i, jj);
2024 if (is_identity_constrained)
2029 is_identity_constrained =
false;
2032 is_identity_constrained =
true;
2034 constraint_factor = entry * periodicity_factor;
2043 if (!is_identity_constrained)
2051 affine_constraints.
add_line(dofs_2[i]);
2053 for (
unsigned int jj = 0; jj < dofs_per_face; ++jj)
2057 const unsigned int j =
2059 jj, 0, face_orientation, face_flip, face_rotation)];
2061 if (
std::abs(transformation(i, jj)) > eps)
2064 transformation(i, jj));
2075 const unsigned int j =
2077 target, 0, face_orientation, face_flip, face_rotation)];
2079 auto dof_left = dofs_1[j];
2080 auto dof_right = dofs_2[i];
2086 (dof_left < dof_right &&
2089 std::swap(dof_left, dof_right);
2090 constraint_factor = 1. / constraint_factor;
2106 bool constraints_are_cyclic =
true;
2107 number cycle_constraint_factor = constraint_factor;
2109 for (
auto test_dof = dof_right; test_dof != dof_left;)
2113 constraints_are_cyclic =
false;
2117 const auto &constraint_entries =
2119 if (constraint_entries.size() == 1)
2121 test_dof = constraint_entries[0].first;
2122 cycle_constraint_factor *= constraint_entries[0].second;
2126 constraints_are_cyclic =
false;
2141 if (constraints_are_cyclic)
2143 if (
std::abs(cycle_constraint_factor - number(1.)) > eps)
2144 affine_constraints.
add_line(dof_left);
2148 affine_constraints.
add_line(dof_left);
2173 ExcMessage(
"The periodicity constraint is too large. "
2174 "The parameter periodicity_factor might "
2175 "be too large or too small."));
2187 template <
int dim,
int spacedim>
2189 compute_transformation(
2192 const std::vector<unsigned int> & first_vector_components)
2197 const unsigned int face_no = 0;
2203 if (
matrix.m() == n_dofs_per_face)
2210 if (first_vector_components.empty() &&
matrix.m() == 0)
2223 quadrature(fe.get_unit_face_support_points(face_no));
2227 using DoFTuple =
std::array<
unsigned int, spacedim>;
2232 for (
unsigned int i = 0; i < n_dofs_per_face; ++i)
2234 std::vector<unsigned int>::const_iterator comp_it =
2235 std::find(first_vector_components.begin(),
2236 first_vector_components.end(),
2238 if (comp_it != first_vector_components.end())
2240 const unsigned int first_vector_component = *comp_it;
2243 DoFTuple vector_dofs;
2245 unsigned int n_found = 1;
2250 "Error: the finite element does not have enough components "
2251 "to define rotated periodic boundaries."));
2253 for (
unsigned int k = 0; k < n_dofs_per_face; ++k)
2254 if ((k != i) && (quadrature.point(k) == quadrature.point(i)) &&
2256 first_vector_component) &&
2258 first_vector_component + spacedim))
2262 first_vector_component] = k;
2270 for (
unsigned int i = 0; i < spacedim; ++i)
2272 transformation[vector_dofs[i]][vector_dofs[i]] = 0.;
2273 for (
unsigned int j = 0; j < spacedim; ++j)
2274 transformation[vector_dofs[i]][vector_dofs[j]] =
2279 return transformation;
2287 template <
typename FaceIterator,
typename number>
2290 const FaceIterator & face_1,
2294 const bool face_orientation,
2295 const bool face_flip,
2296 const bool face_rotation,
2298 const std::vector<unsigned int> & first_vector_components,
2299 const number periodicity_factor)
2304 face_1->get_fe(face_1->nth_active_fe_index(0)).n_unique_faces(), 1);
2306 face_2->get_fe(face_2->nth_active_fe_index(0)).n_unique_faces(), 1);
2307 const unsigned int face_no = 0;
2309 static const int dim = FaceIterator::AccessorType::dimension;
2310 static const int spacedim = FaceIterator::AccessorType::space_dimension;
2312 Assert((dim != 1) || (face_orientation ==
true && face_flip ==
false &&
2313 face_rotation ==
false),
2315 "(face_orientation, face_flip, face_rotation) "
2316 "is invalid for 1D"));
2318 Assert((dim != 2) || (face_orientation ==
true && face_rotation ==
false),
2320 "(face_orientation, face_flip, face_rotation) "
2321 "is invalid for 2D"));
2324 ExcMessage(
"face_1 and face_2 are equal! Cannot constrain DoFs "
2325 "on the very same face"));
2327 Assert(face_1->at_boundary() && face_2->at_boundary(),
2328 ExcMessage(
"Faces for periodicity constraints must be on the "
2331 Assert(matrix.m() == matrix.n(),
2332 ExcMessage(
"The supplied (rotation or interpolation) matrix must "
2333 "be a square matrix"));
2335 Assert(first_vector_components.empty() || matrix.m() == spacedim,
2336 ExcMessage(
"first_vector_components is nonempty, so matrix must "
2337 "be a rotation matrix exactly of size spacedim"));
2340 if (!face_1->has_children())
2343 const unsigned int n_dofs_per_face =
2344 face_1->get_fe(face_1->nth_active_fe_index(0))
2345 .n_dofs_per_face(face_no);
2347 Assert(matrix.m() == 0 ||
2348 (first_vector_components.empty() &&
2349 matrix.m() == n_dofs_per_face) ||
2350 (!first_vector_components.empty() && matrix.m() == spacedim),
2352 "The matrix must have either size 0 or spacedim "
2353 "(if first_vector_components is nonempty) "
2354 "or the size must be equal to the # of DoFs on the face "
2355 "(if first_vector_components is empty)."));
2358 if (!face_2->has_children())
2361 const unsigned int n_dofs_per_face =
2362 face_2->get_fe(face_2->nth_active_fe_index(0))
2363 .n_dofs_per_face(face_no);
2365 Assert(matrix.m() == 0 ||
2366 (first_vector_components.empty() &&
2367 matrix.m() == n_dofs_per_face) ||
2368 (!first_vector_components.empty() && matrix.m() == spacedim),
2370 "The matrix must have either size 0 or spacedim "
2371 "(if first_vector_components is nonempty) "
2372 "or the size must be equal to the # of DoFs on the face "
2373 "(if first_vector_components is empty)."));
2380 static const int lookup_table_2d[2][2] = {
2386 static const int lookup_table_3d[2][2][2][4] = {
2410 if (face_1->has_children() && face_2->has_children())
2415 Assert(face_1->n_children() ==
2417 face_2->n_children() ==
2421 for (
unsigned int i = 0; i < GeometryInfo<dim>::max_children_per_face;
2429 j = lookup_table_2d[face_flip][i];
2432 j = lookup_table_3d[face_orientation][face_flip]
2447 first_vector_components,
2448 periodicity_factor);
2458 face_1->has_children() ?
2459 face_2->get_fe(face_2->nth_active_fe_index(0)) :
2460 face_1->get_fe(face_1->nth_active_fe_index(0));
2466 if (n_dofs_per_face == 0)
2470 compute_transformation(fe, matrix, first_vector_components);
2472 if (!face_2->has_children())
2476 if (first_vector_components.empty() && matrix.m() == 0)
2478 set_periodicity_constraints(face_2,
2486 periodicity_factor);
2491 inverse.
invert(transformation);
2493 set_periodicity_constraints(face_2,
2501 periodicity_factor);
2514 set_periodicity_constraints(face_1,
2521 face_rotation ^ face_flip :
2524 periodicity_factor);
2531 template <
int dim,
int spacedim,
typename number>
2538 const std::vector<unsigned int> &first_vector_components,
2539 const number periodicity_factor)
2542 for (
auto &pair : periodic_faces)
2545 const FaceIterator face_1 = pair.cell[0]->face(pair.face_idx[0]);
2546 const FaceIterator face_2 = pair.cell[1]->face(pair.face_idx[1]);
2548 Assert(face_1->at_boundary() && face_2->at_boundary(),
2559 pair.orientation[0],
2560 pair.orientation[1],
2561 pair.orientation[2],
2563 first_vector_components,
2564 periodicity_factor);
2572 template <
int dim,
int spacedim,
typename number>
2577 const unsigned int direction,
2580 const number periodicity_factor)
2585 ExcMessage(
"The boundary indicators b_id1 and b_id2 must be "
2586 "different to denote different boundaries."));
2594 dof_handler, b_id1, b_id2, direction, matched_faces);
2596 make_periodicity_constraints<dim, spacedim>(matched_faces,
2599 std::vector<unsigned int>(),
2600 periodicity_factor);
2605 template <
int dim,
int spacedim,
typename number>
2609 const unsigned int direction,
2612 const number periodicity_factor)
2628 make_periodicity_constraints<dim, spacedim>(matched_faces,
2631 std::vector<unsigned int>(),
2632 periodicity_factor);
2645 template <
int dim,
int spacedim>
2650#ifdef DEAL_II_WITH_MPI
2651 std::vector<::LinearAlgebra::distributed::Vector<double>>
2666 template <
int dim,
int spacedim>
2668 compute_intergrid_weights_3(
2669 const typename ::DoFHandler<dim, spacedim>::active_cell_iterator
2673 const unsigned int coarse_component,
2676 & coarse_to_fine_grid_map,
2733 for (
unsigned int local_dof = 0; local_dof < copy_data.
dofs_per_cell;
2739 const unsigned int local_parameter_dof =
2748 coarse_to_fine_grid_map[cell]->set_dof_values_by_interpolation(
2749 parameter_dofs[local_parameter_dof],
2761 template <
int dim,
int spacedim>
2763 copy_intergrid_weights_3(
2764 const Assembler::CopyData<dim, spacedim> & copy_data,
2765 const unsigned int coarse_component,
2767 const std::vector<types::global_dof_index> &weight_mapping,
2768 const bool is_called_in_parallel,
2769 std::vector<std::map<types::global_dof_index, float>> &weights)
2771 unsigned int pos = 0;
2772 for (
unsigned int local_dof = 0; local_dof < copy_data.dofs_per_cell;
2799 i < copy_data.global_parameter_representation[pos].size();
2805 if (copy_data.global_parameter_representation[pos](i) != 0)
2808 wi = copy_data.parameter_dof_indices[local_dof],
2809 wj = weight_mapping[i];
2811 copy_data.global_parameter_representation[pos](i);
2814 else if (!is_called_in_parallel)
2819 Assert(copy_data.global_parameter_representation[pos](i) ==
2835 template <
int dim,
int spacedim>
2837 compute_intergrid_weights_2(
2838 const ::DoFHandler<dim, spacedim> &coarse_grid,
2839 const unsigned int coarse_component,
2841 & coarse_to_fine_grid_map,
2843 const std::vector<types::global_dof_index> &weight_mapping,
2844 std::vector<std::map<types::global_dof_index, float>> &weights)
2846 Assembler::Scratch scratch;
2847 Assembler::CopyData<dim, spacedim> copy_data;
2849 unsigned int n_interesting_dofs = 0;
2850 for (
unsigned int local_dof = 0;
2851 local_dof < coarse_grid.get_fe().n_dofs_per_cell();
2853 if (coarse_grid.get_fe().system_to_component_index(local_dof).first ==
2855 ++n_interesting_dofs;
2857 copy_data.global_parameter_representation.resize(n_interesting_dofs);
2859 bool is_called_in_parallel =
false;
2860 for (std::size_t i = 0;
2861 i < copy_data.global_parameter_representation.size();
2864#ifdef DEAL_II_WITH_MPI
2865 MPI_Comm communicator = MPI_COMM_SELF;
2868 const typename ::parallel::TriangulationBase<dim,
2870 &
tria =
dynamic_cast<const typename ::parallel::
2871 TriangulationBase<dim, spacedim> &
>(
2872 coarse_to_fine_grid_map.get_destination_grid()
2873 .get_triangulation());
2875 is_called_in_parallel =
true;
2877 catch (std::bad_cast &)
2885 coarse_to_fine_grid_map.get_destination_grid(),
2886 locally_relevant_dofs);
2888 copy_data.global_parameter_representation[i].reinit(
2889 coarse_to_fine_grid_map.get_destination_grid()
2890 .locally_owned_dofs(),
2891 locally_relevant_dofs,
2895 copy_data.global_parameter_representation[i].reinit(n_fine_dofs);
2902 &coarse_to_fine_grid_map,
2903 ¶meter_dofs](
const typename ::DoFHandler<dim, spacedim>::
2904 active_cell_iterator & cell,
2905 const Assembler::Scratch & scratch_data,
2906 Assembler::CopyData<dim, spacedim> ©_data) {
2907 compute_intergrid_weights_3<dim, spacedim>(cell,
2911 coarse_grid.get_fe(),
2912 coarse_to_fine_grid_map,
2920 is_called_in_parallel,
2921 &weights](
const Assembler::CopyData<dim, spacedim> ©_data) {
2922 copy_intergrid_weights_3<dim, spacedim>(copy_data,
2924 coarse_grid.get_fe(),
2926 is_called_in_parallel,
2937#ifdef DEAL_II_WITH_MPI
2938 for (std::size_t i = 0;
2939 i < copy_data.global_parameter_representation.size();
2941 copy_data.global_parameter_representation[i].update_ghost_values();
2952 template <
int dim,
int spacedim>
2954 compute_intergrid_weights_1(
2955 const ::DoFHandler<dim, spacedim> &coarse_grid,
2956 const unsigned int coarse_component,
2957 const ::DoFHandler<dim, spacedim> &fine_grid,
2958 const unsigned int fine_component,
2960 &coarse_to_fine_grid_map,
2961 std::vector<std::map<types::global_dof_index, float>> &weights,
2962 std::vector<types::global_dof_index> & weight_mapping)
2966 &fine_fe = fine_grid.get_fe();
2970 n_fine_dofs = fine_grid.n_dofs();
2973 const unsigned int fine_dofs_per_cell = fine_fe.n_dofs_per_cell();
2977 const unsigned int coarse_dofs_per_cell_component =
2986 Assert(coarse_grid.get_triangulation().n_cells(0) ==
2987 fine_grid.get_triangulation().n_cells(0),
2991 Assert(&coarse_to_fine_grid_map.get_source_grid() == &coarse_grid,
2993 Assert(&coarse_to_fine_grid_map.get_destination_grid() == &fine_grid,
3005 fine_fe.component_to_base_index(fine_component).first),
3011 for (
const auto &cell : coarse_grid.active_cell_iterators())
3012 Assert(cell->level() <= coarse_to_fine_grid_map[cell]->level(),
3037 std::vector<::Vector<double>> parameter_dofs(
3038 coarse_dofs_per_cell_component,
3043 for (
unsigned int local_coarse_dof = 0;
3044 local_coarse_dof < coarse_dofs_per_cell_component;
3046 for (
unsigned int fine_dof = 0; fine_dof < fine_fe.n_dofs_per_cell();
3048 if (fine_fe.system_to_component_index(fine_dof) ==
3049 std::make_pair(fine_component, local_coarse_dof))
3051 parameter_dofs[local_coarse_dof](fine_dof) = 1.;
3058 unsigned int n_parameters_on_fine_grid = 0;
3062 std::vector<bool> dof_is_interesting(fine_grid.n_dofs(),
false);
3063 std::vector<types::global_dof_index> local_dof_indices(
3064 fine_fe.n_dofs_per_cell());
3066 for (
const auto &cell : fine_grid.active_cell_iterators() |
3069 cell->get_dof_indices(local_dof_indices);
3070 for (
unsigned int i = 0; i < fine_fe.n_dofs_per_cell(); ++i)
3071 if (fine_fe.system_to_component_index(i).first ==
3073 dof_is_interesting[local_dof_indices[i]] =
true;
3076 n_parameters_on_fine_grid = std::count(dof_is_interesting.begin(),
3077 dof_is_interesting.end(),
3084 weights.resize(n_coarse_dofs);
3086 weight_mapping.clear();
3090 std::vector<types::global_dof_index> local_dof_indices(
3091 fine_fe.n_dofs_per_cell());
3092 unsigned int next_free_index = 0;
3093 for (
const auto &cell : fine_grid.active_cell_iterators() |
3096 cell->get_dof_indices(local_dof_indices);
3097 for (
unsigned int i = 0; i < fine_fe.n_dofs_per_cell(); ++i)
3100 if ((fine_fe.system_to_component_index(i).first ==
3102 (weight_mapping[local_dof_indices[i]] ==
3105 weight_mapping[local_dof_indices[i]] = next_free_index;
3110 Assert(next_free_index == n_parameters_on_fine_grid,
3122 compute_intergrid_weights_2(coarse_grid,
3124 coarse_to_fine_grid_map,
3144 for (
unsigned int col = 0; col < n_parameters_on_fine_grid; ++col)
3148 if (weights[row].find(col) != weights[row].
end())
3149 sum += weights[row][col];
3150 Assert((std::fabs(sum - 1) < 1.e-12) ||
3157 return n_parameters_on_fine_grid;
3166 template <
int dim,
int spacedim>
3170 const unsigned int coarse_component,
3172 const unsigned int fine_component,
3178 ExcMessage(
"This function is not yet implemented for DoFHandlers "
3179 "using hp-capabilities."));
3200 std::vector<std::map<types::global_dof_index, float>> weights;
3206 std::vector<types::global_dof_index> weight_mapping;
3208 const unsigned int n_parameters_on_fine_grid =
3209 internal::compute_intergrid_weights_1(coarse_grid,
3213 coarse_to_fine_grid_map,
3216 (void)n_parameters_on_fine_grid;
3220 n_fine_dofs = fine_grid.
n_dofs();
3228 mask[coarse_component] =
true;
3230 coarse_dof_is_parameter =
3231 extract_dofs<dim, spacedim>(coarse_grid,
ComponentMask(mask));
3243 std::vector<types::global_dof_index> representants(
3246 parameter_dof < n_coarse_dofs;
3248 if (coarse_dof_is_parameter.
is_element(parameter_dof))
3255 std::map<types::global_dof_index, float>::const_iterator i =
3256 weights[parameter_dof].begin();
3257 for (; i != weights[parameter_dof].end(); ++i)
3267 for (; global_dof < weight_mapping.size(); ++global_dof)
3268 if (weight_mapping[global_dof] ==
3274 representants[parameter_dof] = global_dof;
3290 std::vector<std::pair<types::global_dof_index, double>> constraint_line;
3309 std::map<types::global_dof_index, float>::const_iterator col_entry =
3311 for (; first_used_row < n_coarse_dofs; ++first_used_row)
3313 col_entry = weights[first_used_row].find(col);
3314 if (col_entry != weights[first_used_row].end())
3318 Assert(col_entry != weights[first_used_row].end(),
3321 if ((col_entry->second == 1) &&
3322 (representants[first_used_row] == global_dof))
3332 constraint_line.clear();
3334 row < n_coarse_dofs;
3337 const std::map<types::global_dof_index, float>::const_iterator j =
3338 weights[row].find(col);
3339 if ((j != weights[row].end()) && (j->second != 0))
3340 constraint_line.emplace_back(representants[row], j->second);
3343 constraints.
add_entries(global_dof, constraint_line);
3349 template <
int dim,
int spacedim>
3353 const unsigned int coarse_component,
3355 const unsigned int fine_component,
3357 std::vector<std::map<types::global_dof_index, float>>
3358 &transfer_representation)
3362 ExcMessage(
"This function is not yet implemented for DoFHandlers "
3363 "using hp-capabilities."));
3384 std::vector<std::map<types::global_dof_index, float>> weights;
3390 std::vector<types::global_dof_index> weight_mapping;
3392 internal::compute_intergrid_weights_1(coarse_grid,
3396 coarse_to_fine_grid_map,
3402 std::count_if(weight_mapping.begin(),
3403 weight_mapping.end(),
3405 return dof != numbers::invalid_dof_index;
3409 std::vector<types::global_dof_index> inverse_weight_mapping(
3418 Assert((inverse_weight_mapping[parameter_dof] ==
3422 inverse_weight_mapping[parameter_dof] = i;
3429 transfer_representation.clear();
3430 transfer_representation.resize(n_rows);
3435 std::map<types::global_dof_index, float>::const_iterator j =
3437 for (; j != weights[i].end(); ++j)
3442 transfer_representation[p][i] = j->second;
3449 template <
int dim,
int spacedim,
typename number>
3458 ExcMessage(
"The number of components in the mask has to be either "
3459 "zero or equal to the number of components in the finite "
3468 std::vector<types::global_dof_index> face_dofs;
3471 std::vector<types::global_dof_index> cell_dofs;
3477 for (; cell != endc; ++cell)
3478 if (!cell->is_artificial() && cell->at_boundary())
3484 cell->get_dof_indices(cell_dofs);
3486 for (
const auto face_no : cell->face_indices())
3489 cell->face(face_no);
3493 if (face->at_boundary() &&
3495 (face->boundary_id() == boundary_id)))
3499 face->get_dof_indices(face_dofs, cell->active_fe_index());
3507 const std::vector<types::global_dof_index>::iterator
3508 it_index_on_cell = std::find(cell_dofs.begin(),
3511 Assert(it_index_on_cell != cell_dofs.end(),
3513 const unsigned int index_on_cell =
3514 std::distance(cell_dofs.begin(), it_index_on_cell);
3518 for (
unsigned int c = 0; c < n_components; ++c)
3519 if (nonzero_component_array[c] && component_mask[c])
3526 zero_boundary_constraints.
add_line(face_dof);
3535 template <
int dim,
int spacedim,
typename number>
3544 zero_boundary_constraints,
3555#include "dof_tools_constraints.inst"
void add_entries(const size_type constrained_dof_index, const std::vector< std::pair< size_type, number > > &col_weight_pairs)
void add_line(const size_type line_n)
void add_entry(const size_type constrained_dof_index, const size_type column, const number weight)
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
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
cell_iterator end() const
const FiniteElement< dim, spacedim > & get_fe(const unsigned int index=0) const
const hp::FECollection< dim, spacedim > & get_fe_collection() const
bool has_active_dofs() const
const Triangulation< dim, spacedim > & get_triangulation() const
active_cell_iterator begin_active(const unsigned int level=0) const
bool has_hp_capabilities() const
types::global_dof_index n_dofs() const
unsigned int n_dofs_per_vertex() const
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 ComponentMask & get_nonzero_components(const unsigned int i) const
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
virtual unsigned int face_to_cell_index(const unsigned int face_dof_index, const unsigned int face, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false) 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 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
virtual MPI_Comm get_communicator() const
bool get_anisotropic_refinement_flag() const
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
#define DEAL_II_NAMESPACE_CLOSE
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_zero_boundary_constraints(const DoFHandler< dim, spacedim > &dof, const types::boundary_id boundary_id, AffineConstraints< number > &zero_boundary_constraints, const ComponentMask &component_mask=ComponentMask())
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)
@ either_element_can_dominate
@ other_element_dominates
@ neither_element_dominates
@ matrix
Contents is actually a matrix.
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
VectorType::value_type * end(VectorType &V)
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)
const types::boundary_id invalid_boundary_id
static const unsigned int invalid_unsigned_int
const types::global_dof_index invalid_dof_index
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
const ::Triangulation< dim, spacedim > & tria