16 #include <deal.II/base/quadrature_lib.h> 17 #include <deal.II/base/table.h> 18 #include <deal.II/base/template_constraints.h> 19 #include <deal.II/base/thread_management.h> 20 #include <deal.II/base/utilities.h> 22 #include <deal.II/distributed/shared_tria.h> 23 #include <deal.II/distributed/tria_base.h> 25 #include <deal.II/dofs/dof_accessor.h> 26 #include <deal.II/dofs/dof_handler.h> 27 #include <deal.II/dofs/dof_tools.h> 29 #include <deal.II/fe/fe.h> 30 #include <deal.II/fe/fe_tools.h> 31 #include <deal.II/fe/fe_values.h> 33 #include <deal.II/grid/grid_tools.h> 34 #include <deal.II/grid/intergrid_map.h> 35 #include <deal.II/grid/tria.h> 36 #include <deal.II/grid/tria_iterator.h> 38 #include <deal.II/hp/fe_collection.h> 39 #include <deal.II/hp/fe_values.h> 40 #include <deal.II/hp/q_collection.h> 42 #include <deal.II/lac/affine_constraints.h> 43 #include <deal.II/lac/block_sparsity_pattern.h> 44 #include <deal.II/lac/dynamic_sparsity_pattern.h> 45 #include <deal.II/lac/sparsity_pattern.h> 46 #include <deal.II/lac/trilinos_sparsity_pattern.h> 47 #include <deal.II/lac/vector.h> 49 #include <deal.II/numerics/vector_tools.h> 54 DEAL_II_NAMESPACE_OPEN
60 template <
typename DoFHandlerType,
61 typename SparsityPatternType,
65 SparsityPatternType & sparsity,
67 const bool keep_constrained_dofs,
73 Assert(sparsity.n_rows() == n_dofs,
75 Assert(sparsity.n_cols() == n_dofs,
81 Assert((dof.get_triangulation().locally_owned_subdomain() ==
85 dof.get_triangulation().locally_owned_subdomain()),
87 "For parallel::distributed::Triangulation objects and " 88 "associated DoF handler objects, asking for any subdomain other " 89 "than the locally owned one does not make sense."));
91 std::vector<types::global_dof_index> dofs_on_this_cell;
93 typename DoFHandlerType::active_cell_iterator cell = dof.begin_active(),
99 for (; cell != endc; ++cell)
101 (subdomain_id == cell->subdomain_id())) &&
102 cell->is_locally_owned())
104 const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
105 dofs_on_this_cell.resize(dofs_per_cell);
106 cell->get_dof_indices(dofs_on_this_cell);
113 keep_constrained_dofs);
119 template <
typename DoFHandlerType,
120 typename SparsityPatternType,
125 SparsityPatternType & sparsity,
127 const bool keep_constrained_dofs,
133 Assert(sparsity.n_rows() == n_dofs,
135 Assert(sparsity.n_cols() == n_dofs,
137 Assert(couplings.n_rows() == dof.get_fe(0).n_components(),
139 dof.get_fe(0).n_components()));
140 Assert(couplings.n_cols() == dof.get_fe(0).n_components(),
142 dof.get_fe(0).n_components()));
147 Assert((dof.get_triangulation().locally_owned_subdomain() ==
151 dof.get_triangulation().locally_owned_subdomain()),
153 "For parallel::distributed::Triangulation objects and " 154 "associated DoF handler objects, asking for any subdomain other " 155 "than the locally owned one does not make sense."));
158 DoFHandlerType::space_dimension> &fe_collection =
159 dof.get_fe_collection();
161 const std::vector<Table<2, Coupling>> dof_mask
166 std::vector<Table<2, bool>> bool_dof_mask(fe_collection.size());
167 for (
unsigned int f = 0; f < fe_collection.size(); ++f)
169 bool_dof_mask[f].reinit(
171 fe_collection[f].dofs_per_cell));
172 bool_dof_mask[f].fill(
false);
173 for (
unsigned int i = 0; i < fe_collection[f].dofs_per_cell; ++i)
174 for (
unsigned int j = 0; j < fe_collection[f].dofs_per_cell; ++j)
175 if (dof_mask[f](i, j) !=
none)
176 bool_dof_mask[f](i, j) =
true;
179 std::vector<types::global_dof_index> dofs_on_this_cell(
180 fe_collection.max_dofs_per_cell());
181 typename DoFHandlerType::active_cell_iterator cell = dof.begin_active(),
187 for (; cell != endc; ++cell)
189 (subdomain_id == cell->subdomain_id())) &&
190 cell->is_locally_owned())
192 const unsigned int fe_index = cell->active_fe_index();
193 const unsigned int dofs_per_cell =
194 fe_collection[fe_index].dofs_per_cell;
196 dofs_on_this_cell.resize(dofs_per_cell);
197 cell->get_dof_indices(dofs_on_this_cell);
205 keep_constrained_dofs,
206 bool_dof_mask[fe_index]);
212 template <
typename DoFHandlerType,
typename SparsityPatternType>
215 const DoFHandlerType &dof_col,
216 SparsityPatternType & sparsity)
223 Assert(sparsity.n_rows() == n_dofs_row,
225 Assert(sparsity.n_cols() == n_dofs_col,
233 constexpr
int dim = DoFHandlerType::dimension;
234 constexpr
int spacedim = DoFHandlerType::space_dimension;
236 &dof_row.get_triangulation()) !=
nullptr ||
238 &dof_col.get_triangulation()) !=
nullptr)
240 Assert(&dof_row.get_triangulation() == &dof_col.get_triangulation(),
241 ExcMessage(
"This function can only be used with with parallel " 242 "Triangulations when the Triangulations are equal."));
247 using cell_iterator =
typename DoFHandlerType::cell_iterator;
248 std::list<std::pair<cell_iterator, cell_iterator>> cell_list =
251 #ifdef DEAL_II_WITH_MPI 256 &dof_row.get_triangulation()) !=
nullptr ||
258 &dof_col.get_triangulation()) !=
nullptr)
261 dof_row.get_triangulation().locally_owned_subdomain();
262 Assert(this_subdomain_id ==
263 dof_col.get_triangulation().locally_owned_subdomain(),
269 [=](
const std::pair<cell_iterator, cell_iterator> &pair) {
270 return pair.first->subdomain_id() != this_subdomain_id ||
271 pair.second->subdomain_id() != this_subdomain_id;
277 for (
const auto &cell_pair : cell_list)
279 const cell_iterator cell_row = cell_pair.first;
280 const cell_iterator cell_col = cell_pair.second;
282 if (!cell_row->has_children() && !cell_col->has_children())
284 const unsigned int dofs_per_cell_row =
285 cell_row->get_fe().dofs_per_cell;
286 const unsigned int dofs_per_cell_col =
287 cell_col->get_fe().dofs_per_cell;
288 std::vector<types::global_dof_index> local_dof_indices_row(
290 std::vector<types::global_dof_index> local_dof_indices_col(
292 cell_row->get_dof_indices(local_dof_indices_row);
293 cell_col->get_dof_indices(local_dof_indices_col);
294 for (
unsigned int i = 0; i < dofs_per_cell_row; ++i)
295 sparsity.add_entries(local_dof_indices_row[i],
296 local_dof_indices_col.begin(),
297 local_dof_indices_col.end());
299 else if (cell_row->has_children())
301 const std::vector<typename DoFHandlerType::active_cell_iterator>
303 GridTools::get_active_child_cells<DoFHandlerType>(cell_row);
304 for (
unsigned int i = 0; i < child_cells.size(); i++)
306 const typename DoFHandlerType::cell_iterator cell_row_child =
308 const unsigned int dofs_per_cell_row =
309 cell_row_child->get_fe().dofs_per_cell;
310 const unsigned int dofs_per_cell_col =
311 cell_col->get_fe().dofs_per_cell;
312 std::vector<types::global_dof_index> local_dof_indices_row(
314 std::vector<types::global_dof_index> local_dof_indices_col(
316 cell_row_child->get_dof_indices(local_dof_indices_row);
317 cell_col->get_dof_indices(local_dof_indices_col);
318 for (
unsigned int r = 0; r < dofs_per_cell_row; ++r)
319 sparsity.add_entries(local_dof_indices_row[r],
320 local_dof_indices_col.begin(),
321 local_dof_indices_col.end());
326 std::vector<typename DoFHandlerType::active_cell_iterator>
328 GridTools::get_active_child_cells<DoFHandlerType>(cell_col);
329 for (
unsigned int i = 0; i < child_cells.size(); i++)
331 const typename DoFHandlerType::active_cell_iterator
332 cell_col_child = child_cells[i];
333 const unsigned int dofs_per_cell_row =
334 cell_row->get_fe().dofs_per_cell;
335 const unsigned int dofs_per_cell_col =
336 cell_col_child->get_fe().dofs_per_cell;
337 std::vector<types::global_dof_index> local_dof_indices_row(
339 std::vector<types::global_dof_index> local_dof_indices_col(
341 cell_row->get_dof_indices(local_dof_indices_row);
342 cell_col_child->get_dof_indices(local_dof_indices_col);
343 for (
unsigned int r = 0; r < dofs_per_cell_row; ++r)
344 sparsity.add_entries(local_dof_indices_row[r],
345 local_dof_indices_col.begin(),
346 local_dof_indices_col.end());
354 template <
typename DoFHandlerType,
typename SparsityPatternType>
357 const DoFHandlerType & dof,
358 const std::vector<types::global_dof_index> &dof_to_boundary_mapping,
359 SparsityPatternType & sparsity)
361 if (DoFHandlerType::dimension == 1)
368 boundary_ids[0] =
nullptr;
369 boundary_ids[1] =
nullptr;
370 make_boundary_sparsity_pattern<DoFHandlerType, SparsityPatternType>(
371 dof, boundary_ids, dof_to_boundary_mapping, sparsity);
382 if (sparsity.n_rows() != 0)
392 std::vector<types::global_dof_index> dofs_on_this_face;
400 typename DoFHandlerType::active_cell_iterator cell = dof.begin_active(),
402 for (; cell != endc; ++cell)
403 for (
unsigned int f = 0;
404 f < GeometryInfo<DoFHandlerType::dimension>::faces_per_cell;
406 if (cell->at_boundary(f))
408 const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
409 dofs_on_this_face.resize(dofs_per_face);
410 cell->face(f)->get_dof_indices(dofs_on_this_face,
411 cell->active_fe_index());
414 for (
unsigned int i = 0; i < dofs_per_face; ++i)
415 for (
unsigned int j = 0; j < dofs_per_face; ++j)
416 sparsity.add(dof_to_boundary_mapping[dofs_on_this_face[i]],
417 dof_to_boundary_mapping[dofs_on_this_face[j]]);
423 template <
typename DoFHandlerType,
424 typename SparsityPatternType,
428 const DoFHandlerType &dof,
432 const std::vector<types::global_dof_index> &dof_to_boundary_mapping,
433 SparsityPatternType & sparsity)
435 if (DoFHandlerType::dimension == 1)
438 for (
unsigned int direction = 0; direction < 2; ++direction)
441 if (boundary_ids.find(direction) == boundary_ids.end())
446 typename DoFHandlerType::level_cell_iterator cell = dof.begin(0);
447 while (!cell->at_boundary(direction))
448 cell = cell->neighbor(direction);
449 while (!cell->active())
450 cell = cell->child(direction);
452 const unsigned int dofs_per_vertex = cell->get_fe().dofs_per_vertex;
453 std::vector<types::global_dof_index> boundary_dof_boundary_indices(
457 for (
unsigned int i = 0; i < dofs_per_vertex; ++i)
458 boundary_dof_boundary_indices[i] =
459 dof_to_boundary_mapping[cell->vertex_dof_index(direction, i)];
461 for (
unsigned int i = 0; i < dofs_per_vertex; ++i)
462 sparsity.add_entries(boundary_dof_boundary_indices[i],
463 boundary_dof_boundary_indices.begin(),
464 boundary_dof_boundary_indices.end());
476 Assert(sparsity.n_rows() == dof.n_boundary_dofs(boundary_ids),
478 dof.n_boundary_dofs(boundary_ids)));
479 Assert(sparsity.n_cols() == dof.n_boundary_dofs(boundary_ids),
481 dof.n_boundary_dofs(boundary_ids)));
483 if (sparsity.n_rows() != 0)
493 std::vector<types::global_dof_index> dofs_on_this_face;
495 typename DoFHandlerType::active_cell_iterator cell = dof.begin_active(),
497 for (; cell != endc; ++cell)
498 for (
unsigned int f = 0;
499 f < GeometryInfo<DoFHandlerType::dimension>::faces_per_cell;
501 if (boundary_ids.find(cell->face(f)->boundary_id()) !=
504 const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
505 dofs_on_this_face.resize(dofs_per_face);
506 cell->face(f)->get_dof_indices(dofs_on_this_face,
507 cell->active_fe_index());
510 for (
unsigned int i = 0; i < dofs_per_face; ++i)
511 for (
unsigned int j = 0; j < dofs_per_face; ++j)
512 sparsity.add(dof_to_boundary_mapping[dofs_on_this_face[i]],
513 dof_to_boundary_mapping[dofs_on_this_face[j]]);
519 template <
typename DoFHandlerType,
520 typename SparsityPatternType,
524 SparsityPatternType & sparsity,
526 const bool keep_constrained_dofs,
541 Assert((dof.get_triangulation().locally_owned_subdomain() ==
545 dof.get_triangulation().locally_owned_subdomain()),
547 "For parallel::distributed::Triangulation objects and " 548 "associated DoF handler objects, asking for any subdomain other " 549 "than the locally owned one does not make sense."));
551 std::vector<types::global_dof_index> dofs_on_this_cell;
552 std::vector<types::global_dof_index> dofs_on_other_cell;
555 typename DoFHandlerType::active_cell_iterator cell = dof.begin_active(),
566 for (; cell != endc; ++cell)
568 (subdomain_id == cell->subdomain_id())) &&
569 cell->is_locally_owned())
571 const unsigned int n_dofs_on_this_cell = cell->get_fe().dofs_per_cell;
572 dofs_on_this_cell.resize(n_dofs_on_this_cell);
573 cell->get_dof_indices(dofs_on_this_cell);
580 keep_constrained_dofs);
582 for (
unsigned int face = 0;
583 face < GeometryInfo<DoFHandlerType::dimension>::faces_per_cell;
586 typename DoFHandlerType::face_iterator cell_face =
588 const bool periodic_neighbor = cell->has_periodic_neighbor(face);
589 if (!cell->at_boundary(face) || periodic_neighbor)
591 typename DoFHandlerType::level_cell_iterator neighbor =
592 cell->neighbor_or_periodic_neighbor(face);
598 if (DoFHandlerType::dimension == 1)
599 while (neighbor->has_children())
600 neighbor = neighbor->child(face == 0 ? 1 : 0);
602 if (neighbor->has_children())
604 for (
unsigned int sub_nr = 0;
605 sub_nr != cell_face->number_of_children();
608 const typename DoFHandlerType::level_cell_iterator
611 cell->periodic_neighbor_child_on_subface(
613 cell->neighbor_child_on_subface(face, sub_nr);
615 const unsigned int n_dofs_on_neighbor =
616 sub_neighbor->get_fe().dofs_per_cell;
617 dofs_on_other_cell.resize(n_dofs_on_neighbor);
618 sub_neighbor->get_dof_indices(dofs_on_other_cell);
624 keep_constrained_dofs);
629 keep_constrained_dofs);
633 if (sub_neighbor->subdomain_id() !=
634 cell->subdomain_id())
638 keep_constrained_dofs);
645 if ((!periodic_neighbor &&
646 cell->neighbor_is_coarser(face)) ||
647 (periodic_neighbor &&
648 cell->periodic_neighbor_is_coarser(face)))
649 if (neighbor->subdomain_id() == cell->subdomain_id())
652 const unsigned int n_dofs_on_neighbor =
653 neighbor->get_fe().dofs_per_cell;
654 dofs_on_other_cell.resize(n_dofs_on_neighbor);
656 neighbor->get_dof_indices(dofs_on_other_cell);
662 keep_constrained_dofs);
668 if (!cell->neighbor_or_periodic_neighbor(face)
670 (neighbor->subdomain_id() != cell->subdomain_id()))
676 keep_constrained_dofs);
677 if (neighbor->subdomain_id() != cell->subdomain_id())
681 keep_constrained_dofs);
691 template <
typename DoFHandlerType,
typename SparsityPatternType>
694 SparsityPatternType & sparsity)
700 template <
int dim,
int spacedim>
717 for (
unsigned int i = 0; i < n_dofs; ++i)
719 const unsigned int ii =
725 for (
unsigned int j = 0; j < n_dofs; ++j)
727 const unsigned int jj =
733 dof_couplings(i, j) = component_couplings(ii, jj);
736 return dof_couplings;
741 template <
int dim,
int spacedim>
742 std::vector<Table<2, Coupling>>
747 std::vector<Table<2, Coupling>> return_value(fe.
size());
748 for (
unsigned int i = 0; i < fe.
size(); ++i)
763 template <
typename DoFHandlerType,
764 typename SparsityPatternType,
768 SparsityPatternType & sparsity,
770 const bool keep_constrained_dofs,
776 DoFHandlerType::space_dimension> &fe = dof.get_fe();
778 std::vector<types::global_dof_index> dofs_on_this_cell(
780 std::vector<types::global_dof_index> dofs_on_other_cell(
790 for (
unsigned int i = 0; i < fe.dofs_per_cell; ++i)
791 for (
unsigned int f = 0;
792 f < GeometryInfo<DoFHandlerType::dimension>::faces_per_cell;
794 support_on_face(i, f) = fe.has_support_on_face(i, f);
798 Table<2, bool> bool_int_dof_mask(fe.dofs_per_cell, fe.dofs_per_cell);
799 bool_int_dof_mask.fill(
false);
800 for (
unsigned int i = 0; i < fe.dofs_per_cell; ++i)
801 for (
unsigned int j = 0; j < fe.dofs_per_cell; ++j)
802 if (int_dof_mask(i, j) !=
none)
803 bool_int_dof_mask(i, j) =
true;
805 typename DoFHandlerType::active_cell_iterator cell = dof.begin_active(),
807 for (; cell != endc; ++cell)
809 (subdomain_id == cell->subdomain_id())) &&
810 cell->is_locally_owned())
812 cell->get_dof_indices(dofs_on_this_cell);
816 keep_constrained_dofs,
819 for (
unsigned int face_n = 0;
824 const typename DoFHandlerType::face_iterator cell_face =
827 const bool periodic_neighbor =
828 cell->has_periodic_neighbor(face_n);
830 if (cell->at_boundary(face_n) && (!periodic_neighbor))
832 for (
unsigned int i = 0; i < fe.dofs_per_cell; ++i)
834 const bool i_non_zero_i = support_on_face(i, face_n);
835 for (
unsigned int j = 0; j < fe.dofs_per_cell; ++j)
837 const bool j_non_zero_i =
838 support_on_face(j, face_n);
840 if (flux_dof_mask(i, j) ==
always ||
841 (flux_dof_mask(i, j) ==
nonzero &&
842 i_non_zero_i && j_non_zero_i))
843 sparsity.add(dofs_on_this_cell[i],
844 dofs_on_this_cell[j]);
850 typename DoFHandlerType::level_cell_iterator neighbor =
851 cell->neighbor_or_periodic_neighbor(face_n);
856 if (neighbor->level() == cell->level() &&
857 neighbor->index() > cell->index() &&
858 neighbor->active() && neighbor->is_locally_owned())
871 if (neighbor->level() != cell->level() &&
872 ((!periodic_neighbor &&
873 !cell->neighbor_is_coarser(face_n)) ||
874 (periodic_neighbor &&
875 !cell->periodic_neighbor_is_coarser(face_n))) &&
876 neighbor->is_locally_owned())
879 const unsigned int neighbor_face_n =
881 cell->periodic_neighbor_face_no(face_n) :
882 cell->neighbor_face_no(face_n);
884 if (neighbor->has_children())
886 for (
unsigned int sub_nr = 0;
887 sub_nr != cell_face->n_children();
890 const typename DoFHandlerType::level_cell_iterator
893 cell->periodic_neighbor_child_on_subface(
895 cell->neighbor_child_on_subface(face_n,
898 sub_neighbor->get_dof_indices(dofs_on_other_cell);
899 for (
unsigned int i = 0; i < fe.dofs_per_cell;
902 const bool i_non_zero_i =
903 support_on_face(i, face_n);
904 const bool i_non_zero_e =
905 support_on_face(i, neighbor_face_n);
906 for (
unsigned int j = 0; j < fe.dofs_per_cell;
909 const bool j_non_zero_i =
910 support_on_face(j, face_n);
911 const bool j_non_zero_e =
912 support_on_face(j, neighbor_face_n);
914 if (flux_dof_mask(i, j) ==
always)
916 sparsity.add(dofs_on_this_cell[i],
917 dofs_on_other_cell[j]);
918 sparsity.add(dofs_on_other_cell[i],
919 dofs_on_this_cell[j]);
920 sparsity.add(dofs_on_this_cell[i],
921 dofs_on_this_cell[j]);
922 sparsity.add(dofs_on_other_cell[i],
923 dofs_on_other_cell[j]);
925 else if (flux_dof_mask(i, j) ==
nonzero)
927 if (i_non_zero_i && j_non_zero_e)
928 sparsity.add(dofs_on_this_cell[i],
929 dofs_on_other_cell[j]);
930 if (i_non_zero_e && j_non_zero_i)
931 sparsity.add(dofs_on_other_cell[i],
932 dofs_on_this_cell[j]);
933 if (i_non_zero_i && j_non_zero_i)
934 sparsity.add(dofs_on_this_cell[i],
935 dofs_on_this_cell[j]);
936 if (i_non_zero_e && j_non_zero_e)
937 sparsity.add(dofs_on_other_cell[i],
938 dofs_on_other_cell[j]);
941 if (flux_dof_mask(j, i) ==
always)
943 sparsity.add(dofs_on_this_cell[j],
944 dofs_on_other_cell[i]);
945 sparsity.add(dofs_on_other_cell[j],
946 dofs_on_this_cell[i]);
947 sparsity.add(dofs_on_this_cell[j],
948 dofs_on_this_cell[i]);
949 sparsity.add(dofs_on_other_cell[j],
950 dofs_on_other_cell[i]);
952 else if (flux_dof_mask(j, i) ==
nonzero)
954 if (j_non_zero_i && i_non_zero_e)
955 sparsity.add(dofs_on_this_cell[j],
956 dofs_on_other_cell[i]);
957 if (j_non_zero_e && i_non_zero_i)
958 sparsity.add(dofs_on_other_cell[j],
959 dofs_on_this_cell[i]);
960 if (j_non_zero_i && i_non_zero_i)
961 sparsity.add(dofs_on_this_cell[j],
962 dofs_on_this_cell[i]);
963 if (j_non_zero_e && i_non_zero_e)
964 sparsity.add(dofs_on_other_cell[j],
965 dofs_on_other_cell[i]);
973 neighbor->get_dof_indices(dofs_on_other_cell);
974 for (
unsigned int i = 0; i < fe.dofs_per_cell; ++i)
976 const bool i_non_zero_i =
977 support_on_face(i, face_n);
978 const bool i_non_zero_e =
979 support_on_face(i, neighbor_face_n);
980 for (
unsigned int j = 0; j < fe.dofs_per_cell;
983 const bool j_non_zero_i =
984 support_on_face(j, face_n);
985 const bool j_non_zero_e =
986 support_on_face(j, neighbor_face_n);
987 if (flux_dof_mask(i, j) ==
always)
989 sparsity.add(dofs_on_this_cell[i],
990 dofs_on_other_cell[j]);
991 sparsity.add(dofs_on_other_cell[i],
992 dofs_on_this_cell[j]);
993 sparsity.add(dofs_on_this_cell[i],
994 dofs_on_this_cell[j]);
995 sparsity.add(dofs_on_other_cell[i],
996 dofs_on_other_cell[j]);
998 if (flux_dof_mask(i, j) ==
nonzero)
1000 if (i_non_zero_i && j_non_zero_e)
1001 sparsity.add(dofs_on_this_cell[i],
1002 dofs_on_other_cell[j]);
1003 if (i_non_zero_e && j_non_zero_i)
1004 sparsity.add(dofs_on_other_cell[i],
1005 dofs_on_this_cell[j]);
1006 if (i_non_zero_i && j_non_zero_i)
1007 sparsity.add(dofs_on_this_cell[i],
1008 dofs_on_this_cell[j]);
1009 if (i_non_zero_e && j_non_zero_e)
1010 sparsity.add(dofs_on_other_cell[i],
1011 dofs_on_other_cell[j]);
1014 if (flux_dof_mask(j, i) ==
always)
1016 sparsity.add(dofs_on_this_cell[j],
1017 dofs_on_other_cell[i]);
1018 sparsity.add(dofs_on_other_cell[j],
1019 dofs_on_this_cell[i]);
1020 sparsity.add(dofs_on_this_cell[j],
1021 dofs_on_this_cell[i]);
1022 sparsity.add(dofs_on_other_cell[j],
1023 dofs_on_other_cell[i]);
1025 if (flux_dof_mask(j, i) ==
nonzero)
1027 if (j_non_zero_i && i_non_zero_e)
1028 sparsity.add(dofs_on_this_cell[j],
1029 dofs_on_other_cell[i]);
1030 if (j_non_zero_e && i_non_zero_i)
1031 sparsity.add(dofs_on_other_cell[j],
1032 dofs_on_this_cell[i]);
1033 if (j_non_zero_i && i_non_zero_i)
1034 sparsity.add(dofs_on_this_cell[j],
1035 dofs_on_this_cell[i]);
1036 if (j_non_zero_e && i_non_zero_e)
1037 sparsity.add(dofs_on_other_cell[j],
1038 dofs_on_other_cell[i]);
1053 typename SparsityPatternType,
1057 const ::hp::DoFHandler<dim, spacedim> &dof,
1058 SparsityPatternType & sparsity,
1060 const bool keep_constrained_dofs,
1072 const ::hp::FECollection<dim, spacedim> &fe =
1073 dof.get_fe_collection();
1075 std::vector<types::global_dof_index> dofs_on_this_cell(
1077 std::vector<types::global_dof_index> dofs_on_other_cell(
1092 if (int_mask(c1, c2) !=
none || flux_mask(c1, c2) !=
none)
1093 int_and_flux_mask(c1, c2) =
always;
1095 std::vector<Table<2, Coupling>> int_and_flux_dof_mask =
1100 std::vector<Table<2, bool>> bool_int_and_flux_dof_mask(fe.size());
1101 for (
unsigned int f = 0; f < fe.size(); ++f)
1103 bool_int_and_flux_dof_mask[f].reinit(
1105 bool_int_and_flux_dof_mask[f].fill(
false);
1106 for (
unsigned int i = 0; i < fe[f].dofs_per_cell; ++i)
1107 for (
unsigned int j = 0; j < fe[f].dofs_per_cell; ++j)
1108 if (int_and_flux_dof_mask[f](i, j) !=
none)
1109 bool_int_and_flux_dof_mask[f](i, j) =
true;
1113 typename ::hp::DoFHandler<dim, spacedim>::active_cell_iterator
1114 cell = dof.begin_active(),
1116 for (; cell != endc; ++cell)
1118 (subdomain_id == cell->subdomain_id())) &&
1119 cell->is_locally_owned())
1121 dofs_on_this_cell.resize(cell->get_fe().dofs_per_cell);
1122 cell->get_dof_indices(dofs_on_this_cell);
1129 keep_constrained_dofs,
1130 bool_int_and_flux_dof_mask[cell->active_fe_index()]);
1133 for (
unsigned int face = 0;
1134 face < GeometryInfo<dim>::faces_per_cell;
1137 const typename ::hp::DoFHandler<dim,
1138 spacedim>::face_iterator
1139 cell_face = cell->face(face);
1141 const bool periodic_neighbor =
1142 cell->has_periodic_neighbor(face);
1144 if ((!cell->at_boundary(face)) || periodic_neighbor)
1146 typename ::hp::DoFHandler<dim, spacedim>::
1147 level_cell_iterator neighbor =
1148 cell->neighbor_or_periodic_neighbor(face);
1154 if (neighbor->level() == cell->level() &&
1155 neighbor->index() > cell->index() &&
1156 neighbor->active() && neighbor->is_locally_owned())
1170 if (neighbor->level() != cell->level() &&
1171 ((!periodic_neighbor &&
1172 !cell->neighbor_is_coarser(face)) ||
1173 (periodic_neighbor &&
1174 !cell->periodic_neighbor_is_coarser(face))) &&
1175 neighbor->is_locally_owned())
1178 if (neighbor->has_children())
1180 for (
unsigned int sub_nr = 0;
1181 sub_nr != cell_face->n_children();
1184 const typename ::hp::DoFHandler<
1186 spacedim>::level_cell_iterator sub_neighbor =
1188 cell->periodic_neighbor_child_on_subface(
1190 cell->neighbor_child_on_subface(face, sub_nr);
1192 dofs_on_other_cell.resize(
1193 sub_neighbor->get_fe().dofs_per_cell);
1194 sub_neighbor->get_dof_indices(dofs_on_other_cell);
1195 for (
unsigned int i = 0;
1196 i < cell->get_fe().dofs_per_cell;
1199 const unsigned int ii =
1200 (cell->get_fe().is_primitive(i) ?
1202 .system_to_component_index(i)
1205 .get_nonzero_components(i)
1206 .first_selected_component());
1211 for (
unsigned int j = 0;
1212 j < sub_neighbor->get_fe().dofs_per_cell;
1215 const unsigned int jj =
1216 (sub_neighbor->get_fe().is_primitive(
1218 sub_neighbor->get_fe()
1219 .system_to_component_index(j)
1221 sub_neighbor->get_fe()
1222 .get_nonzero_components(j)
1223 .first_selected_component());
1225 Assert(jj < sub_neighbor->get_fe()
1229 if ((flux_mask(ii, jj) ==
always) ||
1230 (flux_mask(ii, jj) ==
nonzero))
1232 sparsity.add(dofs_on_this_cell[i],
1233 dofs_on_other_cell[j]);
1236 if ((flux_mask(jj, ii) ==
always) ||
1237 (flux_mask(jj, ii) ==
nonzero))
1239 sparsity.add(dofs_on_other_cell[j],
1240 dofs_on_this_cell[i]);
1248 dofs_on_other_cell.resize(
1249 neighbor->get_fe().dofs_per_cell);
1250 neighbor->get_dof_indices(dofs_on_other_cell);
1251 for (
unsigned int i = 0;
1252 i < cell->get_fe().dofs_per_cell;
1255 const unsigned int ii =
1256 (cell->get_fe().is_primitive(i) ?
1258 .system_to_component_index(i)
1261 .get_nonzero_components(i)
1262 .first_selected_component());
1267 for (
unsigned int j = 0;
1268 j < neighbor->get_fe().dofs_per_cell;
1271 const unsigned int jj =
1272 (neighbor->get_fe().is_primitive(j) ?
1274 .system_to_component_index(j)
1277 .get_nonzero_components(j)
1278 .first_selected_component());
1283 if ((flux_mask(ii, jj) ==
always) ||
1284 (flux_mask(ii, jj) ==
nonzero))
1286 sparsity.add(dofs_on_this_cell[i],
1287 dofs_on_other_cell[j]);
1290 if ((flux_mask(jj, ii) ==
always) ||
1291 (flux_mask(jj, ii) ==
nonzero))
1293 sparsity.add(dofs_on_other_cell[j],
1294 dofs_on_this_cell[i]);
1309 template <
typename DoFHandlerType,
typename SparsityPatternType>
1312 SparsityPatternType & sparsity,
1319 const bool keep_constrained_dofs =
true;
1324 keep_constrained_dofs,
1330 template <
typename DoFHandlerType,
1331 typename SparsityPatternType,
1335 SparsityPatternType & sparsity,
1337 const bool keep_constrained_dofs,
1346 const unsigned int n_comp = dof.get_fe(0).n_components();
1349 Assert(sparsity.n_rows() == n_dofs,
1351 Assert(sparsity.n_cols() == n_dofs,
1353 Assert(int_mask.n_rows() == n_comp,
1355 Assert(int_mask.n_cols() == n_comp,
1357 Assert(flux_mask.n_rows() == n_comp,
1359 Assert(flux_mask.n_cols() == n_comp,
1365 Assert((dof.get_triangulation().locally_owned_subdomain() ==
1369 dof.get_triangulation().locally_owned_subdomain()),
1371 "For parallel::distributed::Triangulation objects and " 1372 "associated DoF handler objects, asking for any subdomain other " 1373 "than the locally owned one does not make sense."));
1378 keep_constrained_dofs,
1390 #include "dof_tools_sparsity.inst" 1394 DEAL_II_NAMESPACE_CLOSE
#define AssertDimension(dim1, dim2)
const types::subdomain_id invalid_subdomain_id
void make_boundary_sparsity_pattern(const DoFHandlerType &dof, const std::vector< types::global_dof_index > &dof_to_boundary_mapping, SparsityPatternType &sparsity_pattern)
unsigned int size() const
bool is_primitive() const
static ::ExceptionBase & ExcMessage(std::string arg1)
unsigned int subdomain_id
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
const ComponentMask & get_nonzero_components(const unsigned int i) const
void make_flux_sparsity_pattern(const DoFHandlerType &dof_handler, SparsityPatternType &sparsity_pattern)
void add_entries_local_to_global(const std::vector< size_type > &local_dof_indices, SparsityPatternType &sparsity_pattern, const bool keep_constrained_entries=true, const Table< 2, bool > &dof_mask=Table< 2, bool >()) const
const unsigned int dofs_per_cell
unsigned int global_dof_index
size_type size(const unsigned int i) const
std::pair< unsigned int, unsigned int > system_to_component_index(const unsigned int index) const
unsigned int n_components() const
unsigned int first_selected_component(const unsigned int overall_number_of_components=numbers::invalid_unsigned_int) const
static ::ExceptionBase & ExcInvalidBoundaryIndicator()
const types::boundary_id internal_face_boundary_id
const types::global_dof_index invalid_dof_index
void make_sparsity_pattern(const DoFHandlerType &dof_handler, SparsityPatternType &sparsity_pattern, const AffineConstraints< number > &constraints=AffineConstraints< number >(), const bool keep_constrained_dofs=true, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id)
static ::ExceptionBase & ExcInternalError()