16 #include <deal.II/base/thread_management.h> 17 #include <deal.II/base/quadrature_lib.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/lac/sparsity_pattern.h> 22 #include <deal.II/lac/dynamic_sparsity_pattern.h> 23 #include <deal.II/lac/trilinos_sparsity_pattern.h> 24 #include <deal.II/lac/block_sparsity_pattern.h> 25 #include <deal.II/lac/vector.h> 26 #include <deal.II/lac/constraint_matrix.h> 27 #include <deal.II/grid/tria.h> 28 #include <deal.II/grid/tria_iterator.h> 29 #include <deal.II/grid/intergrid_map.h> 30 #include <deal.II/grid/grid_tools.h> 31 #include <deal.II/dofs/dof_handler.h> 32 #include <deal.II/dofs/dof_accessor.h> 33 #include <deal.II/fe/fe.h> 34 #include <deal.II/fe/fe_values.h> 35 #include <deal.II/fe/fe_tools.h> 36 #include <deal.II/hp/fe_collection.h> 37 #include <deal.II/hp/q_collection.h> 38 #include <deal.II/hp/fe_values.h> 39 #include <deal.II/dofs/dof_tools.h> 40 #include <deal.II/numerics/vector_tools.h> 46 DEAL_II_NAMESPACE_OPEN
53 template <
typename DoFHandlerType,
typename SparsityPatternType>
56 SparsityPatternType &sparsity,
58 const bool keep_constrained_dofs,
64 Assert (sparsity.n_rows() == n_dofs,
66 Assert (sparsity.n_cols() == n_dofs,
77 (subdomain_id == dof.get_triangulation().locally_owned_subdomain()),
78 ExcMessage (
"For parallel::distributed::Triangulation objects and " 79 "associated DoF handler objects, asking for any subdomain other " 80 "than the locally owned one does not make sense."));
82 std::vector<types::global_dof_index> dofs_on_this_cell;
84 typename DoFHandlerType::active_cell_iterator cell = dof.begin_active(),
90 for (; cell!=endc; ++cell)
93 (subdomain_id == cell->subdomain_id()))
95 cell->is_locally_owned())
97 const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
98 dofs_on_this_cell.resize (dofs_per_cell);
99 cell->get_dof_indices (dofs_on_this_cell);
106 keep_constrained_dofs);
112 template <
typename DoFHandlerType,
typename SparsityPatternType>
116 SparsityPatternType &sparsity,
118 const bool keep_constrained_dofs,
124 Assert (sparsity.n_rows() == n_dofs,
126 Assert (sparsity.n_cols() == n_dofs,
128 Assert (couplings.n_rows() == dof.get_fe(0).n_components(),
130 Assert (couplings.n_cols() == dof.get_fe(0).n_components(),
141 (subdomain_id == dof.get_triangulation().locally_owned_subdomain()),
142 ExcMessage (
"For parallel::distributed::Triangulation objects and " 143 "associated DoF handler objects, asking for any subdomain other " 144 "than the locally owned one does not make sense."));
148 const std::vector<Table<2,Coupling> > dof_mask
154 std::vector<Table<2,bool> > bool_dof_mask (fe_collection.size());
155 for (
unsigned int f=0; f<fe_collection.size(); ++f)
157 bool_dof_mask[f].reinit (
TableIndices<2>(fe_collection[f].dofs_per_cell,fe_collection[f].dofs_per_cell));
158 bool_dof_mask[f].fill (
false);
159 for (
unsigned int i=0; i<fe_collection[f].dofs_per_cell; ++i)
160 for (
unsigned int j=0; j<fe_collection[f].dofs_per_cell; ++j)
161 if (dof_mask[f](i,j) !=
none)
162 bool_dof_mask[f](i,j) =
true;
165 std::vector<types::global_dof_index> dofs_on_this_cell(fe_collection.max_dofs_per_cell());
166 typename DoFHandlerType::active_cell_iterator cell = dof.begin_active(),
172 for (; cell!=endc; ++cell)
175 (subdomain_id == cell->subdomain_id()))
177 cell->is_locally_owned())
179 const unsigned int fe_index = cell->active_fe_index();
180 const unsigned int dofs_per_cell =fe_collection[fe_index].dofs_per_cell;
182 dofs_on_this_cell.resize (dofs_per_cell);
183 cell->get_dof_indices (dofs_on_this_cell);
191 keep_constrained_dofs,
192 bool_dof_mask[fe_index]);
198 template <
typename DoFHandlerType,
typename SparsityPatternType>
201 const DoFHandlerType &dof_col,
202 SparsityPatternType &sparsity)
209 Assert (sparsity.n_rows() == n_dofs_row,
211 Assert (sparsity.n_cols() == n_dofs_col,
216 const std::list<std::pair<
typename DoFHandlerType::cell_iterator,
217 typename DoFHandlerType::cell_iterator> >
222 typename std::list<std::pair<
typename DoFHandlerType::cell_iterator,
223 typename DoFHandlerType::cell_iterator> >::const_iterator
224 cell_iter = cell_list.begin();
226 for (; cell_iter!=cell_list.end(); ++cell_iter)
228 const typename DoFHandlerType::cell_iterator cell_row = cell_iter->first;
229 const typename DoFHandlerType::cell_iterator cell_col = cell_iter->second;
231 if (!cell_row->has_children() && !cell_col->has_children())
233 const unsigned int dofs_per_cell_row =
234 cell_row->get_fe().dofs_per_cell;
235 const unsigned int dofs_per_cell_col =
236 cell_col->get_fe().dofs_per_cell;
237 std::vector<types::global_dof_index>
238 local_dof_indices_row(dofs_per_cell_row);
239 std::vector<types::global_dof_index>
240 local_dof_indices_col(dofs_per_cell_col);
241 cell_row->get_dof_indices (local_dof_indices_row);
242 cell_col->get_dof_indices (local_dof_indices_col);
243 for (
unsigned int i=0; i<dofs_per_cell_row; ++i)
244 sparsity.add_entries (local_dof_indices_row[i],
245 local_dof_indices_col.begin(),
246 local_dof_indices_col.end());
248 else if (cell_row->has_children())
250 const std::vector<typename DoFHandlerType::active_cell_iterator >
251 child_cells = GridTools::get_active_child_cells<DoFHandlerType> (cell_row);
252 for (
unsigned int i=0; i<child_cells.size(); i++)
254 const typename DoFHandlerType::cell_iterator
255 cell_row_child = child_cells[i];
256 const unsigned int dofs_per_cell_row =
257 cell_row_child->get_fe().dofs_per_cell;
258 const unsigned int dofs_per_cell_col =
259 cell_col->get_fe().dofs_per_cell;
260 std::vector<types::global_dof_index>
261 local_dof_indices_row(dofs_per_cell_row);
262 std::vector<types::global_dof_index>
263 local_dof_indices_col(dofs_per_cell_col);
264 cell_row_child->get_dof_indices (local_dof_indices_row);
265 cell_col->get_dof_indices (local_dof_indices_col);
266 for (
unsigned int r=0; r<dofs_per_cell_row; ++r)
267 sparsity.add_entries (local_dof_indices_row[r],
268 local_dof_indices_col.begin(),
269 local_dof_indices_col.end());
274 std::vector<typename DoFHandlerType::active_cell_iterator>
275 child_cells = GridTools::get_active_child_cells<DoFHandlerType> (cell_col);
276 for (
unsigned int i=0; i<child_cells.size(); i++)
278 const typename DoFHandlerType::active_cell_iterator
279 cell_col_child = child_cells[i];
280 const unsigned int dofs_per_cell_row =
281 cell_row->get_fe().dofs_per_cell;
282 const unsigned int dofs_per_cell_col =
283 cell_col_child->get_fe().dofs_per_cell;
284 std::vector<types::global_dof_index>
285 local_dof_indices_row(dofs_per_cell_row);
286 std::vector<types::global_dof_index>
287 local_dof_indices_col(dofs_per_cell_col);
288 cell_row->get_dof_indices (local_dof_indices_row);
289 cell_col_child->get_dof_indices (local_dof_indices_col);
290 for (
unsigned int r=0; r<dofs_per_cell_row; ++r)
291 sparsity.add_entries (local_dof_indices_row[r],
292 local_dof_indices_col.begin(),
293 local_dof_indices_col.end());
301 template <
typename DoFHandlerType,
typename SparsityPatternType>
304 (
const DoFHandlerType &dof,
305 const std::vector<types::global_dof_index> &dof_to_boundary_mapping,
306 SparsityPatternType &sparsity)
308 if (DoFHandlerType::dimension == 1)
312 std::map<types::boundary_id, const Function<DoFHandlerType::space_dimension,double>*> boundary_ids;
313 boundary_ids[0] =
nullptr;
314 boundary_ids[1] =
nullptr;
315 make_boundary_sparsity_pattern<DoFHandlerType, SparsityPatternType>
318 dof_to_boundary_mapping,
330 if (sparsity.n_rows() != 0)
333 for (std::vector<types::global_dof_index>::const_iterator i=dof_to_boundary_mapping.begin();
334 i!=dof_to_boundary_mapping.end(); ++i)
342 std::vector<types::global_dof_index> dofs_on_this_face;
350 typename DoFHandlerType::active_cell_iterator cell = dof.begin_active(),
352 for (; cell!=endc; ++cell)
353 for (
unsigned int f=0; f<GeometryInfo<DoFHandlerType::dimension>::faces_per_cell; ++f)
354 if (cell->at_boundary(f))
356 const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
357 dofs_on_this_face.resize (dofs_per_face);
358 cell->face(f)->get_dof_indices (dofs_on_this_face,
359 cell->active_fe_index());
362 for (
unsigned int i=0; i<dofs_per_face; ++i)
363 for (
unsigned int j=0; j<dofs_per_face; ++j)
364 sparsity.add (dof_to_boundary_mapping[dofs_on_this_face[i]],
365 dof_to_boundary_mapping[dofs_on_this_face[j]]);
371 template <
typename DoFHandlerType,
typename SparsityPatternType,
typename number>
373 (
const DoFHandlerType &dof,
375 const std::vector<types::global_dof_index> &dof_to_boundary_mapping,
376 SparsityPatternType &sparsity)
378 if (DoFHandlerType::dimension == 1)
381 for (
unsigned int direction=0; direction<2; ++direction)
384 if (boundary_ids.find(direction) ==
390 typename DoFHandlerType::level_cell_iterator cell = dof.begin(0);
391 while (!cell->at_boundary(direction))
392 cell = cell->neighbor(direction);
393 while (!cell->active())
394 cell = cell->child(direction);
396 const unsigned int dofs_per_vertex = cell->get_fe().dofs_per_vertex;
397 std::vector<types::global_dof_index> boundary_dof_boundary_indices (dofs_per_vertex);
400 for (
unsigned int i=0; i<dofs_per_vertex; ++i)
401 boundary_dof_boundary_indices[i]
402 = dof_to_boundary_mapping[cell->vertex_dof_index(direction,i)];
404 for (
unsigned int i=0; i<dofs_per_vertex; ++i)
405 sparsity.add_entries (boundary_dof_boundary_indices[i],
406 boundary_dof_boundary_indices.begin(),
407 boundary_dof_boundary_indices.end());
418 Assert (sparsity.n_rows() == dof.n_boundary_dofs (boundary_ids),
420 Assert (sparsity.n_cols() == dof.n_boundary_dofs (boundary_ids),
423 if (sparsity.n_rows() != 0)
426 for (std::vector<types::global_dof_index>::const_iterator i=dof_to_boundary_mapping.begin();
427 i!=dof_to_boundary_mapping.end(); ++i)
435 std::vector<types::global_dof_index> dofs_on_this_face;
437 typename DoFHandlerType::active_cell_iterator cell = dof.begin_active(),
439 for (; cell!=endc; ++cell)
440 for (
unsigned int f=0; f<GeometryInfo<DoFHandlerType::dimension>::faces_per_cell; ++f)
441 if (boundary_ids.find(cell->face(f)->boundary_id()) !=
444 const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
445 dofs_on_this_face.resize (dofs_per_face);
446 cell->face(f)->get_dof_indices (dofs_on_this_face,
447 cell->active_fe_index());
450 for (
unsigned int i=0; i<dofs_per_face; ++i)
451 for (
unsigned int j=0; j<dofs_per_face; ++j)
452 sparsity.add (dof_to_boundary_mapping[dofs_on_this_face[i]],
453 dof_to_boundary_mapping[dofs_on_this_face[j]]);
459 template <
typename DoFHandlerType,
typename SparsityPatternType>
462 SparsityPatternType &sparsity,
464 const bool keep_constrained_dofs,
484 (subdomain_id == dof.get_triangulation().locally_owned_subdomain()),
485 ExcMessage (
"For parallel::distributed::Triangulation objects and " 486 "associated DoF handler objects, asking for any subdomain other " 487 "than the locally owned one does not make sense."));
489 std::vector<types::global_dof_index> dofs_on_this_cell;
490 std::vector<types::global_dof_index> dofs_on_other_cell;
493 typename DoFHandlerType::active_cell_iterator cell = dof.begin_active(),
504 for (; cell!=endc; ++cell)
507 (subdomain_id == cell->subdomain_id()))
509 cell->is_locally_owned())
511 const unsigned int n_dofs_on_this_cell = cell->get_fe().dofs_per_cell;
512 dofs_on_this_cell.resize (n_dofs_on_this_cell);
513 cell->get_dof_indices (dofs_on_this_cell);
520 keep_constrained_dofs);
522 for (
unsigned int face = 0;
523 face < GeometryInfo<DoFHandlerType::dimension>::faces_per_cell;
526 typename DoFHandlerType::face_iterator cell_face = cell->face(face);
527 const bool periodic_neighbor = cell->has_periodic_neighbor(face);
528 if (! cell->at_boundary(face) || periodic_neighbor)
530 typename DoFHandlerType::level_cell_iterator neighbor
531 = cell->neighbor_or_periodic_neighbor(face);
537 if (DoFHandlerType::dimension==1)
538 while (neighbor->has_children())
539 neighbor = neighbor->child(face==0 ? 1 : 0);
541 if (neighbor->has_children())
543 for (
unsigned int sub_nr = 0;
544 sub_nr != cell_face->number_of_children();
547 const typename DoFHandlerType::level_cell_iterator sub_neighbor
549 cell->periodic_neighbor_child_on_subface (face, sub_nr):
550 cell->neighbor_child_on_subface (face, sub_nr);
552 const unsigned int n_dofs_on_neighbor
553 = sub_neighbor->get_fe().dofs_per_cell;
554 dofs_on_other_cell.resize (n_dofs_on_neighbor);
555 sub_neighbor->get_dof_indices (dofs_on_other_cell);
558 (dofs_on_this_cell, dofs_on_other_cell,
559 sparsity, keep_constrained_dofs);
561 (dofs_on_other_cell, dofs_on_this_cell,
562 sparsity, keep_constrained_dofs);
566 if (sub_neighbor->subdomain_id() != cell->subdomain_id())
568 (dofs_on_other_cell, sparsity, keep_constrained_dofs);
575 if ((!periodic_neighbor && cell->neighbor_is_coarser(face)) ||
576 (periodic_neighbor && cell->periodic_neighbor_is_coarser(face)))
577 if (neighbor->subdomain_id() == cell->subdomain_id())
580 const unsigned int n_dofs_on_neighbor
581 = neighbor->get_fe().dofs_per_cell;
582 dofs_on_other_cell.resize (n_dofs_on_neighbor);
584 neighbor->get_dof_indices (dofs_on_other_cell);
587 (dofs_on_this_cell, dofs_on_other_cell,
588 sparsity, keep_constrained_dofs);
594 if (!cell->neighbor_or_periodic_neighbor(face)->active()
596 (neighbor->subdomain_id() != cell->subdomain_id()))
599 (dofs_on_other_cell, dofs_on_this_cell,
600 sparsity, keep_constrained_dofs);
601 if (neighbor->subdomain_id() != cell->subdomain_id())
603 (dofs_on_other_cell, sparsity, keep_constrained_dofs);
613 template <
typename DoFHandlerType,
typename SparsityPatternType>
616 SparsityPatternType &sparsity)
622 template <
int dim,
int spacedim>
638 for (
unsigned int i=0; i<n_dofs; ++i)
640 const unsigned int ii
648 for (
unsigned int j=0; j<n_dofs; ++j)
650 const unsigned int jj
658 dof_couplings(i,j) = component_couplings(ii,jj);
661 return dof_couplings;
666 template <
int dim,
int spacedim>
667 std::vector<Table<2,Coupling> >
672 std::vector<Table<2,Coupling> > return_value (fe.
size());
673 for (
unsigned int i=0; i<fe.
size(); ++i)
689 template <
typename DoFHandlerType,
typename SparsityPatternType>
692 SparsityPatternType &sparsity,
694 const bool keep_constrained_dofs,
702 std::vector<types::global_dof_index> dofs_on_this_cell (fe.
dofs_per_cell);
703 std::vector<types::global_dof_index> dofs_on_other_cell (fe.
dofs_per_cell);
712 for (
unsigned int f=0; f<GeometryInfo<DoFHandlerType::dimension>::faces_per_cell; ++f)
718 bool_int_dof_mask.fill (
false);
721 if (int_dof_mask(i,j) !=
none)
722 bool_int_dof_mask(i,j) =
true;
724 typename DoFHandlerType::active_cell_iterator cell = dof.begin_active (),
726 for (; cell!=endc; ++cell)
729 (subdomain_id == cell->subdomain_id()))
731 cell->is_locally_owned())
733 cell->get_dof_indices (dofs_on_this_cell);
737 keep_constrained_dofs,
740 for (
unsigned int face_n = 0;
741 face_n < GeometryInfo<DoFHandlerType::dimension>::faces_per_cell;
744 const typename DoFHandlerType::face_iterator
745 cell_face = cell->face (face_n);
747 const bool periodic_neighbor = cell->has_periodic_neighbor (face_n);
749 if (cell->at_boundary (face_n) && (!periodic_neighbor))
753 const bool i_non_zero_i = support_on_face (i, face_n);
756 const bool j_non_zero_i = support_on_face (j, face_n);
758 if (flux_dof_mask (i,j) ==
always 760 (flux_dof_mask (i,j) ==
nonzero 765 sparsity.add (dofs_on_this_cell[i],
766 dofs_on_this_cell[j]);
772 typename DoFHandlerType::level_cell_iterator
773 neighbor = cell->neighbor_or_periodic_neighbor (face_n);
778 if (neighbor->level () == cell->level ()
780 neighbor->index () > cell->index ()
784 neighbor->is_locally_owned ())
797 if (neighbor->level () != cell->level ()
799 ((!periodic_neighbor && !cell->neighbor_is_coarser (face_n))
800 ||(periodic_neighbor && !cell->periodic_neighbor_is_coarser (face_n)))
802 neighbor->is_locally_owned ())
806 neighbor_face_n = periodic_neighbor?
807 cell->periodic_neighbor_face_no (face_n):
808 cell->neighbor_face_no (face_n);
810 if (neighbor->has_children ())
812 for (
unsigned int sub_nr = 0;
813 sub_nr != cell_face->n_children ();
816 const typename DoFHandlerType::level_cell_iterator
819 cell->periodic_neighbor_child_on_subface (face_n, sub_nr):
820 cell->neighbor_child_on_subface (face_n, sub_nr);
822 sub_neighbor->get_dof_indices (dofs_on_other_cell);
825 const bool i_non_zero_i = support_on_face (i, face_n);
826 const bool i_non_zero_e = support_on_face (i, neighbor_face_n);
829 const bool j_non_zero_i = support_on_face (j, face_n);
830 const bool j_non_zero_e = support_on_face (j, neighbor_face_n);
832 if (flux_dof_mask (i,j) ==
always)
834 sparsity.add (dofs_on_this_cell[i],
835 dofs_on_other_cell[j]);
836 sparsity.add (dofs_on_other_cell[i],
837 dofs_on_this_cell[j]);
838 sparsity.add (dofs_on_this_cell[i],
839 dofs_on_this_cell[j]);
840 sparsity.add (dofs_on_other_cell[i],
841 dofs_on_other_cell[j]);
843 else if (flux_dof_mask (i,j) ==
nonzero)
845 if (i_non_zero_i && j_non_zero_e)
846 sparsity.add (dofs_on_this_cell[i],
847 dofs_on_other_cell[j]);
848 if (i_non_zero_e && j_non_zero_i)
849 sparsity.add (dofs_on_other_cell[i],
850 dofs_on_this_cell[j]);
851 if (i_non_zero_i && j_non_zero_i)
852 sparsity.add (dofs_on_this_cell[i],
853 dofs_on_this_cell[j]);
854 if (i_non_zero_e && j_non_zero_e)
855 sparsity.add (dofs_on_other_cell[i],
856 dofs_on_other_cell[j]);
859 if (flux_dof_mask (j,i) ==
always)
861 sparsity.add (dofs_on_this_cell[j],
862 dofs_on_other_cell[i]);
863 sparsity.add (dofs_on_other_cell[j],
864 dofs_on_this_cell[i]);
865 sparsity.add (dofs_on_this_cell[j],
866 dofs_on_this_cell[i]);
867 sparsity.add (dofs_on_other_cell[j],
868 dofs_on_other_cell[i]);
870 else if (flux_dof_mask (j,i) ==
nonzero)
872 if (j_non_zero_i && i_non_zero_e)
873 sparsity.add (dofs_on_this_cell[j],
874 dofs_on_other_cell[i]);
875 if (j_non_zero_e && i_non_zero_i)
876 sparsity.add (dofs_on_other_cell[j],
877 dofs_on_this_cell[i]);
878 if (j_non_zero_i && i_non_zero_i)
879 sparsity.add (dofs_on_this_cell[j],
880 dofs_on_this_cell[i]);
881 if (j_non_zero_e && i_non_zero_e)
882 sparsity.add (dofs_on_other_cell[j],
883 dofs_on_other_cell[i]);
891 neighbor->get_dof_indices (dofs_on_other_cell);
894 const bool i_non_zero_i = support_on_face (i, face_n);
895 const bool i_non_zero_e = support_on_face (i, neighbor_face_n);
898 const bool j_non_zero_i = support_on_face (j, face_n);
899 const bool j_non_zero_e = support_on_face (j, neighbor_face_n);
900 if (flux_dof_mask (i,j) ==
always)
902 sparsity.add (dofs_on_this_cell[i],
903 dofs_on_other_cell[j]);
904 sparsity.add (dofs_on_other_cell[i],
905 dofs_on_this_cell[j]);
906 sparsity.add (dofs_on_this_cell[i],
907 dofs_on_this_cell[j]);
908 sparsity.add (dofs_on_other_cell[i],
909 dofs_on_other_cell[j]);
911 if (flux_dof_mask (i,j) ==
nonzero)
913 if (i_non_zero_i && j_non_zero_e)
914 sparsity.add (dofs_on_this_cell[i],
915 dofs_on_other_cell[j]);
916 if (i_non_zero_e && j_non_zero_i)
917 sparsity.add (dofs_on_other_cell[i],
918 dofs_on_this_cell[j]);
919 if (i_non_zero_i && j_non_zero_i)
920 sparsity.add (dofs_on_this_cell[i],
921 dofs_on_this_cell[j]);
922 if (i_non_zero_e && j_non_zero_e)
923 sparsity.add (dofs_on_other_cell[i],
924 dofs_on_other_cell[j]);
927 if (flux_dof_mask (j,i) ==
always)
929 sparsity.add (dofs_on_this_cell[j],
930 dofs_on_other_cell[i]);
931 sparsity.add (dofs_on_other_cell[j],
932 dofs_on_this_cell[i]);
933 sparsity.add (dofs_on_this_cell[j],
934 dofs_on_this_cell[i]);
935 sparsity.add (dofs_on_other_cell[j],
936 dofs_on_other_cell[i]);
938 if (flux_dof_mask (j,i) ==
nonzero)
940 if (j_non_zero_i && i_non_zero_e)
941 sparsity.add (dofs_on_this_cell[j],
942 dofs_on_other_cell[i]);
943 if (j_non_zero_e && i_non_zero_i)
944 sparsity.add (dofs_on_other_cell[j],
945 dofs_on_this_cell[i]);
946 if (j_non_zero_i && i_non_zero_i)
947 sparsity.add (dofs_on_this_cell[j],
948 dofs_on_this_cell[i]);
949 if (j_non_zero_e && i_non_zero_e)
950 sparsity.add (dofs_on_other_cell[j],
951 dofs_on_other_cell[i]);
964 template <
int dim,
int spacedim,
typename SparsityPatternType>
967 SparsityPatternType &sparsity,
969 const bool keep_constrained_dofs,
981 const ::hp::FECollection<dim,spacedim> &fe = dof.get_fe_collection();
986 std::vector<Table<2,Coupling> > int_dof_mask (fe.size());
992 std::vector<Table<2,bool> > bool_int_dof_mask (fe.size());
993 for (
unsigned int f=0; f<fe.size(); ++f)
995 bool_int_dof_mask[f].reinit (
TableIndices<2>(fe[f].dofs_per_cell,fe[f].dofs_per_cell));
996 bool_int_dof_mask[f].fill (
false);
997 for (
unsigned int i=0; i<fe[f].dofs_per_cell; ++i)
998 for (
unsigned int j=0; j<fe[f].dofs_per_cell; ++j)
999 if (int_dof_mask[f](i,j) !=
none)
1000 bool_int_dof_mask[f](i,j) =
true;
1004 typename ::hp::DoFHandler<dim,spacedim>::active_cell_iterator
1005 cell = dof.begin_active(),
1007 for (; cell!=endc; ++cell)
1010 (subdomain_id == cell->subdomain_id()))
1012 cell->is_locally_owned())
1014 dofs_on_this_cell.resize (cell->get_fe().dofs_per_cell);
1015 cell->get_dof_indices (dofs_on_this_cell);
1020 keep_constrained_dofs,
1021 bool_int_dof_mask[cell->active_fe_index()]);
1023 for (
unsigned int face = 0;
1024 face < GeometryInfo<dim>::faces_per_cell;
1027 const typename ::hp::DoFHandler<dim,spacedim>::face_iterator
1028 cell_face = cell->face(face);
1030 const bool periodic_neighbor = cell->has_periodic_neighbor (face);
1032 if (cell->at_boundary (face) && (!periodic_neighbor))
1034 for (
unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
1036 const unsigned int ii
1037 = (cell->get_fe().is_primitive(i) ?
1038 cell->get_fe().system_to_component_index(i).first
1040 cell->get_fe().get_nonzero_components(i).first_selected_component()
1045 for (
unsigned int j=0; j<cell->get_fe().dofs_per_cell; ++j)
1047 const unsigned int jj
1048 = (cell->get_fe().is_primitive(j) ?
1049 cell->get_fe().system_to_component_index(j).first
1051 cell->get_fe().get_nonzero_components(j).first_selected_component()
1056 if ((flux_mask(ii,jj) ==
always)
1058 (flux_mask(ii,jj) ==
nonzero))
1059 sparsity.add (dofs_on_this_cell[i],
1060 dofs_on_this_cell[j]);
1066 typename ::hp::DoFHandler<dim,spacedim>::level_cell_iterator
1067 neighbor = cell->neighbor_or_periodic_neighbor(face);
1073 if (neighbor->level () == cell->level ()
1075 neighbor->index () > cell->index ()
1079 neighbor->is_locally_owned ())
1093 if (neighbor->level () != cell->level ()
1095 ((!periodic_neighbor && !cell->neighbor_is_coarser (face))
1096 ||(periodic_neighbor && !cell->periodic_neighbor_is_coarser (face)))
1098 neighbor->is_locally_owned ())
1101 if (neighbor->has_children())
1103 for (
unsigned int sub_nr = 0;
1104 sub_nr != cell_face->n_children();
1107 const typename ::hp::DoFHandler<dim,spacedim>::level_cell_iterator
1109 = periodic_neighbor?
1110 cell->periodic_neighbor_child_on_subface (face, sub_nr):
1111 cell->neighbor_child_on_subface (face, sub_nr);
1113 dofs_on_other_cell.resize (sub_neighbor->get_fe().dofs_per_cell);
1114 sub_neighbor->get_dof_indices (dofs_on_other_cell);
1115 for (
unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
1117 const unsigned int ii
1118 = (cell->get_fe().is_primitive(i) ?
1119 cell->get_fe().system_to_component_index(i).first
1121 cell->get_fe().get_nonzero_components(i).first_selected_component()
1126 for (
unsigned int j=0; j<sub_neighbor->get_fe().dofs_per_cell;
1129 const unsigned int jj
1130 = (sub_neighbor->get_fe().is_primitive(j) ?
1131 sub_neighbor->get_fe().system_to_component_index(j).first
1133 sub_neighbor->get_fe().get_nonzero_components(j).first_selected_component()
1138 if ((flux_mask(ii,jj) ==
always)
1140 (flux_mask(ii,jj) ==
nonzero))
1142 sparsity.add (dofs_on_this_cell[i],
1143 dofs_on_other_cell[j]);
1144 sparsity.add (dofs_on_other_cell[i],
1145 dofs_on_this_cell[j]);
1146 sparsity.add (dofs_on_this_cell[i],
1147 dofs_on_this_cell[j]);
1148 sparsity.add (dofs_on_other_cell[i],
1149 dofs_on_other_cell[j]);
1152 if ((flux_mask(jj,ii) ==
always)
1154 (flux_mask(jj,ii) ==
nonzero))
1156 sparsity.add (dofs_on_this_cell[j],
1157 dofs_on_other_cell[i]);
1158 sparsity.add (dofs_on_other_cell[j],
1159 dofs_on_this_cell[i]);
1160 sparsity.add (dofs_on_this_cell[j],
1161 dofs_on_this_cell[i]);
1162 sparsity.add (dofs_on_other_cell[j],
1163 dofs_on_other_cell[i]);
1171 dofs_on_other_cell.resize (neighbor->get_fe().dofs_per_cell);
1172 neighbor->get_dof_indices (dofs_on_other_cell);
1173 for (
unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
1175 const unsigned int ii
1176 = (cell->get_fe().is_primitive(i) ?
1177 cell->get_fe().system_to_component_index(i).first
1179 cell->get_fe().get_nonzero_components(i).first_selected_component()
1184 for (
unsigned int j=0; j<neighbor->get_fe().dofs_per_cell; ++j)
1186 const unsigned int jj
1187 = (neighbor->get_fe().is_primitive(j) ?
1188 neighbor->get_fe().system_to_component_index(j).first
1190 neighbor->get_fe().get_nonzero_components(j).first_selected_component()
1195 if ((flux_mask(ii,jj) ==
always)
1197 (flux_mask(ii,jj) ==
nonzero))
1199 sparsity.add (dofs_on_this_cell[i],
1200 dofs_on_other_cell[j]);
1201 sparsity.add (dofs_on_other_cell[i],
1202 dofs_on_this_cell[j]);
1203 sparsity.add (dofs_on_this_cell[i],
1204 dofs_on_this_cell[j]);
1205 sparsity.add (dofs_on_other_cell[i],
1206 dofs_on_other_cell[j]);
1209 if ((flux_mask(jj,ii) ==
always)
1211 (flux_mask(jj,ii) ==
nonzero))
1213 sparsity.add (dofs_on_this_cell[j],
1214 dofs_on_other_cell[i]);
1215 sparsity.add (dofs_on_other_cell[j],
1216 dofs_on_this_cell[i]);
1217 sparsity.add (dofs_on_this_cell[j],
1218 dofs_on_this_cell[i]);
1219 sparsity.add (dofs_on_other_cell[j],
1220 dofs_on_other_cell[i]);
1236 template <
typename DoFHandlerType,
typename SparsityPatternType>
1239 SparsityPatternType &sparsity,
1245 const bool keep_constrained_dofs =
true;
1247 constraints, keep_constrained_dofs,
1248 int_mask, flux_mask,
1252 template <
typename DoFHandlerType,
typename SparsityPatternType>
1255 SparsityPatternType &sparsity,
1257 const bool keep_constrained_dofs,
1266 const unsigned int n_comp = dof.get_fe(0).n_components();
1269 Assert (sparsity.n_rows() == n_dofs,
1271 Assert (sparsity.n_cols() == n_dofs,
1273 Assert (int_mask.n_rows() == n_comp,
1275 Assert (int_mask.n_cols() == n_comp,
1277 Assert (flux_mask.n_rows() == n_comp,
1279 Assert (flux_mask.n_cols() == n_comp,
1290 (subdomain_id == dof.get_triangulation().locally_owned_subdomain()),
1291 ExcMessage (
"For parallel::distributed::Triangulation objects and " 1292 "associated DoF handler objects, asking for any subdomain other " 1293 "than the locally owned one does not make sense."));
1296 constraints, keep_constrained_dofs,
1297 int_mask, flux_mask,
1307 #include "dof_tools_sparsity.inst" 1311 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 global_dof_index
#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)
unsigned int subdomain_id
const unsigned int dofs_per_cell
std::pair< unsigned int, unsigned int > system_to_component_index(const unsigned int index) const
void make_sparsity_pattern(const DoFHandlerType &dof_handler, SparsityPatternType &sparsity_pattern, const ConstraintMatrix &constraints=ConstraintMatrix(), const bool keep_constrained_dofs=true, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id)
unsigned int n_components() const
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=default_empty_table) 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
virtual bool has_support_on_face(const unsigned int shape_index, const unsigned int face_index) const
static ::ExceptionBase & ExcInternalError()