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 =
888 (5 * fe.dofs_per_vertex + 12 * fe.dofs_per_line +
889 4 * fe.dofs_per_quad);
894 dofs_on_mother.resize(n_dofs_on_mother);
897 dofs_on_children.clear();
898 dofs_on_children.reserve(n_dofs_on_children);
900 Assert(n_dofs_on_mother == fe.constraints().n(),
902 fe.constraints().n()));
903 Assert(n_dofs_on_children == fe.constraints().m(),
905 fe.constraints().m()));
907 const typename DoFHandlerType::face_iterator this_face =
912 unsigned int next_index = 0;
913 for (
unsigned int vertex = 0; vertex < 4; ++vertex)
914 for (
unsigned int dof = 0; dof != fe.dofs_per_vertex; ++dof)
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)
918 for (
unsigned int dof = 0; dof != fe.dofs_per_line; ++dof)
919 dofs_on_mother[next_index++] =
920 this_face->line(line)->dof_index(dof, fe_index);
921 for (
unsigned int dof = 0; dof != fe.dofs_per_quad; ++dof)
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))),
940 for (
unsigned int dof = 0; dof != fe.dofs_per_vertex; ++dof)
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)
946 for (
unsigned int dof = 0; dof != fe.dofs_per_vertex; ++dof)
947 dofs_on_children.push_back(
948 this_face->line(line)->child(0)->vertex_dof_index(
954 for (
unsigned int dof = 0; dof < fe.dofs_per_line; ++dof)
955 dofs_on_children.push_back(
956 this_face->child(0)->line(1)->dof_index(dof, fe_index));
957 for (
unsigned int dof = 0; dof < fe.dofs_per_line; ++dof)
958 dofs_on_children.push_back(
959 this_face->child(2)->line(1)->dof_index(dof, fe_index));
960 for (
unsigned int dof = 0; dof < fe.dofs_per_line; ++dof)
961 dofs_on_children.push_back(
962 this_face->child(0)->line(3)->dof_index(dof, fe_index));
963 for (
unsigned int dof = 0; dof < fe.dofs_per_line; ++dof)
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)
971 for (
unsigned int dof = 0; dof != fe.dofs_per_line; ++dof)
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)
984 for (
unsigned int dof = 0; dof != fe.dofs_per_quad; ++dof)
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],
1001 fe.constraints()(row, i));
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_face_domination(
1149 subcell->get_fe()));
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_face_domination(
1203 subface->get_fe(subface_fe_index)) ==
1210 subface->get_fe(subface_fe_index).dofs_per_face);
1211 subface->get_dof_indices(slave_dofs,
1214 for (
unsigned int i = 0; i < slave_dofs.size(); ++i)
1241 ensure_existence_of_subface_matrix(
1243 subface->get_fe(subface_fe_index),
1245 subface_interpolation_matrices
1246 [cell->active_fe_index()][subface_fe_index][c]);
1249 filter_constraints(master_dofs,
1251 *(subface_interpolation_matrices
1252 [cell->active_fe_index()]
1253 [subface_fe_index][c]),
1270 Assert(DoFHandlerSupportsDifferentFEs<
1271 DoFHandlerType>::value ==
true,
1274 const ::hp::FECollection<dim, spacedim>
1275 &fe_collection = dof_handler.get_fe_collection();
1296 const unsigned int dominating_fe_index =
1297 fe_collection.find_least_face_dominating_fe(
1298 fe_ind_face_subface);
1302 "Could not find a least face dominating FE."));
1305 dof_handler.get_fe(dominating_fe_index);
1310 cell->get_fe().dofs_per_face,
1313 ensure_existence_of_face_matrix(
1316 face_interpolation_matrices[dominating_fe_index]
1317 [cell->active_fe_index()]);
1321 ensure_existence_of_master_dof_mask(
1324 (*face_interpolation_matrices
1325 [dominating_fe_index][cell->active_fe_index()]),
1326 master_dof_masks[dominating_fe_index]
1327 [cell->active_fe_index()]);
1329 ensure_existence_of_split_face_matrix(
1330 *face_interpolation_matrices[dominating_fe_index]
1331 [cell->active_fe_index()],
1332 (*master_dof_masks[dominating_fe_index]
1333 [cell->active_fe_index()]),
1334 split_face_interpolation_matrices
1335 [dominating_fe_index][cell->active_fe_index()]);
1338 &restrict_mother_to_virtual_master_inv =
1339 (split_face_interpolation_matrices
1340 [dominating_fe_index][cell->active_fe_index()]
1344 &restrict_mother_to_virtual_slave =
1345 (split_face_interpolation_matrices
1346 [dominating_fe_index][cell->active_fe_index()]
1351 constraint_matrix.
reinit(cell->get_fe().dofs_per_face -
1354 restrict_mother_to_virtual_slave.
mmult(
1356 restrict_mother_to_virtual_master_inv);
1360 scratch_dofs.resize(cell->get_fe().dofs_per_face);
1361 cell->face(face)->get_dof_indices(
1362 scratch_dofs, cell->active_fe_index());
1365 master_dofs.clear();
1367 for (
unsigned int i = 0;
1368 i < cell->get_fe().dofs_per_face;
1370 if ((*master_dof_masks[dominating_fe_index]
1371 [cell->active_fe_index()])[i] ==
1373 master_dofs.push_back(scratch_dofs[i]);
1375 slave_dofs.push_back(scratch_dofs[i]);
1380 cell->get_fe().dofs_per_face -
1383 filter_constraints(master_dofs,
1392 for (
unsigned int sf = 0;
1393 sf < cell->face(face)->n_children();
1398 if (cell->neighbor_child_on_subface(face, sf)
1399 ->is_artificial() ||
1400 (dim == 2 && cell->is_ghost() &&
1401 cell->neighbor_child_on_subface(face, sf)
1407 ->n_active_fe_indices() == 1,
1410 const unsigned int subface_fe_index =
1411 cell->face(face)->child(sf)->nth_active_fe_index(
1414 dof_handler.get_fe(subface_fe_index);
1421 ensure_existence_of_subface_matrix(
1425 subface_interpolation_matrices
1426 [dominating_fe_index][subface_fe_index][sf]);
1429 &restrict_subface_to_virtual = *(
1430 subface_interpolation_matrices
1431 [dominating_fe_index][subface_fe_index][sf]);
1433 constraint_matrix.
reinit(
1437 restrict_subface_to_virtual.
mmult(
1439 restrict_mother_to_virtual_master_inv);
1442 cell->face(face)->child(sf)->get_dof_indices(
1443 slave_dofs, subface_fe_index);
1445 filter_constraints(master_dofs,
1468 Assert(cell->face(face)->fe_index_is_active(
1469 cell->active_fe_index()) ==
true,
1476 if (!cell->at_boundary(face) &&
1477 cell->neighbor(face)->is_artificial())
1482 if ((DoFHandlerSupportsDifferentFEs<DoFHandlerType>::value ==
1484 !cell->face(face)->at_boundary() &&
1485 (cell->neighbor(face)->active_fe_index() !=
1486 cell->active_fe_index()) &&
1487 (!cell->face(face)->has_children() &&
1488 !cell->neighbor_is_coarser(face)))
1490 const typename DoFHandlerType::level_cell_iterator
1491 neighbor = cell->neighbor(face);
1494 switch (cell->get_fe().compare_for_face_domination(
1495 neighbor->get_fe()))
1501 master_dofs.resize(cell->get_fe().dofs_per_face);
1502 cell->face(face)->get_dof_indices(
1503 master_dofs, cell->active_fe_index());
1508 if (master_dofs.size() == 0)
1511 slave_dofs.resize(neighbor->get_fe().dofs_per_face);
1512 cell->face(face)->get_dof_indices(
1513 slave_dofs, neighbor->active_fe_index());
1517 ensure_existence_of_face_matrix(
1520 face_interpolation_matrices
1521 [cell->active_fe_index()]
1522 [neighbor->active_fe_index()]);
1528 *(face_interpolation_matrices
1529 [cell->active_fe_index()]
1530 [neighbor->active_fe_index()]),
1573 if (cell < neighbor)
1586 const unsigned int this_fe_index =
1587 cell->active_fe_index();
1588 const unsigned int neighbor_fe_index =
1589 neighbor->active_fe_index();
1590 std::set<unsigned int> fes;
1591 fes.insert(this_fe_index);
1592 fes.insert(neighbor_fe_index);
1593 const ::hp::FECollection<dim, spacedim>
1594 &fe_collection = dof_handler.get_fe_collection();
1595 const unsigned int dominating_fe_index =
1596 fe_collection.find_least_face_dominating_fe(fes);
1599 dominating_fe_index !=
1602 "Could not find the dominating FE for " +
1603 cell->get_fe().get_name() +
" and " +
1604 neighbor->get_fe().get_name() +
1605 " inside FECollection."));
1608 fe_collection[dominating_fe_index];
1616 cell->get_fe().dofs_per_face,
1619 ensure_existence_of_face_matrix(
1622 face_interpolation_matrices
1623 [dominating_fe_index][cell->active_fe_index()]);
1627 ensure_existence_of_master_dof_mask(
1630 (*face_interpolation_matrices
1631 [dominating_fe_index]
1632 [cell->active_fe_index()]),
1633 master_dof_masks[dominating_fe_index]
1634 [cell->active_fe_index()]);
1636 ensure_existence_of_split_face_matrix(
1637 *face_interpolation_matrices
1638 [dominating_fe_index][cell->active_fe_index()],
1639 (*master_dof_masks[dominating_fe_index]
1640 [cell->active_fe_index()]),
1641 split_face_interpolation_matrices
1642 [dominating_fe_index][cell->active_fe_index()]);
1645 double> &restrict_mother_to_virtual_master_inv =
1646 (split_face_interpolation_matrices
1647 [dominating_fe_index][cell->active_fe_index()]
1651 double> &restrict_mother_to_virtual_slave =
1652 (split_face_interpolation_matrices
1653 [dominating_fe_index][cell->active_fe_index()]
1658 constraint_matrix.
reinit(
1659 cell->get_fe().dofs_per_face -
1662 restrict_mother_to_virtual_slave.mmult(
1664 restrict_mother_to_virtual_master_inv);
1668 scratch_dofs.resize(cell->get_fe().dofs_per_face);
1669 cell->face(face)->get_dof_indices(
1670 scratch_dofs, cell->active_fe_index());
1673 master_dofs.clear();
1675 for (
unsigned int i = 0;
1676 i < cell->get_fe().dofs_per_face;
1678 if ((*master_dof_masks[dominating_fe_index]
1679 [cell->active_fe_index()])
1681 master_dofs.push_back(scratch_dofs[i]);
1683 slave_dofs.push_back(scratch_dofs[i]);
1688 cell->get_fe().dofs_per_face -
1691 filter_constraints(master_dofs,
1700 neighbor->get_fe().dofs_per_face,
1703 ensure_existence_of_face_matrix(
1706 face_interpolation_matrices
1707 [dominating_fe_index]
1708 [neighbor->active_fe_index()]);
1711 &restrict_secondface_to_virtual =
1712 *(face_interpolation_matrices
1713 [dominating_fe_index]
1714 [neighbor->active_fe_index()]);
1716 constraint_matrix.
reinit(
1717 neighbor->get_fe().dofs_per_face,
1720 restrict_secondface_to_virtual.mmult(
1722 restrict_mother_to_virtual_master_inv);
1724 slave_dofs.resize(neighbor->get_fe().dofs_per_face);
1725 cell->face(face)->get_dof_indices(
1726 slave_dofs, neighbor->active_fe_index());
1728 filter_constraints(master_dofs,
1754 template <
typename DoFHandlerType,
typename number>
1763 if (dof_handler.get_fe_collection().hp_constraints_are_implemented())
1764 internal::make_hp_hanging_node_constraints(dof_handler, constraints);
1766 internal::make_oldstyle_hanging_node_constraints(
1769 std::integral_constant<int, DoFHandlerType::dimension>());
1799 template <
typename FaceIterator>
1801 set_periodicity_constraints(
1802 const FaceIterator & face_1,
1803 const typename identity<FaceIterator>::type &face_2,
1807 const bool face_orientation,
1808 const bool face_flip,
1809 const bool face_rotation)
1811 static const int dim = FaceIterator::AccessorType::dimension;
1812 static const int spacedim = FaceIterator::AccessorType::space_dimension;
1820 if (face_2->has_children())
1822 Assert(face_2->n_children() ==
1825 const unsigned int dofs_per_face =
1826 face_1->get_fe(face_1->nth_active_fe_index(0)).dofs_per_face;
1830 for (
unsigned int c = 0; c < face_2->n_children(); ++c)
1835 face_1->get_fe(face_1->nth_active_fe_index(0))
1836 .get_subface_interpolation_matrix(
1837 face_1->get_fe(face_1->nth_active_fe_index(0)),
1839 subface_interpolation);
1840 subface_interpolation.
mmult(child_transformation, transformation);
1841 set_periodicity_constraints(face_1,
1843 child_transformation,
1855 const unsigned int face_1_index = face_1->nth_active_fe_index(0);
1856 const unsigned int face_2_index = face_2->nth_active_fe_index(0);
1858 face_1->get_fe(face_1_index) == face_2->get_fe(face_2_index),
1860 "Matching periodic cells need to use the same finite element"));
1866 "The number of components in the mask has to be either " 1867 "zero or equal to the number of components in the finite " 1870 const unsigned int dofs_per_face = fe.dofs_per_face;
1872 std::vector<types::global_dof_index> dofs_1(dofs_per_face);
1873 std::vector<types::global_dof_index> dofs_2(dofs_per_face);
1875 face_1->get_dof_indices(dofs_1, face_1_index);
1876 face_2->get_dof_indices(dofs_2, face_2_index);
1878 for (
unsigned int i = 0; i < dofs_per_face; i++)
1918 std::map<unsigned int, unsigned int> cell_to_rotated_face_index;
1921 for (
unsigned int i = 0; i < dofs_per_face; ++i)
1923 const unsigned int cell_index =
1924 fe.face_to_cell_index(i,
1932 cell_to_rotated_face_index[cell_index] = i;
1937 for (
unsigned int i = 0; i < dofs_per_face; ++i)
1939 fe.n_components()) ||
1940 component_mask[fe.face_system_to_component_index(i).first])
1952 bool is_identity_constrained =
true;
1953 const double eps = 1.e-13;
1954 for (
unsigned int jj = 0; jj < dofs_per_face; ++jj)
1955 if (std::abs(transformation(i, jj)) > eps &&
1956 std::abs(transformation(i, jj) - 1.) > eps)
1958 is_identity_constrained =
false;
1961 unsigned int identity_constraint_target =
1963 if (is_identity_constrained ==
true)
1965 bool one_identity_found =
false;
1966 for (
unsigned int jj = 0; jj < dofs_per_face; ++jj)
1967 if (std::abs(transformation(i, jj) - 1.) < eps)
1969 if (one_identity_found ==
false)
1971 one_identity_found =
true;
1972 identity_constraint_target = jj;
1976 is_identity_constrained =
false;
1977 identity_constraint_target =
1984 bool is_inverse_constrained = !is_identity_constrained;
1985 unsigned int inverse_constraint_target =
1987 if (is_inverse_constrained)
1988 for (
unsigned int jj = 0; jj < dofs_per_face; ++jj)
1989 if (std::abs(transformation(i, jj)) > eps &&
1990 std::abs(transformation(i, jj) + 1.) > eps)
1992 is_inverse_constrained =
false;
1995 if (is_inverse_constrained)
1997 bool one_identity_found =
false;
1998 for (
unsigned int jj = 0; jj < dofs_per_face; ++jj)
1999 if (std::abs(transformation(i, jj) + 1) < eps)
2001 if (one_identity_found ==
false)
2003 one_identity_found =
true;
2004 inverse_constraint_target = jj;
2008 is_inverse_constrained =
false;
2009 inverse_constraint_target =
2016 const unsigned int target = is_identity_constrained ?
2017 identity_constraint_target :
2018 inverse_constraint_target;
2023 bool constraint_set =
false;
2024 for (
unsigned int j = 0; j < dofs_per_face; ++j)
2026 if (dofs_2[i] == dofs_1[j])
2027 if (!(is_identity_constrained && target == i))
2029 constraint_matrix.
add_line(dofs_2[i]);
2030 constraint_set =
true;
2034 if (!constraint_set)
2038 if (is_identity_constrained || is_inverse_constrained)
2042 const unsigned int j =
2043 cell_to_rotated_face_index[fe.face_to_cell_index(
2059 bool enter_constraint =
false;
2065 while (new_dof != dofs_1[j])
2070 double>> *constraint_entries =
2073 if (constraint_entries->size() == 1)
2075 (*constraint_entries)[0].first;
2078 enter_constraint =
true;
2084 enter_constraint =
true;
2089 if (enter_constraint)
2091 constraint_matrix.
add_line(dofs_1[j]);
2095 is_identity_constrained ? 1.0 : -1.0);
2105 bool enter_constraint =
false;
2108 if (dofs_2[i] != dofs_1[j])
2109 enter_constraint =
true;
2115 std::pair<types::global_dof_index, double>>
2116 *constraint_entries =
2119 if (constraint_entries->size() == 1 &&
2120 (*constraint_entries)[0].first == dofs_2[i])
2122 if ((is_identity_constrained &&
2124 (*constraint_entries)[0].second -
2126 (is_inverse_constrained &&
2128 (*constraint_entries)[0].second +
2134 constraint_matrix.
add_line(dofs_2[i]);
2142 while (new_dof != dofs_2[i])
2146 const std::vector<std::pair<
2148 double>> *constraint_entries =
2151 if (constraint_entries->size() == 1)
2153 (*constraint_entries)[0].first;
2156 enter_constraint =
true;
2162 enter_constraint =
true;
2168 if (enter_constraint)
2170 constraint_matrix.
add_line(dofs_2[i]);
2174 is_identity_constrained ? 1.0 : -1.0);
2182 constraint_matrix.
add_line(dofs_2[i]);
2183 for (
unsigned int jj = 0; jj < dofs_per_face; ++jj)
2187 const unsigned int j =
2188 cell_to_rotated_face_index[fe.face_to_cell_index(
2197 if (transformation(i, jj) != 0)
2199 dofs_2[i], dofs_1[j], transformation(i, jj));
2213 template <
int dim,
int spacedim>
2215 compute_transformation(
2218 const std::vector<unsigned int> & first_vector_components)
2224 if (matrix.
m() == n_dofs_per_face)
2231 if (first_vector_components.empty() && matrix.
m() == 0)
2248 using DoFTuple = std::array<unsigned int, spacedim>;
2253 for (
unsigned int i = 0; i < n_dofs_per_face; ++i)
2255 std::vector<unsigned int>::const_iterator comp_it =
2256 std::find(first_vector_components.begin(),
2257 first_vector_components.end(),
2259 if (comp_it != first_vector_components.end())
2261 const unsigned int first_vector_component = *comp_it;
2264 DoFTuple vector_dofs;
2266 unsigned int n_found = 1;
2271 "Error: the finite element does not have enough components " 2272 "to define rotated periodic boundaries."));
2274 for (
unsigned int k = 0; k < n_dofs_per_face; ++k)
2275 if ((k != i) && (quadrature.point(k) == quadrature.point(i)) &&
2277 first_vector_component) &&
2279 first_vector_component + spacedim))
2282 first_vector_component] = k;
2290 for (
int i = 0; i < spacedim; ++i)
2292 transformation[vector_dofs[i]][vector_dofs[i]] = 0.;
2293 for (
int j = 0; j < spacedim; ++j)
2294 transformation[vector_dofs[i]][vector_dofs[j]] =
2299 return transformation;
2308 template <
typename FaceIterator>
2311 const FaceIterator & face_1,
2312 const typename identity<FaceIterator>::type &face_2,
2315 const bool face_orientation,
2316 const bool face_flip,
2317 const bool face_rotation,
2319 const std::vector<unsigned int> & first_vector_components)
2321 static const int dim = FaceIterator::AccessorType::dimension;
2322 static const int spacedim = FaceIterator::AccessorType::space_dimension;
2324 Assert((dim != 1) || (face_orientation ==
true && face_flip ==
false &&
2325 face_rotation ==
false),
2327 "(face_orientation, face_flip, face_rotation) " 2328 "is invalid for 1D"));
2330 Assert((dim != 2) || (face_orientation ==
true && face_rotation ==
false),
2332 "(face_orientation, face_flip, face_rotation) " 2333 "is invalid for 2D"));
2336 ExcMessage(
"face_1 and face_2 are equal! Cannot constrain DoFs " 2337 "on the very same face"));
2339 Assert(face_1->at_boundary() && face_2->at_boundary(),
2340 ExcMessage(
"Faces for periodicity constraints must be on the " 2344 ExcMessage(
"The supplied (rotation or interpolation) matrix must " 2345 "be a square matrix"));
2347 Assert(first_vector_components.empty() || matrix.
m() == (int)spacedim,
2348 ExcMessage(
"first_vector_components is nonempty, so matrix must " 2349 "be a rotation matrix exactly of size spacedim"));
2352 if (!face_1->has_children())
2355 const unsigned int n_dofs_per_face =
2356 face_1->get_fe(face_1->nth_active_fe_index(0)).dofs_per_face;
2360 (first_vector_components.empty() &&
2361 matrix.
m() == n_dofs_per_face) ||
2362 (!first_vector_components.empty() && matrix.
m() == (int)spacedim),
2363 ExcMessage(
"The matrix must have either size 0 or spacedim " 2364 "(if first_vector_components is nonempty) " 2365 "or the size must be equal to the # of DoFs on the face " 2366 "(if first_vector_components is empty)."));
2369 if (!face_2->has_children())
2372 const unsigned int n_dofs_per_face =
2373 face_2->get_fe(face_2->nth_active_fe_index(0)).dofs_per_face;
2377 (first_vector_components.empty() &&
2378 matrix.
m() == n_dofs_per_face) ||
2379 (!first_vector_components.empty() && matrix.
m() == (int)spacedim),
2380 ExcMessage(
"The matrix must have either size 0 or spacedim " 2381 "(if first_vector_components is nonempty) " 2382 "or the size must be equal to the # of DoFs on the face " 2383 "(if first_vector_components is empty)."));
2390 static const int lookup_table_2d[2][2] = {
2396 static const int lookup_table_3d[2][2][2][4] = {
2420 if (face_1->has_children() && face_2->has_children())
2425 Assert(face_1->n_children() ==
2427 face_2->n_children() ==
2431 for (
unsigned int i = 0; i < GeometryInfo<dim>::max_children_per_face;
2439 j = lookup_table_2d[face_flip][i];
2442 j = lookup_table_3d[face_orientation][face_flip]
2457 first_vector_components);
2467 face_1->has_children() ?
2468 face_2->get_fe(face_2->nth_active_fe_index(0)) :
2469 face_1->get_fe(face_1->nth_active_fe_index(0));
2475 if (n_dofs_per_face == 0)
2479 compute_transformation(fe, matrix, first_vector_components);
2481 if (!face_2->has_children())
2485 if (first_vector_components.empty() && matrix.
m() == 0)
2487 set_periodicity_constraints(face_2,
2499 inverse.
invert(transformation);
2501 set_periodicity_constraints(face_2,
2521 set_periodicity_constraints(face_1,
2528 face_rotation ^ face_flip :
2537 template <
typename DoFHandlerType>
2545 const std::vector<unsigned int> &first_vector_components)
2547 using FaceVector = std::vector<
2549 typename FaceVector::const_iterator it, end_periodic;
2550 it = periodic_faces.begin();
2551 end_periodic = periodic_faces.end();
2554 for (; it != end_periodic; ++it)
2556 using FaceIterator =
typename DoFHandlerType::face_iterator;
2557 const FaceIterator face_1 = it->
cell[0]->face(it->face_idx[0]);
2558 const FaceIterator face_2 = it->cell[1]->face(it->face_idx[1]);
2560 Assert(face_1->at_boundary() && face_2->at_boundary(),
2575 first_vector_components);
2583 template <
typename DoFHandlerType>
2588 const int direction,
2592 static const int space_dim = DoFHandlerType::space_dimension;
2594 Assert(0 <= direction && direction < space_dim,
2598 ExcMessage(
"The boundary indicators b_id1 and b_id2 must be" 2599 "different to denote different boundaries."));
2607 dof_handler, b_id1, b_id2, direction, matched_faces);
2609 make_periodicity_constraints<DoFHandlerType>(matched_faces,
2616 template <
typename DoFHandlerType>
2620 const int direction,
2624 static const int dim = DoFHandlerType::dimension;
2625 static const int space_dim = DoFHandlerType::space_dimension;
2629 Assert(0 <= direction && direction < space_dim,
2644 make_periodicity_constraints<DoFHandlerType>(matched_faces,
2659 template <
int dim,
int spacedim>
2662 unsigned int dofs_per_cell;
2663 std::vector<types::global_dof_index> parameter_dof_indices;
2664 #ifdef DEAL_II_WITH_MPI 2665 std::vector<::LinearAlgebra::distributed::Vector<double>>
2666 global_parameter_representation;
2668 std::vector<::Vector<double>> global_parameter_representation;
2680 template <
int dim,
int spacedim>
2682 compute_intergrid_weights_3(
2683 const typename ::DoFHandler<dim, spacedim>::active_cell_iterator
2685 const Assembler::Scratch &,
2686 Assembler::CopyData<dim, spacedim> ©_data,
2687 const unsigned int coarse_component,
2690 & coarse_to_fine_grid_map,
2739 copy_data.parameter_dof_indices.resize(copy_data.dofs_per_cell);
2743 cell->get_dof_indices(copy_data.parameter_dof_indices);
2747 for (
unsigned int local_dof = 0; local_dof < copy_data.dofs_per_cell;
2753 const unsigned int local_parameter_dof =
2756 copy_data.global_parameter_representation[local_parameter_dof] =
2762 coarse_to_fine_grid_map[cell]->set_dof_values_by_interpolation(
2763 parameter_dofs[local_parameter_dof],
2764 copy_data.global_parameter_representation[local_parameter_dof]);
2775 template <
int dim,
int spacedim>
2777 copy_intergrid_weights_3(
2778 const Assembler::CopyData<dim, spacedim> & copy_data,
2779 const unsigned int coarse_component,
2781 const std::vector<types::global_dof_index> &weight_mapping,
2782 const bool is_called_in_parallel,
2783 std::vector<std::map<types::global_dof_index, float>> &weights)
2785 unsigned int pos = 0;
2786 for (
unsigned int local_dof = 0; local_dof < copy_data.dofs_per_cell;
2813 i < copy_data.global_parameter_representation[pos].size();
2819 if (copy_data.global_parameter_representation[pos](i) != 0)
2822 wi = copy_data.parameter_dof_indices[local_dof],
2823 wj = weight_mapping[i];
2825 copy_data.global_parameter_representation[pos](i);
2828 else if (!is_called_in_parallel)
2833 Assert(copy_data.global_parameter_representation[pos](i) ==
2849 template <
int dim,
int spacedim>
2851 compute_intergrid_weights_2(
2852 const ::DoFHandler<dim, spacedim> &coarse_grid,
2853 const unsigned int coarse_component,
2855 & coarse_to_fine_grid_map,
2857 const std::vector<types::global_dof_index> &weight_mapping,
2858 std::vector<std::map<types::global_dof_index, float>> &weights)
2860 Assembler::Scratch scratch;
2861 Assembler::CopyData<dim, spacedim> copy_data;
2863 unsigned int n_interesting_dofs = 0;
2864 for (
unsigned int local_dof = 0;
2865 local_dof < coarse_grid.get_fe().dofs_per_cell;
2867 if (coarse_grid.get_fe().system_to_component_index(local_dof).first ==
2869 ++n_interesting_dofs;
2871 copy_data.global_parameter_representation.resize(n_interesting_dofs);
2873 bool is_called_in_parallel =
false;
2874 for (
size_t i = 0; i < copy_data.global_parameter_representation.size();
2877 #ifdef DEAL_II_WITH_MPI 2878 MPI_Comm communicator = MPI_COMM_SELF;
2881 const typename ::parallel::Triangulation<dim, spacedim>
2882 &tria =
dynamic_cast<const typename ::parallel::
2883 Triangulation<dim, spacedim> &
>(
2884 coarse_to_fine_grid_map.get_destination_grid()
2885 .get_triangulation());
2886 communicator = tria.get_communicator();
2887 is_called_in_parallel =
true;
2889 catch (std::bad_cast &)
2897 coarse_to_fine_grid_map.get_destination_grid(),
2898 locally_relevant_dofs);
2900 copy_data.global_parameter_representation[i].reinit(
2901 coarse_to_fine_grid_map.get_destination_grid()
2902 .locally_owned_dofs(),
2903 locally_relevant_dofs,
2907 copy_data.global_parameter_representation[i].reinit(n_fine_dofs);
2913 std::bind(&compute_intergrid_weights_3<dim, spacedim>,
2914 std::placeholders::_1,
2915 std::placeholders::_2,
2916 std::placeholders::_3,
2918 std::cref(coarse_grid.get_fe()),
2919 std::cref(coarse_to_fine_grid_map),
2920 std::cref(parameter_dofs)),
2921 std::bind(©_intergrid_weights_3<dim, spacedim>,
2922 std::placeholders::_1,
2924 std::cref(coarse_grid.get_fe()),
2925 std::cref(weight_mapping),
2926 is_called_in_parallel,
2931 #ifdef DEAL_II_WITH_MPI 2932 for (
size_t i = 0; i < copy_data.global_parameter_representation.size();
2934 copy_data.global_parameter_representation[i].update_ghost_values();
2945 template <
int dim,
int spacedim>
2947 compute_intergrid_weights_1(
2948 const ::DoFHandler<dim, spacedim> &coarse_grid,
2949 const unsigned int coarse_component,
2950 const ::DoFHandler<dim, spacedim> &fine_grid,
2951 const unsigned int fine_component,
2953 &coarse_to_fine_grid_map,
2954 std::vector<std::map<types::global_dof_index, float>> &weights,
2955 std::vector<types::global_dof_index> & weight_mapping)
2959 &fine_fe = fine_grid.get_fe();
2963 n_fine_dofs = fine_grid.n_dofs();
2966 const unsigned int fine_dofs_per_cell = fine_fe.
dofs_per_cell;
2970 const unsigned int coarse_dofs_per_cell_component =
2979 Assert(coarse_grid.get_triangulation().n_cells(0) ==
2980 fine_grid.get_triangulation().n_cells(0),
2984 Assert(&coarse_to_fine_grid_map.get_source_grid() == &coarse_grid,
2986 Assert(&coarse_to_fine_grid_map.get_destination_grid() == &fine_grid,
2997 fine_fe.base_element(
2998 fine_fe.component_to_base_index(fine_component).first),
3004 for (typename ::DoFHandler<dim, spacedim>::active_cell_iterator
3005 cell = coarse_grid.begin_active();
3006 cell != coarse_grid.end();
3008 Assert(cell->level() <= coarse_to_fine_grid_map[cell]->level(),
3033 std::vector<::Vector<double>> parameter_dofs(
3034 coarse_dofs_per_cell_component,
3039 for (
unsigned int local_coarse_dof = 0;
3040 local_coarse_dof < coarse_dofs_per_cell_component;
3042 for (
unsigned int fine_dof = 0; fine_dof < fine_fe.dofs_per_cell;
3044 if (fine_fe.system_to_component_index(fine_dof) ==
3045 std::make_pair(fine_component, local_coarse_dof))
3047 parameter_dofs[local_coarse_dof](fine_dof) = 1.;
3054 unsigned int n_parameters_on_fine_grid = 0;
3059 std::vector<bool> dof_is_interesting(fine_grid.n_dofs(),
false);
3060 std::vector<types::global_dof_index> local_dof_indices(
3061 fine_fe.dofs_per_cell);
3063 for (typename ::DoFHandler<dim,
3064 spacedim>::active_cell_iterator
3065 cell = fine_grid.begin_active();
3066 cell != fine_grid.end();
3068 if (cell->is_locally_owned())
3070 cell->get_dof_indices(local_dof_indices);
3071 for (
unsigned int i = 0; i < fine_fe.dofs_per_cell; ++i)
3072 if (fine_fe.system_to_component_index(i).first ==
3074 dof_is_interesting[local_dof_indices[i]] =
true;
3077 n_parameters_on_fine_grid = std::count(dof_is_interesting.begin(),
3078 dof_is_interesting.end(),
3085 weights.resize(n_coarse_dofs);
3087 weight_mapping.clear();
3092 std::vector<types::global_dof_index> local_dof_indices(
3093 fine_fe.dofs_per_cell);
3094 unsigned int next_free_index = 0;
3095 for (typename ::DoFHandler<dim,
3096 spacedim>::active_cell_iterator
3097 cell = fine_grid.begin_active();
3098 cell != fine_grid.end();
3100 if (cell->is_locally_owned())
3102 cell->get_dof_indices(local_dof_indices);
3103 for (
unsigned int i = 0; i < fine_fe.dofs_per_cell; ++i)
3106 if ((fine_fe.system_to_component_index(i).first ==
3108 (weight_mapping[local_dof_indices[i]] ==
3111 weight_mapping[local_dof_indices[i]] = next_free_index;
3116 Assert(next_free_index == n_parameters_on_fine_grid,
3128 compute_intergrid_weights_2(coarse_grid,
3130 coarse_to_fine_grid_map,
3150 for (
unsigned int col = 0; col < n_parameters_on_fine_grid; ++col)
3154 if (weights[row].find(col) != weights[row].end())
3155 sum += weights[row][col];
3156 Assert((std::fabs(sum - 1) < 1.e-12) ||
3163 return n_parameters_on_fine_grid;
3172 template <
int dim,
int spacedim>
3176 const unsigned int coarse_component,
3178 const unsigned int fine_component,
3202 std::vector<std::map<types::global_dof_index, float>> weights;
3208 std::vector<types::global_dof_index> weight_mapping;
3210 const unsigned int n_parameters_on_fine_grid =
3211 internal::compute_intergrid_weights_1(coarse_grid,
3215 coarse_to_fine_grid_map,
3218 (void)n_parameters_on_fine_grid;
3222 n_fine_dofs = fine_grid.
n_dofs();
3227 std::vector<bool> coarse_dof_is_parameter(coarse_grid.
n_dofs());
3230 std::vector<bool> mask(coarse_grid.
get_fe(0).n_components(),
false);
3231 mask[coarse_component] =
true;
3244 std::vector<types::global_dof_index> representants(
3247 parameter_dof < n_coarse_dofs;
3249 if (coarse_dof_is_parameter[parameter_dof] ==
true)
3256 std::map<types::global_dof_index, float>::const_iterator i =
3257 weights[parameter_dof].begin();
3258 for (; i != weights[parameter_dof].end(); ++i)
3268 for (; global_dof < weight_mapping.size(); ++global_dof)
3269 if (weight_mapping[global_dof] ==
3270 static_cast<types::global_dof_index>(column))
3275 representants[parameter_dof] = global_dof;
3291 std::vector<std::pair<types::global_dof_index, double>> constraint_line;
3310 std::map<types::global_dof_index, float>::const_iterator col_entry =
3312 for (; first_used_row < n_coarse_dofs; ++first_used_row)
3314 col_entry = weights[first_used_row].find(col);
3315 if (col_entry != weights[first_used_row].end())
3319 Assert(col_entry != weights[first_used_row].end(),
3322 if ((col_entry->second == 1) &&
3323 (representants[first_used_row] == global_dof))
3333 constraint_line.clear();
3335 row < n_coarse_dofs;
3338 const std::map<types::global_dof_index, float>::const_iterator j =
3339 weights[row].find(col);
3340 if ((j != weights[row].end()) && (j->second != 0))
3341 constraint_line.emplace_back(representants[row], j->second);
3344 constraints.
add_entries(global_dof, constraint_line);
3350 template <
int dim,
int spacedim>
3354 const unsigned int coarse_component,
3356 const unsigned int fine_component,
3358 std::vector<std::map<types::global_dof_index, float>>
3359 &transfer_representation)
3381 std::vector<std::map<types::global_dof_index, float>> weights;
3387 std::vector<types::global_dof_index> weight_mapping;
3389 internal::compute_intergrid_weights_1(coarse_grid,
3393 coarse_to_fine_grid_map,
3399 std::count_if(weight_mapping.begin(),
3400 weight_mapping.end(),
3401 std::bind(std::not_equal_to<types::global_dof_index>(),
3402 std::placeholders::_1,
3406 std::vector<types::global_dof_index> inverse_weight_mapping(
3415 Assert((inverse_weight_mapping[parameter_dof] ==
3419 inverse_weight_mapping[parameter_dof] = i;
3426 transfer_representation.clear();
3427 transfer_representation.resize(n_rows);
3432 std::map<types::global_dof_index, float>::const_iterator j =
3434 for (; j != weights[i].end(); ++j)
3439 transfer_representation[p][i] = j->second;
3448 template <
int,
int>
class DoFHandlerType,
3452 const DoFHandlerType<dim, spacedim> &dof,
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;
3474 typename DoFHandlerType<dim, spacedim>::active_cell_iterator
3475 cell = dof.begin_active(),
3477 for (; cell != endc; ++cell)
3478 if (!cell->is_artificial() && cell->at_boundary())
3484 cell->get_dof_indices(cell_dofs);
3486 for (
unsigned int face_no = 0;
3487 face_no < GeometryInfo<dim>::faces_per_cell;
3490 const typename DoFHandlerType<dim, spacedim>::face_iterator face =
3491 cell->face(face_no);
3495 if (face->at_boundary() &&
3497 (face->boundary_id() == boundary_id)))
3501 face->get_dof_indices(face_dofs, cell->active_fe_index());
3505 for (
unsigned int i = 0; i < face_dofs.size(); ++i)
3509 const std::vector<types::global_dof_index>::iterator
3510 it_index_on_cell = std::find(cell_dofs.begin(),
3513 Assert(it_index_on_cell != cell_dofs.end(),
3515 const unsigned int index_on_cell =
3516 std::distance(cell_dofs.begin(), it_index_on_cell);
3518 cell->get_fe().get_nonzero_components(index_on_cell);
3521 if (nonzero_component_array[c] && component_mask[c])
3528 zero_boundary_constraints.
add_line(face_dofs[i]);
3539 template <
int,
int>
class DoFHandlerType,
3543 const DoFHandlerType<dim, spacedim> &dof,
3549 zero_boundary_constraints,
3560 #include "dof_tools_constraints.inst" 3564 DEAL_II_NAMESPACE_CLOSE
static const unsigned int invalid_unsigned_int
#define AssertDimension(dim1, dim2)
static::ExceptionBase & ExcGridsDontMatch()
void add_entry(const size_type line, const size_type column, const number value)
Contents is actually a matrix.
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
unsigned int n_selected_components(const unsigned int overall_number_of_components=numbers::invalid_unsigned_int) const
#define AssertIndexRange(index, range)
const unsigned int dofs_per_quad
static::ExceptionBase & ExcFiniteElementsDontMatch()
#define AssertThrow(cond, exc)
bool is_constrained(const size_type index) const
static::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
const unsigned int dofs_per_line
void make_hanging_node_constraints(const DoFHandlerType &dof_handler, AffineConstraints< number > &constraints)
void add_line(const size_type line)
unsigned long long int global_dof_index
void add_entries(const size_type line, const std::vector< std::pair< size_type, number >> &col_val_pairs)
bool represents_n_components(const unsigned int n) const
static::ExceptionBase & ExcInvalidIterator()
static::ExceptionBase & ExcMessage(std::string arg1)
static::ExceptionBase & ExcGridNotCoarser()
void invert(const FullMatrix< number2 > &M)
void reinit(const TableIndices< N > &new_size, const bool omit_default_initialization=false)
#define Assert(cond, exc)
types::global_dof_index n_dofs() const
static::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
const types::boundary_id invalid_boundary_id
std::pair< unsigned int, unsigned int > component_to_base_index(const unsigned int component) const
static::ExceptionBase & ExcNoComponentSelected()
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)
const FullMatrix< double > & constraints(const ::internal::SubfaceCase< dim > &subface_case=::internal::SubfaceCase< dim >::case_isotropic) const
void mmult(FullMatrix< number2 > &C, const FullMatrix< number2 > &B, const bool adding=false) const
unsigned int n_components() const
std::pair< unsigned int, unsigned int > face_system_to_component_index(const unsigned int index) const
virtual void get_face_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix) const
virtual void get_subface_interpolation_matrix(const FiniteElement< dim, spacedim > &source, const unsigned int subface, FullMatrix< double > &matrix) 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 swap(Vector< Number > &u, Vector< Number > &v)
const FiniteElement< dim, spacedim > & get_fe(const unsigned int index=0) const
std::pair< unsigned int, unsigned int > system_to_component_index(const unsigned int index) const
const unsigned int dofs_per_face
void set_inhomogeneity(const size_type line, const number value)
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)
const std::vector< std::pair< size_type, number > > * get_constraint_entries(const size_type line) const
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)
const std::vector< Point< dim-1 > > & get_unit_face_support_points() const
const types::global_dof_index invalid_dof_index
virtual const FiniteElement< dim, spacedim > & base_element(const unsigned int index) const
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()