16 #include <deal.II/base/std_cxx1x/array.h> 17 #include <deal.II/base/thread_management.h> 18 #include <deal.II/base/table.h> 19 #include <deal.II/base/template_constraints.h> 20 #include <deal.II/base/utilities.h> 21 #include <deal.II/base/work_stream.h> 22 #include <deal.II/lac/vector.h> 23 #include <deal.II/lac/constraint_matrix.h> 24 #include <deal.II/grid/tria.h> 25 #include <deal.II/grid/tria_iterator.h> 26 #include <deal.II/grid/intergrid_map.h> 27 #include <deal.II/grid/grid_tools.h> 28 #include <deal.II/dofs/dof_handler.h> 29 #include <deal.II/dofs/dof_accessor.h> 30 #include <deal.II/fe/fe.h> 31 #include <deal.II/fe/fe_values.h> 32 #include <deal.II/fe/fe_tools.h> 33 #include <deal.II/hp/fe_collection.h> 34 #include <deal.II/hp/fe_values.h> 35 #include <deal.II/dofs/dof_tools.h> 37 #ifdef DEAL_II_WITH_MPI 38 #include <deal.II/lac/la_parallel_vector.h> 44 DEAL_II_NAMESPACE_OPEN
56 const std::vector<types::global_dof_index> &master_dof_list)
58 const unsigned int N = master_dof_list.size();
61 for (
unsigned int i=0; i<N; ++i)
62 for (
unsigned int j=0; j<N; ++j)
63 tmp(i,j) = face_interpolation_matrix (master_dof_list[i], j);
76 double diagonal_sum = 0;
77 for (
unsigned int i=0; i<N; ++i)
78 diagonal_sum += std::fabs(tmp(i,i));
79 const double typical_diagonal_element = diagonal_sum/N;
83 std::vector<unsigned int> p(N);
84 for (
unsigned int i=0; i<N; ++i)
87 for (
unsigned int j=0; j<N; ++j)
91 double max = std::fabs(tmp(j,j));
93 for (
unsigned int i=j+1; i<N; ++i)
95 if (std::fabs(tmp(i,j)) > max)
97 max = std::fabs(tmp(i,j));
104 if (max < 1.e-12*typical_diagonal_element)
110 for (
unsigned int k=0; k<N; ++k)
111 std::swap (tmp(j,k), tmp(r,k));
113 std::swap (p[j], p[r]);
117 const double hr = 1./tmp(j,j);
119 for (
unsigned int k=0; k<N; ++k)
122 for (
unsigned int i=0; i<N; ++i)
125 tmp(i,k) -= tmp(i,j)*tmp(j,k)*hr;
128 for (
unsigned int i=0; i<N; ++i)
164 template <
int dim,
int spacedim>
169 std::vector<bool> &master_dof_mask)
205 std::vector<types::global_dof_index> master_dof_list;
206 unsigned int index = 0;
211 unsigned int dofs_added = 0;
222 master_dof_list.push_back (index+i);
225 if (check_master_dof_list (face_interpolation_matrix,
232 master_dof_list.pop_back ();
245 unsigned int dofs_added = 0;
252 master_dof_list.push_back (index+i);
253 if (check_master_dof_list (face_interpolation_matrix,
258 master_dof_list.pop_back ();
270 unsigned int dofs_added = 0;
277 master_dof_list.push_back (index+i);
278 if (check_master_dof_list (face_interpolation_matrix,
283 master_dof_list.pop_back ();
294 std::fill (master_dof_mask.begin(), master_dof_mask.end(),
false);
295 for (std::vector<types::global_dof_index>::const_iterator i=master_dof_list.begin();
296 i!=master_dof_list.end(); ++i)
297 master_dof_mask[*i] =
true;
306 template <
int dim,
int spacedim>
311 std_cxx11::shared_ptr<std::vector<bool> > &master_dof_mask)
313 if (master_dof_mask == std_cxx11::shared_ptr<std::vector<bool> >())
315 master_dof_mask = std_cxx11::shared_ptr<std::vector<bool> >
317 select_master_dofs_for_face_restriction (fe1,
319 face_interpolation_matrix,
332 template <
int dim,
int spacedim>
340 matrix = std_cxx11::shared_ptr<FullMatrix<double> >
353 template <
int dim,
int spacedim>
357 const unsigned int subface,
362 matrix = std_cxx11::shared_ptr<FullMatrix<double> >
379 ensure_existence_of_split_face_matrix (
const FullMatrix<double> &face_interpolation_matrix,
380 const std::vector<bool> &master_dof_mask,
384 Assert (std::count (master_dof_mask.begin(), master_dof_mask.end(),
true) ==
385 static_cast<signed int>(face_interpolation_matrix.
n()),
395 const unsigned int n_master_dofs = face_interpolation_matrix.
n();
396 const unsigned int n_dofs = face_interpolation_matrix.
m();
403 split_matrix->first.reinit (n_master_dofs, n_master_dofs);
404 split_matrix->second.reinit (n_dofs-n_master_dofs, n_master_dofs);
406 unsigned int nth_master_dof = 0,
409 for (
unsigned int i=0; i<n_dofs; ++i)
410 if (master_dof_mask[i] ==
true)
412 for (
unsigned int j=0; j<n_master_dofs; ++j)
413 split_matrix->first(nth_master_dof,j)
414 = face_interpolation_matrix(i,j);
419 for (
unsigned int j=0; j<n_master_dofs; ++j)
420 split_matrix->second(nth_slave_dof,j)
421 = face_interpolation_matrix(i,j);
429 split_matrix->first.gauss_jordan ();
437 struct DoFHandlerSupportsDifferentFEs
439 static const bool value =
true;
443 template <
int dim,
int spacedim>
444 struct DoFHandlerSupportsDifferentFEs< ::
DoFHandler<dim,spacedim> >
446 static const bool value =
false;
455 template <
int dim,
int spacedim>
457 n_finite_elements (const ::hp::DoFHandler<dim,spacedim> &dof_handler)
459 return dof_handler.get_fe().size();
463 template <
typename DoFHandlerType>
465 n_finite_elements (
const DoFHandlerType &)
483 filter_constraints (
const std::vector<types::global_dof_index> &master_dofs,
484 const std::vector<types::global_dof_index> &slave_dofs,
488 Assert (face_constraints.
n () == master_dofs.size (),
490 face_constraints.
n()));
491 Assert (face_constraints.
m () == slave_dofs.size (),
493 face_constraints.
m()));
495 const unsigned int n_master_dofs = master_dofs.size ();
496 const unsigned int n_slave_dofs = slave_dofs.size ();
500 for (
unsigned int row=0; row!=n_slave_dofs; ++row)
503 for (
unsigned int col=0; col!=n_master_dofs; ++col)
508 for (
unsigned int row=0; row!=n_slave_dofs; ++row)
511 bool constraint_already_satisfied =
false;
516 for (
unsigned int i=0; i<n_master_dofs; ++i)
517 if (face_constraints (row,i) == 1.0)
518 if (master_dofs[i] == slave_dofs[row])
520 constraint_already_satisfied =
true;
524 if (constraint_already_satisfied ==
false)
529 for (
unsigned int i=0; i<n_master_dofs; ++i)
530 abs_sum += std::abs (face_constraints(row,i));
539 constraints.
add_line (slave_dofs[row]);
540 for (
unsigned int i=0; i<n_master_dofs; ++i)
541 if ((face_constraints(row,i) != 0)
543 (std::fabs(face_constraints(row,i)) >= 1e-14*abs_sum))
546 face_constraints (row,i));
557 make_hp_hanging_node_constraints (const ::DoFHandler<1> &,
566 make_oldstyle_hanging_node_constraints (const ::DoFHandler<1> &,
575 make_hp_hanging_node_constraints (const ::hp::DoFHandler<1> &,
587 make_oldstyle_hanging_node_constraints (const ::hp::DoFHandler<1> &,
599 make_hp_hanging_node_constraints (const ::DoFHandler<1,2> &,
608 make_oldstyle_hanging_node_constraints (const ::DoFHandler<1,2> &,
617 make_hp_hanging_node_constraints (const ::DoFHandler<1,3> &,
624 make_oldstyle_hanging_node_constraints (const ::DoFHandler<1,3> &,
670 template <
typename DoFHandlerType>
672 make_oldstyle_hanging_node_constraints (
const DoFHandlerType &dof_handler,
676 const unsigned int dim = 2;
678 const unsigned int spacedim = DoFHandlerType::space_dimension;
680 std::vector<types::global_dof_index> dofs_on_mother;
681 std::vector<types::global_dof_index> dofs_on_children;
692 typename DoFHandlerType::active_cell_iterator cell = dof_handler.begin_active(),
693 endc = dof_handler.end();
694 for (; cell!=endc; ++cell)
698 if (cell->is_artificial ())
701 for (
unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
702 if (cell->face(face)->has_children())
708 Assert (cell->face(face)->n_active_fe_indices() == 1,
710 Assert (cell->face(face)->fe_index_is_active(cell->active_fe_index())
713 for (
unsigned int c=0; c<cell->face(face)->n_children(); ++c)
714 if (!cell->neighbor_child_on_subface(face,c)->is_artificial())
715 Assert (cell->face(face)->child(c)->n_active_fe_indices() == 1,
720 for (
unsigned int c=0; c<cell->face(face)->n_children(); ++c)
721 if (!cell->neighbor_child_on_subface(face,c)->is_artificial())
722 Assert (cell->face(face)->child(c)
723 ->fe_index_is_active(cell->active_fe_index()) ==
true,
728 const unsigned int fe_index = cell->active_fe_index();
734 dofs_on_mother.resize (n_dofs_on_mother);
737 dofs_on_children.clear();
738 dofs_on_children.reserve (n_dofs_on_children);
747 const typename DoFHandlerType::line_iterator this_face = cell->face(face);
751 unsigned int next_index = 0;
752 for (
unsigned int vertex=0; vertex<2; ++vertex)
754 dofs_on_mother[next_index++] = this_face->vertex_dof_index(vertex,dof,
757 dofs_on_mother[next_index++] = this_face->dof_index(dof, fe_index);
761 dofs_on_children.push_back(
762 this_face->child(0)->vertex_dof_index(1,dof,fe_index));
763 for (
unsigned int child=0; child<2; ++child)
766 if (cell->neighbor_child_on_subface (face, child)->is_artificial())
769 dofs_on_children.push_back(
770 this_face->child(child)->dof_index(dof, fe_index));
776 for (
unsigned int row=0; row!=dofs_on_children.size(); ++row)
778 constraints.
add_line (dofs_on_children[row]);
779 for (
unsigned int i=0; i!=dofs_on_mother.size(); ++i)
780 constraints.
add_entry (dofs_on_children[row],
793 if (!cell->at_boundary(face) &&
794 !cell->neighbor(face)->is_artificial())
796 Assert (cell->face(face)->n_active_fe_indices() == 1,
799 ->fe_index_is_active(cell->active_fe_index()) ==
true,
808 template <
typename DoFHandlerType>
810 make_oldstyle_hanging_node_constraints (
const DoFHandlerType &dof_handler,
814 const unsigned int dim = 3;
816 std::vector<types::global_dof_index> dofs_on_mother;
817 std::vector<types::global_dof_index> dofs_on_children;
828 typename DoFHandlerType::active_cell_iterator cell = dof_handler.begin_active(),
829 endc = dof_handler.end();
830 for (; cell!=endc; ++cell)
834 if (cell->is_artificial ())
837 for (
unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
838 if (cell->face(face)->has_children())
843 if (cell->get_fe().dofs_per_face == 0)
854 Assert (cell->face(face)->fe_index_is_active(cell->active_fe_index())
857 for (
unsigned int c=0; c<cell->face(face)->n_children(); ++c)
858 AssertDimension (cell->face(face)->child(c)->n_active_fe_indices(), 1);
864 for (
unsigned int c=0; c<cell->face(face)->n_children(); ++c)
865 if (!cell->neighbor_child_on_subface(face,c)->is_artificial())
867 Assert (cell->face(face)->child(c)
868 ->fe_index_is_active(cell->active_fe_index()) ==
true,
870 for (
unsigned int e=0;
e<4; ++
e)
872 Assert (cell->face(face)->child(c)->line(e)
873 ->n_active_fe_indices() == 1,
875 Assert (cell->face(face)->child(c)->line(e)
876 ->fe_index_is_active(cell->active_fe_index()) ==
true,
880 for (
unsigned int e=0;
e<4; ++
e)
882 Assert (cell->face(face)->line(e)
883 ->n_active_fe_indices() == 1,
885 Assert (cell->face(face)->line(e)
886 ->fe_index_is_active(cell->active_fe_index()) ==
true,
892 const unsigned int fe_index = cell->active_fe_index();
901 dofs_on_mother.resize (n_dofs_on_mother);
904 dofs_on_children.clear();
905 dofs_on_children.reserve (n_dofs_on_children);
914 const typename DoFHandlerType::face_iterator this_face = cell->face(face);
918 unsigned int next_index = 0;
919 for (
unsigned int vertex=0; vertex<4; ++vertex)
921 dofs_on_mother[next_index++] = this_face->vertex_dof_index(vertex,dof,
923 for (
unsigned int line=0; line<4; ++line)
925 dofs_on_mother[next_index++]
926 = this_face->line(line)->dof_index(dof, fe_index);
928 dofs_on_mother[next_index++] = this_face->dof_index(dof, fe_index);
936 Assert (dof_handler.get_triangulation().get_anisotropic_refinement_flag() ||
937 ((this_face->child(0)->vertex_index(3) ==
938 this_face->child(1)->vertex_index(2)) &&
939 (this_face->child(0)->vertex_index(3) ==
940 this_face->child(2)->vertex_index(1)) &&
941 (this_face->child(0)->vertex_index(3) ==
942 this_face->child(3)->vertex_index(0))),
946 dofs_on_children.push_back(
947 this_face->child(0)->vertex_dof_index(3,dof));
951 for (
unsigned int line=0; line<4; ++line)
953 dofs_on_children.push_back(
954 this_face->line(line)->child(0)->vertex_dof_index(1,dof, fe_index));
960 dofs_on_children.push_back(
961 this_face->child(0)->line(1)->dof_index(dof, fe_index));
963 dofs_on_children.push_back(
964 this_face->child(2)->line(1)->dof_index(dof, fe_index));
966 dofs_on_children.push_back(
967 this_face->child(0)->line(3)->dof_index(dof, fe_index));
969 dofs_on_children.push_back(
970 this_face->child(1)->line(3)->dof_index(dof, fe_index));
973 for (
unsigned int line=0; line<4; ++line)
974 for (
unsigned int child=0; child<2; ++child)
977 dofs_on_children.push_back(
978 this_face->line(line)->child(child)->dof_index(dof, fe_index));
982 for (
unsigned int child=0; child<4; ++child)
985 if (cell->neighbor_child_on_subface (face, child)->is_artificial())
988 dofs_on_children.push_back(
989 this_face->child(child)->dof_index(dof, fe_index));
996 for (
unsigned int row=0; row!=dofs_on_children.size(); ++row)
998 constraints.
add_line (dofs_on_children[row]);
999 for (
unsigned int i=0; i!=dofs_on_mother.size(); ++i)
1000 constraints.
add_entry (dofs_on_children[row],
1013 if (!cell->at_boundary(face) &&
1014 !cell->neighbor(face)->is_artificial())
1016 Assert (cell->face(face)->n_active_fe_indices() == 1,
1019 ->fe_index_is_active(cell->active_fe_index()) ==
true,
1031 template <
int dim,
int spacedim>
1032 const ::hp::FECollection<dim,spacedim> *
1033 get_fe_collection (const ::hp::DoFHandler<dim,spacedim> &dof_handler)
1035 return &dof_handler.get_fe();
1038 template <
int dim,
int spacedim>
1039 const ::hp::FECollection<dim,spacedim> *
1040 get_fe_collection (const ::DoFHandler<dim,spacedim> &)
1048 template <
typename DoFHandlerType>
1050 make_hp_hanging_node_constraints (
const DoFHandlerType &dof_handler,
1058 const unsigned int dim = DoFHandlerType::dimension;
1060 const unsigned int spacedim = DoFHandlerType::space_dimension;
1070 std::vector<types::global_dof_index> master_dofs;
1071 std::vector<types::global_dof_index> slave_dofs;
1072 std::vector<types::global_dof_index> scratch_dofs;
1079 face_interpolation_matrices (n_finite_elements (dof_handler),
1080 n_finite_elements (dof_handler));
1082 subface_interpolation_matrices (n_finite_elements (dof_handler),
1083 n_finite_elements (dof_handler),
1091 split_face_interpolation_matrices (n_finite_elements (dof_handler),
1092 n_finite_elements (dof_handler));
1098 master_dof_masks (n_finite_elements (dof_handler),
1099 n_finite_elements (dof_handler));
1106 typename DoFHandlerType::active_cell_iterator cell = dof_handler.begin_active(),
1107 endc = dof_handler.end();
1108 for (; cell!=endc; ++cell)
1112 if (cell->is_artificial ())
1115 for (
unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
1116 if (cell->face(face)->has_children())
1121 if (cell->get_fe().dofs_per_face == 0)
1135 Assert (cell->face(face)->n_active_fe_indices() == 1,
1137 Assert (cell->face(face)->fe_index_is_active(cell->active_fe_index())
1140 for (
unsigned int c=0; c<cell->face(face)->n_children(); ++c)
1141 Assert (cell->face(face)->child(c)->n_active_fe_indices() == 1,
1157 std::set<unsigned int> fe_ind_face_subface;
1158 fe_ind_face_subface.insert(cell->active_fe_index());
1160 if (DoFHandlerSupportsDifferentFEs<DoFHandlerType>::value ==
true)
1161 for (
unsigned int c=0; c<cell->face(face)->number_of_children(); ++c)
1162 if (!cell->neighbor_child_on_subface (face, c)->is_artificial())
1164 mother_face_dominates = mother_face_dominates &
1165 (cell->get_fe().compare_for_face_domination
1166 (cell->neighbor_child_on_subface (face, c)->get_fe()));
1167 fe_ind_face_subface.insert(cell->neighbor_child_on_subface (face, c)->active_fe_index());
1170 switch (mother_face_dominates)
1182 master_dofs.resize (cell->get_fe().dofs_per_face);
1184 cell->face(face)->get_dof_indices (master_dofs,
1185 cell->active_fe_index ());
1191 for (
unsigned int c=0; c<cell->face(face)->n_children(); ++c)
1193 if (cell->neighbor_child_on_subface (face, c)->is_artificial())
1196 const typename DoFHandlerType::active_face_iterator
1197 subface = cell->face(face)->child(c);
1199 Assert (subface->n_active_fe_indices() == 1,
1203 subface_fe_index = subface->nth_active_fe_index(0);
1214 if (cell->get_fe().compare_for_face_domination
1215 (subface->get_fe(subface_fe_index))
1222 slave_dofs.resize (subface->get_fe(subface_fe_index)
1224 subface->get_dof_indices (slave_dofs, subface_fe_index);
1226 for (
unsigned int i=0; i<slave_dofs.size(); ++i)
1252 ensure_existence_of_subface_matrix
1254 subface->get_fe(subface_fe_index),
1256 subface_interpolation_matrices
1257 [cell->active_fe_index()][subface_fe_index][c]);
1260 filter_constraints (master_dofs,
1262 *(subface_interpolation_matrices
1263 [cell->active_fe_index()][subface_fe_index][c]),
1280 Assert (DoFHandlerSupportsDifferentFEs<DoFHandlerType>::value ==
true,
1283 const ::hp::FECollection<dim,spacedim> &fe_collection =
1284 *internal::get_fe_collection (dof_handler);
1304 const unsigned int dominating_fe_index = fe_collection.find_least_face_dominating_fe(fe_ind_face_subface);
1306 ExcMessage(
"Could not find a least face dominating FE."));
1309 = dof_handler.get_fe()[dominating_fe_index];
1314 cell->get_fe().dofs_per_face,
1317 ensure_existence_of_face_matrix
1320 face_interpolation_matrices
1321 [dominating_fe_index][cell->active_fe_index()]);
1325 ensure_existence_of_master_dof_mask
1328 (*face_interpolation_matrices
1329 [dominating_fe_index]
1330 [cell->active_fe_index()]),
1332 [dominating_fe_index]
1333 [cell->active_fe_index()]);
1335 ensure_existence_of_split_face_matrix
1336 (*face_interpolation_matrices
1337 [dominating_fe_index][cell->active_fe_index()],
1339 [dominating_fe_index][cell->active_fe_index()]),
1340 split_face_interpolation_matrices
1341 [dominating_fe_index][cell->active_fe_index()]);
1344 = (split_face_interpolation_matrices
1345 [dominating_fe_index][cell->active_fe_index()]->first);
1348 = (split_face_interpolation_matrices
1349 [dominating_fe_index][cell->active_fe_index()]->second);
1353 constraint_matrix.
reinit (cell->get_fe().dofs_per_face -
1356 restrict_mother_to_virtual_slave
1357 .
mmult (constraint_matrix,
1358 restrict_mother_to_virtual_master_inv);
1362 scratch_dofs.resize (cell->get_fe().dofs_per_face);
1363 cell->face(face)->get_dof_indices (scratch_dofs,
1364 cell->active_fe_index ());
1367 master_dofs.clear ();
1368 slave_dofs.clear ();
1369 for (
unsigned int i=0; i<cell->get_fe().dofs_per_face; ++i)
1370 if ((*master_dof_masks
1371 [dominating_fe_index][cell->active_fe_index()])[i] ==
true)
1372 master_dofs.push_back (scratch_dofs[i]);
1374 slave_dofs.push_back (scratch_dofs[i]);
1378 cell->get_fe().dofs_per_face - dominating_fe.
dofs_per_face);
1380 filter_constraints (master_dofs,
1389 for (
unsigned int sf=0;
1390 sf<cell->face(face)->n_children(); ++sf)
1394 if (cell->neighbor_child_on_subface (face, sf)->is_artificial()
1396 (dim==2 && cell->is_ghost()
1398 cell->neighbor_child_on_subface (face, sf)->is_ghost()))
1401 Assert (cell->face(face)->child(sf)
1402 ->n_active_fe_indices() == 1,
1405 const unsigned int subface_fe_index
1406 = cell->face(face)->child(sf)->nth_active_fe_index(0);
1408 = dof_handler.get_fe()[subface_fe_index];
1415 ensure_existence_of_subface_matrix
1419 subface_interpolation_matrices
1420 [dominating_fe_index][subface_fe_index][sf]);
1423 = *(subface_interpolation_matrices
1424 [dominating_fe_index][subface_fe_index][sf]);
1429 restrict_subface_to_virtual
1430 .
mmult (constraint_matrix,
1431 restrict_mother_to_virtual_master_inv);
1434 cell->face(face)->child(sf)->get_dof_indices (slave_dofs,
1437 filter_constraints (master_dofs,
1461 ->fe_index_is_active(cell->active_fe_index()) ==
true,
1468 if (!cell->at_boundary(face)
1470 cell->neighbor(face)->is_artificial())
1476 if ((DoFHandlerSupportsDifferentFEs<DoFHandlerType>::value ==
true)
1478 !cell->face(face)->at_boundary ()
1480 (cell->neighbor(face)->active_fe_index () !=
1481 cell->active_fe_index ())
1483 (!cell->face(face)->has_children() &&
1484 !cell->neighbor_is_coarser(face) ))
1486 const typename DoFHandlerType::level_cell_iterator neighbor = cell->neighbor (face);
1489 switch (cell->get_fe().compare_for_face_domination (neighbor->get_fe ()))
1495 master_dofs.resize (cell->get_fe().dofs_per_face);
1496 cell->face(face)->get_dof_indices (master_dofs,
1497 cell->active_fe_index ());
1499 slave_dofs.resize (neighbor->get_fe().dofs_per_face);
1500 cell->face(face)->get_dof_indices (slave_dofs,
1501 neighbor->active_fe_index ());
1506 if (master_dofs.size() == 0)
break;
1510 ensure_existence_of_face_matrix
1513 face_interpolation_matrices
1514 [cell->active_fe_index()][neighbor->active_fe_index()]);
1517 filter_constraints (master_dofs,
1519 *(face_interpolation_matrices
1520 [cell->active_fe_index()]
1521 [neighbor->active_fe_index()]),
1564 if (cell < neighbor)
1578 const unsigned int this_fe_index = cell->active_fe_index();
1579 const unsigned int neighbor_fe_index = neighbor->active_fe_index();
1580 std::set<unsigned int> fes;
1581 fes.insert(this_fe_index);
1582 fes.insert(neighbor_fe_index);
1583 const ::hp::FECollection<dim,spacedim> &fe_collection =
1584 *internal::get_fe_collection (dof_handler);
1585 const unsigned int dominating_fe_index = fe_collection.find_least_face_dominating_fe(fes);
1588 ExcMessage(
"Could not find the dominating FE for " 1589 +cell->get_fe().get_name()
1591 +neighbor->get_fe().get_name()
1592 +
" inside FECollection."));
1602 cell->get_fe().dofs_per_face,
1605 ensure_existence_of_face_matrix
1608 face_interpolation_matrices
1609 [dominating_fe_index][cell->active_fe_index()]);
1613 ensure_existence_of_master_dof_mask
1616 (*face_interpolation_matrices
1617 [dominating_fe_index]
1618 [cell->active_fe_index()]),
1620 [dominating_fe_index]
1621 [cell->active_fe_index()]);
1623 ensure_existence_of_split_face_matrix
1624 (*face_interpolation_matrices
1625 [dominating_fe_index][cell->active_fe_index()],
1627 [dominating_fe_index][cell->active_fe_index()]),
1628 split_face_interpolation_matrices
1629 [dominating_fe_index][cell->active_fe_index()]);
1632 = (split_face_interpolation_matrices
1633 [dominating_fe_index][cell->active_fe_index()]->first);
1636 = (split_face_interpolation_matrices
1637 [dominating_fe_index][cell->active_fe_index()]->second);
1641 constraint_matrix.
reinit (cell->get_fe().dofs_per_face -
1644 restrict_mother_to_virtual_slave
1645 .
mmult (constraint_matrix,
1646 restrict_mother_to_virtual_master_inv);
1650 scratch_dofs.resize (cell->get_fe().dofs_per_face);
1651 cell->face(face)->get_dof_indices (scratch_dofs,
1652 cell->active_fe_index ());
1655 master_dofs.clear ();
1656 slave_dofs.clear ();
1657 for (
unsigned int i=0; i<cell->get_fe().dofs_per_face; ++i)
1658 if ((*master_dof_masks
1659 [dominating_fe_index][cell->active_fe_index()])[i] ==
true)
1660 master_dofs.push_back (scratch_dofs[i]);
1662 slave_dofs.push_back (scratch_dofs[i]);
1666 cell->get_fe().dofs_per_face - dominating_fe.
dofs_per_face);
1668 filter_constraints (master_dofs,
1677 neighbor->get_fe().dofs_per_face,
1680 ensure_existence_of_face_matrix
1683 face_interpolation_matrices
1684 [dominating_fe_index][neighbor->active_fe_index()]);
1687 = *(face_interpolation_matrices
1688 [dominating_fe_index][neighbor->active_fe_index()]);
1690 constraint_matrix.
reinit (neighbor->get_fe().dofs_per_face,
1693 restrict_secondface_to_virtual
1694 .mmult (constraint_matrix,
1695 restrict_mother_to_virtual_master_inv);
1697 slave_dofs.resize (neighbor->get_fe().dofs_per_face);
1698 cell->face(face)->get_dof_indices (slave_dofs,
1699 neighbor->active_fe_index ());
1701 filter_constraints (master_dofs,
1728 template <
typename DoFHandlerType>
1737 if (dof_handler.get_fe().hp_constraints_are_implemented ())
1739 make_hp_hanging_node_constraints (dof_handler,
1743 make_oldstyle_hanging_node_constraints (dof_handler,
1775 template <
typename FaceIterator>
1777 set_periodicity_constraints (
const FaceIterator &face_1,
1778 const typename identity<FaceIterator>::type &face_2,
1782 const bool face_orientation,
1783 const bool face_flip,
1784 const bool face_rotation)
1786 static const int dim = FaceIterator::AccessorType::dimension;
1787 static const int spacedim = FaceIterator::AccessorType::space_dimension;
1790 Assert (!face_1->has_children(),
1793 Assert (face_1->n_active_fe_indices() == 1,
1797 if (face_2->has_children())
1801 const unsigned int dofs_per_face
1802 = face_1->get_fe(face_1->nth_active_fe_index(0)).dofs_per_face;
1805 for (
unsigned int c=0; c<face_2->n_children(); ++c)
1811 face_1->get_fe(face_1->nth_active_fe_index(0))
1812 .get_subface_interpolation_matrix (face_1->get_fe(face_1->nth_active_fe_index(0)),
1814 subface_interpolation);
1815 subface_interpolation.mmult (child_transformation, transformation);
1816 set_periodicity_constraints(face_1, face_2->child(c),
1817 child_transformation,
1818 constraint_matrix, component_mask,
1819 face_orientation, face_flip, face_rotation);
1825 const unsigned int face_1_index = face_1->nth_active_fe_index(0);
1826 const unsigned int face_2_index = face_2->nth_active_fe_index(0);
1827 Assert(face_1->get_fe(face_1_index) == face_2->get_fe(face_2_index),
1828 ExcMessage (
"Matching periodic cells need to use the same finite element"));
1833 ExcMessage (
"The number of components in the mask has to be either " 1834 "zero or equal to the number of components in the finite " "element."));
1836 const unsigned int dofs_per_face = fe.dofs_per_face;
1838 std::vector<types::global_dof_index> dofs_1(dofs_per_face);
1839 std::vector<types::global_dof_index> dofs_2(dofs_per_face);
1841 face_1->get_dof_indices(dofs_1, face_1_index);
1842 face_2->get_dof_indices(dofs_2, face_2_index);
1844 for (
unsigned int i=0; i < dofs_per_face; i++)
1884 std::map<unsigned int, unsigned int> cell_to_rotated_face_index;
1887 for (
unsigned int i = 0; i < dofs_per_face; ++i)
1889 const unsigned int cell_index = fe.face_to_cell_index(i, 0,
1894 cell_to_rotated_face_index[cell_index] = i;
1898 for (
unsigned int i=0; i<dofs_per_face; ++i)
1901 == fe.n_components())
1903 component_mask[fe.face_system_to_component_index(i).first])
1915 bool is_identity_constrained =
true;
1916 const double eps = 1.e-13;
1917 for (
unsigned int jj=0; jj<dofs_per_face; ++jj)
1918 if (((std::abs(transformation(i,jj)) < eps) ||
1919 (std::abs(transformation(i,jj)-1) < eps)) ==
false)
1921 is_identity_constrained =
false;
1925 if (is_identity_constrained ==
true)
1927 bool one_identity_found =
false;
1928 for (
unsigned int jj=0; jj<dofs_per_face; ++jj)
1929 if (std::abs(transformation(i,jj)-1.) <
eps)
1931 if (one_identity_found ==
false)
1933 one_identity_found =
true;
1934 identity_constraint_target = jj;
1938 is_identity_constrained =
false;
1945 bool is_inverse_constrained = !is_identity_constrained;
1947 if (is_inverse_constrained)
1948 for (
unsigned int jj=0; jj<dofs_per_face; ++jj)
1949 if (((std::abs(transformation(i,jj)) < eps) ||
1950 (std::abs(transformation(i,jj)+1) < eps)) ==
false)
1952 is_inverse_constrained =
false;
1955 if (is_inverse_constrained)
1957 bool one_identity_found =
false;
1958 for (
unsigned int jj=0; jj<dofs_per_face; ++jj)
1959 if (std::abs(transformation(i,jj)+1) <
eps)
1961 if (one_identity_found ==
false)
1963 one_identity_found =
true;
1964 inverse_constraint_target = jj;
1968 is_inverse_constrained =
false;
1975 const unsigned int target = is_identity_constrained
1976 ? identity_constraint_target
1977 : inverse_constraint_target;
1982 bool constrained_set =
false;
1983 for (
unsigned int j=0; j<dofs_per_face; ++j)
1985 if (dofs_2[i] == dofs_1[j])
1986 if (!(is_identity_constrained && target==i))
1988 constraint_matrix.
add_line(dofs_2[i]);
1989 constrained_set =
true;
1993 if (!constrained_set)
1997 if (is_identity_constrained ==
true || is_inverse_constrained ==
true)
2001 const unsigned int j
2002 = cell_to_rotated_face_index[fe.face_to_cell_index(target,
2006 face_orientation, face_flip, face_rotation)];
2011 bool enter_constraint =
false;
2014 if (dofs_2[i] != dofs_1[j])
2015 enter_constraint =
true;
2019 const std::vector<std::pair<types::global_dof_index, double > > *constraint_entries
2021 if (constraint_entries->size()==1 && (*constraint_entries)[0].first == dofs_2[i])
2023 if ((is_identity_constrained && std::abs((*constraint_entries)[0].second-1) > eps) ||
2024 (is_inverse_constrained && std::abs((*constraint_entries)[0].second+1) >
eps))
2027 constraint_matrix.
add_line(dofs_2[i]);
2031 enter_constraint =
true;
2034 if (enter_constraint)
2036 constraint_matrix.
add_line(dofs_2[i]);
2037 constraint_matrix.
add_entry(dofs_2[i], dofs_1[j], is_identity_constrained?1.0:-1.0);
2043 constraint_matrix.
add_line(dofs_2[i]);
2044 for (
unsigned int jj=0; jj<dofs_per_face; ++jj)
2048 const unsigned int j =
2049 cell_to_rotated_face_index[fe.face_to_cell_index
2050 (jj, 0, face_orientation, face_flip, face_rotation)];
2053 if (transformation(i,jj) != 0)
2054 constraint_matrix.
add_entry(dofs_2[i], dofs_1[j],
2055 transformation(i,jj));
2069 template<
int dim,
int spacedim>
2073 const std::vector<unsigned int> &first_vector_components)
2079 if (matrix.m() == n_dofs_per_face)
2086 if (first_vector_components.empty() && matrix.m() == 0)
2102 typedef std_cxx1x::array<unsigned int, spacedim> DoFTuple;
2107 for (
unsigned int i=0; i < n_dofs_per_face; ++i)
2109 std::vector<unsigned int>::const_iterator comp_it
2110 = std::find (first_vector_components.begin(),
2111 first_vector_components.end(),
2113 if (comp_it != first_vector_components.end())
2115 const unsigned int first_vector_component = *comp_it;
2118 DoFTuple vector_dofs;
2120 unsigned int n_found = 1;
2123 ExcMessage(
"Error: the finite element does not have enough components " 2124 "to define rotated periodic boundaries."));
2126 for (
unsigned int k = 0; k < n_dofs_per_face; ++k)
2128 (quadrature.point(k) == quadrature.point(i)) &&
2130 first_vector_component) &&
2132 first_vector_component + spacedim))
2135 first_vector_component]
2144 for (
int i = 0; i < spacedim; ++i)
2146 transformation[vector_dofs[i]][vector_dofs[i]] = 0.;
2147 for (
int j = 0; j < spacedim; ++j)
2148 transformation[vector_dofs[i]][vector_dofs[j]] = matrix[i][j];
2152 return transformation;
2161 template <
typename FaceIterator>
2164 const typename identity<FaceIterator>::type &face_2,
2167 const bool face_orientation,
2168 const bool face_flip,
2169 const bool face_rotation,
2171 const std::vector<unsigned int> &first_vector_components)
2173 static const int dim = FaceIterator::AccessorType::dimension;
2174 static const int spacedim = FaceIterator::AccessorType::space_dimension;
2177 (face_orientation ==
true &&
2178 face_flip ==
false &&
2179 face_rotation ==
false),
2181 "(face_orientation, face_flip, face_rotation) " 2182 "is invalid for 1D"));
2185 (face_orientation ==
true &&
2186 face_rotation ==
false),
2188 "(face_orientation, face_flip, face_rotation) " 2189 "is invalid for 2D"));
2192 ExcMessage (
"face_1 and face_2 are equal! Cannot constrain DoFs " 2193 "on the very same face"));
2195 Assert(face_1->at_boundary() && face_2->at_boundary(),
2196 ExcMessage (
"Faces for periodicity constraints must be on the " 2199 Assert(matrix.m() == matrix.n(),
2200 ExcMessage(
"The supplied (rotation or interpolation) matrix must " 2201 "be a square matrix"));
2203 Assert(first_vector_components.empty() || matrix.m() == (int)spacedim,
2204 ExcMessage (
"first_vector_components is nonempty, so matrix must " 2205 "be a rotation matrix exactly of size spacedim"));
2208 if (!face_1->has_children())
2211 const unsigned int n_dofs_per_face =
2212 face_1->get_fe(face_1->nth_active_fe_index(0)).dofs_per_face;
2215 || (first_vector_components.empty() && matrix.m() == n_dofs_per_face)
2216 || (!first_vector_components.empty() && matrix.m() == (int)spacedim),
2217 ExcMessage (
"The matrix must have either size 0 or spacedim " 2218 "(if first_vector_components is nonempty) " 2219 "or the size must be equal to the # of DoFs on the face " 2220 "(if first_vector_components is empty)."));
2223 if (!face_2->has_children())
2226 const unsigned int n_dofs_per_face =
2227 face_2->get_fe(face_2->nth_active_fe_index(0)).dofs_per_face;
2230 || (first_vector_components.empty() && matrix.m() == n_dofs_per_face)
2231 || (!first_vector_components.empty() && matrix.m() == (int)spacedim),
2232 ExcMessage (
"The matrix must have either size 0 or spacedim " 2233 "(if first_vector_components is nonempty) " 2234 "or the size must be equal to the # of DoFs on the face " 2235 "(if first_vector_components is empty)."));
2242 static const int lookup_table_2d[2][2] =
2249 static const int lookup_table_3d[2][2][2][4] =
2268 if (face_1->has_children() && face_2->has_children())
2274 face_2->n_children() ==
2278 for (
unsigned int i = 0; i < GeometryInfo<dim>::max_children_per_face;
2286 j = lookup_table_2d[face_flip][i];
2289 j = lookup_table_3d[face_orientation][face_flip][face_rotation][i];
2303 first_vector_components);
2313 face_1->has_children()
2314 ? face_2->get_fe(face_2->nth_active_fe_index(0))
2315 : face_1->get_fe(face_1->nth_active_fe_index(0));
2322 if (n_dofs_per_face == 0)
2326 compute_transformation(fe, matrix, first_vector_components);
2328 if (! face_2->has_children())
2332 if (first_vector_components.empty() && matrix.m() == 0)
2334 set_periodicity_constraints(face_2,
2346 inverse.
invert(transformation);
2348 set_periodicity_constraints(face_2,
2369 set_periodicity_constraints(face_1,
2376 ? face_rotation ^ face_flip
2385 template<
typename DoFHandlerType>
2392 const std::vector<unsigned int> &first_vector_components)
2394 typedef std::vector<GridTools::PeriodicFacePair<typename DoFHandlerType::cell_iterator> >
2396 typename FaceVector::const_iterator it, end_periodic;
2397 it = periodic_faces.begin();
2398 end_periodic = periodic_faces.end();
2401 for (; it!=end_periodic; ++it)
2403 typedef typename DoFHandlerType::face_iterator FaceIterator;
2404 const FaceIterator face_1 = it->cell[0]->face(it->face_idx[0]);
2405 const FaceIterator face_2 = it->cell[1]->face(it->face_idx[1]);
2407 Assert(face_1->at_boundary() && face_2->at_boundary(),
2410 Assert (face_1 != face_2,
2423 first_vector_components);
2431 template<
typename DoFHandlerType>
2436 const int direction,
2440 static const int space_dim = DoFHandlerType::space_dimension;
2442 Assert (0<=direction && direction<space_dim,
2446 ExcMessage (
"The boundary indicators b_id1 and b_id2 must be" 2447 "different to denote different boundaries."));
2450 <
typename DoFHandlerType::cell_iterator> > matched_faces;
2456 make_periodicity_constraints<DoFHandlerType>
2457 (matched_faces, constraint_matrix, component_mask);
2462 template<
typename DoFHandlerType>
2466 const int direction,
2470 static const int dim = DoFHandlerType::dimension;
2471 static const int space_dim = DoFHandlerType::space_dimension;
2475 Assert (0<=direction && direction<space_dim,
2482 <
typename DoFHandlerType::cell_iterator> > matched_faces;
2488 make_periodicity_constraints<DoFHandlerType>
2489 (matched_faces, constraint_matrix, component_mask);
2501 template <
int dim,
int spacedim>
2504 unsigned int dofs_per_cell;
2505 std::vector<types::global_dof_index> parameter_dof_indices;
2506 #ifdef DEAL_II_WITH_MPI 2507 std::vector<::LinearAlgebra::distributed::Vector<double> > global_parameter_representation;
2509 std::vector<::Vector<double> > global_parameter_representation;
2521 template <
int dim,
int spacedim>
2522 void compute_intergrid_weights_3 (
2523 const typename ::DoFHandler<dim,spacedim>::active_cell_iterator &cell,
2524 const Assembler::Scratch &,
2525 Assembler::CopyData<dim,spacedim> ©_data,
2526 const unsigned int coarse_component,
2579 copy_data.parameter_dof_indices.resize(copy_data.dofs_per_cell);
2583 cell->get_dof_indices (copy_data.parameter_dof_indices);
2587 for (
unsigned int local_dof=0; local_dof<copy_data.dofs_per_cell; ++local_dof)
2593 const unsigned int local_parameter_dof
2596 copy_data.global_parameter_representation[local_parameter_dof] = 0.;
2601 coarse_to_fine_grid_map[cell]->
2602 set_dof_values_by_interpolation (parameter_dofs[local_parameter_dof],
2603 copy_data.global_parameter_representation[local_parameter_dof]);
2614 template <
int dim,
int spacedim>
2615 void copy_intergrid_weights_3(
const Assembler::CopyData<dim,spacedim> ©_data,
2616 const unsigned int coarse_component,
2618 const std::vector<types::global_dof_index> &weight_mapping,
2619 const bool is_called_in_parallel,
2620 std::vector<std::map<types::global_dof_index, float> > &weights)
2622 unsigned int pos = 0;
2623 for (
unsigned int local_dof=0; local_dof<copy_data.dofs_per_cell; ++local_dof)
2657 if (copy_data.global_parameter_representation[pos](i) != 0)
2660 wj = weight_mapping[i];
2661 weights[wi][wj] = copy_data.global_parameter_representation[pos](i);
2664 else if (!is_called_in_parallel)
2669 Assert (copy_data.global_parameter_representation[pos](i) == 0,
2685 template <
int dim,
int spacedim>
2687 compute_intergrid_weights_2 (
2688 const ::DoFHandler<dim,spacedim> &coarse_grid,
2689 const unsigned int coarse_component,
2692 const std::vector<types::global_dof_index> &weight_mapping,
2693 std::vector<std::map<types::global_dof_index,float> > &weights)
2695 Assembler::Scratch scratch;
2696 Assembler::CopyData<dim,spacedim> copy_data;
2698 unsigned int n_interesting_dofs = 0;
2699 for (
unsigned int local_dof=0; local_dof<coarse_grid.get_fe().dofs_per_cell; ++local_dof)
2700 if (coarse_grid.get_fe().system_to_component_index(local_dof).first
2703 ++n_interesting_dofs;
2705 copy_data.global_parameter_representation.resize(n_interesting_dofs);
2707 bool is_called_in_parallel =
false;
2708 for (
size_t i=0; i<copy_data.global_parameter_representation.size(); ++i)
2710 #ifdef DEAL_II_WITH_MPI 2711 MPI_Comm communicator = MPI_COMM_SELF;
2714 const typename ::parallel::Triangulation<dim, spacedim> &tria =
2715 dynamic_cast<const typename ::parallel::Triangulation<dim, spacedim>&
> 2716 (coarse_to_fine_grid_map.get_destination_grid().get_triangulation());
2717 communicator = tria.get_communicator ();
2718 is_called_in_parallel =
true;
2720 catch (std::bad_cast &exp)
2725 IndexSet locally_owned_dofs, locally_relevant_dofs;
2727 (coarse_to_fine_grid_map.get_destination_grid (), locally_owned_dofs);
2729 (coarse_to_fine_grid_map.get_destination_grid (), locally_relevant_dofs);
2731 copy_data.global_parameter_representation[i].reinit
2732 (locally_owned_dofs, locally_relevant_dofs, communicator);
2735 copy_data.global_parameter_representation[i].reinit (n_fine_dofs);
2741 std_cxx11::bind(&compute_intergrid_weights_3<dim,spacedim>,
2746 std_cxx11::cref(coarse_grid.get_fe()),
2747 std_cxx11::cref(coarse_to_fine_grid_map),
2748 std_cxx11::cref(parameter_dofs)),
2749 std_cxx11::bind(©_intergrid_weights_3<dim,spacedim>,
2752 std_cxx11::cref(coarse_grid.get_fe()),
2753 std_cxx11::cref(weight_mapping),
2754 is_called_in_parallel,
2755 std_cxx11::ref(weights)),
2759 #ifdef DEAL_II_WITH_MPI 2760 for (
size_t i=0; i<copy_data.global_parameter_representation.size(); ++i)
2761 copy_data.global_parameter_representation[i].update_ghost_values ();
2772 template <
int dim,
int spacedim>
2774 compute_intergrid_weights_1 (
2775 const ::DoFHandler<dim,spacedim> &coarse_grid,
2776 const unsigned int coarse_component,
2777 const ::DoFHandler<dim,spacedim> &fine_grid,
2778 const unsigned int fine_component,
2780 std::vector<std::map<types::global_dof_index, float> > &weights,
2781 std::vector<types::global_dof_index> &weight_mapping)
2785 &fine_fe = fine_grid.get_fe();
2789 n_fine_dofs = fine_grid.n_dofs();
2792 const unsigned int fine_dofs_per_cell = fine_fe.
dofs_per_cell;
2797 const unsigned int coarse_dofs_per_cell_component
2803 Assert (coarse_grid.get_triangulation().n_cells(0) == fine_grid.get_triangulation().n_cells(0),
2807 Assert (&coarse_to_fine_grid_map.get_source_grid() == &coarse_grid,
2809 Assert (&coarse_to_fine_grid_map.get_destination_grid() == &fine_grid,
2820 fine_fe.base_element (fine_fe.component_to_base_index(fine_component).first),
2826 for (typename ::DoFHandler<dim,spacedim>::active_cell_iterator
2827 cell=coarse_grid.begin_active();
2828 cell != coarse_grid.end(); ++cell)
2829 Assert (cell->level() <= coarse_to_fine_grid_map[cell]->level(),
2856 std::vector<::Vector<double> >
2857 parameter_dofs (coarse_dofs_per_cell_component,
2862 for (
unsigned int local_coarse_dof=0;
2863 local_coarse_dof<coarse_dofs_per_cell_component;
2865 for (
unsigned int fine_dof=0; fine_dof<fine_fe.dofs_per_cell; ++fine_dof)
2866 if (fine_fe.system_to_component_index(fine_dof)
2868 std::make_pair (fine_component, local_coarse_dof))
2870 parameter_dofs[local_coarse_dof](fine_dof) = 1.;
2877 unsigned int n_parameters_on_fine_grid=0;
2883 std::vector<bool> dof_is_interesting (fine_grid.n_dofs(),
false);
2884 std::vector<types::global_dof_index> local_dof_indices (fine_fe.dofs_per_cell);
2886 for (typename ::DoFHandler<dim,spacedim>::active_cell_iterator
2887 cell=fine_grid.begin_active();
2888 cell!=fine_grid.end(); ++cell)
2889 if (cell->is_locally_owned ())
2891 cell->get_dof_indices (local_dof_indices);
2892 for (
unsigned int i=0; i<fine_fe.dofs_per_cell; ++i)
2893 if (fine_fe.system_to_component_index(i).first == fine_component)
2894 dof_is_interesting[local_dof_indices[i]] =
true;
2897 n_parameters_on_fine_grid = std::count (dof_is_interesting.begin(),
2898 dof_is_interesting.end(),
2905 weights.resize (n_coarse_dofs);
2907 weight_mapping.clear ();
2912 std::vector<types::global_dof_index> local_dof_indices(fine_fe.dofs_per_cell);
2913 unsigned int next_free_index=0;
2914 for (typename ::DoFHandler<dim,spacedim>::active_cell_iterator
2915 cell=fine_grid.begin_active();
2916 cell != fine_grid.end(); ++cell)
2917 if (cell->is_locally_owned ())
2919 cell->get_dof_indices (local_dof_indices);
2920 for (
unsigned int i=0; i<fine_fe.dofs_per_cell; ++i)
2923 if ((fine_fe.system_to_component_index(i).first == fine_component) &&
2926 weight_mapping[local_dof_indices[i]] = next_free_index;
2931 Assert (next_free_index == n_parameters_on_fine_grid,
2943 compute_intergrid_weights_2 (coarse_grid, coarse_component,
2944 coarse_to_fine_grid_map, parameter_dofs,
2945 weight_mapping, weights);
2962 for (
unsigned int col=0; col<n_parameters_on_fine_grid; ++col)
2966 if (weights[row].find(col) != weights[row].end())
2967 sum += weights[row][col];
2968 Assert ((std::fabs(sum-1) < 1.e-12) ||
2974 return n_parameters_on_fine_grid;
2983 template <
int dim,
int spacedim>
2987 const unsigned int coarse_component,
2989 const unsigned int fine_component,
3014 std::vector<std::map<types::global_dof_index, float> > weights;
3020 std::vector<types::global_dof_index> weight_mapping;
3022 const unsigned int n_parameters_on_fine_grid
3023 = internal::compute_intergrid_weights_1 (coarse_grid, coarse_component,
3024 fine_grid, fine_component,
3025 coarse_to_fine_grid_map,
3026 weights, weight_mapping);
3027 (void)n_parameters_on_fine_grid;
3031 n_fine_dofs = fine_grid.
n_dofs();
3036 std::vector<bool> coarse_dof_is_parameter (coarse_grid.
n_dofs());
3039 std::vector<bool> mask (coarse_grid.
get_fe().n_components(),
3041 mask[coarse_component] =
true;
3057 if (coarse_dof_is_parameter[parameter_dof] ==
true)
3065 std::map<types::global_dof_index,float>::const_iterator i = weights[parameter_dof].begin();
3066 for (; i!=weights[parameter_dof].end(); ++i)
3076 for (; global_dof<weight_mapping.size(); ++global_dof)
3077 if (weight_mapping[global_dof] == static_cast<types::global_dof_index>(column))
3082 representants[parameter_dof] = global_dof;
3098 std::vector<std::pair<types::global_dof_index,double> > constraint_line;
3116 std::map<types::global_dof_index,float>::const_iterator
3117 col_entry = weights[0].end();
3118 for (; first_used_row<n_coarse_dofs; ++first_used_row)
3120 col_entry = weights[first_used_row].find(col);
3121 if (col_entry != weights[first_used_row].end())
3127 if ((col_entry->second == 1) &&
3128 (representants[first_used_row] == global_dof))
3139 constraint_line.clear ();
3142 const std::map<types::global_dof_index,float>::const_iterator
3143 j = weights[row].find(col);
3144 if ((j != weights[row].end()) && (j->second != 0))
3145 constraint_line.push_back (std::pair<types::global_dof_index,double>(representants[row],
3149 constraints.
add_entries (global_dof, constraint_line);
3155 template <
int dim,
int spacedim>
3159 const unsigned int coarse_component,
3161 const unsigned int fine_component,
3163 std::vector<std::map<types::global_dof_index, float> > &transfer_representation)
3186 std::vector<std::map<types::global_dof_index, float> > weights;
3192 std::vector<types::global_dof_index> weight_mapping;
3194 internal::compute_intergrid_weights_1 (coarse_grid, coarse_component,
3195 fine_grid, fine_component,
3196 coarse_to_fine_grid_map,
3197 weights, weight_mapping);
3201 = std::count_if (weight_mapping.begin(), weight_mapping.end(),
3205 std::vector<types::global_dof_index> inverse_weight_mapping (n_global_parm_dofs,
3217 inverse_weight_mapping[parameter_dof] = i;
3224 transfer_representation.clear ();
3225 transfer_representation.resize (n_rows);
3230 std::map<types::global_dof_index, float>::const_iterator j = weights[i].begin();
3231 for (; j!=weights[i].end(); ++j)
3236 transfer_representation[p][i] = j->second;
3243 template <
int dim,
int spacedim,
template <
int,
int>
class DoFHandlerType>
3251 ExcMessage (
"The number of components in the mask has to be either " 3252 "zero or equal to the number of components in the finite " 3255 const unsigned int n_components = DoFTools::n_components (dof);
3261 std::vector<types::global_dof_index> face_dofs;
3262 face_dofs.reserve (max_dofs_per_face(dof));
3264 std::vector<types::global_dof_index> cell_dofs;
3265 cell_dofs.reserve (max_dofs_per_cell(dof));
3267 typename DoFHandlerType<dim,spacedim>::active_cell_iterator
3268 cell = dof.begin_active(),
3270 for (; cell!=endc; ++cell)
3271 if (!cell->is_artificial()
3273 cell->at_boundary ())
3279 cell->get_dof_indices (cell_dofs);
3281 for (
unsigned int face_no = 0; face_no < GeometryInfo<dim>::faces_per_cell;
3284 const typename DoFHandlerType<dim,spacedim>::face_iterator face = cell->face(face_no);
3288 if (face->at_boundary ()
3292 (face->boundary_id() == boundary_id)))
3296 face->get_dof_indices (face_dofs, cell->active_fe_index());
3300 for (
unsigned int i=0; i<face_dofs.size(); ++i)
3304 const std::vector<types::global_dof_index>::iterator it_index_on_cell
3305 = std::find (cell_dofs.begin(), cell_dofs.end(), face_dofs[i]);
3307 const unsigned int index_on_cell = std::distance(cell_dofs.begin(),
3310 = cell->get_fe().get_nonzero_components (index_on_cell);
3312 for (
unsigned int c=0; c<n_components; ++c)
3313 if (nonzero_component_array[c] && component_mask[c])
3320 zero_boundary_constraints.
add_line (face_dofs[i]);
3329 template <
int dim,
int spacedim,
template <
int,
int>
class DoFHandlerType>
3336 zero_boundary_constraints, component_mask);
3346 #include "dof_tools_constraints.inst" 3350 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()
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)
const FiniteElement< dim, spacedim > & get_fe() const
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
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
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
unsigned char boundary_id
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()