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,
65 ExcDimensionMismatch (sparsity.n_rows(), n_dofs));
66 Assert (sparsity.n_cols() == n_dofs,
67 ExcDimensionMismatch (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;
83 dofs_on_this_cell.reserve (max_dofs_per_cell(dof));
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,
125 ExcDimensionMismatch (sparsity.n_rows(), n_dofs));
126 Assert (sparsity.n_cols() == n_dofs,
127 ExcDimensionMismatch (sparsity.n_cols(), n_dofs));
128 Assert (couplings.n_rows() == dof.get_fe().n_components(),
129 ExcDimensionMismatch(couplings.n_rows(), dof.get_fe().n_components()));
130 Assert (couplings.n_cols() == dof.get_fe().n_components(),
131 ExcDimensionMismatch(couplings.n_cols(), dof.get_fe().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."));
152 std::vector<Table<2,bool> > dof_mask(fe_collection.size());
157 bool need_dof_mask =
false;
158 for (
unsigned int i=0; i<couplings.n_rows(); ++i)
159 for (
unsigned int j=0; j<couplings.n_cols(); ++j)
160 if (couplings(i,j) ==
none)
161 need_dof_mask =
true;
163 if (need_dof_mask ==
true)
164 for (
unsigned int f=0; f<fe_collection.size(); ++f)
166 const unsigned int dofs_per_cell = fe_collection[f].dofs_per_cell;
168 dof_mask[f].reinit (dofs_per_cell, dofs_per_cell);
170 for (
unsigned int i=0; i<dofs_per_cell; ++i)
171 for (
unsigned int j=0; j<dofs_per_cell; ++j)
172 if (fe_collection[f].is_primitive(i) &&
173 fe_collection[f].is_primitive(j))
175 = (couplings(fe_collection[f].system_to_component_index(i).first,
176 fe_collection[f].system_to_component_index(j).first) !=
none);
179 const unsigned int first_nonzero_comp_i
180 = fe_collection[f].get_nonzero_components(i).first_selected_component();
181 const unsigned int first_nonzero_comp_j
182 = fe_collection[f].get_nonzero_components(j).first_selected_component();
183 Assert (first_nonzero_comp_i < fe_collection[f].n_components(),
185 Assert (first_nonzero_comp_j < fe_collection[f].n_components(),
189 = (couplings(first_nonzero_comp_i,first_nonzero_comp_j) !=
none);
194 std::vector<types::global_dof_index> dofs_on_this_cell(fe_collection.max_dofs_per_cell());
195 typename DoFHandlerType::active_cell_iterator cell = dof.begin_active(),
201 for (; cell!=endc; ++cell)
204 (subdomain_id == cell->subdomain_id()))
206 cell->is_locally_owned())
208 const unsigned int fe_index = cell->active_fe_index();
209 const unsigned int dofs_per_cell =fe_collection[fe_index].dofs_per_cell;
211 dofs_on_this_cell.resize (dofs_per_cell);
212 cell->get_dof_indices (dofs_on_this_cell);
220 keep_constrained_dofs,
227 template <
typename DoFHandlerType,
typename SparsityPatternType>
230 const DoFHandlerType &dof_col,
231 SparsityPatternType &sparsity)
238 Assert (sparsity.n_rows() == n_dofs_row,
239 ExcDimensionMismatch (sparsity.n_rows(), n_dofs_row));
240 Assert (sparsity.n_cols() == n_dofs_col,
241 ExcDimensionMismatch (sparsity.n_cols(), n_dofs_col));
245 const std::list<std::pair<
typename DoFHandlerType::cell_iterator,
246 typename DoFHandlerType::cell_iterator> >
251 typename std::list<std::pair<
typename DoFHandlerType::cell_iterator,
252 typename DoFHandlerType::cell_iterator> >::const_iterator
253 cell_iter = cell_list.begin();
255 for (; cell_iter!=cell_list.end(); ++cell_iter)
257 const typename DoFHandlerType::cell_iterator cell_row = cell_iter->first;
258 const typename DoFHandlerType::cell_iterator cell_col = cell_iter->second;
260 if (!cell_row->has_children() && !cell_col->has_children())
262 const unsigned int dofs_per_cell_row =
263 cell_row->get_fe().dofs_per_cell;
264 const unsigned int dofs_per_cell_col =
265 cell_col->get_fe().dofs_per_cell;
266 std::vector<types::global_dof_index>
267 local_dof_indices_row(dofs_per_cell_row);
268 std::vector<types::global_dof_index>
269 local_dof_indices_col(dofs_per_cell_col);
270 cell_row->get_dof_indices (local_dof_indices_row);
271 cell_col->get_dof_indices (local_dof_indices_col);
272 for (
unsigned int i=0; i<dofs_per_cell_row; ++i)
273 sparsity.add_entries (local_dof_indices_row[i],
274 local_dof_indices_col.begin(),
275 local_dof_indices_col.end());
277 else if (cell_row->has_children())
279 const std::vector<typename DoFHandlerType::active_cell_iterator >
280 child_cells = GridTools::get_active_child_cells<DoFHandlerType> (cell_row);
281 for (
unsigned int i=0; i<child_cells.size(); i++)
283 const typename DoFHandlerType::cell_iterator
284 cell_row_child = child_cells[i];
285 const unsigned int dofs_per_cell_row =
286 cell_row_child->get_fe().dofs_per_cell;
287 const unsigned int dofs_per_cell_col =
288 cell_col->get_fe().dofs_per_cell;
289 std::vector<types::global_dof_index>
290 local_dof_indices_row(dofs_per_cell_row);
291 std::vector<types::global_dof_index>
292 local_dof_indices_col(dofs_per_cell_col);
293 cell_row_child->get_dof_indices (local_dof_indices_row);
294 cell_col->get_dof_indices (local_dof_indices_col);
295 for (
unsigned int r=0; r<dofs_per_cell_row; ++r)
296 sparsity.add_entries (local_dof_indices_row[r],
297 local_dof_indices_col.begin(),
298 local_dof_indices_col.end());
303 std::vector<typename DoFHandlerType::active_cell_iterator>
304 child_cells = GridTools::get_active_child_cells<DoFHandlerType> (cell_col);
305 for (
unsigned int i=0; i<child_cells.size(); i++)
307 const typename DoFHandlerType::active_cell_iterator
308 cell_col_child = child_cells[i];
309 const unsigned int dofs_per_cell_row =
310 cell_row->get_fe().dofs_per_cell;
311 const unsigned int dofs_per_cell_col =
312 cell_col_child->get_fe().dofs_per_cell;
313 std::vector<types::global_dof_index>
314 local_dof_indices_row(dofs_per_cell_row);
315 std::vector<types::global_dof_index>
316 local_dof_indices_col(dofs_per_cell_col);
317 cell_row->get_dof_indices (local_dof_indices_row);
318 cell_col_child->get_dof_indices (local_dof_indices_col);
319 for (
unsigned int r=0; r<dofs_per_cell_row; ++r)
320 sparsity.add_entries (local_dof_indices_row[r],
321 local_dof_indices_col.begin(),
322 local_dof_indices_col.end());
330 template <
typename DoFHandlerType,
typename SparsityPatternType>
333 (
const DoFHandlerType &dof,
334 const std::vector<types::global_dof_index> &dof_to_boundary_mapping,
335 SparsityPatternType &sparsity)
337 if (DoFHandlerType::dimension == 1)
341 typename DoFHandlerType::FunctionMap boundary_ids;
344 make_boundary_sparsity_pattern<DoFHandlerType, SparsityPatternType>
347 dof_to_boundary_mapping,
359 if (sparsity.n_rows() != 0)
362 for (std::vector<types::global_dof_index>::const_iterator i=dof_to_boundary_mapping.begin();
363 i!=dof_to_boundary_mapping.end(); ++i)
364 if ((*i != DoFHandlerType::invalid_dof_index) &&
371 std::vector<types::global_dof_index> dofs_on_this_face;
372 dofs_on_this_face.reserve (max_dofs_per_face(dof));
379 typename DoFHandlerType::active_cell_iterator cell = dof.begin_active(),
381 for (; cell!=endc; ++cell)
382 for (
unsigned int f=0; f<GeometryInfo<DoFHandlerType::dimension>::faces_per_cell; ++f)
383 if (cell->at_boundary(f))
385 const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
386 dofs_on_this_face.resize (dofs_per_face);
387 cell->face(f)->get_dof_indices (dofs_on_this_face,
388 cell->active_fe_index());
391 for (
unsigned int i=0; i<dofs_per_face; ++i)
392 for (
unsigned int j=0; j<dofs_per_face; ++j)
393 sparsity.add (dof_to_boundary_mapping[dofs_on_this_face[i]],
394 dof_to_boundary_mapping[dofs_on_this_face[j]]);
400 template <
typename DoFHandlerType,
typename SparsityPatternType>
402 (
const DoFHandlerType &dof,
404 const std::vector<types::global_dof_index> &dof_to_boundary_mapping,
405 SparsityPatternType &sparsity)
407 if (DoFHandlerType::dimension == 1)
410 for (
unsigned int direction=0; direction<2; ++direction)
413 if (boundary_ids.find(direction) ==
419 typename DoFHandlerType::level_cell_iterator cell = dof.begin(0);
420 while (!cell->at_boundary(direction))
421 cell = cell->neighbor(direction);
422 while (!cell->active())
423 cell = cell->child(direction);
425 const unsigned int dofs_per_vertex = cell->get_fe().dofs_per_vertex;
426 std::vector<types::global_dof_index> boundary_dof_boundary_indices (dofs_per_vertex);
429 for (
unsigned int i=0; i<dofs_per_vertex; ++i)
430 boundary_dof_boundary_indices[i]
431 = dof_to_boundary_mapping[cell->vertex_dof_index(direction,i)];
433 for (
unsigned int i=0; i<dofs_per_vertex; ++i)
434 sparsity.add_entries (boundary_dof_boundary_indices[i],
435 boundary_dof_boundary_indices.begin(),
436 boundary_dof_boundary_indices.end());
446 typename DoFHandlerType::ExcInvalidBoundaryIndicator());
447 Assert (sparsity.n_rows() == dof.n_boundary_dofs (boundary_ids),
448 ExcDimensionMismatch (sparsity.n_rows(), dof.n_boundary_dofs (boundary_ids)));
449 Assert (sparsity.n_cols() == dof.n_boundary_dofs (boundary_ids),
450 ExcDimensionMismatch (sparsity.n_cols(), dof.n_boundary_dofs (boundary_ids)));
452 if (sparsity.n_rows() != 0)
455 for (std::vector<types::global_dof_index>::const_iterator i=dof_to_boundary_mapping.begin();
456 i!=dof_to_boundary_mapping.end(); ++i)
457 if ((*i != DoFHandlerType::invalid_dof_index) &&
464 std::vector<types::global_dof_index> dofs_on_this_face;
465 dofs_on_this_face.reserve (max_dofs_per_face(dof));
466 typename DoFHandlerType::active_cell_iterator cell = dof.begin_active(),
468 for (; cell!=endc; ++cell)
469 for (
unsigned int f=0; f<GeometryInfo<DoFHandlerType::dimension>::faces_per_cell; ++f)
470 if (boundary_ids.find(cell->face(f)->boundary_id()) !=
473 const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
474 dofs_on_this_face.resize (dofs_per_face);
475 cell->face(f)->get_dof_indices (dofs_on_this_face,
476 cell->active_fe_index());
479 for (
unsigned int i=0; i<dofs_per_face; ++i)
480 for (
unsigned int j=0; j<dofs_per_face; ++j)
481 sparsity.add (dof_to_boundary_mapping[dofs_on_this_face[i]],
482 dof_to_boundary_mapping[dofs_on_this_face[j]]);
488 template <
typename DoFHandlerType,
typename SparsityPatternType>
491 SparsityPatternType &sparsity,
493 const bool keep_constrained_dofs,
513 (subdomain_id == dof.get_triangulation().locally_owned_subdomain()),
514 ExcMessage (
"For parallel::distributed::Triangulation objects and " 515 "associated DoF handler objects, asking for any subdomain other " 516 "than the locally owned one does not make sense."));
518 std::vector<types::global_dof_index> dofs_on_this_cell;
519 std::vector<types::global_dof_index> dofs_on_other_cell;
520 dofs_on_this_cell.reserve (max_dofs_per_cell(dof));
521 dofs_on_other_cell.reserve (max_dofs_per_cell(dof));
522 typename DoFHandlerType::active_cell_iterator cell = dof.begin_active(),
533 for (; cell!=endc; ++cell)
536 (subdomain_id == cell->subdomain_id()))
538 cell->is_locally_owned())
540 const unsigned int n_dofs_on_this_cell = cell->get_fe().dofs_per_cell;
541 dofs_on_this_cell.resize (n_dofs_on_this_cell);
542 cell->get_dof_indices (dofs_on_this_cell);
549 keep_constrained_dofs);
551 for (
unsigned int face = 0;
552 face < GeometryInfo<DoFHandlerType::dimension>::faces_per_cell;
555 typename DoFHandlerType::face_iterator cell_face = cell->face(face);
556 if (! cell->at_boundary(face) )
558 typename DoFHandlerType::level_cell_iterator neighbor = cell->neighbor(face);
564 if (DoFHandlerType::dimension==1)
565 while (neighbor->has_children())
566 neighbor = neighbor->child(face==0 ? 1 : 0);
568 if (neighbor->has_children())
570 for (
unsigned int sub_nr = 0;
571 sub_nr != cell_face->number_of_children();
574 const typename DoFHandlerType::level_cell_iterator
576 = cell->neighbor_child_on_subface (face, sub_nr);
578 const unsigned int n_dofs_on_neighbor
579 = sub_neighbor->get_fe().dofs_per_cell;
580 dofs_on_other_cell.resize (n_dofs_on_neighbor);
581 sub_neighbor->get_dof_indices (dofs_on_other_cell);
584 (dofs_on_this_cell, dofs_on_other_cell,
585 sparsity, keep_constrained_dofs);
587 (dofs_on_other_cell, dofs_on_this_cell,
588 sparsity, keep_constrained_dofs);
592 if (sub_neighbor->subdomain_id() != cell->subdomain_id())
594 (dofs_on_other_cell, sparsity, keep_constrained_dofs);
601 if (cell->neighbor_is_coarser(face) &&
602 neighbor->subdomain_id() == cell->subdomain_id())
605 const unsigned int n_dofs_on_neighbor
606 = neighbor->get_fe().dofs_per_cell;
607 dofs_on_other_cell.resize (n_dofs_on_neighbor);
609 neighbor->get_dof_indices (dofs_on_other_cell);
612 (dofs_on_this_cell, dofs_on_other_cell,
613 sparsity, keep_constrained_dofs);
619 if (!cell->neighbor(face)->active()
621 (neighbor->subdomain_id() != cell->subdomain_id()))
624 (dofs_on_other_cell, dofs_on_this_cell,
625 sparsity, keep_constrained_dofs);
626 if (neighbor->subdomain_id() != cell->subdomain_id())
628 (dofs_on_other_cell, sparsity, keep_constrained_dofs);
638 template <
typename DoFHandlerType,
typename SparsityPatternType>
641 SparsityPatternType &sparsity)
647 template <
int dim,
int spacedim>
653 ExcDimensionMismatch(component_couplings.n_rows(),
656 ExcDimensionMismatch(component_couplings.n_cols(),
663 for (
unsigned int i=0; i<n_dofs; ++i)
665 const unsigned int ii
673 for (
unsigned int j=0; j<n_dofs; ++j)
675 const unsigned int jj
683 dof_couplings(i,j) = component_couplings(ii,jj);
686 return dof_couplings;
691 template <
int dim,
int spacedim>
692 std::vector<Table<2,Coupling> >
697 std::vector<Table<2,Coupling> > return_value (fe.
size());
698 for (
unsigned int i=0; i<fe.
size(); ++i)
714 template <
typename DoFHandlerType,
typename SparsityPatternType>
717 SparsityPatternType &sparsity,
723 std::vector<types::global_dof_index> dofs_on_this_cell(fe.
dofs_per_cell);
724 std::vector<types::global_dof_index> dofs_on_other_cell(fe.
dofs_per_cell);
733 for (
unsigned int f=0; f<GeometryInfo<DoFHandlerType::dimension>::faces_per_cell; ++f)
736 typename DoFHandlerType::active_cell_iterator cell = dof.begin_active(),
738 for (; cell!=endc; ++cell)
739 if (cell->is_locally_owned())
741 cell->get_dof_indices (dofs_on_this_cell);
745 if (int_dof_mask(i,j) !=
none)
746 sparsity.add (dofs_on_this_cell[i],
747 dofs_on_this_cell[j]);
750 for (
unsigned int face = 0;
751 face < GeometryInfo<DoFHandlerType::dimension>::faces_per_cell;
754 const typename DoFHandlerType::face_iterator
755 cell_face = cell->face(face);
756 if (cell_face->user_flag_set ())
759 if (cell->at_boundary (face) )
763 const bool i_non_zero_i = support_on_face (i, face);
766 const bool j_non_zero_i = support_on_face (j, face);
768 if ((flux_dof_mask(i,j) ==
always)
775 sparsity.add (dofs_on_this_cell[i],
776 dofs_on_this_cell[j]);
782 typename DoFHandlerType::level_cell_iterator
783 neighbor = cell->neighbor(face);
786 if (cell->neighbor_is_coarser(face))
790 neighbor_face = cell->neighbor_of_neighbor(face);
792 if (cell_face->has_children())
794 for (
unsigned int sub_nr = 0;
795 sub_nr != cell_face->n_children();
798 const typename DoFHandlerType::level_cell_iterator
800 = cell->neighbor_child_on_subface (face, sub_nr);
802 sub_neighbor->get_dof_indices (dofs_on_other_cell);
805 const bool i_non_zero_i = support_on_face (i, face);
806 const bool i_non_zero_e = support_on_face (i, neighbor_face);
809 const bool j_non_zero_i = support_on_face (j, face);
810 const bool j_non_zero_e = support_on_face (j, neighbor_face);
812 if (flux_dof_mask(i,j) ==
always)
814 sparsity.add (dofs_on_this_cell[i],
815 dofs_on_other_cell[j]);
816 sparsity.add (dofs_on_other_cell[i],
817 dofs_on_this_cell[j]);
818 sparsity.add (dofs_on_this_cell[i],
819 dofs_on_this_cell[j]);
820 sparsity.add (dofs_on_other_cell[i],
821 dofs_on_other_cell[j]);
823 else if (flux_dof_mask(i,j) ==
nonzero)
825 if (i_non_zero_i && j_non_zero_e)
826 sparsity.add (dofs_on_this_cell[i],
827 dofs_on_other_cell[j]);
828 if (i_non_zero_e && j_non_zero_i)
829 sparsity.add (dofs_on_other_cell[i],
830 dofs_on_this_cell[j]);
831 if (i_non_zero_i && j_non_zero_i)
832 sparsity.add (dofs_on_this_cell[i],
833 dofs_on_this_cell[j]);
834 if (i_non_zero_e && j_non_zero_e)
835 sparsity.add (dofs_on_other_cell[i],
836 dofs_on_other_cell[j]);
839 if (flux_dof_mask(j,i) ==
always)
841 sparsity.add (dofs_on_this_cell[j],
842 dofs_on_other_cell[i]);
843 sparsity.add (dofs_on_other_cell[j],
844 dofs_on_this_cell[i]);
845 sparsity.add (dofs_on_this_cell[j],
846 dofs_on_this_cell[i]);
847 sparsity.add (dofs_on_other_cell[j],
848 dofs_on_other_cell[i]);
850 else if (flux_dof_mask(j,i) ==
nonzero)
852 if (j_non_zero_i && i_non_zero_e)
853 sparsity.add (dofs_on_this_cell[j],
854 dofs_on_other_cell[i]);
855 if (j_non_zero_e && i_non_zero_i)
856 sparsity.add (dofs_on_other_cell[j],
857 dofs_on_this_cell[i]);
858 if (j_non_zero_i && i_non_zero_i)
859 sparsity.add (dofs_on_this_cell[j],
860 dofs_on_this_cell[i]);
861 if (j_non_zero_e && i_non_zero_e)
862 sparsity.add (dofs_on_other_cell[j],
863 dofs_on_other_cell[i]);
867 sub_neighbor->face(neighbor_face)->set_user_flag ();
872 neighbor->get_dof_indices (dofs_on_other_cell);
875 const bool i_non_zero_i = support_on_face (i, face);
876 const bool i_non_zero_e = support_on_face (i, neighbor_face);
879 const bool j_non_zero_i = support_on_face (j, face);
880 const bool j_non_zero_e = support_on_face (j, neighbor_face);
881 if (flux_dof_mask(i,j) ==
always)
883 sparsity.add (dofs_on_this_cell[i],
884 dofs_on_other_cell[j]);
885 sparsity.add (dofs_on_other_cell[i],
886 dofs_on_this_cell[j]);
887 sparsity.add (dofs_on_this_cell[i],
888 dofs_on_this_cell[j]);
889 sparsity.add (dofs_on_other_cell[i],
890 dofs_on_other_cell[j]);
892 if (flux_dof_mask(i,j) ==
nonzero)
894 if (i_non_zero_i && j_non_zero_e)
895 sparsity.add (dofs_on_this_cell[i],
896 dofs_on_other_cell[j]);
897 if (i_non_zero_e && j_non_zero_i)
898 sparsity.add (dofs_on_other_cell[i],
899 dofs_on_this_cell[j]);
900 if (i_non_zero_i && j_non_zero_i)
901 sparsity.add (dofs_on_this_cell[i],
902 dofs_on_this_cell[j]);
903 if (i_non_zero_e && j_non_zero_e)
904 sparsity.add (dofs_on_other_cell[i],
905 dofs_on_other_cell[j]);
908 if (flux_dof_mask(j,i) ==
always)
910 sparsity.add (dofs_on_this_cell[j],
911 dofs_on_other_cell[i]);
912 sparsity.add (dofs_on_other_cell[j],
913 dofs_on_this_cell[i]);
914 sparsity.add (dofs_on_this_cell[j],
915 dofs_on_this_cell[i]);
916 sparsity.add (dofs_on_other_cell[j],
917 dofs_on_other_cell[i]);
919 if (flux_dof_mask(j,i) ==
nonzero)
921 if (j_non_zero_i && i_non_zero_e)
922 sparsity.add (dofs_on_this_cell[j],
923 dofs_on_other_cell[i]);
924 if (j_non_zero_e && i_non_zero_i)
925 sparsity.add (dofs_on_other_cell[j],
926 dofs_on_this_cell[i]);
927 if (j_non_zero_i && i_non_zero_i)
928 sparsity.add (dofs_on_this_cell[j],
929 dofs_on_this_cell[i]);
930 if (j_non_zero_e && i_non_zero_e)
931 sparsity.add (dofs_on_other_cell[j],
932 dofs_on_other_cell[i]);
936 neighbor->face(neighbor_face)->set_user_flag ();
946 template <
int dim,
int spacedim,
typename SparsityPatternType>
949 SparsityPatternType &sparsity,
960 const ::hp::FECollection<dim,spacedim> &fe = dof.get_fe();
962 std::vector<types::global_dof_index> dofs_on_this_cell(DoFTools::max_dofs_per_cell(dof));
963 std::vector<types::global_dof_index> dofs_on_other_cell(DoFTools::max_dofs_per_cell(dof));
965 const std::vector<Table<2,Coupling> >
969 typename ::hp::DoFHandler<dim,spacedim>::active_cell_iterator
970 cell = dof.begin_active(),
972 for (; cell!=endc; ++cell)
974 dofs_on_this_cell.resize (cell->get_fe().dofs_per_cell);
975 cell->get_dof_indices (dofs_on_this_cell);
978 for (
unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
979 for (
unsigned int j=0; j<cell->get_fe().dofs_per_cell; ++j)
980 if (int_dof_mask[cell->active_fe_index()](i,j) !=
none)
981 sparsity.add (dofs_on_this_cell[i],
982 dofs_on_this_cell[j]);
985 for (
unsigned int face = 0;
986 face < GeometryInfo<dim>::faces_per_cell;
989 const typename ::hp::DoFHandler<dim,spacedim>::face_iterator
990 cell_face = cell->face(face);
991 if (cell_face->user_flag_set ())
994 if (cell->at_boundary (face) )
996 for (
unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
997 for (
unsigned int j=0; j<cell->get_fe().dofs_per_cell; ++j)
998 if ((flux_mask(cell->get_fe().system_to_component_index(i).first,
999 cell->get_fe().system_to_component_index(j).first)
1002 (flux_mask(cell->get_fe().system_to_component_index(i).first,
1003 cell->get_fe().system_to_component_index(j).first)
1005 sparsity.add (dofs_on_this_cell[i],
1006 dofs_on_this_cell[j]);
1010 typename ::hp::DoFHandler<dim,spacedim>::level_cell_iterator
1011 neighbor = cell->neighbor(face);
1014 if (cell->neighbor_is_coarser(face))
1018 neighbor_face = cell->neighbor_of_neighbor(face);
1020 if (cell_face->has_children())
1022 for (
unsigned int sub_nr = 0;
1023 sub_nr != cell_face->n_children();
1026 const typename ::hp::DoFHandler<dim,spacedim>::level_cell_iterator
1028 = cell->neighbor_child_on_subface (face, sub_nr);
1030 dofs_on_other_cell.resize (sub_neighbor->get_fe().dofs_per_cell);
1031 sub_neighbor->get_dof_indices (dofs_on_other_cell);
1032 for (
unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
1034 for (
unsigned int j=0; j<sub_neighbor->get_fe().dofs_per_cell;
1037 if ((flux_mask(cell->get_fe().system_to_component_index(i).first,
1038 sub_neighbor->get_fe().system_to_component_index(j).first)
1041 (flux_mask(cell->get_fe().system_to_component_index(i).first,
1042 sub_neighbor->get_fe().system_to_component_index(j).first)
1045 sparsity.add (dofs_on_this_cell[i],
1046 dofs_on_other_cell[j]);
1047 sparsity.add (dofs_on_other_cell[i],
1048 dofs_on_this_cell[j]);
1049 sparsity.add (dofs_on_this_cell[i],
1050 dofs_on_this_cell[j]);
1051 sparsity.add (dofs_on_other_cell[i],
1052 dofs_on_other_cell[j]);
1055 if ((flux_mask(sub_neighbor->get_fe().system_to_component_index(j).first,
1056 cell->get_fe().system_to_component_index(i).first)
1059 (flux_mask(sub_neighbor->get_fe().system_to_component_index(j).first,
1060 cell->get_fe().system_to_component_index(i).first)
1063 sparsity.add (dofs_on_this_cell[j],
1064 dofs_on_other_cell[i]);
1065 sparsity.add (dofs_on_other_cell[j],
1066 dofs_on_this_cell[i]);
1067 sparsity.add (dofs_on_this_cell[j],
1068 dofs_on_this_cell[i]);
1069 sparsity.add (dofs_on_other_cell[j],
1070 dofs_on_other_cell[i]);
1074 sub_neighbor->face(neighbor_face)->set_user_flag ();
1079 dofs_on_other_cell.resize (neighbor->get_fe().dofs_per_cell);
1080 neighbor->get_dof_indices (dofs_on_other_cell);
1081 for (
unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
1083 for (
unsigned int j=0; j<neighbor->get_fe().dofs_per_cell; ++j)
1085 if ((flux_mask(cell->get_fe().system_to_component_index(i).first,
1086 neighbor->get_fe().system_to_component_index(j).first)
1089 (flux_mask(cell->get_fe().system_to_component_index(i).first,
1090 neighbor->get_fe().system_to_component_index(j).first)
1093 sparsity.add (dofs_on_this_cell[i],
1094 dofs_on_other_cell[j]);
1095 sparsity.add (dofs_on_other_cell[i],
1096 dofs_on_this_cell[j]);
1097 sparsity.add (dofs_on_this_cell[i],
1098 dofs_on_this_cell[j]);
1099 sparsity.add (dofs_on_other_cell[i],
1100 dofs_on_other_cell[j]);
1103 if ((flux_mask(neighbor->get_fe().system_to_component_index(j).first,
1104 cell->get_fe().system_to_component_index(i).first)
1107 (flux_mask(neighbor->get_fe().system_to_component_index(j).first,
1108 cell->get_fe().system_to_component_index(i).first)
1111 sparsity.add (dofs_on_this_cell[j],
1112 dofs_on_other_cell[i]);
1113 sparsity.add (dofs_on_other_cell[j],
1114 dofs_on_this_cell[i]);
1115 sparsity.add (dofs_on_this_cell[j],
1116 dofs_on_this_cell[i]);
1117 sparsity.add (dofs_on_other_cell[j],
1118 dofs_on_other_cell[i]);
1122 neighbor->face(neighbor_face)->set_user_flag ();
1135 template <
typename DoFHandlerType,
typename SparsityPatternType>
1138 SparsityPatternType &sparsity,
1146 const unsigned int n_comp = dof.get_fe().n_components();
1149 Assert (sparsity.n_rows() == n_dofs,
1150 ExcDimensionMismatch (sparsity.n_rows(), n_dofs));
1151 Assert (sparsity.n_cols() == n_dofs,
1152 ExcDimensionMismatch (sparsity.n_cols(), n_dofs));
1153 Assert (int_mask.n_rows() == n_comp,
1154 ExcDimensionMismatch (int_mask.n_rows(), n_comp));
1155 Assert (int_mask.n_cols() == n_comp,
1156 ExcDimensionMismatch (int_mask.n_cols(), n_comp));
1157 Assert (flux_mask.n_rows() == n_comp,
1158 ExcDimensionMismatch (flux_mask.n_rows(), n_comp));
1159 Assert (flux_mask.n_cols() == n_comp,
1160 ExcDimensionMismatch (flux_mask.n_cols(), n_comp));
1166 std::vector<bool> user_flags;
1167 dof.get_triangulation().save_user_flags(user_flags);
1169 (dof.get_triangulation()).clear_user_flags ();
1172 int_mask, flux_mask);
1176 (dof.get_triangulation()).load_user_flags(user_flags);
1185 #include "dof_tools_sparsity.inst" 1189 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)
::ExceptionBase & ExcMessage(std::string arg1)
unsigned int size() const
unsigned int global_dof_index
#define Assert(cond, exc)
bool is_primitive(const unsigned int i) const
const ComponentMask & get_nonzero_components(const unsigned int i) const
void make_flux_sparsity_pattern(const DoFHandlerType &dof_handler, SparsityPatternType &sparsity_pattern)
std::map< types::boundary_id, const Function< dim, Number > * > type
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
const types::boundary_id internal_face_boundary_id
virtual bool has_support_on_face(const unsigned int shape_index, const unsigned int face_index) const