16 #include <deal.II/base/thread_management.h> 17 #include <deal.II/base/table.h> 18 #include <deal.II/base/template_constraints.h> 19 #include <deal.II/base/utilities.h> 20 #include <deal.II/base/work_stream.h> 21 #include <deal.II/lac/vector.h> 22 #include <deal.II/lac/constraint_matrix.h> 23 #include <deal.II/grid/tria.h> 24 #include <deal.II/grid/tria_iterator.h> 25 #include <deal.II/grid/intergrid_map.h> 26 #include <deal.II/grid/grid_tools.h> 27 #include <deal.II/dofs/dof_handler.h> 28 #include <deal.II/dofs/dof_accessor.h> 29 #include <deal.II/fe/fe.h> 30 #include <deal.II/fe/fe_values.h> 31 #include <deal.II/fe/fe_tools.h> 32 #include <deal.II/hp/fe_collection.h> 33 #include <deal.II/hp/fe_values.h> 34 #include <deal.II/dofs/dof_tools.h> 36 #ifdef DEAL_II_WITH_MPI 37 #include <deal.II/lac/la_parallel_vector.h> 44 #include <deal.II/base/std_cxx14/memory.h> 46 DEAL_II_NAMESPACE_OPEN
58 const std::vector<types::global_dof_index> &master_dof_list)
60 const unsigned int N = master_dof_list.size();
63 for (
unsigned int i=0; i<N; ++i)
64 for (
unsigned int j=0; j<N; ++j)
65 tmp(i,j) = face_interpolation_matrix (master_dof_list[i], j);
78 double diagonal_sum = 0;
79 for (
unsigned int i=0; i<N; ++i)
80 diagonal_sum += std::fabs(tmp(i,i));
81 const double typical_diagonal_element = diagonal_sum/N;
85 std::vector<unsigned int> p(N);
86 for (
unsigned int i=0; i<N; ++i)
89 for (
unsigned int j=0; j<N; ++j)
93 double max = std::fabs(tmp(j,j));
95 for (
unsigned int i=j+1; i<N; ++i)
97 if (std::fabs(tmp(i,j)) > max)
99 max = std::fabs(tmp(i,j));
106 if (max < 1.e-12*typical_diagonal_element)
112 for (
unsigned int k=0; k<N; ++k)
119 const double hr = 1./tmp(j,j);
121 for (
unsigned int k=0; k<N; ++k)
124 for (
unsigned int i=0; i<N; ++i)
127 tmp(i,k) -= tmp(i,j)*tmp(j,k)*hr;
130 for (
unsigned int i=0; i<N; ++i)
166 template <
int dim,
int spacedim>
171 std::vector<bool> &master_dof_mask)
207 std::vector<types::global_dof_index> master_dof_list;
208 unsigned int index = 0;
213 unsigned int dofs_added = 0;
224 master_dof_list.push_back (index+i);
227 if (check_master_dof_list (face_interpolation_matrix,
234 master_dof_list.pop_back ();
247 unsigned int dofs_added = 0;
254 master_dof_list.push_back (index+i);
255 if (check_master_dof_list (face_interpolation_matrix,
260 master_dof_list.pop_back ();
272 unsigned int dofs_added = 0;
279 master_dof_list.push_back (index+i);
280 if (check_master_dof_list (face_interpolation_matrix,
285 master_dof_list.pop_back ();
296 std::fill (master_dof_mask.begin(), master_dof_mask.end(),
false);
297 for (std::vector<types::global_dof_index>::const_iterator i=master_dof_list.begin();
298 i!=master_dof_list.end(); ++i)
299 master_dof_mask[*i] =
true;
308 template <
int dim,
int spacedim>
313 std::unique_ptr<std::vector<bool> > &master_dof_mask)
315 if (master_dof_mask ==
nullptr)
317 master_dof_mask = std_cxx14::make_unique<std::vector<bool> > (fe1.
dofs_per_face);
318 select_master_dofs_for_face_restriction (fe1,
320 face_interpolation_matrix,
333 template <
int dim,
int spacedim>
339 if (matrix ==
nullptr)
353 template <
int dim,
int spacedim>
357 const unsigned int subface,
360 if (matrix ==
nullptr)
378 ensure_existence_of_split_face_matrix (
const FullMatrix<double> &face_interpolation_matrix,
379 const std::vector<bool> &master_dof_mask,
383 Assert (std::count (master_dof_mask.begin(), master_dof_mask.end(),
true) ==
384 static_cast<signed int>(face_interpolation_matrix.
n()),
387 if (split_matrix ==
nullptr)
389 split_matrix = std_cxx14::make_unique<std::pair<FullMatrix<double>,
FullMatrix<double> > >();
391 const unsigned int n_master_dofs = face_interpolation_matrix.
n();
392 const unsigned int n_dofs = face_interpolation_matrix.
m();
399 split_matrix->first.reinit (n_master_dofs, n_master_dofs);
400 split_matrix->second.reinit (n_dofs-n_master_dofs, n_master_dofs);
402 unsigned int nth_master_dof = 0,
405 for (
unsigned int i=0; i<n_dofs; ++i)
406 if (master_dof_mask[i] ==
true)
408 for (
unsigned int j=0; j<n_master_dofs; ++j)
409 split_matrix->first(nth_master_dof,j)
410 = face_interpolation_matrix(i,j);
415 for (
unsigned int j=0; j<n_master_dofs; ++j)
416 split_matrix->second(nth_slave_dof,j)
417 = face_interpolation_matrix(i,j);
425 split_matrix->first.gauss_jordan ();
433 struct DoFHandlerSupportsDifferentFEs
435 static const bool value =
true;
439 template <
int dim,
int spacedim>
440 struct DoFHandlerSupportsDifferentFEs< ::
DoFHandler<dim,spacedim> >
442 static const bool value =
false;
451 template <
int dim,
int spacedim>
453 n_finite_elements (const ::hp::DoFHandler<dim,spacedim> &dof_handler)
455 return dof_handler.get_fe_collection().size();
459 template <
typename DoFHandlerType>
461 n_finite_elements (
const DoFHandlerType &)
479 filter_constraints (
const std::vector<types::global_dof_index> &master_dofs,
480 const std::vector<types::global_dof_index> &slave_dofs,
484 Assert (face_constraints.
n () == master_dofs.size (),
486 face_constraints.
n()));
487 Assert (face_constraints.
m () == slave_dofs.size (),
489 face_constraints.
m()));
491 const unsigned int n_master_dofs = master_dofs.size ();
492 const unsigned int n_slave_dofs = slave_dofs.size ();
496 for (
unsigned int row=0; row!=n_slave_dofs; ++row)
499 for (
unsigned int col=0; col!=n_master_dofs; ++col)
504 for (
unsigned int row=0; row!=n_slave_dofs; ++row)
507 bool constraint_already_satisfied =
false;
512 for (
unsigned int i=0; i<n_master_dofs; ++i)
513 if (face_constraints (row,i) == 1.0)
514 if (master_dofs[i] == slave_dofs[row])
516 constraint_already_satisfied =
true;
520 if (constraint_already_satisfied ==
false)
525 for (
unsigned int i=0; i<n_master_dofs; ++i)
526 abs_sum += std::abs (face_constraints(row,i));
535 constraints.
add_line (slave_dofs[row]);
536 for (
unsigned int i=0; i<n_master_dofs; ++i)
537 if ((face_constraints(row,i) != 0)
539 (std::fabs(face_constraints(row,i)) >= 1e-14*abs_sum))
542 face_constraints (row,i));
553 make_hp_hanging_node_constraints (const ::DoFHandler<1> &,
562 make_oldstyle_hanging_node_constraints (const ::DoFHandler<1> &,
564 std::integral_constant<int, 1>)
571 make_hp_hanging_node_constraints (const ::hp::DoFHandler<1> &,
583 make_oldstyle_hanging_node_constraints (const ::hp::DoFHandler<1> &,
585 std::integral_constant<int, 1>)
595 make_hp_hanging_node_constraints (const ::DoFHandler<1,2> &,
604 make_oldstyle_hanging_node_constraints (const ::DoFHandler<1,2> &,
606 std::integral_constant<int, 1>)
613 make_hp_hanging_node_constraints (const ::DoFHandler<1,3> &,
620 make_oldstyle_hanging_node_constraints (const ::DoFHandler<1,3> &,
622 std::integral_constant<int, 1>)
666 template <
typename DoFHandlerType>
668 make_oldstyle_hanging_node_constraints (
const DoFHandlerType &dof_handler,
670 std::integral_constant<int, 2>)
672 const unsigned int dim = 2;
674 const unsigned int spacedim = DoFHandlerType::space_dimension;
676 std::vector<types::global_dof_index> dofs_on_mother;
677 std::vector<types::global_dof_index> dofs_on_children;
688 typename DoFHandlerType::active_cell_iterator cell = dof_handler.begin_active(),
689 endc = dof_handler.end();
690 for (; cell!=endc; ++cell)
694 if (cell->is_artificial ())
697 for (
unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
698 if (cell->face(face)->has_children())
704 Assert (cell->face(face)->n_active_fe_indices() == 1,
706 Assert (cell->face(face)->fe_index_is_active(cell->active_fe_index())
709 for (
unsigned int c=0; c<cell->face(face)->n_children(); ++c)
710 if (!cell->neighbor_child_on_subface(face,c)->is_artificial())
711 Assert (cell->face(face)->child(c)->n_active_fe_indices() == 1,
716 for (
unsigned int c=0; c<cell->face(face)->n_children(); ++c)
717 if (!cell->neighbor_child_on_subface(face,c)->is_artificial())
718 Assert (cell->face(face)->child(c)
719 ->fe_index_is_active(cell->active_fe_index()) ==
true,
724 const unsigned int fe_index = cell->active_fe_index();
730 dofs_on_mother.resize (n_dofs_on_mother);
733 dofs_on_children.clear();
734 dofs_on_children.reserve (n_dofs_on_children);
743 const typename DoFHandlerType::line_iterator this_face = cell->face(face);
747 unsigned int next_index = 0;
748 for (
unsigned int vertex=0; vertex<2; ++vertex)
750 dofs_on_mother[next_index++] = this_face->vertex_dof_index(vertex,dof,
753 dofs_on_mother[next_index++] = this_face->dof_index(dof, fe_index);
757 dofs_on_children.push_back(
758 this_face->child(0)->vertex_dof_index(1,dof,fe_index));
759 for (
unsigned int child=0; child<2; ++child)
762 if (cell->neighbor_child_on_subface (face, child)->is_artificial())
765 dofs_on_children.push_back(
766 this_face->child(child)->dof_index(dof, fe_index));
772 for (
unsigned int row=0; row!=dofs_on_children.size(); ++row)
774 constraints.
add_line (dofs_on_children[row]);
775 for (
unsigned int i=0; i!=dofs_on_mother.size(); ++i)
776 constraints.
add_entry (dofs_on_children[row],
789 if (!cell->at_boundary(face) &&
790 !cell->neighbor(face)->is_artificial())
792 Assert (cell->face(face)->n_active_fe_indices() == 1,
795 ->fe_index_is_active(cell->active_fe_index()) ==
true,
804 template <
typename DoFHandlerType>
806 make_oldstyle_hanging_node_constraints (
const DoFHandlerType &dof_handler,
808 std::integral_constant<int, 3>)
810 const unsigned int dim = 3;
812 std::vector<types::global_dof_index> dofs_on_mother;
813 std::vector<types::global_dof_index> dofs_on_children;
824 typename DoFHandlerType::active_cell_iterator cell = dof_handler.begin_active(),
825 endc = dof_handler.end();
826 for (; cell!=endc; ++cell)
830 if (cell->is_artificial ())
833 for (
unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
834 if (cell->face(face)->has_children())
839 if (cell->get_fe().dofs_per_face == 0)
850 Assert (cell->face(face)->fe_index_is_active(cell->active_fe_index())
853 for (
unsigned int c=0; c<cell->face(face)->n_children(); ++c)
854 AssertDimension (cell->face(face)->child(c)->n_active_fe_indices(), 1);
860 for (
unsigned int c=0; c<cell->face(face)->n_children(); ++c)
861 if (!cell->neighbor_child_on_subface(face,c)->is_artificial())
863 Assert (cell->face(face)->child(c)
864 ->fe_index_is_active(cell->active_fe_index()) ==
true,
866 for (
unsigned int e=0;
e<4; ++
e)
868 Assert (cell->face(face)->child(c)->line(e)
869 ->n_active_fe_indices() == 1,
871 Assert (cell->face(face)->child(c)->line(e)
872 ->fe_index_is_active(cell->active_fe_index()) ==
true,
876 for (
unsigned int e=0;
e<4; ++
e)
878 Assert (cell->face(face)->line(e)
879 ->n_active_fe_indices() == 1,
881 Assert (cell->face(face)->line(e)
882 ->fe_index_is_active(cell->active_fe_index()) ==
true,
888 const unsigned int fe_index = cell->active_fe_index();
897 dofs_on_mother.resize (n_dofs_on_mother);
900 dofs_on_children.clear();
901 dofs_on_children.reserve (n_dofs_on_children);
910 const typename DoFHandlerType::face_iterator this_face = cell->face(face);
914 unsigned int next_index = 0;
915 for (
unsigned int vertex=0; vertex<4; ++vertex)
917 dofs_on_mother[next_index++] = this_face->vertex_dof_index(vertex,dof,
919 for (
unsigned int line=0; line<4; ++line)
921 dofs_on_mother[next_index++]
922 = this_face->line(line)->dof_index(dof, fe_index);
924 dofs_on_mother[next_index++] = this_face->dof_index(dof, fe_index);
932 Assert (dof_handler.get_triangulation().get_anisotropic_refinement_flag() ||
933 ((this_face->child(0)->vertex_index(3) ==
934 this_face->child(1)->vertex_index(2)) &&
935 (this_face->child(0)->vertex_index(3) ==
936 this_face->child(2)->vertex_index(1)) &&
937 (this_face->child(0)->vertex_index(3) ==
938 this_face->child(3)->vertex_index(0))),
942 dofs_on_children.push_back(
943 this_face->child(0)->vertex_dof_index(3,dof));
947 for (
unsigned int line=0; line<4; ++line)
949 dofs_on_children.push_back(
950 this_face->line(line)->child(0)->vertex_dof_index(1,dof, fe_index));
956 dofs_on_children.push_back(
957 this_face->child(0)->line(1)->dof_index(dof, fe_index));
959 dofs_on_children.push_back(
960 this_face->child(2)->line(1)->dof_index(dof, fe_index));
962 dofs_on_children.push_back(
963 this_face->child(0)->line(3)->dof_index(dof, fe_index));
965 dofs_on_children.push_back(
966 this_face->child(1)->line(3)->dof_index(dof, fe_index));
969 for (
unsigned int line=0; line<4; ++line)
970 for (
unsigned int child=0; child<2; ++child)
973 dofs_on_children.push_back(
974 this_face->line(line)->child(child)->dof_index(dof, fe_index));
978 for (
unsigned int child=0; child<4; ++child)
981 if (cell->neighbor_child_on_subface (face, child)->is_artificial())
984 dofs_on_children.push_back(
985 this_face->child(child)->dof_index(dof, fe_index));
992 for (
unsigned int row=0; row!=dofs_on_children.size(); ++row)
994 constraints.
add_line (dofs_on_children[row]);
995 for (
unsigned int i=0; i!=dofs_on_mother.size(); ++i)
996 constraints.
add_entry (dofs_on_children[row],
1009 if (!cell->at_boundary(face) &&
1010 !cell->neighbor(face)->is_artificial())
1012 Assert (cell->face(face)->n_active_fe_indices() == 1,
1015 ->fe_index_is_active(cell->active_fe_index()) ==
true,
1024 template <
typename DoFHandlerType>
1026 make_hp_hanging_node_constraints (
const DoFHandlerType &dof_handler,
1034 const unsigned int dim = DoFHandlerType::dimension;
1036 const unsigned int spacedim = DoFHandlerType::space_dimension;
1046 std::vector<types::global_dof_index> master_dofs;
1047 std::vector<types::global_dof_index> slave_dofs;
1048 std::vector<types::global_dof_index> scratch_dofs;
1055 face_interpolation_matrices (n_finite_elements (dof_handler),
1056 n_finite_elements (dof_handler));
1058 subface_interpolation_matrices (n_finite_elements (dof_handler),
1059 n_finite_elements (dof_handler),
1067 split_face_interpolation_matrices (n_finite_elements (dof_handler),
1068 n_finite_elements (dof_handler));
1074 master_dof_masks (n_finite_elements (dof_handler),
1075 n_finite_elements (dof_handler));
1082 typename DoFHandlerType::active_cell_iterator cell = dof_handler.begin_active(),
1083 endc = dof_handler.end();
1084 for (; cell!=endc; ++cell)
1088 if (cell->is_artificial ())
1091 for (
unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
1092 if (cell->face(face)->has_children())
1097 if (cell->get_fe().dofs_per_face == 0)
1111 Assert (cell->face(face)->n_active_fe_indices() == 1,
1113 Assert (cell->face(face)->fe_index_is_active(cell->active_fe_index())
1116 for (
unsigned int c=0; c<cell->face(face)->n_children(); ++c)
1117 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 ==
true)
1137 for (
unsigned int c=0; c<cell->face(face)->number_of_children(); ++c)
1138 if (!cell->neighbor_child_on_subface (face, c)->is_artificial())
1140 mother_face_dominates = mother_face_dominates &
1141 (cell->get_fe().compare_for_face_domination
1142 (cell->neighbor_child_on_subface (face, c)->get_fe()));
1143 fe_ind_face_subface.insert(cell->neighbor_child_on_subface (face, c)->active_fe_index());
1146 switch (mother_face_dominates)
1158 master_dofs.resize (cell->get_fe().dofs_per_face);
1160 cell->face(face)->get_dof_indices (master_dofs,
1161 cell->active_fe_index ());
1167 for (
unsigned int c=0; c<cell->face(face)->n_children(); ++c)
1169 if (cell->neighbor_child_on_subface (face, c)->is_artificial())
1172 const typename DoFHandlerType::active_face_iterator
1173 subface = cell->face(face)->child(c);
1175 Assert (subface->n_active_fe_indices() == 1,
1179 subface_fe_index = subface->nth_active_fe_index(0);
1190 if (cell->get_fe().compare_for_face_domination
1191 (subface->get_fe(subface_fe_index))
1198 slave_dofs.resize (subface->get_fe(subface_fe_index)
1200 subface->get_dof_indices (slave_dofs, subface_fe_index);
1202 for (
unsigned int i=0; i<slave_dofs.size(); ++i)
1228 ensure_existence_of_subface_matrix
1230 subface->get_fe(subface_fe_index),
1232 subface_interpolation_matrices
1233 [cell->active_fe_index()][subface_fe_index][c]);
1236 filter_constraints (master_dofs,
1238 *(subface_interpolation_matrices
1239 [cell->active_fe_index()][subface_fe_index][c]),
1256 Assert (DoFHandlerSupportsDifferentFEs<DoFHandlerType>::value ==
true,
1259 const ::hp::FECollection<dim,spacedim> &fe_collection =
1260 dof_handler.get_fe_collection ();
1280 const unsigned int dominating_fe_index = fe_collection.find_least_face_dominating_fe(fe_ind_face_subface);
1282 ExcMessage(
"Could not find a least face dominating FE."));
1285 = dof_handler.get_fe(dominating_fe_index);
1290 cell->get_fe().dofs_per_face,
1293 ensure_existence_of_face_matrix
1296 face_interpolation_matrices
1297 [dominating_fe_index][cell->active_fe_index()]);
1301 ensure_existence_of_master_dof_mask
1304 (*face_interpolation_matrices
1305 [dominating_fe_index]
1306 [cell->active_fe_index()]),
1308 [dominating_fe_index]
1309 [cell->active_fe_index()]);
1311 ensure_existence_of_split_face_matrix
1312 (*face_interpolation_matrices
1313 [dominating_fe_index][cell->active_fe_index()],
1315 [dominating_fe_index][cell->active_fe_index()]),
1316 split_face_interpolation_matrices
1317 [dominating_fe_index][cell->active_fe_index()]);
1320 = (split_face_interpolation_matrices
1321 [dominating_fe_index][cell->active_fe_index()]->first);
1324 = (split_face_interpolation_matrices
1325 [dominating_fe_index][cell->active_fe_index()]->second);
1329 constraint_matrix.
reinit (cell->get_fe().dofs_per_face -
1332 restrict_mother_to_virtual_slave
1333 .
mmult (constraint_matrix,
1334 restrict_mother_to_virtual_master_inv);
1338 scratch_dofs.resize (cell->get_fe().dofs_per_face);
1339 cell->face(face)->get_dof_indices (scratch_dofs,
1340 cell->active_fe_index ());
1343 master_dofs.clear ();
1344 slave_dofs.clear ();
1345 for (
unsigned int i=0; i<cell->get_fe().dofs_per_face; ++i)
1346 if ((*master_dof_masks
1347 [dominating_fe_index][cell->active_fe_index()])[i] ==
true)
1348 master_dofs.push_back (scratch_dofs[i]);
1350 slave_dofs.push_back (scratch_dofs[i]);
1354 cell->get_fe().dofs_per_face - dominating_fe.
dofs_per_face);
1356 filter_constraints (master_dofs,
1365 for (
unsigned int sf=0;
1366 sf<cell->face(face)->n_children(); ++sf)
1370 if (cell->neighbor_child_on_subface (face, sf)->is_artificial()
1372 (dim==2 && cell->is_ghost()
1374 cell->neighbor_child_on_subface (face, sf)->is_ghost()))
1377 Assert (cell->face(face)->child(sf)
1378 ->n_active_fe_indices() == 1,
1381 const unsigned int subface_fe_index
1382 = cell->face(face)->child(sf)->nth_active_fe_index(0);
1384 = dof_handler.get_fe(subface_fe_index);
1391 ensure_existence_of_subface_matrix
1395 subface_interpolation_matrices
1396 [dominating_fe_index][subface_fe_index][sf]);
1399 = *(subface_interpolation_matrices
1400 [dominating_fe_index][subface_fe_index][sf]);
1405 restrict_subface_to_virtual
1406 .
mmult (constraint_matrix,
1407 restrict_mother_to_virtual_master_inv);
1410 cell->face(face)->child(sf)->get_dof_indices (slave_dofs,
1413 filter_constraints (master_dofs,
1437 ->fe_index_is_active(cell->active_fe_index()) ==
true,
1444 if (!cell->at_boundary(face)
1446 cell->neighbor(face)->is_artificial())
1452 if ((DoFHandlerSupportsDifferentFEs<DoFHandlerType>::value ==
true)
1454 !cell->face(face)->at_boundary ()
1456 (cell->neighbor(face)->active_fe_index () !=
1457 cell->active_fe_index ())
1459 (!cell->face(face)->has_children() &&
1460 !cell->neighbor_is_coarser(face) ))
1462 const typename DoFHandlerType::level_cell_iterator neighbor = cell->neighbor (face);
1465 switch (cell->get_fe().compare_for_face_domination (neighbor->get_fe ()))
1471 master_dofs.resize (cell->get_fe().dofs_per_face);
1472 cell->face(face)->get_dof_indices (master_dofs,
1473 cell->active_fe_index ());
1478 if (master_dofs.size() == 0)
1481 slave_dofs.resize (neighbor->get_fe().dofs_per_face);
1482 cell->face(face)->get_dof_indices (slave_dofs,
1483 neighbor->active_fe_index ());
1487 ensure_existence_of_face_matrix
1490 face_interpolation_matrices
1491 [cell->active_fe_index()][neighbor->active_fe_index()]);
1494 filter_constraints (master_dofs,
1496 *(face_interpolation_matrices
1497 [cell->active_fe_index()]
1498 [neighbor->active_fe_index()]),
1541 if (cell < neighbor)
1555 const unsigned int this_fe_index = cell->active_fe_index();
1556 const unsigned int neighbor_fe_index = neighbor->active_fe_index();
1557 std::set<unsigned int> fes;
1558 fes.insert(this_fe_index);
1559 fes.insert(neighbor_fe_index);
1560 const ::hp::FECollection<dim,spacedim> &fe_collection =
1561 dof_handler.get_fe_collection ();
1562 const unsigned int dominating_fe_index = fe_collection.find_least_face_dominating_fe(fes);
1565 ExcMessage(
"Could not find the dominating FE for " 1566 +cell->get_fe().get_name()
1568 +neighbor->get_fe().get_name()
1569 +
" inside FECollection."));
1579 cell->get_fe().dofs_per_face,
1582 ensure_existence_of_face_matrix
1585 face_interpolation_matrices
1586 [dominating_fe_index][cell->active_fe_index()]);
1590 ensure_existence_of_master_dof_mask
1593 (*face_interpolation_matrices
1594 [dominating_fe_index]
1595 [cell->active_fe_index()]),
1597 [dominating_fe_index]
1598 [cell->active_fe_index()]);
1600 ensure_existence_of_split_face_matrix
1601 (*face_interpolation_matrices
1602 [dominating_fe_index][cell->active_fe_index()],
1604 [dominating_fe_index][cell->active_fe_index()]),
1605 split_face_interpolation_matrices
1606 [dominating_fe_index][cell->active_fe_index()]);
1609 = (split_face_interpolation_matrices
1610 [dominating_fe_index][cell->active_fe_index()]->first);
1613 = (split_face_interpolation_matrices
1614 [dominating_fe_index][cell->active_fe_index()]->second);
1618 constraint_matrix.
reinit (cell->get_fe().dofs_per_face -
1621 restrict_mother_to_virtual_slave
1622 .
mmult (constraint_matrix,
1623 restrict_mother_to_virtual_master_inv);
1627 scratch_dofs.resize (cell->get_fe().dofs_per_face);
1628 cell->face(face)->get_dof_indices (scratch_dofs,
1629 cell->active_fe_index ());
1632 master_dofs.clear ();
1633 slave_dofs.clear ();
1634 for (
unsigned int i=0; i<cell->get_fe().dofs_per_face; ++i)
1635 if ((*master_dof_masks
1636 [dominating_fe_index][cell->active_fe_index()])[i] ==
true)
1637 master_dofs.push_back (scratch_dofs[i]);
1639 slave_dofs.push_back (scratch_dofs[i]);
1643 cell->get_fe().dofs_per_face - dominating_fe.
dofs_per_face);
1645 filter_constraints (master_dofs,
1654 neighbor->get_fe().dofs_per_face,
1657 ensure_existence_of_face_matrix
1660 face_interpolation_matrices
1661 [dominating_fe_index][neighbor->active_fe_index()]);
1664 = *(face_interpolation_matrices
1665 [dominating_fe_index][neighbor->active_fe_index()]);
1667 constraint_matrix.
reinit (neighbor->get_fe().dofs_per_face,
1670 restrict_secondface_to_virtual
1671 .mmult (constraint_matrix,
1672 restrict_mother_to_virtual_master_inv);
1674 slave_dofs.resize (neighbor->get_fe().dofs_per_face);
1675 cell->face(face)->get_dof_indices (slave_dofs,
1676 neighbor->active_fe_index ());
1678 filter_constraints (master_dofs,
1705 template <
typename DoFHandlerType>
1714 if (dof_handler.get_fe_collection().hp_constraints_are_implemented ())
1716 make_hp_hanging_node_constraints (dof_handler,
1720 make_oldstyle_hanging_node_constraints (dof_handler,
1722 std::integral_constant<int, DoFHandlerType::dimension>());
1752 template <
typename FaceIterator>
1754 set_periodicity_constraints (
const FaceIterator &face_1,
1755 const typename identity<FaceIterator>::type &face_2,
1759 const bool face_orientation,
1760 const bool face_flip,
1761 const bool face_rotation)
1763 static const int dim = FaceIterator::AccessorType::dimension;
1764 static const int spacedim = FaceIterator::AccessorType::space_dimension;
1767 Assert (!face_1->has_children(),
1770 Assert (face_1->n_active_fe_indices() == 1,
1774 if (face_2->has_children())
1778 const unsigned int dofs_per_face
1779 = face_1->get_fe(face_1->nth_active_fe_index(0)).dofs_per_face;
1782 for (
unsigned int c=0; c<face_2->n_children(); ++c)
1788 face_1->get_fe(face_1->nth_active_fe_index(0))
1789 .get_subface_interpolation_matrix (face_1->get_fe(face_1->nth_active_fe_index(0)),
1791 subface_interpolation);
1792 subface_interpolation.mmult (child_transformation, transformation);
1793 set_periodicity_constraints(face_1, face_2->child(c),
1794 child_transformation,
1795 constraint_matrix, component_mask,
1796 face_orientation, face_flip, face_rotation);
1802 const unsigned int face_1_index = face_1->nth_active_fe_index(0);
1803 const unsigned int face_2_index = face_2->nth_active_fe_index(0);
1804 Assert(face_1->get_fe(face_1_index) == face_2->get_fe(face_2_index),
1805 ExcMessage (
"Matching periodic cells need to use the same finite element"));
1810 ExcMessage (
"The number of components in the mask has to be either " 1811 "zero or equal to the number of components in the finite " "element."));
1813 const unsigned int dofs_per_face = fe.dofs_per_face;
1815 std::vector<types::global_dof_index> dofs_1(dofs_per_face);
1816 std::vector<types::global_dof_index> dofs_2(dofs_per_face);
1818 face_1->get_dof_indices(dofs_1, face_1_index);
1819 face_2->get_dof_indices(dofs_2, face_2_index);
1821 for (
unsigned int i=0; i < dofs_per_face; i++)
1861 std::map<unsigned int, unsigned int> cell_to_rotated_face_index;
1864 for (
unsigned int i = 0; i < dofs_per_face; ++i)
1866 const unsigned int cell_index = fe.face_to_cell_index(i, 0,
1871 cell_to_rotated_face_index[cell_index] = i;
1875 for (
unsigned int i=0; i<dofs_per_face; ++i)
1877 == fe.n_components())
1879 component_mask[fe.face_system_to_component_index(i).first])
1891 bool is_identity_constrained =
true;
1892 const double eps = 1.e-13;
1893 for (
unsigned int jj=0; jj<dofs_per_face; ++jj)
1894 if (std::abs(transformation(i,jj)) >
eps &&
1895 std::abs(transformation(i,jj)-1.) >
eps)
1897 is_identity_constrained =
false;
1901 if (is_identity_constrained ==
true)
1903 bool one_identity_found =
false;
1904 for (
unsigned int jj=0; jj<dofs_per_face; ++jj)
1905 if (std::abs(transformation(i,jj)-1.) <
eps)
1907 if (one_identity_found ==
false)
1909 one_identity_found =
true;
1910 identity_constraint_target = jj;
1914 is_identity_constrained =
false;
1921 bool is_inverse_constrained = !is_identity_constrained;
1923 if (is_inverse_constrained)
1924 for (
unsigned int jj=0; jj<dofs_per_face; ++jj)
1925 if (std::abs(transformation(i,jj)) >
eps &&
1926 std::abs(transformation(i,jj)+1.) >
eps)
1928 is_inverse_constrained =
false;
1931 if (is_inverse_constrained)
1933 bool one_identity_found =
false;
1934 for (
unsigned int jj=0; jj<dofs_per_face; ++jj)
1935 if (std::abs(transformation(i,jj)+1) <
eps)
1937 if (one_identity_found ==
false)
1939 one_identity_found =
true;
1940 inverse_constraint_target = jj;
1944 is_inverse_constrained =
false;
1951 const unsigned int target = is_identity_constrained
1952 ? identity_constraint_target
1953 : inverse_constraint_target;
1958 bool constraint_set =
false;
1959 for (
unsigned int j=0; j<dofs_per_face; ++j)
1961 if (dofs_2[i] == dofs_1[j])
1962 if (!(is_identity_constrained && target==i))
1964 constraint_matrix.
add_line(dofs_2[i]);
1965 constraint_set =
true;
1969 if (!constraint_set)
1973 if (is_identity_constrained || is_inverse_constrained)
1977 const unsigned int j
1978 = cell_to_rotated_face_index[fe.face_to_cell_index(target,
1982 face_orientation, face_flip, face_rotation)];
1989 bool enter_constraint =
false;
1994 while (new_dof != dofs_1[j])
1997 const std::vector<std::pair<types::global_dof_index, double > > *constraint_entries
1999 if (constraint_entries->size()==1)
2000 new_dof = (*constraint_entries)[0].first;
2003 enter_constraint =
true;
2009 enter_constraint =
true;
2014 if (enter_constraint)
2016 constraint_matrix.
add_line(dofs_1[j]);
2017 constraint_matrix.
add_entry(dofs_1[j], dofs_2[i], is_identity_constrained?1.0:-1.0);
2025 bool enter_constraint =
false;
2028 if (dofs_2[i] != dofs_1[j])
2029 enter_constraint =
true;
2033 const std::vector<std::pair<types::global_dof_index, double > > *constraint_entries
2035 if (constraint_entries->size()==1 && (*constraint_entries)[0].first == dofs_2[i])
2037 if ((is_identity_constrained && std::abs((*constraint_entries)[0].second-1) > eps) ||
2038 (is_inverse_constrained && std::abs((*constraint_entries)[0].second+1) >
eps))
2041 constraint_matrix.
add_line(dofs_2[i]);
2048 while (new_dof != dofs_2[i])
2051 const std::vector<std::pair<types::global_dof_index, double > > *constraint_entries
2053 if (constraint_entries->size()==1)
2054 new_dof = (*constraint_entries)[0].first;
2057 enter_constraint =
true;
2063 enter_constraint =
true;
2069 if (enter_constraint)
2071 constraint_matrix.
add_line(dofs_2[i]);
2072 constraint_matrix.
add_entry(dofs_2[i], dofs_1[j], is_identity_constrained?1.0:-1.0);
2079 constraint_matrix.
add_line(dofs_2[i]);
2080 for (
unsigned int jj=0; jj<dofs_per_face; ++jj)
2084 const unsigned int j =
2085 cell_to_rotated_face_index[fe.face_to_cell_index
2086 (jj, 0, face_orientation, face_flip, face_rotation)];
2089 if (transformation(i,jj) != 0)
2090 constraint_matrix.
add_entry(dofs_2[i], dofs_1[j],
2091 transformation(i,jj));
2105 template <
int dim,
int spacedim>
2109 const std::vector<unsigned int> &first_vector_components)
2115 if (
matrix.m() == n_dofs_per_face)
2122 if (first_vector_components.empty() &&
matrix.m() == 0)
2138 typedef std::array<unsigned int, spacedim> DoFTuple;
2143 for (
unsigned int i=0; i < n_dofs_per_face; ++i)
2145 std::vector<unsigned int>::const_iterator comp_it
2146 = std::find (first_vector_components.begin(),
2147 first_vector_components.end(),
2149 if (comp_it != first_vector_components.end())
2151 const unsigned int first_vector_component = *comp_it;
2154 DoFTuple vector_dofs;
2156 unsigned int n_found = 1;
2159 ExcMessage(
"Error: the finite element does not have enough components " 2160 "to define rotated periodic boundaries."));
2162 for (
unsigned int k = 0; k < n_dofs_per_face; ++k)
2164 (quadrature.point(k) == quadrature.point(i)) &&
2166 first_vector_component) &&
2168 first_vector_component + spacedim))
2171 first_vector_component]
2180 for (
int i = 0; i < spacedim; ++i)
2182 transformation[vector_dofs[i]][vector_dofs[i]] = 0.;
2183 for (
int j = 0; j < spacedim; ++j)
2184 transformation[vector_dofs[i]][vector_dofs[j]] = matrix[i][j];
2188 return transformation;
2197 template <
typename FaceIterator>
2200 const typename identity<FaceIterator>::type &face_2,
2203 const bool face_orientation,
2204 const bool face_flip,
2205 const bool face_rotation,
2207 const std::vector<unsigned int> &first_vector_components)
2209 static const int dim = FaceIterator::AccessorType::dimension;
2210 static const int spacedim = FaceIterator::AccessorType::space_dimension;
2213 (face_orientation ==
true &&
2214 face_flip ==
false &&
2215 face_rotation ==
false),
2217 "(face_orientation, face_flip, face_rotation) " 2218 "is invalid for 1D"));
2221 (face_orientation ==
true &&
2222 face_rotation ==
false),
2224 "(face_orientation, face_flip, face_rotation) " 2225 "is invalid for 2D"));
2228 ExcMessage (
"face_1 and face_2 are equal! Cannot constrain DoFs " 2229 "on the very same face"));
2231 Assert(face_1->at_boundary() && face_2->at_boundary(),
2232 ExcMessage (
"Faces for periodicity constraints must be on the " 2235 Assert(matrix.m() == matrix.n(),
2236 ExcMessage(
"The supplied (rotation or interpolation) matrix must " 2237 "be a square matrix"));
2239 Assert(first_vector_components.empty() || matrix.m() == (int)spacedim,
2240 ExcMessage (
"first_vector_components is nonempty, so matrix must " 2241 "be a rotation matrix exactly of size spacedim"));
2244 if (!face_1->has_children())
2247 const unsigned int n_dofs_per_face =
2248 face_1->get_fe(face_1->nth_active_fe_index(0)).dofs_per_face;
2251 || (first_vector_components.empty() && matrix.m() == n_dofs_per_face)
2252 || (!first_vector_components.empty() && matrix.m() == (int)spacedim),
2253 ExcMessage (
"The matrix must have either size 0 or spacedim " 2254 "(if first_vector_components is nonempty) " 2255 "or the size must be equal to the # of DoFs on the face " 2256 "(if first_vector_components is empty)."));
2259 if (!face_2->has_children())
2262 const unsigned int n_dofs_per_face =
2263 face_2->get_fe(face_2->nth_active_fe_index(0)).dofs_per_face;
2266 || (first_vector_components.empty() && matrix.m() == n_dofs_per_face)
2267 || (!first_vector_components.empty() && matrix.m() == (int)spacedim),
2268 ExcMessage (
"The matrix must have either size 0 or spacedim " 2269 "(if first_vector_components is nonempty) " 2270 "or the size must be equal to the # of DoFs on the face " 2271 "(if first_vector_components is empty)."));
2278 static const int lookup_table_2d[2][2] =
2285 static const int lookup_table_3d[2][2][2][4] =
2304 if (face_1->has_children() && face_2->has_children())
2310 face_2->n_children() ==
2314 for (
unsigned int i = 0; i < GeometryInfo<dim>::max_children_per_face;
2322 j = lookup_table_2d[face_flip][i];
2325 j = lookup_table_3d[face_orientation][face_flip][face_rotation][i];
2339 first_vector_components);
2349 face_1->has_children()
2350 ? face_2->get_fe(face_2->nth_active_fe_index(0))
2351 : face_1->get_fe(face_1->nth_active_fe_index(0));
2358 if (n_dofs_per_face == 0)
2362 compute_transformation(fe, matrix, first_vector_components);
2364 if (! face_2->has_children())
2368 if (first_vector_components.empty() && matrix.m() == 0)
2370 set_periodicity_constraints(face_2,
2382 inverse.
invert(transformation);
2384 set_periodicity_constraints(face_2,
2405 set_periodicity_constraints(face_1,
2412 ? face_rotation ^ face_flip
2421 template <
typename DoFHandlerType>
2428 const std::vector<unsigned int> &first_vector_components)
2430 typedef std::vector<GridTools::PeriodicFacePair<typename DoFHandlerType::cell_iterator> >
2432 typename FaceVector::const_iterator it, end_periodic;
2433 it = periodic_faces.begin();
2434 end_periodic = periodic_faces.end();
2437 for (; it!=end_periodic; ++it)
2439 typedef typename DoFHandlerType::face_iterator FaceIterator;
2440 const FaceIterator face_1 = it->cell[0]->face(it->face_idx[0]);
2441 const FaceIterator face_2 = it->cell[1]->face(it->face_idx[1]);
2443 Assert(face_1->at_boundary() && face_2->at_boundary(),
2446 Assert (face_1 != face_2,
2459 first_vector_components);
2467 template <
typename DoFHandlerType>
2472 const int direction,
2476 static const int space_dim = DoFHandlerType::space_dimension;
2478 Assert (0<=direction && direction<space_dim,
2482 ExcMessage (
"The boundary indicators b_id1 and b_id2 must be" 2483 "different to denote different boundaries."));
2486 <
typename DoFHandlerType::cell_iterator> > matched_faces;
2492 make_periodicity_constraints<DoFHandlerType>
2493 (matched_faces, constraint_matrix, component_mask);
2498 template <
typename DoFHandlerType>
2502 const int direction,
2506 static const int dim = DoFHandlerType::dimension;
2507 static const int space_dim = DoFHandlerType::space_dimension;
2511 Assert (0<=direction && direction<space_dim,
2518 <
typename DoFHandlerType::cell_iterator> > matched_faces;
2524 make_periodicity_constraints<DoFHandlerType>
2525 (matched_faces, constraint_matrix, component_mask);
2537 template <
int dim,
int spacedim>
2540 unsigned int dofs_per_cell;
2541 std::vector<types::global_dof_index> parameter_dof_indices;
2542 #ifdef DEAL_II_WITH_MPI 2543 std::vector<::LinearAlgebra::distributed::Vector<double> > global_parameter_representation;
2545 std::vector<::Vector<double> > global_parameter_representation;
2557 template <
int dim,
int spacedim>
2558 void compute_intergrid_weights_3 (
2559 const typename ::DoFHandler<dim,spacedim>::active_cell_iterator &cell,
2560 const Assembler::Scratch &,
2561 Assembler::CopyData<dim,spacedim> ©_data,
2562 const unsigned int coarse_component,
2615 copy_data.parameter_dof_indices.resize(copy_data.dofs_per_cell);
2619 cell->get_dof_indices (copy_data.parameter_dof_indices);
2623 for (
unsigned int local_dof=0; local_dof<copy_data.dofs_per_cell; ++local_dof)
2629 const unsigned int local_parameter_dof
2632 copy_data.global_parameter_representation[local_parameter_dof] = 0.;
2637 coarse_to_fine_grid_map[cell]->
2638 set_dof_values_by_interpolation (parameter_dofs[local_parameter_dof],
2639 copy_data.global_parameter_representation[local_parameter_dof]);
2650 template <
int dim,
int spacedim>
2651 void copy_intergrid_weights_3(
const Assembler::CopyData<dim,spacedim> ©_data,
2652 const unsigned int coarse_component,
2654 const std::vector<types::global_dof_index> &weight_mapping,
2655 const bool is_called_in_parallel,
2656 std::vector<std::map<types::global_dof_index, float> > &weights)
2658 unsigned int pos = 0;
2659 for (
unsigned int local_dof=0; local_dof<copy_data.dofs_per_cell; ++local_dof)
2693 if (copy_data.global_parameter_representation[pos](i) != 0)
2696 wj = weight_mapping[i];
2697 weights[wi][wj] = copy_data.global_parameter_representation[pos](i);
2700 else if (!is_called_in_parallel)
2705 Assert (copy_data.global_parameter_representation[pos](i) == 0,
2721 template <
int dim,
int spacedim>
2723 compute_intergrid_weights_2 (
2724 const ::DoFHandler<dim,spacedim> &coarse_grid,
2725 const unsigned int coarse_component,
2728 const std::vector<types::global_dof_index> &weight_mapping,
2729 std::vector<std::map<types::global_dof_index,float> > &weights)
2731 Assembler::Scratch scratch;
2732 Assembler::CopyData<dim,spacedim> copy_data;
2734 unsigned int n_interesting_dofs = 0;
2735 for (
unsigned int local_dof=0; local_dof<coarse_grid.get_fe().dofs_per_cell; ++local_dof)
2736 if (coarse_grid.get_fe().system_to_component_index(local_dof).first
2739 ++n_interesting_dofs;
2741 copy_data.global_parameter_representation.resize(n_interesting_dofs);
2743 bool is_called_in_parallel =
false;
2744 for (
size_t i=0; i<copy_data.global_parameter_representation.size(); ++i)
2746 #ifdef DEAL_II_WITH_MPI 2747 MPI_Comm communicator = MPI_COMM_SELF;
2750 const typename ::parallel::Triangulation<dim, spacedim> &tria =
2751 dynamic_cast<const typename ::parallel::Triangulation<dim, spacedim>&
> 2752 (coarse_to_fine_grid_map.get_destination_grid().get_triangulation());
2753 communicator = tria.get_communicator ();
2754 is_called_in_parallel =
true;
2756 catch (std::bad_cast &)
2764 (coarse_to_fine_grid_map.get_destination_grid (), locally_relevant_dofs);
2766 copy_data.global_parameter_representation[i].reinit
2767 (coarse_to_fine_grid_map.get_destination_grid().locally_owned_dofs(),
2768 locally_relevant_dofs, communicator);
2771 copy_data.global_parameter_representation[i].reinit (n_fine_dofs);
2777 std::bind(&compute_intergrid_weights_3<dim,spacedim>,
2778 std::placeholders::_1,
2779 std::placeholders::_2,
2780 std::placeholders::_3,
2782 std::cref(coarse_grid.get_fe()),
2783 std::cref(coarse_to_fine_grid_map),
2784 std::cref(parameter_dofs)),
2785 std::bind(©_intergrid_weights_3<dim,spacedim>,
2786 std::placeholders::_1,
2788 std::cref(coarse_grid.get_fe()),
2789 std::cref(weight_mapping),
2790 is_called_in_parallel,
2795 #ifdef DEAL_II_WITH_MPI 2796 for (
size_t i=0; i<copy_data.global_parameter_representation.size(); ++i)
2797 copy_data.global_parameter_representation[i].update_ghost_values ();
2808 template <
int dim,
int spacedim>
2810 compute_intergrid_weights_1 (
2811 const ::DoFHandler<dim,spacedim> &coarse_grid,
2812 const unsigned int coarse_component,
2813 const ::DoFHandler<dim,spacedim> &fine_grid,
2814 const unsigned int fine_component,
2816 std::vector<std::map<types::global_dof_index, float> > &weights,
2817 std::vector<types::global_dof_index> &weight_mapping)
2821 &fine_fe = fine_grid.get_fe();
2825 n_fine_dofs = fine_grid.n_dofs();
2828 const unsigned int fine_dofs_per_cell = fine_fe.
dofs_per_cell;
2833 const unsigned int coarse_dofs_per_cell_component
2839 Assert (coarse_grid.get_triangulation().n_cells(0) == fine_grid.get_triangulation().n_cells(0),
2843 Assert (&coarse_to_fine_grid_map.get_source_grid() == &coarse_grid,
2845 Assert (&coarse_to_fine_grid_map.get_destination_grid() == &fine_grid,
2856 fine_fe.base_element (fine_fe.component_to_base_index(fine_component).first),
2862 for (typename ::DoFHandler<dim,spacedim>::active_cell_iterator
2863 cell=coarse_grid.begin_active();
2864 cell != coarse_grid.end(); ++cell)
2865 Assert (cell->level() <= coarse_to_fine_grid_map[cell]->level(),
2892 std::vector<::Vector<double> >
2893 parameter_dofs (coarse_dofs_per_cell_component,
2898 for (
unsigned int local_coarse_dof=0;
2899 local_coarse_dof<coarse_dofs_per_cell_component;
2901 for (
unsigned int fine_dof=0; fine_dof<fine_fe.dofs_per_cell; ++fine_dof)
2902 if (fine_fe.system_to_component_index(fine_dof)
2904 std::make_pair (fine_component, local_coarse_dof))
2906 parameter_dofs[local_coarse_dof](fine_dof) = 1.;
2913 unsigned int n_parameters_on_fine_grid=0;
2919 std::vector<bool> dof_is_interesting (fine_grid.n_dofs(),
false);
2920 std::vector<types::global_dof_index> local_dof_indices (fine_fe.dofs_per_cell);
2922 for (typename ::DoFHandler<dim,spacedim>::active_cell_iterator
2923 cell=fine_grid.begin_active();
2924 cell!=fine_grid.end(); ++cell)
2925 if (cell->is_locally_owned ())
2927 cell->get_dof_indices (local_dof_indices);
2928 for (
unsigned int i=0; i<fine_fe.dofs_per_cell; ++i)
2929 if (fine_fe.system_to_component_index(i).first == fine_component)
2930 dof_is_interesting[local_dof_indices[i]] =
true;
2933 n_parameters_on_fine_grid = std::count (dof_is_interesting.begin(),
2934 dof_is_interesting.end(),
2941 weights.resize (n_coarse_dofs);
2943 weight_mapping.clear ();
2948 std::vector<types::global_dof_index> local_dof_indices(fine_fe.dofs_per_cell);
2949 unsigned int next_free_index=0;
2950 for (typename ::DoFHandler<dim,spacedim>::active_cell_iterator
2951 cell=fine_grid.begin_active();
2952 cell != fine_grid.end(); ++cell)
2953 if (cell->is_locally_owned ())
2955 cell->get_dof_indices (local_dof_indices);
2956 for (
unsigned int i=0; i<fine_fe.dofs_per_cell; ++i)
2959 if ((fine_fe.system_to_component_index(i).first == fine_component) &&
2962 weight_mapping[local_dof_indices[i]] = next_free_index;
2967 Assert (next_free_index == n_parameters_on_fine_grid,
2979 compute_intergrid_weights_2 (coarse_grid, coarse_component,
2980 coarse_to_fine_grid_map, parameter_dofs,
2981 weight_mapping, weights);
2998 for (
unsigned int col=0; col<n_parameters_on_fine_grid; ++col)
3002 if (weights[row].find(col) != weights[row].end())
3003 sum += weights[row][col];
3004 Assert ((std::fabs(sum-1) < 1.e-12) ||
3010 return n_parameters_on_fine_grid;
3019 template <
int dim,
int spacedim>
3023 const unsigned int coarse_component,
3025 const unsigned int fine_component,
3050 std::vector<std::map<types::global_dof_index, float> > weights;
3056 std::vector<types::global_dof_index> weight_mapping;
3058 const unsigned int n_parameters_on_fine_grid
3059 = internal::compute_intergrid_weights_1 (coarse_grid, coarse_component,
3060 fine_grid, fine_component,
3061 coarse_to_fine_grid_map,
3062 weights, weight_mapping);
3063 (void)n_parameters_on_fine_grid;
3067 n_fine_dofs = fine_grid.
n_dofs();
3072 std::vector<bool> coarse_dof_is_parameter (coarse_grid.
n_dofs());
3075 std::vector<bool> mask (coarse_grid.
get_fe(0).n_components(),
3077 mask[coarse_component] =
true;
3093 if (coarse_dof_is_parameter[parameter_dof] ==
true)
3101 std::map<types::global_dof_index,float>::const_iterator i = weights[parameter_dof].begin();
3102 for (; i!=weights[parameter_dof].end(); ++i)
3112 for (; global_dof<weight_mapping.size(); ++global_dof)
3113 if (weight_mapping[global_dof] == static_cast<types::global_dof_index>(column))
3118 representants[parameter_dof] = global_dof;
3134 std::vector<std::pair<types::global_dof_index,double> > constraint_line;
3152 std::map<types::global_dof_index,float>::const_iterator
3153 col_entry = weights[0].end();
3154 for (; first_used_row<n_coarse_dofs; ++first_used_row)
3156 col_entry = weights[first_used_row].find(col);
3157 if (col_entry != weights[first_used_row].end())
3163 if ((col_entry->second == 1) &&
3164 (representants[first_used_row] == global_dof))
3175 constraint_line.clear ();
3178 const std::map<types::global_dof_index,float>::const_iterator
3179 j = weights[row].find(col);
3180 if ((j != weights[row].end()) && (j->second != 0))
3181 constraint_line.emplace_back (representants[row], j->second);
3184 constraints.
add_entries (global_dof, constraint_line);
3190 template <
int dim,
int spacedim>
3194 const unsigned int coarse_component,
3196 const unsigned int fine_component,
3198 std::vector<std::map<types::global_dof_index, float> > &transfer_representation)
3221 std::vector<std::map<types::global_dof_index, float> > weights;
3227 std::vector<types::global_dof_index> weight_mapping;
3229 internal::compute_intergrid_weights_1 (coarse_grid, coarse_component,
3230 fine_grid, fine_component,
3231 coarse_to_fine_grid_map,
3232 weights, weight_mapping);
3236 = std::count_if (weight_mapping.begin(), weight_mapping.end(),
3240 std::vector<types::global_dof_index> inverse_weight_mapping (n_global_parm_dofs,
3252 inverse_weight_mapping[parameter_dof] = i;
3259 transfer_representation.clear ();
3260 transfer_representation.resize (n_rows);
3265 std::map<types::global_dof_index, float>::const_iterator j = weights[i].begin();
3266 for (; j!=weights[i].end(); ++j)
3271 transfer_representation[p][i] = j->second;
3278 template <
int dim,
int spacedim,
template <
int,
int>
class DoFHandlerType>
3286 ExcMessage (
"The number of components in the mask has to be either " 3287 "zero or equal to the number of components in the finite " 3296 std::vector<types::global_dof_index> face_dofs;
3299 std::vector<types::global_dof_index> cell_dofs;
3302 typename DoFHandlerType<dim,spacedim>::active_cell_iterator
3303 cell = dof.begin_active(),
3305 for (; cell!=endc; ++cell)
3306 if (!cell->is_artificial()
3308 cell->at_boundary ())
3314 cell->get_dof_indices (cell_dofs);
3316 for (
unsigned int face_no = 0; face_no < GeometryInfo<dim>::faces_per_cell;
3319 const typename DoFHandlerType<dim,spacedim>::face_iterator face = cell->face(face_no);
3323 if (face->at_boundary ()
3327 (face->boundary_id() == boundary_id)))
3331 face->get_dof_indices (face_dofs, cell->active_fe_index());
3335 for (
unsigned int i=0; i<face_dofs.size(); ++i)
3339 const std::vector<types::global_dof_index>::iterator it_index_on_cell
3340 = std::find (cell_dofs.begin(), cell_dofs.end(), face_dofs[i]);
3342 const unsigned int index_on_cell = std::distance(cell_dofs.begin(),
3345 = cell->get_fe().get_nonzero_components (index_on_cell);
3348 if (nonzero_component_array[c] && component_mask[c])
3355 zero_boundary_constraints.
add_line (face_dofs[i]);
3364 template <
int dim,
int spacedim,
template <
int,
int>
class DoFHandlerType>
3371 zero_boundary_constraints, component_mask);
3381 #include "dof_tools_constraints.inst" 3385 DEAL_II_NAMESPACE_CLOSE
static const unsigned int invalid_unsigned_int
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)
#define AssertDimension(dim1, dim2)
const std::vector< Point< dim-1 > > & get_unit_face_support_points() const
virtual void get_face_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix) const
static ::ExceptionBase & ExcGridsDontMatch()
Contents is actually a matrix.
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
#define AssertIndexRange(index, range)
const unsigned int dofs_per_quad
void add_entries(const size_type line, const std::vector< std::pair< size_type, double > > &col_val_pairs)
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
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, ConstraintMatrix &constraints)
static ::ExceptionBase & ExcInvalidIterator()
void add_line(const size_type line)
void make_hanging_node_constraints(const DoFHandlerType &dof_handler, ConstraintMatrix &constraints)
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 add_entry(const size_type line, const size_type column, const double value)
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)
unsigned int global_dof_index
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
const FiniteElement< dim, spacedim > & get_fe(const unsigned int index=0) const
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
virtual const FiniteElement< dim, spacedim > & base_element(const unsigned int index) const
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)
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
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)
static ::ExceptionBase & ExcNotImplemented()
const unsigned int dofs_per_vertex
const std::vector< std::pair< size_type, double > > * get_constraint_entries(const size_type line) const
void set_inhomogeneity(const size_type line, const double value)
void make_zero_boundary_constraints(const DoFHandlerType< dim, spacedim > &dof, const types::boundary_id boundary_id, ConstraintMatrix &zero_boundary_constraints, const ComponentMask &component_mask=ComponentMask())
const types::global_dof_index invalid_dof_index
bool is_constrained(const size_type 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()