16 #include <deal.II/base/table.h> 17 #include <deal.II/base/template_constraints.h> 18 #include <deal.II/base/thread_management.h> 19 #include <deal.II/base/utilities.h> 20 #include <deal.II/base/work_stream.h> 22 #include <deal.II/dofs/dof_accessor.h> 23 #include <deal.II/dofs/dof_handler.h> 24 #include <deal.II/dofs/dof_tools.h> 26 #include <deal.II/fe/fe.h> 27 #include <deal.II/fe/fe_tools.h> 28 #include <deal.II/fe/fe_values.h> 30 #include <deal.II/grid/grid_tools.h> 31 #include <deal.II/grid/intergrid_map.h> 32 #include <deal.II/grid/tria.h> 33 #include <deal.II/grid/tria_iterator.h> 35 #include <deal.II/hp/fe_collection.h> 36 #include <deal.II/hp/fe_values.h> 38 #include <deal.II/lac/affine_constraints.h> 39 #include <deal.II/lac/vector.h> 41 #ifdef DEAL_II_WITH_MPI 42 # include <deal.II/lac/la_parallel_vector.h> 45 #include <deal.II/base/std_cxx14/memory.h> 52 DEAL_II_NAMESPACE_OPEN
63 check_master_dof_list(
65 const std::vector<types::global_dof_index> &master_dof_list)
67 const unsigned int N = master_dof_list.size();
70 for (
unsigned int i = 0; i < N; ++i)
71 for (
unsigned int j = 0; j < N; ++j)
72 tmp(i, j) = face_interpolation_matrix(master_dof_list[i], j);
83 double diagonal_sum = 0;
84 for (
unsigned int i = 0; i < N; ++i)
85 diagonal_sum += std::fabs(tmp(i, i));
86 const double typical_diagonal_element = diagonal_sum / N;
90 std::vector<unsigned int> p(N);
91 for (
unsigned int i = 0; i < N; ++i)
94 for (
unsigned int j = 0; j < N; ++j)
98 double max = std::fabs(tmp(j, j));
100 for (
unsigned int i = j + 1; i < N; ++i)
102 if (std::fabs(tmp(i, j)) > max)
104 max = std::fabs(tmp(i, j));
111 if (max < 1.e-12 * typical_diagonal_element)
117 for (
unsigned int k = 0; k < N; ++k)
124 const double hr = 1. / tmp(j, j);
126 for (
unsigned int k = 0; k < N; ++k)
130 for (
unsigned int i = 0; i < N; ++i)
134 tmp(i, k) -= tmp(i, j) * tmp(j, k) * hr;
137 for (
unsigned int i = 0; i < N; ++i)
173 template <
int dim,
int spacedim>
175 select_master_dofs_for_face_restriction(
179 std::vector<bool> & master_dof_mask)
209 std::vector<types::global_dof_index> master_dof_list;
210 unsigned int index = 0;
215 unsigned int dofs_added = 0;
224 master_dof_list.push_back(index + i);
227 if (check_master_dof_list(face_interpolation_matrix,
228 master_dof_list) ==
true)
233 master_dof_list.pop_back();
246 unsigned int dofs_added = 0;
252 master_dof_list.push_back(index + i);
253 if (check_master_dof_list(face_interpolation_matrix,
254 master_dof_list) ==
true)
257 master_dof_list.pop_back();
269 unsigned int dofs_added = 0;
275 master_dof_list.push_back(index + i);
276 if (check_master_dof_list(face_interpolation_matrix,
277 master_dof_list) ==
true)
280 master_dof_list.pop_back();
291 std::fill(master_dof_mask.begin(), master_dof_mask.end(),
false);
292 for (std::vector<types::global_dof_index>::const_iterator i =
293 master_dof_list.begin();
294 i != master_dof_list.end();
296 master_dof_mask[*i] =
true;
305 template <
int dim,
int spacedim>
307 ensure_existence_of_master_dof_mask(
311 std::unique_ptr<std::vector<bool>> &master_dof_mask)
313 if (master_dof_mask ==
nullptr)
316 std_cxx14::make_unique<std::vector<bool>>(fe1.
dofs_per_face);
317 select_master_dofs_for_face_restriction(fe1,
319 face_interpolation_matrix,
331 template <
int dim,
int spacedim>
333 ensure_existence_of_face_matrix(
338 if (matrix ==
nullptr)
341 std_cxx14::make_unique<FullMatrix<double>>(fe2.
dofs_per_face,
352 template <
int dim,
int spacedim>
354 ensure_existence_of_subface_matrix(
357 const unsigned int subface,
360 if (matrix ==
nullptr)
363 std_cxx14::make_unique<FullMatrix<double>>(fe2.
dofs_per_face,
377 ensure_existence_of_split_face_matrix(
379 const std::vector<bool> & master_dof_mask,
384 Assert(std::count(master_dof_mask.begin(),
385 master_dof_mask.end(),
387 static_cast<signed int>(face_interpolation_matrix.
n()),
390 if (split_matrix ==
nullptr)
392 split_matrix = std_cxx14::make_unique<
395 const unsigned int n_master_dofs = face_interpolation_matrix.
n();
396 const unsigned int n_dofs = face_interpolation_matrix.
m();
401 split_matrix->first.reinit(n_master_dofs, n_master_dofs);
402 split_matrix->second.reinit(n_dofs - n_master_dofs, n_master_dofs);
404 unsigned int nth_master_dof = 0, nth_slave_dof = 0;
406 for (
unsigned int i = 0; i < n_dofs; ++i)
407 if (master_dof_mask[i] ==
true)
409 for (
unsigned int j = 0; j < n_master_dofs; ++j)
410 split_matrix->first(nth_master_dof, j) =
411 face_interpolation_matrix(i, j);
416 for (
unsigned int j = 0; j < n_master_dofs; ++j)
417 split_matrix->second(nth_slave_dof, j) =
418 face_interpolation_matrix(i, j);
427 split_matrix->first.gauss_jordan();
435 struct DoFHandlerSupportsDifferentFEs
437 static const bool value =
true;
441 template <
int dim,
int spacedim>
442 struct DoFHandlerSupportsDifferentFEs<::
DoFHandler<dim, spacedim>>
444 static const bool value =
false;
453 template <
int dim,
int spacedim>
456 const ::hp::DoFHandler<dim, spacedim> &dof_handler)
458 return dof_handler.get_fe_collection().size();
462 template <
typename DoFHandlerType>
464 n_finite_elements(
const DoFHandlerType &)
481 template <
typename number1,
typename number2>
484 const std::vector<types::global_dof_index> &master_dofs,
485 const std::vector<types::global_dof_index> &slave_dofs,
489 Assert(face_constraints.
n() == master_dofs.size(),
491 Assert(face_constraints.
m() == slave_dofs.size(),
494 const unsigned int n_master_dofs = master_dofs.size();
495 const unsigned int n_slave_dofs = slave_dofs.size();
499 for (
unsigned int row = 0; row != n_slave_dofs; ++row)
502 for (
unsigned int col = 0; col != n_master_dofs; ++col)
507 for (
unsigned int row = 0; row != n_slave_dofs; ++row)
510 bool constraint_already_satisfied =
false;
515 for (
unsigned int i = 0; i < n_master_dofs; ++i)
516 if (face_constraints(row, i) == 1.0)
517 if (master_dofs[i] == slave_dofs[row])
519 constraint_already_satisfied =
true;
523 if (constraint_already_satisfied ==
false)
528 for (
unsigned int i = 0; i < n_master_dofs; ++i)
529 abs_sum += std::abs(face_constraints(row, i));
537 constraints.
add_line(slave_dofs[row]);
538 for (
unsigned int i = 0; i < n_master_dofs; ++i)
539 if ((face_constraints(row, i) != 0) &&
540 (std::fabs(face_constraints(row, i)) >=
544 face_constraints(row, i));
553 template <
typename number>
555 make_hp_hanging_node_constraints(const ::DoFHandler<1> &,
562 template <
typename number>
564 make_oldstyle_hanging_node_constraints(const ::DoFHandler<1> &,
566 std::integral_constant<int, 1>)
572 template <
typename number>
574 make_hp_hanging_node_constraints(
575 const ::hp::DoFHandler<1> & ,
585 template <
typename number>
587 make_oldstyle_hanging_node_constraints(
588 const ::hp::DoFHandler<1> & ,
590 std::integral_constant<int, 1>)
599 template <
typename number>
601 make_hp_hanging_node_constraints(const ::DoFHandler<1, 2> &,
608 template <
typename number>
610 make_oldstyle_hanging_node_constraints(const ::DoFHandler<1, 2> &,
612 std::integral_constant<int, 1>)
618 template <
typename number>
620 make_hp_hanging_node_constraints(const ::DoFHandler<1, 3> &,
627 template <
typename number>
629 make_oldstyle_hanging_node_constraints(const ::DoFHandler<1, 3> &,
631 std::integral_constant<int, 1>)
638 template <
typename DoFHandlerType,
typename number>
640 make_oldstyle_hanging_node_constraints(
641 const DoFHandlerType & dof_handler,
643 std::integral_constant<int, 2>)
645 const unsigned int dim = 2;
647 const unsigned int spacedim = DoFHandlerType::space_dimension;
649 std::vector<types::global_dof_index> dofs_on_mother;
650 std::vector<types::global_dof_index> dofs_on_children;
660 typename DoFHandlerType::active_cell_iterator cell = dof_handler
662 endc = dof_handler.end();
663 for (; cell != endc; ++cell)
667 if (cell->is_artificial())
670 for (
unsigned int face = 0; face < GeometryInfo<dim>::faces_per_cell;
672 if (cell->face(face)->has_children())
678 Assert(cell->face(face)->n_active_fe_indices() == 1,
680 Assert(cell->face(face)->fe_index_is_active(
681 cell->active_fe_index()) ==
true,
683 for (
unsigned int c = 0; c < cell->face(face)->n_children();
685 if (!cell->neighbor_child_on_subface(face, c)
687 Assert(cell->face(face)->child(c)->n_active_fe_indices() ==
693 for (
unsigned int c = 0; c < cell->face(face)->n_children();
695 if (!cell->neighbor_child_on_subface(face, c)
697 Assert(cell->face(face)->child(c)->fe_index_is_active(
698 cell->active_fe_index()) ==
true,
703 const unsigned int fe_index = cell->active_fe_index();
705 const unsigned int n_dofs_on_mother =
710 dofs_on_mother.resize(n_dofs_on_mother);
713 dofs_on_children.clear();
714 dofs_on_children.reserve(n_dofs_on_children);
723 const typename DoFHandlerType::line_iterator this_face =
728 unsigned int next_index = 0;
729 for (
unsigned int vertex = 0; vertex < 2; ++vertex)
731 dofs_on_mother[next_index++] =
732 this_face->vertex_dof_index(vertex, dof, fe_index);
734 dofs_on_mother[next_index++] =
735 this_face->dof_index(dof, fe_index);
739 dofs_on_children.push_back(
740 this_face->child(0)->vertex_dof_index(1, dof, fe_index));
741 for (
unsigned int child = 0; child < 2; ++child)
744 if (cell->neighbor_child_on_subface(face, child)
748 dofs_on_children.push_back(
749 this_face->child(child)->dof_index(dof, fe_index));
752 Assert(dofs_on_children.size() <= n_dofs_on_children,
756 for (
unsigned int row = 0; row != dofs_on_children.size();
759 constraints.
add_line(dofs_on_children[row]);
760 for (
unsigned int i = 0; i != dofs_on_mother.size(); ++i)
761 constraints.
add_entry(dofs_on_children[row],
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 <
typename DoFHandlerType,
typename number>
791 make_oldstyle_hanging_node_constraints(
792 const DoFHandlerType & dof_handler,
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;
809 typename DoFHandlerType::active_cell_iterator cell = dof_handler
811 endc = dof_handler.end();
812 for (; cell != endc; ++cell)
816 if (cell->is_artificial())
819 for (
unsigned int face = 0; face < GeometryInfo<dim>::faces_per_cell;
821 if (cell->face(face)->has_children())
826 if (cell->get_fe().dofs_per_face == 0)
829 Assert(cell->face(face)->refinement_case() ==
838 Assert(cell->face(face)->fe_index_is_active(
839 cell->active_fe_index()) ==
true,
841 for (
unsigned int c = 0; c < cell->face(face)->n_children();
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);
907 const typename DoFHandlerType::face_iterator this_face =
912 unsigned int next_index = 0;
913 for (
unsigned int vertex = 0; vertex < 4; ++vertex)
915 dofs_on_mother[next_index++] =
916 this_face->vertex_dof_index(vertex, dof, fe_index);
917 for (
unsigned int line = 0; line < 4; ++line)
919 dofs_on_mother[next_index++] =
920 this_face->line(line)->dof_index(dof, fe_index);
922 dofs_on_mother[next_index++] =
923 this_face->dof_index(dof, fe_index);
930 Assert(dof_handler.get_triangulation()
931 .get_anisotropic_refinement_flag() ||
932 ((this_face->child(0)->vertex_index(3) ==
933 this_face->child(1)->vertex_index(2)) &&
934 (this_face->child(0)->vertex_index(3) ==
935 this_face->child(2)->vertex_index(1)) &&
936 (this_face->child(0)->vertex_index(3) ==
937 this_face->child(3)->vertex_index(0))),
941 dofs_on_children.push_back(
942 this_face->child(0)->vertex_dof_index(3, dof));
945 for (
unsigned int line = 0; line < 4; ++line)
947 dofs_on_children.push_back(
948 this_face->line(line)->child(0)->vertex_dof_index(
955 dofs_on_children.push_back(
956 this_face->child(0)->line(1)->dof_index(dof, fe_index));
958 dofs_on_children.push_back(
959 this_face->child(2)->line(1)->dof_index(dof, fe_index));
961 dofs_on_children.push_back(
962 this_face->child(0)->line(3)->dof_index(dof, fe_index));
964 dofs_on_children.push_back(
965 this_face->child(1)->line(3)->dof_index(dof, fe_index));
968 for (
unsigned int line = 0; line < 4; ++line)
969 for (
unsigned int child = 0; child < 2; ++child)
972 dofs_on_children.push_back(
973 this_face->line(line)->child(child)->dof_index(
978 for (
unsigned int child = 0; child < 4; ++child)
981 if (cell->neighbor_child_on_subface(face, child)
985 dofs_on_children.push_back(
986 this_face->child(child)->dof_index(dof, fe_index));
990 Assert(dofs_on_children.size() <= n_dofs_on_children,
994 for (
unsigned int row = 0; row != dofs_on_children.size();
997 constraints.
add_line(dofs_on_children[row]);
998 for (
unsigned int i = 0; i != dofs_on_mother.size(); ++i)
999 constraints.
add_entry(dofs_on_children[row],
1012 if (!cell->at_boundary(face) &&
1013 !cell->neighbor(face)->is_artificial())
1015 Assert(cell->face(face)->n_active_fe_indices() == 1,
1017 Assert(cell->face(face)->fe_index_is_active(
1018 cell->active_fe_index()) ==
true,
1027 template <
typename DoFHandlerType,
typename number>
1029 make_hp_hanging_node_constraints(
const DoFHandlerType & dof_handler,
1037 const unsigned int dim = DoFHandlerType::dimension;
1039 const unsigned int spacedim = DoFHandlerType::space_dimension;
1048 std::vector<types::global_dof_index> master_dofs;
1049 std::vector<types::global_dof_index> slave_dofs;
1050 std::vector<types::global_dof_index> scratch_dofs;
1056 n_finite_elements(dof_handler), n_finite_elements(dof_handler));
1058 subface_interpolation_matrices(
1059 n_finite_elements(dof_handler),
1060 n_finite_elements(dof_handler),
1069 split_face_interpolation_matrices(n_finite_elements(dof_handler),
1070 n_finite_elements(dof_handler));
1076 n_finite_elements(dof_handler), n_finite_elements(dof_handler));
1083 for (
const auto &cell : dof_handler.active_cell_iterators())
1087 if (cell->is_artificial())
1090 for (
unsigned int face = 0; face < GeometryInfo<dim>::faces_per_cell;
1092 if (cell->face(face)->has_children())
1097 if (cell->get_fe().dofs_per_face == 0)
1100 Assert(cell->face(face)->refinement_case() ==
1111 Assert(cell->face(face)->n_active_fe_indices() == 1,
1113 Assert(cell->face(face)->fe_index_is_active(
1114 cell->active_fe_index()) ==
true,
1116 for (
unsigned int c = 0; c < cell->face(face)->n_children();
1118 Assert(cell->face(face)->child(c)->n_active_fe_indices() == 1,
1133 std::set<unsigned int> fe_ind_face_subface;
1134 fe_ind_face_subface.insert(cell->active_fe_index());
1136 if (DoFHandlerSupportsDifferentFEs<DoFHandlerType>::value ==
1138 for (
unsigned int c = 0;
1139 c < cell->face(face)->number_of_children();
1142 const auto subcell =
1143 cell->neighbor_child_on_subface(face, c);
1144 if (!subcell->is_artificial())
1146 mother_face_dominates =
1147 mother_face_dominates &
1148 (cell->get_fe().compare_for_domination(
1149 subcell->get_fe(), 1));
1150 fe_ind_face_subface.insert(
1151 subcell->active_fe_index());
1155 switch (mother_face_dominates)
1167 master_dofs.resize(cell->get_fe().dofs_per_face);
1169 cell->face(face)->get_dof_indices(
1170 master_dofs, cell->active_fe_index());
1176 for (
unsigned int c = 0;
1177 c < cell->face(face)->n_children();
1180 if (cell->neighbor_child_on_subface(face, c)
1184 const typename DoFHandlerType::active_face_iterator
1185 subface = cell->face(face)->child(c);
1187 Assert(subface->n_active_fe_indices() == 1,
1190 const unsigned int subface_fe_index =
1191 subface->nth_active_fe_index(0);
1202 if (cell->get_fe().compare_for_domination(
1203 subface->get_fe(subface_fe_index),
1211 subface->get_fe(subface_fe_index).dofs_per_face);
1212 subface->get_dof_indices(slave_dofs,
1245 ensure_existence_of_subface_matrix(
1247 subface->get_fe(subface_fe_index),
1249 subface_interpolation_matrices
1250 [cell->active_fe_index()][subface_fe_index][c]);
1254 filter_constraints(master_dofs,
1256 *(subface_interpolation_matrices
1257 [cell->active_fe_index()]
1258 [subface_fe_index][c]),
1275 Assert(DoFHandlerSupportsDifferentFEs<
1276 DoFHandlerType>::value ==
true,
1279 const ::hp::FECollection<dim, spacedim>
1280 &fe_collection = dof_handler.get_fe_collection();
1306 unsigned int dominating_fe_index =
1307 fe_collection.find_dominating_fe_extended(
1308 fe_ind_face_subface,
1314 "Could not find a least face dominating FE."));
1317 dof_handler.get_fe(dominating_fe_index);
1322 cell->get_fe().dofs_per_face,
1325 ensure_existence_of_face_matrix(
1328 face_interpolation_matrices[dominating_fe_index]
1329 [cell->active_fe_index()]);
1333 ensure_existence_of_master_dof_mask(
1336 (*face_interpolation_matrices
1337 [dominating_fe_index][cell->active_fe_index()]),
1338 master_dof_masks[dominating_fe_index]
1339 [cell->active_fe_index()]);
1341 ensure_existence_of_split_face_matrix(
1342 *face_interpolation_matrices[dominating_fe_index]
1343 [cell->active_fe_index()],
1344 (*master_dof_masks[dominating_fe_index]
1345 [cell->active_fe_index()]),
1346 split_face_interpolation_matrices
1347 [dominating_fe_index][cell->active_fe_index()]);
1350 &restrict_mother_to_virtual_master_inv =
1351 (split_face_interpolation_matrices
1352 [dominating_fe_index][cell->active_fe_index()]
1356 &restrict_mother_to_virtual_slave =
1357 (split_face_interpolation_matrices
1358 [dominating_fe_index][cell->active_fe_index()]
1363 constraint_matrix.
reinit(cell->get_fe().dofs_per_face -
1366 restrict_mother_to_virtual_slave.
mmult(
1368 restrict_mother_to_virtual_master_inv);
1372 scratch_dofs.resize(cell->get_fe().dofs_per_face);
1373 cell->face(face)->get_dof_indices(
1374 scratch_dofs, cell->active_fe_index());
1377 master_dofs.clear();
1379 for (
unsigned int i = 0;
1380 i < cell->get_fe().dofs_per_face;
1382 if ((*master_dof_masks[dominating_fe_index]
1383 [cell->active_fe_index()])[i] ==
1385 master_dofs.push_back(scratch_dofs[i]);
1387 slave_dofs.push_back(scratch_dofs[i]);
1392 cell->get_fe().dofs_per_face -
1395 filter_constraints(master_dofs,
1404 for (
unsigned int sf = 0;
1405 sf < cell->face(face)->n_children();
1410 if (cell->neighbor_child_on_subface(face, sf)
1411 ->is_artificial() ||
1412 (dim == 2 && cell->is_ghost() &&
1413 cell->neighbor_child_on_subface(face, sf)
1419 ->n_active_fe_indices() == 1,
1422 const unsigned int subface_fe_index =
1423 cell->face(face)->child(sf)->nth_active_fe_index(
1426 dof_handler.get_fe(subface_fe_index);
1433 ensure_existence_of_subface_matrix(
1437 subface_interpolation_matrices
1438 [dominating_fe_index][subface_fe_index][sf]);
1441 &restrict_subface_to_virtual = *(
1442 subface_interpolation_matrices
1443 [dominating_fe_index][subface_fe_index][sf]);
1445 constraint_matrix.
reinit(
1449 restrict_subface_to_virtual.
mmult(
1451 restrict_mother_to_virtual_master_inv);
1454 cell->face(face)->child(sf)->get_dof_indices(
1455 slave_dofs, subface_fe_index);
1457 filter_constraints(master_dofs,
1480 Assert(cell->face(face)->fe_index_is_active(
1481 cell->active_fe_index()) ==
true,
1488 if (!cell->at_boundary(face) &&
1489 cell->neighbor(face)->is_artificial())
1494 if ((DoFHandlerSupportsDifferentFEs<DoFHandlerType>::value ==
1496 !cell->face(face)->at_boundary() &&
1497 (cell->neighbor(face)->active_fe_index() !=
1498 cell->active_fe_index()) &&
1499 (!cell->face(face)->has_children() &&
1500 !cell->neighbor_is_coarser(face)))
1502 const typename DoFHandlerType::level_cell_iterator
1503 neighbor = cell->neighbor(face);
1507 cell->get_fe().compare_for_domination(neighbor->get_fe(),
1514 master_dofs.resize(cell->get_fe().dofs_per_face);
1515 cell->face(face)->get_dof_indices(
1516 master_dofs, cell->active_fe_index());
1521 if (master_dofs.size() == 0)
1524 slave_dofs.resize(neighbor->get_fe().dofs_per_face);
1525 cell->face(face)->get_dof_indices(
1526 slave_dofs, neighbor->active_fe_index());
1530 ensure_existence_of_face_matrix(
1533 face_interpolation_matrices
1534 [cell->active_fe_index()]
1535 [neighbor->active_fe_index()]);
1541 *(face_interpolation_matrices
1542 [cell->active_fe_index()]
1543 [neighbor->active_fe_index()]),
1586 if (cell < neighbor)
1599 const unsigned int this_fe_index =
1600 cell->active_fe_index();
1601 const unsigned int neighbor_fe_index =
1602 neighbor->active_fe_index();
1603 std::set<unsigned int> fes;
1604 fes.insert(this_fe_index);
1605 fes.insert(neighbor_fe_index);
1606 const ::hp::FECollection<dim, spacedim>
1607 &fe_collection = dof_handler.get_fe_collection();
1609 unsigned int dominating_fe_index =
1610 fe_collection.find_dominating_fe_extended(
1615 dominating_fe_index !=
1618 "Could not find the dominating FE for " +
1619 cell->get_fe().get_name() +
" and " +
1620 neighbor->get_fe().get_name() +
1621 " inside FECollection."));
1624 fe_collection[dominating_fe_index];
1632 cell->get_fe().dofs_per_face,
1635 ensure_existence_of_face_matrix(
1638 face_interpolation_matrices
1639 [dominating_fe_index][cell->active_fe_index()]);
1643 ensure_existence_of_master_dof_mask(
1646 (*face_interpolation_matrices
1647 [dominating_fe_index]
1648 [cell->active_fe_index()]),
1649 master_dof_masks[dominating_fe_index]
1650 [cell->active_fe_index()]);
1652 ensure_existence_of_split_face_matrix(
1653 *face_interpolation_matrices
1654 [dominating_fe_index][cell->active_fe_index()],
1655 (*master_dof_masks[dominating_fe_index]
1656 [cell->active_fe_index()]),
1657 split_face_interpolation_matrices
1658 [dominating_fe_index][cell->active_fe_index()]);
1661 double> &restrict_mother_to_virtual_master_inv =
1662 (split_face_interpolation_matrices
1663 [dominating_fe_index][cell->active_fe_index()]
1667 double> &restrict_mother_to_virtual_slave =
1668 (split_face_interpolation_matrices
1669 [dominating_fe_index][cell->active_fe_index()]
1674 constraint_matrix.
reinit(
1675 cell->get_fe().dofs_per_face -
1678 restrict_mother_to_virtual_slave.mmult(
1680 restrict_mother_to_virtual_master_inv);
1684 scratch_dofs.resize(cell->get_fe().dofs_per_face);
1685 cell->face(face)->get_dof_indices(
1686 scratch_dofs, cell->active_fe_index());
1689 master_dofs.clear();
1691 for (
unsigned int i = 0;
1692 i < cell->get_fe().dofs_per_face;
1694 if ((*master_dof_masks[dominating_fe_index]
1695 [cell->active_fe_index()])
1697 master_dofs.push_back(scratch_dofs[i]);
1699 slave_dofs.push_back(scratch_dofs[i]);
1704 cell->get_fe().dofs_per_face -
1707 filter_constraints(master_dofs,
1716 neighbor->get_fe().dofs_per_face,
1719 ensure_existence_of_face_matrix(
1722 face_interpolation_matrices
1723 [dominating_fe_index]
1724 [neighbor->active_fe_index()]);
1727 &restrict_secondface_to_virtual =
1728 *(face_interpolation_matrices
1729 [dominating_fe_index]
1730 [neighbor->active_fe_index()]);
1732 constraint_matrix.
reinit(
1733 neighbor->get_fe().dofs_per_face,
1736 restrict_secondface_to_virtual.mmult(
1738 restrict_mother_to_virtual_master_inv);
1740 slave_dofs.resize(neighbor->get_fe().dofs_per_face);
1741 cell->face(face)->get_dof_indices(
1742 slave_dofs, neighbor->active_fe_index());
1744 filter_constraints(master_dofs,
1770 template <
typename DoFHandlerType,
typename number>
1779 if (dof_handler.get_fe_collection().hp_constraints_are_implemented())
1780 internal::make_hp_hanging_node_constraints(dof_handler, constraints);
1782 internal::make_oldstyle_hanging_node_constraints(
1785 std::integral_constant<int, DoFHandlerType::dimension>());
1817 template <
typename FaceIterator>
1819 set_periodicity_constraints(
1820 const FaceIterator & face_1,
1821 const typename identity<FaceIterator>::type &face_2,
1825 const bool face_orientation,
1826 const bool face_flip,
1827 const bool face_rotation)
1829 static const int dim = FaceIterator::AccessorType::dimension;
1830 static const int spacedim = FaceIterator::AccessorType::space_dimension;
1840 if (face_2->has_children())
1842 Assert(face_2->n_children() ==
1846 const unsigned int dofs_per_face =
1847 face_1->get_fe(face_1->nth_active_fe_index(0)).dofs_per_face;
1852 for (
unsigned int c = 0; c < face_2->n_children(); ++c)
1857 const auto &fe = face_1->get_fe(face_1->nth_active_fe_index(0));
1859 subface_interpolation.mmult(child_transformation, transformation);
1861 set_periodicity_constraints(face_1,
1863 child_transformation,
1878 const unsigned int face_1_index = face_1->nth_active_fe_index(0);
1879 const unsigned int face_2_index = face_2->nth_active_fe_index(0);
1880 Assert(face_1->get_fe(face_1_index) == face_2->get_fe(face_2_index),
1882 "Matching periodic cells need to use the same finite element"));
1888 "The number of components in the mask has to be either " 1889 "zero or equal to the number of components in the finite " 1892 const unsigned int dofs_per_face = fe.dofs_per_face;
1894 std::vector<types::global_dof_index> dofs_1(dofs_per_face);
1895 std::vector<types::global_dof_index> dofs_2(dofs_per_face);
1897 face_1->get_dof_indices(dofs_1, face_1_index);
1898 face_2->get_dof_indices(dofs_2, face_2_index);
1916 for (
unsigned int i = 0; i < dofs_per_face; i++)
1938 std::map<unsigned int, unsigned int> cell_to_rotated_face_index;
1941 for (
unsigned int i = 0; i < dofs_per_face; ++i)
1943 const unsigned int cell_index =
1944 fe.face_to_cell_index(i,
1952 cell_to_rotated_face_index[cell_index] = i;
1960 for (
unsigned int i = 0; i < dofs_per_face; ++i)
1964 fe.n_components()) &&
1965 !component_mask[fe.face_system_to_component_index(i).first])
1980 bool is_identity_constrained =
false;
1984 constexpr
double eps = 1.e-13;
1985 for (
unsigned int jj = 0; jj < dofs_per_face; ++jj)
1987 const auto entry = transformation(i, jj);
1988 if (std::abs(entry) > eps)
1990 if (is_identity_constrained)
1995 is_identity_constrained =
false;
1998 is_identity_constrained =
true;
2009 if (!is_identity_constrained)
2017 affine_constraints.
add_line(dofs_2[i]);
2019 for (
unsigned int jj = 0; jj < dofs_per_face; ++jj)
2023 const unsigned int j =
2024 cell_to_rotated_face_index[fe.face_to_cell_index(
2025 jj, 0, face_orientation, face_flip, face_rotation)];
2027 if (std::abs(transformation(i, jj)) > eps)
2030 transformation(i, jj));
2041 const unsigned int j =
2042 cell_to_rotated_face_index[fe.face_to_cell_index(
2043 target, 0, face_orientation, face_flip, face_rotation)];
2045 auto dof_left = dofs_1[j];
2046 auto dof_right = dofs_2[i];
2052 (dof_left < dof_right &&
2056 factor = 1. / factor;
2072 bool constraints_are_cyclic =
true;
2073 double cycle_factor = factor;
2075 for (
auto test_dof = dof_right; test_dof != dof_left;)
2079 constraints_are_cyclic =
false;
2083 const auto &constraint_entries =
2085 if (constraint_entries.size() == 1)
2087 test_dof = constraint_entries[0].first;
2088 cycle_factor *= constraint_entries[0].second;
2092 constraints_are_cyclic =
false;
2106 if (constraints_are_cyclic)
2108 if (std::abs(cycle_factor - 1.) >
eps)
2109 affine_constraints.
add_line(dof_left);
2113 affine_constraints.
add_line(dof_left);
2114 affine_constraints.
add_entry(dof_left, dof_right, factor);
2126 template <
int dim,
int spacedim>
2128 compute_transformation(
2131 const std::vector<unsigned int> & first_vector_components)
2137 if (
matrix.m() == n_dofs_per_face)
2144 if (first_vector_components.empty() &&
matrix.m() == 0)
2161 using DoFTuple = std::array<unsigned int, spacedim>;
2166 for (
unsigned int i = 0; i < n_dofs_per_face; ++i)
2168 std::vector<unsigned int>::const_iterator comp_it =
2169 std::find(first_vector_components.begin(),
2170 first_vector_components.end(),
2172 if (comp_it != first_vector_components.end())
2174 const unsigned int first_vector_component = *comp_it;
2177 DoFTuple vector_dofs;
2179 unsigned int n_found = 1;
2184 "Error: the finite element does not have enough components " 2185 "to define rotated periodic boundaries."));
2187 for (
unsigned int k = 0; k < n_dofs_per_face; ++k)
2188 if ((k != i) && (quadrature.point(k) == quadrature.point(i)) &&
2190 first_vector_component) &&
2192 first_vector_component + spacedim))
2195 first_vector_component] = k;
2203 for (
int i = 0; i < spacedim; ++i)
2205 transformation[vector_dofs[i]][vector_dofs[i]] = 0.;
2206 for (
int j = 0; j < spacedim; ++j)
2207 transformation[vector_dofs[i]][vector_dofs[j]] =
2212 return transformation;
2220 template <
typename FaceIterator>
2223 const FaceIterator & face_1,
2224 const typename identity<FaceIterator>::type &face_2,
2227 const bool face_orientation,
2228 const bool face_flip,
2229 const bool face_rotation,
2231 const std::vector<unsigned int> & first_vector_components)
2233 static const int dim = FaceIterator::AccessorType::dimension;
2234 static const int spacedim = FaceIterator::AccessorType::space_dimension;
2236 Assert((dim != 1) || (face_orientation ==
true && face_flip ==
false &&
2237 face_rotation ==
false),
2239 "(face_orientation, face_flip, face_rotation) " 2240 "is invalid for 1D"));
2242 Assert((dim != 2) || (face_orientation ==
true && face_rotation ==
false),
2244 "(face_orientation, face_flip, face_rotation) " 2245 "is invalid for 2D"));
2248 ExcMessage(
"face_1 and face_2 are equal! Cannot constrain DoFs " 2249 "on the very same face"));
2251 Assert(face_1->at_boundary() && face_2->at_boundary(),
2252 ExcMessage(
"Faces for periodicity constraints must be on the " 2255 Assert(matrix.m() == matrix.n(),
2256 ExcMessage(
"The supplied (rotation or interpolation) matrix must " 2257 "be a square matrix"));
2259 Assert(first_vector_components.empty() || matrix.m() == spacedim,
2260 ExcMessage(
"first_vector_components is nonempty, so matrix must " 2261 "be a rotation matrix exactly of size spacedim"));
2264 if (!face_1->has_children())
2267 const unsigned int n_dofs_per_face =
2268 face_1->get_fe(face_1->nth_active_fe_index(0)).dofs_per_face;
2270 Assert(matrix.m() == 0 ||
2271 (first_vector_components.empty() &&
2272 matrix.m() == n_dofs_per_face) ||
2273 (!first_vector_components.empty() && matrix.m() == spacedim),
2275 "The matrix must have either size 0 or spacedim " 2276 "(if first_vector_components is nonempty) " 2277 "or the size must be equal to the # of DoFs on the face " 2278 "(if first_vector_components is empty)."));
2281 if (!face_2->has_children())
2284 const unsigned int n_dofs_per_face =
2285 face_2->get_fe(face_2->nth_active_fe_index(0)).dofs_per_face;
2287 Assert(matrix.m() == 0 ||
2288 (first_vector_components.empty() &&
2289 matrix.m() == n_dofs_per_face) ||
2290 (!first_vector_components.empty() && matrix.m() == spacedim),
2292 "The matrix must have either size 0 or spacedim " 2293 "(if first_vector_components is nonempty) " 2294 "or the size must be equal to the # of DoFs on the face " 2295 "(if first_vector_components is empty)."));
2302 static const int lookup_table_2d[2][2] = {
2308 static const int lookup_table_3d[2][2][2][4] = {
2332 if (face_1->has_children() && face_2->has_children())
2337 Assert(face_1->n_children() ==
2339 face_2->n_children() ==
2343 for (
unsigned int i = 0; i < GeometryInfo<dim>::max_children_per_face;
2351 j = lookup_table_2d[face_flip][i];
2354 j = lookup_table_3d[face_orientation][face_flip]
2369 first_vector_components);
2379 face_1->has_children() ?
2380 face_2->get_fe(face_2->nth_active_fe_index(0)) :
2381 face_1->get_fe(face_1->nth_active_fe_index(0));
2387 if (n_dofs_per_face == 0)
2391 compute_transformation(fe, matrix, first_vector_components);
2393 if (!face_2->has_children())
2397 if (first_vector_components.empty() && matrix.m() == 0)
2399 set_periodicity_constraints(face_2,
2411 inverse.
invert(transformation);
2413 set_periodicity_constraints(face_2,
2433 set_periodicity_constraints(face_1,
2440 face_rotation ^ face_flip :
2449 template <
typename DoFHandlerType>
2457 const std::vector<unsigned int> &first_vector_components)
2460 for (
auto &pair : periodic_faces)
2462 using FaceIterator =
typename DoFHandlerType::face_iterator;
2463 const FaceIterator face_1 = pair.cell[0]->face(pair.face_idx[0]);
2464 const FaceIterator face_2 = pair.cell[1]->face(pair.face_idx[1]);
2466 Assert(face_1->at_boundary() && face_2->at_boundary(),
2477 pair.orientation[0],
2478 pair.orientation[1],
2479 pair.orientation[2],
2481 first_vector_components);
2489 template <
typename DoFHandlerType>
2494 const int direction,
2498 static const int space_dim = DoFHandlerType::space_dimension;
2500 Assert(0 <= direction && direction < space_dim,
2504 ExcMessage(
"The boundary indicators b_id1 and b_id2 must be" 2505 "different to denote different boundaries."));
2513 dof_handler, b_id1, b_id2, direction, matched_faces);
2515 make_periodicity_constraints<DoFHandlerType>(matched_faces,
2522 template <
typename DoFHandlerType>
2526 const int direction,
2530 static const int dim = DoFHandlerType::dimension;
2531 static const int space_dim = DoFHandlerType::space_dimension;
2535 Assert(0 <= direction && direction < space_dim,
2550 make_periodicity_constraints<DoFHandlerType>(matched_faces,
2565 template <
int dim,
int spacedim>
2568 unsigned int dofs_per_cell;
2569 std::vector<types::global_dof_index> parameter_dof_indices;
2570 #ifdef DEAL_II_WITH_MPI 2571 std::vector<::LinearAlgebra::distributed::Vector<double>>
2572 global_parameter_representation;
2574 std::vector<::Vector<double>> global_parameter_representation;
2586 template <
int dim,
int spacedim>
2588 compute_intergrid_weights_3(
2589 const typename ::DoFHandler<dim, spacedim>::active_cell_iterator
2591 const Assembler::Scratch &,
2592 Assembler::CopyData<dim, spacedim> ©_data,
2593 const unsigned int coarse_component,
2596 & coarse_to_fine_grid_map,
2645 copy_data.parameter_dof_indices.resize(copy_data.dofs_per_cell);
2649 cell->get_dof_indices(copy_data.parameter_dof_indices);
2653 for (
unsigned int local_dof = 0; local_dof < copy_data.dofs_per_cell;
2659 const unsigned int local_parameter_dof =
2662 copy_data.global_parameter_representation[local_parameter_dof] =
2668 coarse_to_fine_grid_map[cell]->set_dof_values_by_interpolation(
2669 parameter_dofs[local_parameter_dof],
2670 copy_data.global_parameter_representation[local_parameter_dof]);
2681 template <
int dim,
int spacedim>
2683 copy_intergrid_weights_3(
2684 const Assembler::CopyData<dim, spacedim> & copy_data,
2685 const unsigned int coarse_component,
2687 const std::vector<types::global_dof_index> &weight_mapping,
2688 const bool is_called_in_parallel,
2689 std::vector<std::map<types::global_dof_index, float>> &weights)
2691 unsigned int pos = 0;
2692 for (
unsigned int local_dof = 0; local_dof < copy_data.dofs_per_cell;
2719 i < copy_data.global_parameter_representation[pos].size();
2725 if (copy_data.global_parameter_representation[pos](i) != 0)
2728 wi = copy_data.parameter_dof_indices[local_dof],
2729 wj = weight_mapping[i];
2731 copy_data.global_parameter_representation[pos](i);
2734 else if (!is_called_in_parallel)
2739 Assert(copy_data.global_parameter_representation[pos](i) ==
2755 template <
int dim,
int spacedim>
2757 compute_intergrid_weights_2(
2758 const ::DoFHandler<dim, spacedim> &coarse_grid,
2759 const unsigned int coarse_component,
2761 & coarse_to_fine_grid_map,
2763 const std::vector<types::global_dof_index> &weight_mapping,
2764 std::vector<std::map<types::global_dof_index, float>> &weights)
2766 Assembler::Scratch scratch;
2767 Assembler::CopyData<dim, spacedim> copy_data;
2769 unsigned int n_interesting_dofs = 0;
2770 for (
unsigned int local_dof = 0;
2771 local_dof < coarse_grid.get_fe().dofs_per_cell;
2773 if (coarse_grid.get_fe().system_to_component_index(local_dof).first ==
2775 ++n_interesting_dofs;
2777 copy_data.global_parameter_representation.resize(n_interesting_dofs);
2779 bool is_called_in_parallel =
false;
2780 for (std::size_t i = 0;
2781 i < copy_data.global_parameter_representation.size();
2784 #ifdef DEAL_II_WITH_MPI 2785 MPI_Comm communicator = MPI_COMM_SELF;
2788 const typename ::parallel::Triangulation<dim, spacedim>
2789 &tria =
dynamic_cast<const typename ::parallel::
2790 Triangulation<dim, spacedim> &
>(
2791 coarse_to_fine_grid_map.get_destination_grid()
2792 .get_triangulation());
2793 communicator = tria.get_communicator();
2794 is_called_in_parallel =
true;
2796 catch (std::bad_cast &)
2804 coarse_to_fine_grid_map.get_destination_grid(),
2805 locally_relevant_dofs);
2807 copy_data.global_parameter_representation[i].reinit(
2808 coarse_to_fine_grid_map.get_destination_grid()
2809 .locally_owned_dofs(),
2810 locally_relevant_dofs,
2814 copy_data.global_parameter_representation[i].reinit(n_fine_dofs);
2820 std::bind(&compute_intergrid_weights_3<dim, spacedim>,
2821 std::placeholders::_1,
2822 std::placeholders::_2,
2823 std::placeholders::_3,
2825 std::cref(coarse_grid.get_fe()),
2826 std::cref(coarse_to_fine_grid_map),
2827 std::cref(parameter_dofs)),
2828 std::bind(©_intergrid_weights_3<dim, spacedim>,
2829 std::placeholders::_1,
2831 std::cref(coarse_grid.get_fe()),
2832 std::cref(weight_mapping),
2833 is_called_in_parallel,
2838 #ifdef DEAL_II_WITH_MPI 2839 for (std::size_t i = 0;
2840 i < copy_data.global_parameter_representation.size();
2842 copy_data.global_parameter_representation[i].update_ghost_values();
2853 template <
int dim,
int spacedim>
2855 compute_intergrid_weights_1(
2856 const ::DoFHandler<dim, spacedim> &coarse_grid,
2857 const unsigned int coarse_component,
2858 const ::DoFHandler<dim, spacedim> &fine_grid,
2859 const unsigned int fine_component,
2861 &coarse_to_fine_grid_map,
2862 std::vector<std::map<types::global_dof_index, float>> &weights,
2863 std::vector<types::global_dof_index> & weight_mapping)
2867 &fine_fe = fine_grid.get_fe();
2871 n_fine_dofs = fine_grid.n_dofs();
2874 const unsigned int fine_dofs_per_cell = fine_fe.
dofs_per_cell;
2878 const unsigned int coarse_dofs_per_cell_component =
2887 Assert(coarse_grid.get_triangulation().n_cells(0) ==
2888 fine_grid.get_triangulation().n_cells(0),
2892 Assert(&coarse_to_fine_grid_map.get_source_grid() == &coarse_grid,
2894 Assert(&coarse_to_fine_grid_map.get_destination_grid() == &fine_grid,
2905 fine_fe.base_element(
2906 fine_fe.component_to_base_index(fine_component).first),
2912 for (typename ::DoFHandler<dim, spacedim>::active_cell_iterator
2913 cell = coarse_grid.begin_active();
2914 cell != coarse_grid.end();
2916 Assert(cell->level() <= coarse_to_fine_grid_map[cell]->level(),
2941 std::vector<::Vector<double>> parameter_dofs(
2942 coarse_dofs_per_cell_component,
2947 for (
unsigned int local_coarse_dof = 0;
2948 local_coarse_dof < coarse_dofs_per_cell_component;
2950 for (
unsigned int fine_dof = 0; fine_dof < fine_fe.dofs_per_cell;
2952 if (fine_fe.system_to_component_index(fine_dof) ==
2953 std::make_pair(fine_component, local_coarse_dof))
2955 parameter_dofs[local_coarse_dof](fine_dof) = 1.;
2962 unsigned int n_parameters_on_fine_grid = 0;
2966 std::vector<bool> dof_is_interesting(fine_grid.n_dofs(),
false);
2967 std::vector<types::global_dof_index> local_dof_indices(
2968 fine_fe.dofs_per_cell);
2970 for (typename ::DoFHandler<dim, spacedim>::active_cell_iterator
2971 cell = fine_grid.begin_active();
2972 cell != fine_grid.end();
2974 if (cell->is_locally_owned())
2976 cell->get_dof_indices(local_dof_indices);
2977 for (
unsigned int i = 0; i < fine_fe.dofs_per_cell; ++i)
2978 if (fine_fe.system_to_component_index(i).first ==
2980 dof_is_interesting[local_dof_indices[i]] =
true;
2983 n_parameters_on_fine_grid = std::count(dof_is_interesting.begin(),
2984 dof_is_interesting.end(),
2991 weights.resize(n_coarse_dofs);
2993 weight_mapping.clear();
2997 std::vector<types::global_dof_index> local_dof_indices(
2998 fine_fe.dofs_per_cell);
2999 unsigned int next_free_index = 0;
3000 for (typename ::DoFHandler<dim, spacedim>::active_cell_iterator
3001 cell = fine_grid.begin_active();
3002 cell != fine_grid.end();
3004 if (cell->is_locally_owned())
3006 cell->get_dof_indices(local_dof_indices);
3007 for (
unsigned int i = 0; i < fine_fe.dofs_per_cell; ++i)
3010 if ((fine_fe.system_to_component_index(i).first ==
3012 (weight_mapping[local_dof_indices[i]] ==
3015 weight_mapping[local_dof_indices[i]] = next_free_index;
3020 Assert(next_free_index == n_parameters_on_fine_grid,
3032 compute_intergrid_weights_2(coarse_grid,
3034 coarse_to_fine_grid_map,
3054 for (
unsigned int col = 0; col < n_parameters_on_fine_grid; ++col)
3058 if (weights[row].find(col) != weights[row].end())
3059 sum += weights[row][col];
3060 Assert((std::fabs(sum - 1) < 1.e-12) ||
3067 return n_parameters_on_fine_grid;
3076 template <
int dim,
int spacedim>
3080 const unsigned int coarse_component,
3082 const unsigned int fine_component,
3106 std::vector<std::map<types::global_dof_index, float>> weights;
3112 std::vector<types::global_dof_index> weight_mapping;
3114 const unsigned int n_parameters_on_fine_grid =
3115 internal::compute_intergrid_weights_1(coarse_grid,
3119 coarse_to_fine_grid_map,
3122 (void)n_parameters_on_fine_grid;
3126 n_fine_dofs = fine_grid.
n_dofs();
3131 std::vector<bool> coarse_dof_is_parameter(coarse_grid.
n_dofs());
3134 std::vector<bool> mask(coarse_grid.
get_fe(0).n_components(),
false);
3135 mask[coarse_component] =
true;
3148 std::vector<types::global_dof_index> representants(
3151 parameter_dof < n_coarse_dofs;
3153 if (coarse_dof_is_parameter[parameter_dof] ==
true)
3160 std::map<types::global_dof_index, float>::const_iterator i =
3161 weights[parameter_dof].begin();
3162 for (; i != weights[parameter_dof].end(); ++i)
3172 for (; global_dof < weight_mapping.size(); ++global_dof)
3173 if (weight_mapping[global_dof] ==
3174 static_cast<types::global_dof_index>(column))
3179 representants[parameter_dof] = global_dof;
3195 std::vector<std::pair<types::global_dof_index, double>> constraint_line;
3214 std::map<types::global_dof_index, float>::const_iterator col_entry =
3216 for (; first_used_row < n_coarse_dofs; ++first_used_row)
3218 col_entry = weights[first_used_row].find(col);
3219 if (col_entry != weights[first_used_row].end())
3223 Assert(col_entry != weights[first_used_row].end(),
3226 if ((col_entry->second == 1) &&
3227 (representants[first_used_row] == global_dof))
3237 constraint_line.clear();
3239 row < n_coarse_dofs;
3242 const std::map<types::global_dof_index, float>::const_iterator j =
3243 weights[row].find(col);
3244 if ((j != weights[row].end()) && (j->second != 0))
3245 constraint_line.emplace_back(representants[row], j->second);
3248 constraints.
add_entries(global_dof, constraint_line);
3254 template <
int dim,
int spacedim>
3258 const unsigned int coarse_component,
3260 const unsigned int fine_component,
3262 std::vector<std::map<types::global_dof_index, float>>
3263 &transfer_representation)
3285 std::vector<std::map<types::global_dof_index, float>> weights;
3291 std::vector<types::global_dof_index> weight_mapping;
3293 internal::compute_intergrid_weights_1(coarse_grid,
3297 coarse_to_fine_grid_map,
3303 std::count_if(weight_mapping.begin(),
3304 weight_mapping.end(),
3305 std::bind(std::not_equal_to<types::global_dof_index>(),
3306 std::placeholders::_1,
3310 std::vector<types::global_dof_index> inverse_weight_mapping(
3319 Assert((inverse_weight_mapping[parameter_dof] ==
3323 inverse_weight_mapping[parameter_dof] = i;
3330 transfer_representation.clear();
3331 transfer_representation.resize(n_rows);
3336 std::map<types::global_dof_index, float>::const_iterator j =
3338 for (; j != weights[i].end(); ++j)
3343 transfer_representation[p][i] = j->second;
3352 template <
int,
int>
class DoFHandlerType,
3356 const DoFHandlerType<dim, spacedim> &dof,
3362 ExcMessage(
"The number of components in the mask has to be either " 3363 "zero or equal to the number of components in the finite " 3372 std::vector<types::global_dof_index> face_dofs;
3375 std::vector<types::global_dof_index> cell_dofs;
3378 typename DoFHandlerType<dim, spacedim>::active_cell_iterator
3379 cell = dof.begin_active(),
3381 for (; cell != endc; ++cell)
3382 if (!cell->is_artificial() && cell->at_boundary())
3388 cell->get_dof_indices(cell_dofs);
3390 for (
unsigned int face_no = 0;
3391 face_no < GeometryInfo<dim>::faces_per_cell;
3394 const typename DoFHandlerType<dim, spacedim>::face_iterator face =
3395 cell->face(face_no);
3399 if (face->at_boundary() &&
3401 (face->boundary_id() == boundary_id)))
3405 face->get_dof_indices(face_dofs, cell->active_fe_index());
3413 const std::vector<types::global_dof_index>::iterator
3414 it_index_on_cell = std::find(cell_dofs.begin(),
3417 Assert(it_index_on_cell != cell_dofs.end(),
3419 const unsigned int index_on_cell =
3420 std::distance(cell_dofs.begin(), it_index_on_cell);
3422 cell->get_fe().get_nonzero_components(index_on_cell);
3425 if (nonzero_component_array[c] && component_mask[c])
3432 zero_boundary_constraints.
add_line(face_dof);
3443 template <
int,
int>
class DoFHandlerType,
3447 const DoFHandlerType<dim, spacedim> &dof,
3453 zero_boundary_constraints,
3464 #include "dof_tools_constraints.inst" 3468 DEAL_II_NAMESPACE_CLOSE
static const unsigned int invalid_unsigned_int
bool is_constrained(const size_type line_n) const
#define AssertDimension(dim1, dim2)
virtual void get_face_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix) const
static ::ExceptionBase & ExcGridsDontMatch()
Contents is actually a matrix.
void add_entries(const size_type line_n, const std::vector< std::pair< size_type, number >> &col_val_pairs)
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
const std::vector< Point< dim - 1 > > & get_unit_face_support_points() const
void add_entry(const size_type line_n, const size_type column, const number value)
#define AssertIndexRange(index, range)
const unsigned int dofs_per_quad
bool represents_n_components(const unsigned int n) const
static ::ExceptionBase & ExcFiniteElementsDontMatch()
#define AssertThrow(cond, exc)
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
const unsigned int dofs_per_line
const FiniteElement< dim, spacedim > & get_fe(const unsigned int index=0) const
void make_hanging_node_constraints(const DoFHandlerType &dof_handler, AffineConstraints< number > &constraints)
static ::ExceptionBase & ExcInvalidIterator()
static ::ExceptionBase & ExcMessage(std::string arg1)
const FullMatrix< double > & constraints(const ::internal::SubfaceCase< dim > &subface_case=::internal::SubfaceCase< dim >::case_isotropic) const
static ::ExceptionBase & ExcGridNotCoarser()
void invert(const FullMatrix< number2 > &M)
std::pair< unsigned int, unsigned int > component_to_base_index(const unsigned int component) const
T sum(const T &t, const MPI_Comm &mpi_communicator)
void reinit(const TableIndices< N > &new_size, const bool omit_default_initialization=false)
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
const types::boundary_id invalid_boundary_id
virtual void get_subface_interpolation_matrix(const FiniteElement< dim, spacedim > &source, const unsigned int subface, FullMatrix< double > &matrix) const
static ::ExceptionBase & ExcNoComponentSelected()
std::pair< unsigned int, unsigned int > face_system_to_component_index(const unsigned int index) const
types::global_dof_index n_dofs() const
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)
virtual const FiniteElement< dim, spacedim > & base_element(const unsigned int index) const
void make_zero_boundary_constraints(const DoFHandlerType< dim, spacedim > &dof, const types::boundary_id boundary_id, AffineConstraints< number > &zero_boundary_constraints, const ComponentMask &component_mask=ComponentMask())
const unsigned int dofs_per_cell
void mmult(FullMatrix< number2 > &C, const FullMatrix< number2 > &B, const bool adding=false) const
void swap(Vector< Number > &u, Vector< Number > &v)
const std::vector< std::pair< size_type, number > > * get_constraint_entries(const size_type line_n) const
unsigned int global_dof_index
std::pair< unsigned int, unsigned int > system_to_component_index(const unsigned int index) const
unsigned int n_components() const
unsigned int n_selected_components(const unsigned int overall_number_of_components=numbers::invalid_unsigned_int) const
const unsigned int dofs_per_face
static ::ExceptionBase & ExcNotImplemented()
const unsigned int dofs_per_vertex
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)
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 add_line(const size_type line_n)
const types::global_dof_index invalid_dof_index
void set_inhomogeneity(const size_type line_n, const number value)
T max(const T &t, const MPI_Comm &mpi_communicator)
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
static ::ExceptionBase & ExcInternalError()