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.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/filtered_iterator.h> 34 #include <deal.II/grid/grid_tools.h> 35 #include <deal.II/grid/intergrid_map.h> 36 #include <deal.II/grid/tria.h> 37 #include <deal.II/grid/tria_iterator.h> 39 #include <deal.II/hp/dof_handler.h> 40 #include <deal.II/hp/fe_collection.h> 41 #include <deal.II/hp/fe_values.h> 42 #include <deal.II/hp/mapping_collection.h> 43 #include <deal.II/hp/q_collection.h> 45 #include <deal.II/lac/affine_constraints.h> 46 #include <deal.II/lac/block_sparsity_pattern.h> 47 #include <deal.II/lac/dynamic_sparsity_pattern.h> 48 #include <deal.II/lac/sparsity_pattern.h> 49 #include <deal.II/lac/trilinos_sparsity_pattern.h> 50 #include <deal.II/lac/vector.h> 55 DEAL_II_NAMESPACE_OPEN
77 template <
int dim,
typename Number =
double>
89 double downstream_size = 0;
91 for (
unsigned int d = 0; d < dim; ++d)
93 downstream_size += (rhs[d] - lhs[d]) * weight;
96 if (downstream_size < 0)
98 else if (downstream_size > 0)
102 for (
unsigned int d = 0; d < dim; ++d)
104 if (lhs[d] == rhs[d])
106 return lhs[d] < rhs[d];
126 template <
int dim,
int spacedim>
127 std::vector<unsigned char>
131 std::vector<unsigned char> local_component_association(
140 local_component_association[i] =
151 const unsigned int first_comp =
156 local_component_association[i] = first_comp;
163 for (
unsigned int c = first_comp; c < fe.
n_components(); ++c)
164 if (component_mask[c] ==
true)
166 local_component_association[i] = c;
171 Assert(std::find(local_component_association.begin(),
172 local_component_association.end(),
173 static_cast<unsigned char>(-1)) ==
174 local_component_association.end(),
177 return local_component_association;
197 template <
typename DoFHandlerType>
199 get_component_association(
const DoFHandlerType & dof,
201 std::vector<unsigned char> &dofs_by_component)
203 const ::hp::FECollection<DoFHandlerType::dimension,
204 DoFHandlerType::space_dimension>
205 &fe_collection = dof.get_fe_collection();
207 Assert(dofs_by_component.size() == dof.n_locally_owned_dofs(),
209 dof.n_locally_owned_dofs()));
218 std::vector<std::vector<unsigned char>> local_component_association(
219 fe_collection.size());
220 for (
unsigned int f = 0; f < fe_collection.size(); ++f)
223 DoFHandlerType::space_dimension> &fe =
225 local_component_association[f] =
226 get_local_component_association(fe, component_mask);
230 std::vector<types::global_dof_index> indices;
231 for (
typename DoFHandlerType::active_cell_iterator c = dof.begin_active();
234 if (c->is_locally_owned())
236 const unsigned int fe_index = c->active_fe_index();
237 const unsigned int dofs_per_cell = c->get_fe().dofs_per_cell;
238 indices.resize(dofs_per_cell);
239 c->get_dof_indices(indices);
240 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
241 if (dof.locally_owned_dofs().is_element(indices[i]))
242 dofs_by_component[dof.locally_owned_dofs().index_within_set(
243 indices[i])] = local_component_association[fe_index][i];
255 template <
typename DoFHandlerType>
257 get_block_association(
const DoFHandlerType & dof,
258 std::vector<unsigned char> &dofs_by_block)
260 const ::hp::FECollection<DoFHandlerType::dimension,
261 DoFHandlerType::space_dimension>
262 &fe_collection = dof.get_fe_collection();
264 Assert(dofs_by_block.size() == dof.n_locally_owned_dofs(),
266 dof.n_locally_owned_dofs()));
275 std::vector<std::vector<unsigned char>> local_block_association(
276 fe_collection.size());
277 for (
unsigned int f = 0; f < fe_collection.size(); ++f)
280 DoFHandlerType::space_dimension> &fe =
282 local_block_association[f].resize(fe.dofs_per_cell,
283 static_cast<unsigned char>(-1));
284 for (
unsigned int i = 0; i < fe.dofs_per_cell; ++i)
287 Assert(std::find(local_block_association[f].begin(),
288 local_block_association[f].end(),
289 static_cast<unsigned char>(-1)) ==
290 local_block_association[f].end(),
295 std::vector<types::global_dof_index> indices;
296 for (
typename DoFHandlerType::active_cell_iterator c = dof.begin_active();
299 if (c->is_locally_owned())
301 const unsigned int fe_index = c->active_fe_index();
302 const unsigned int dofs_per_cell = c->get_fe().dofs_per_cell;
303 indices.resize(dofs_per_cell);
304 c->get_dof_indices(indices);
305 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
306 if (dof.locally_owned_dofs().is_element(indices[i]))
307 dofs_by_block[dof.locally_owned_dofs().index_within_set(
308 indices[i])] = local_block_association[fe_index][i];
315 template <
typename DoFHandlerType,
typename Number>
318 const Vector<Number> &cell_data,
320 const unsigned int component)
322 const unsigned int dim = DoFHandlerType::dimension;
323 const unsigned int spacedim = DoFHandlerType::space_dimension;
336 const bool consider_components = (
n_components(dof_handler) != 1);
339 if (consider_components ==
false)
343 std::vector<unsigned char> component_dofs(
344 dof_handler.n_locally_owned_dofs());
345 internal::get_component_association(
347 dof_handler.get_fe_collection().component_mask(
351 for (
unsigned int i = 0; i < dof_data.
size(); ++i)
352 if (component_dofs[i] == static_cast<unsigned char>(component))
357 std::vector<unsigned char> touch_count(dof_handler.n_dofs(), 0);
359 typename DoFHandlerType::active_cell_iterator cell =
360 dof_handler.begin_active(),
361 endc = dof_handler.
end();
362 std::vector<types::global_dof_index> dof_indices;
365 for (
unsigned int present_cell = 0; cell != endc; ++cell, ++present_cell)
367 const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
368 dof_indices.resize(dofs_per_cell);
369 cell->get_dof_indices(dof_indices);
371 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
374 if (!consider_components ||
375 (cell->get_fe().system_to_component_index(i).first == component))
378 dof_data(dof_indices[i]) += cell_data(present_cell);
381 ++touch_count[dof_indices[i]];
391 Assert(consider_components || (touch_count[i] != 0),
393 if (touch_count[i] != 0)
394 dof_data(i) /= touch_count[i];
400 template <
int dim,
int spacedim>
404 std::vector<bool> & selected_dofs)
411 "The given component mask is not sized correctly to represent the " 412 "components of the given finite element."));
438 internal::get_component_association(dof, component_mask, dofs_by_component);
441 if (component_mask[dofs_by_component[i]] ==
true)
442 selected_dofs[i] =
true;
448 template <
int dim,
int spacedim>
452 std::vector<bool> & selected_dofs)
459 "The given component mask is not sized correctly to represent the " 460 "components of the given finite element."));
468 std::fill_n(selected_dofs.begin(), dof.
n_dofs(),
false);
474 std::fill_n(selected_dofs.begin(), dof.
n_dofs(),
true);
480 std::fill_n(selected_dofs.begin(), dof.
n_dofs(),
false);
484 std::vector<unsigned char> dofs_by_component(dof.
n_dofs());
485 internal::get_component_association(dof, component_mask, dofs_by_component);
488 if (component_mask[dofs_by_component[i]] ==
true)
489 selected_dofs[i] =
true;
494 template <
int dim,
int spacedim>
498 std::vector<bool> & selected_dofs)
506 template <
int dim,
int spacedim>
510 std::vector<bool> & selected_dofs)
518 template <
typename DoFHandlerType>
521 const DoFHandlerType &dof,
523 std::vector<bool> & selected_dofs)
526 DoFHandlerType::space_dimension> &fe = dof.get_fe();
530 "The given component mask is not sized correctly to represent the " 531 "components of the given finite element."));
532 Assert(selected_dofs.size() == dof.n_dofs(level),
539 std::fill_n(selected_dofs.begin(), dof.n_dofs(level),
false);
545 std::fill_n(selected_dofs.begin(), dof.n_dofs(level),
true);
550 std::fill_n(selected_dofs.begin(), dof.n_dofs(level),
false);
554 std::vector<unsigned char> local_component_asssociation =
555 internal::get_local_component_association(fe, component_mask);
556 std::vector<bool> local_selected_dofs(fe.dofs_per_cell);
557 for (
unsigned int i = 0; i < fe.dofs_per_cell; ++i)
558 local_selected_dofs[i] = component_mask[local_component_asssociation[i]];
561 std::vector<types::global_dof_index> indices(fe.dofs_per_cell);
562 typename DoFHandlerType::level_cell_iterator c;
563 for (c = dof.begin(level); c != dof.end(level); ++c)
565 c->get_mg_dof_indices(indices);
566 for (
unsigned int i = 0; i < fe.dofs_per_cell; ++i)
567 selected_dofs[indices[i]] = local_selected_dofs[i];
573 template <
typename DoFHandlerType>
576 const DoFHandlerType &dof,
578 std::vector<bool> & selected_dofs)
583 dof.get_fe().component_mask(block_mask),
589 template <
typename DoFHandlerType>
593 std::vector<bool> & selected_dofs,
594 const std::set<types::boundary_id> &boundary_ids)
597 DoFHandlerType::dimension,
598 DoFHandlerType::space_dimension
> *>(
599 &dof_handler.get_triangulation()) ==
nullptr),
601 "This function can not be used with distributed triangulations." 602 "See the documentation for more information."));
608 selected_dofs.clear();
609 selected_dofs.resize(dof_handler.n_dofs(),
false);
612 indices.fill_binary_vector(selected_dofs);
616 template <
typename DoFHandlerType>
621 const std::set<types::boundary_id> &boundary_ids)
624 ExcMessage(
"Component mask has invalid size."));
628 const unsigned int dim = DoFHandlerType::dimension;
631 selected_dofs.
clear();
632 selected_dofs.
set_size(dof_handler.n_dofs());
636 const bool check_boundary_id = (boundary_ids.size() != 0);
640 const bool check_vector_component =
645 std::vector<types::global_dof_index> face_dof_indices;
654 for (
typename DoFHandlerType::active_cell_iterator cell =
655 dof_handler.begin_active();
656 cell != dof_handler.end();
661 if (cell->is_artificial() ==
false)
662 for (
unsigned int face = 0;
663 face < GeometryInfo<DoFHandlerType::dimension>::faces_per_cell;
665 if (cell->at_boundary(face))
666 if (!check_boundary_id ||
667 (boundary_ids.find(cell->face(face)->boundary_id()) !=
671 DoFHandlerType::space_dimension> &fe =
675 face_dof_indices.resize(dofs_per_face);
676 cell->face(face)->get_dof_indices(face_dof_indices,
677 cell->active_fe_index());
679 for (
unsigned int i = 0; i < fe.dofs_per_face; ++i)
680 if (!check_vector_component)
681 selected_dofs.
add_index(face_dof_indices[i]);
689 const unsigned int cell_index =
693 (i < 2 * fe.dofs_per_vertex ?
695 i + 2 * fe.dofs_per_vertex) :
696 (dim == 3 ? (i < 4 * fe.dofs_per_vertex ?
698 (i < 4 * fe.dofs_per_vertex +
699 4 * fe.dofs_per_line ?
700 i + 4 * fe.dofs_per_vertex :
701 i + 4 * fe.dofs_per_vertex +
702 8 * fe.dofs_per_line)) :
704 if (fe.is_primitive(cell_index))
707 [fe.face_system_to_component_index(i).first] ==
709 selected_dofs.
add_index(face_dof_indices[i]);
713 const unsigned int first_nonzero_comp =
714 fe.get_nonzero_components(cell_index)
715 .first_selected_component();
716 Assert(first_nonzero_comp < fe.n_components(),
719 if (component_mask[first_nonzero_comp] ==
true)
720 selected_dofs.
add_index(face_dof_indices[i]);
728 template <
typename DoFHandlerType>
731 const DoFHandlerType & dof_handler,
733 std::vector<bool> & selected_dofs,
734 const std::set<types::boundary_id> &boundary_ids)
737 ExcMessage(
"This component mask has the wrong size."));
744 const bool check_boundary_id = (boundary_ids.size() != 0);
748 const bool check_vector_component =
752 selected_dofs.clear();
753 selected_dofs.resize(dof_handler.n_dofs(),
false);
754 std::vector<types::global_dof_index> cell_dof_indices;
763 for (
typename DoFHandlerType::active_cell_iterator cell =
764 dof_handler.begin_active();
765 cell != dof_handler.end();
767 for (
unsigned int face = 0;
768 face < GeometryInfo<DoFHandlerType::dimension>::faces_per_cell;
770 if (cell->at_boundary(face))
771 if (!check_boundary_id ||
772 (boundary_ids.find(cell->face(face)->boundary_id()) !=
776 DoFHandlerType::space_dimension> &fe =
780 cell_dof_indices.resize(dofs_per_cell);
781 cell->get_dof_indices(cell_dof_indices);
783 for (
unsigned int i = 0; i < fe.dofs_per_cell; ++i)
784 if (fe.has_support_on_face(i, face))
786 if (!check_vector_component)
787 selected_dofs[cell_dof_indices[i]] =
true;
793 if (fe.is_primitive(i))
794 selected_dofs[cell_dof_indices[i]] =
795 (component_mask[fe.system_to_component_index(i)
799 const unsigned int first_nonzero_comp =
800 fe.get_nonzero_components(i)
801 .first_selected_component();
802 Assert(first_nonzero_comp < fe.n_components(),
805 selected_dofs[cell_dof_indices[i]] =
806 (component_mask[first_nonzero_comp] ==
true);
815 template <
typename DoFHandlerType,
typename number>
818 const DoFHandlerType &dof_handler,
820 bool(
const typename DoFHandlerType::active_cell_iterator &)> &predicate,
823 const std::function<bool(
824 const typename DoFHandlerType::active_cell_iterator &)>
826 [=](
const typename DoFHandlerType::active_cell_iterator &cell) ->
bool {
827 return cell->is_locally_owned() && predicate(cell);
830 std::vector<types::global_dof_index> local_dof_indices;
834 std::set<types::global_dof_index> predicate_dofs;
836 typename DoFHandlerType::active_cell_iterator cell =
837 dof_handler.begin_active(),
838 endc = dof_handler.end();
839 for (; cell != endc; ++cell)
840 if (!cell->is_artificial() && predicate(cell))
842 local_dof_indices.resize(cell->get_fe().dofs_per_cell);
843 cell->get_dof_indices(local_dof_indices);
844 predicate_dofs.insert(local_dof_indices.begin(),
845 local_dof_indices.end());
849 std::set<types::global_dof_index> dofs_with_support_on_halo_cells;
851 const std::vector<typename DoFHandlerType::active_cell_iterator>
854 for (
typename std::vector<
855 typename DoFHandlerType::active_cell_iterator>::const_iterator it =
857 it != halo_cells.end();
869 const unsigned int dofs_per_cell = (*it)->get_fe().dofs_per_cell;
870 local_dof_indices.resize(dofs_per_cell);
871 (*it)->get_dof_indices(local_dof_indices);
872 dofs_with_support_on_halo_cells.insert(local_dof_indices.begin(),
873 local_dof_indices.end());
885 std::set<types::global_dof_index> extra_halo;
886 for (
const auto dof : dofs_with_support_on_halo_cells)
892 const unsigned int line_size = line_ptr->size();
893 for (
unsigned int j = 0; j < line_size; ++j)
894 extra_halo.insert((*line_ptr)[j].first);
897 dofs_with_support_on_halo_cells.insert(extra_halo.begin(),
903 IndexSet support_set(dof_handler.n_dofs());
904 support_set.
add_indices(predicate_dofs.begin(), predicate_dofs.end());
905 support_set.compress();
907 IndexSet halo_set(dof_handler.n_dofs());
908 halo_set.
add_indices(dofs_with_support_on_halo_cells.begin(),
909 dofs_with_support_on_halo_cells.end());
912 support_set.subtract_set(halo_set);
924 template <
int spacedim>
927 const ::DoFHandler<1, spacedim> &dof_handler)
930 return IndexSet(dof_handler.n_dofs());
934 template <
int spacedim>
937 const ::DoFHandler<2, spacedim> &dof_handler)
939 const unsigned int dim = 2;
941 IndexSet selected_dofs(dof_handler.n_dofs());
947 for (
const auto &cell : dof_handler.active_cell_iterators())
948 if (!cell->is_artificial())
950 for (
unsigned int face = 0;
951 face < GeometryInfo<dim>::faces_per_cell;
953 if (cell->face(face)->has_children())
955 const typename ::DoFHandler<dim,
956 spacedim>::line_iterator
957 line = cell->face(face);
959 for (
unsigned int dof = 0; dof != fe.dofs_per_vertex; ++dof)
960 selected_dofs.add_index(
961 line->child(0)->vertex_dof_index(1, dof));
963 for (
unsigned int child = 0; child < 2; ++child)
965 if (cell->neighbor_child_on_subface(face, child)
968 for (
unsigned int dof = 0; dof != fe.dofs_per_line;
970 selected_dofs.add_index(
971 line->child(child)->dof_index(dof));
976 selected_dofs.compress();
977 return selected_dofs;
981 template <
int spacedim>
984 const ::DoFHandler<3, spacedim> &dof_handler)
986 const unsigned int dim = 3;
988 IndexSet selected_dofs(dof_handler.n_dofs());
989 IndexSet unconstrained_dofs(dof_handler.n_dofs());
993 for (
const auto &cell : dof_handler.active_cell_iterators())
994 if (!cell->is_artificial())
995 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
997 const typename ::DoFHandler<dim, spacedim>::face_iterator
998 face = cell->face(f);
999 if (cell->face(f)->has_children())
1001 for (
unsigned int child = 0; child < 4; ++child)
1002 if (!cell->neighbor_child_on_subface(f, child)
1006 std::vector<types::global_dof_index> ldi(
1008 face->child(child)->get_dof_indices(ldi);
1009 selected_dofs.add_indices(ldi.begin(), ldi.end());
1014 for (
unsigned int vertex = 0; vertex < 4; ++vertex)
1015 for (
unsigned int dof = 0; dof != fe.dofs_per_vertex;
1017 unconstrained_dofs.add_index(
1018 face->vertex_dof_index(vertex, dof));
1021 selected_dofs.subtract_set(unconstrained_dofs);
1022 return selected_dofs;
1029 template <
int dim,
int spacedim>
1032 std::vector<bool> & selected_dofs)
1034 const IndexSet selected_dofs_as_index_set =
1039 std::fill(selected_dofs.begin(), selected_dofs.end(),
false);
1040 for (
const auto index : selected_dofs_as_index_set)
1041 selected_dofs[index] =
true;
1046 template <
int dim,
int spacedim>
1050 return internal::extract_hanging_node_dofs(dof_handler);
1055 template <
typename DoFHandlerType>
1059 std::vector<bool> & selected_dofs)
1061 Assert(selected_dofs.size() == dof_handler.n_dofs(),
1065 std::fill_n(selected_dofs.begin(), dof_handler.n_dofs(),
false);
1067 std::vector<types::global_dof_index> local_dof_indices;
1072 typename DoFHandlerType::active_cell_iterator cell =
1073 dof_handler.begin_active(),
1074 endc = dof_handler.end();
1075 for (; cell != endc; ++cell)
1076 if (cell->subdomain_id() == subdomain_id)
1078 const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
1079 local_dof_indices.resize(dofs_per_cell);
1080 cell->get_dof_indices(local_dof_indices);
1081 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1082 selected_dofs[local_dof_indices[i]] =
true;
1088 template <
typename DoFHandlerType>
1094 dof_set = dof_handler.locally_owned_dofs();
1100 template <
typename DoFHandlerType>
1106 dof_set = dof_handler.locally_owned_dofs();
1111 std::vector<types::global_dof_index> dof_indices;
1112 std::set<types::global_dof_index> global_dof_indices;
1114 typename DoFHandlerType::active_cell_iterator cell =
1115 dof_handler.begin_active(),
1116 endc = dof_handler.
end();
1117 for (; cell != endc; ++cell)
1118 if (cell->is_locally_owned())
1120 dof_indices.resize(cell->get_fe().dofs_per_cell);
1121 cell->get_dof_indices(dof_indices);
1125 global_dof_indices.insert(dof_index);
1128 dof_set.
add_indices(global_dof_indices.begin(), global_dof_indices.end());
1135 template <
typename DoFHandlerType>
1141 dof_set = dof_handler.locally_owned_dofs();
1151 std::vector<types::global_dof_index> dof_indices;
1152 std::vector<types::global_dof_index> dofs_on_ghosts;
1154 typename DoFHandlerType::active_cell_iterator cell =
1155 dof_handler.begin_active(),
1156 endc = dof_handler.
end();
1157 for (; cell != endc; ++cell)
1158 if (cell->is_ghost())
1160 dof_indices.resize(cell->get_fe().dofs_per_cell);
1161 cell->get_dof_indices(dof_indices);
1162 for (
const auto dof_index : dof_indices)
1164 dofs_on_ghosts.push_back(dof_index);
1168 std::sort(dofs_on_ghosts.begin(), dofs_on_ghosts.end());
1170 std::unique(dofs_on_ghosts.begin(),
1171 dofs_on_ghosts.end()));
1177 template <
typename DoFHandlerType>
1180 const unsigned int level,
1184 dof_set = dof_handler.locally_owned_mg_dofs(level);
1194 std::vector<types::global_dof_index> dof_indices;
1195 std::vector<types::global_dof_index> dofs_on_ghosts;
1197 typename DoFHandlerType::cell_iterator cell = dof_handler.
begin(level),
1198 endc = dof_handler.end(level);
1199 for (; cell != endc; ++cell)
1204 if (
id == dof_handler.get_triangulation().locally_owned_subdomain() ||
1208 dof_indices.resize(cell->get_fe().dofs_per_cell);
1209 cell->get_mg_dof_indices(dof_indices);
1210 for (
const auto dof_index : dof_indices)
1212 dofs_on_ghosts.push_back(dof_index);
1216 std::sort(dofs_on_ghosts.begin(), dofs_on_ghosts.end());
1218 std::unique(dofs_on_ghosts.begin(),
1219 dofs_on_ghosts.end()));
1226 template <
typename DoFHandlerType>
1230 std::vector<std::vector<bool>> &constant_modes)
1232 const unsigned int n_components = dof_handler.get_fe(0).n_components();
1236 std::vector<unsigned char> dofs_by_component(
1237 dof_handler.n_locally_owned_dofs());
1238 internal::get_component_association(dof_handler,
1241 unsigned int n_selected_dofs = 0;
1243 if (component_mask[i] ==
true)
1245 std::count(dofs_by_component.begin(), dofs_by_component.end(), i);
1248 const IndexSet &locally_owned_dofs = dof_handler.locally_owned_dofs();
1249 std::vector<unsigned int> component_numbering(
1251 for (
unsigned int i = 0, count = 0; i < locally_owned_dofs.n_elements();
1253 if (component_mask[dofs_by_component[i]])
1254 component_numbering[i] = count++;
1261 const ::hp::FECollection<DoFHandlerType::dimension,
1262 DoFHandlerType::space_dimension>
1263 & fe_collection = dof_handler.get_fe_collection();
1264 std::vector<Table<2, bool>> element_constant_modes;
1265 std::vector<std::vector<std::pair<unsigned int, unsigned int>>>
1267 unsigned int n_constant_modes = 0;
1268 for (
unsigned int f = 0; f < fe_collection.size(); ++f)
1270 std::pair<Table<2, bool>, std::vector<unsigned int>> data =
1271 fe_collection[f].get_constant_modes();
1272 element_constant_modes.push_back(data.first);
1274 for (
unsigned int i = 0; i < data.second.size(); ++i)
1275 if (component_mask[data.second[i]])
1276 constant_mode_to_component_translation[data.second[i]]
1277 .emplace_back(n_constant_modes++, i);
1279 element_constant_modes[0].n_rows());
1283 constant_modes.clear();
1284 constant_modes.resize(n_constant_modes,
1285 std::vector<bool>(n_selected_dofs,
false));
1288 std::vector<types::global_dof_index> dof_indices;
1289 for (
const auto &cell : dof_handler.active_cell_iterators())
1290 if (cell->is_locally_owned())
1292 dof_indices.resize(cell->get_fe().dofs_per_cell);
1293 cell->get_dof_indices(dof_indices);
1295 for (
unsigned int i = 0; i < dof_indices.size(); ++i)
1296 if (locally_owned_dofs.is_element(dof_indices[i]))
1298 const unsigned int loc_index =
1299 locally_owned_dofs.index_within_set(dof_indices[i]);
1300 const unsigned int comp = dofs_by_component[loc_index];
1301 if (component_mask[comp])
1302 for (
auto &indices :
1303 constant_mode_to_component_translation[comp])
1304 constant_modes[indices
1305 .first][component_numbering[loc_index]] =
1306 element_constant_modes[cell->active_fe_index()](
1314 template <
typename DoFHandlerType>
1317 std::vector<unsigned int> &active_fe_indices)
1320 dof_handler.get_triangulation().n_active_cells());
1322 typename DoFHandlerType::active_cell_iterator cell =
1323 dof_handler.begin_active(),
1324 endc = dof_handler.end();
1325 for (; cell != endc; ++cell)
1326 active_fe_indices[cell->active_cell_index()] = cell->active_fe_index();
1329 template <
typename DoFHandlerType>
1330 std::vector<IndexSet>
1333 Assert(dof_handler.n_dofs() > 0,
1334 ExcMessage(
"The given DoFHandler has no DoFs."));
1339 DoFHandlerType::dimension,
1340 DoFHandlerType::space_dimension
> *>(
1341 &dof_handler.get_triangulation()) ==
nullptr),
1343 "For parallel::distributed::Triangulation objects and " 1344 "associated DoF handler objects, asking for any information " 1345 "related to a subdomain other than the locally owned one does " 1346 "not make sense."));
1350 std::vector<::types::subdomain_id> subdomain_association(
1351 dof_handler.n_dofs());
1352 ::DoFTools::get_subdomain_association(dof_handler,
1353 subdomain_association);
1367 const unsigned int n_subdomains =
1370 DoFHandlerType::space_dimension
> *>(
1371 &dof_handler.get_triangulation()) ==
nullptr ?
1373 unsigned int max_subdomain_id = 0;
1374 for (
const auto &cell : dof_handler.active_cell_iterators())
1376 std::max(max_subdomain_id, cell->subdomain_id());
1377 return max_subdomain_id + 1;
1382 DoFHandlerType::space_dimension
> *>(
1383 &dof_handler.get_triangulation())
1384 ->get_communicator()));
1385 Assert(n_subdomains > *std::max_element(subdomain_association.begin(),
1386 subdomain_association.end()),
1389 std::vector<::IndexSet> index_sets(
1390 n_subdomains, ::
IndexSet(dof_handler.n_dofs()));
1398 index < subdomain_association.size();
1402 if (subdomain_association[index] != this_subdomain)
1404 index_sets[this_subdomain].add_range(i_min, index);
1406 this_subdomain = subdomain_association[index];
1411 if (i_min == subdomain_association.size() - 1)
1413 index_sets[this_subdomain].add_index(i_min);
1419 index_sets[this_subdomain].add_range(i_min,
1420 subdomain_association.size());
1423 for (
unsigned int i = 0; i < n_subdomains; i++)
1424 index_sets[i].compress();
1429 template <
typename DoFHandlerType>
1430 std::vector<IndexSet>
1436 DoFHandlerType::dimension,
1437 DoFHandlerType::space_dimension
> *>(
1438 &dof_handler.get_triangulation()) ==
nullptr),
1440 "For parallel::distributed::Triangulation objects and " 1441 "associated DoF handler objects, asking for any information " 1442 "related to a subdomain other than the locally owned one does " 1443 "not make sense."));
1451 std::vector<IndexSet> dof_set =
1453 const ::types::subdomain_id n_subdomains = dof_set.size();
1459 subdomain_id < n_subdomains;
1464 const typename DoFHandlerType::active_cell_iterator &)>
1466 const std::vector<typename DoFHandlerType::active_cell_iterator>
1471 std::vector<types::global_dof_index> local_dof_indices;
1472 std::set<types::global_dof_index> subdomain_halo_global_dof_indices;
1473 for (
typename std::vector<
1474 typename DoFHandlerType::active_cell_iterator>::const_iterator
1475 it_cell = active_halo_layer.begin();
1476 it_cell != active_halo_layer.end();
1479 const typename DoFHandlerType::active_cell_iterator &cell =
1482 cell->subdomain_id() != subdomain_id,
1484 "The subdomain ID of the halo cell should not match that of the vector entry."));
1486 local_dof_indices.resize(cell->get_fe().dofs_per_cell);
1487 cell->get_dof_indices(local_dof_indices);
1491 subdomain_halo_global_dof_indices.insert(local_dof_index);
1494 dof_set[subdomain_id].add_indices(
1495 subdomain_halo_global_dof_indices.begin(),
1496 subdomain_halo_global_dof_indices.end());
1498 dof_set[subdomain_id].compress();
1504 template <
typename DoFHandlerType>
1507 const DoFHandlerType & dof_handler,
1508 std::vector<types::subdomain_id> &subdomain_association)
1513 DoFHandlerType::dimension,
1514 DoFHandlerType::space_dimension
> *>(
1515 &dof_handler.get_triangulation()) ==
nullptr),
1517 "For parallel::distributed::Triangulation objects and " 1518 "associated DoF handler objects, asking for any subdomain other " 1519 "than the locally owned one does not make sense."));
1521 Assert(subdomain_association.size() == dof_handler.n_dofs(),
1523 dof_handler.n_dofs()));
1535 std::vector<types::subdomain_id> cell_owners(
1536 dof_handler.get_triangulation().n_active_cells());
1538 DoFHandlerType::space_dimension>
1540 DoFHandlerType::dimension,
1541 DoFHandlerType::space_dimension
> *>(
1542 &dof_handler.get_triangulation())))
1544 cell_owners = tr->get_true_subdomain_ids_of_cells();
1545 Assert(tr->get_true_subdomain_ids_of_cells().size() ==
1546 tr->n_active_cells(),
1551 for (
typename DoFHandlerType::active_cell_iterator cell =
1552 dof_handler.begin_active();
1553 cell != dof_handler.end();
1555 if (cell->is_locally_owned())
1556 cell_owners[cell->active_cell_index()] = cell->subdomain_id();
1560 std::fill_n(subdomain_association.begin(),
1561 dof_handler.n_dofs(),
1564 std::vector<types::global_dof_index> local_dof_indices;
1569 typename DoFHandlerType::active_cell_iterator cell =
1570 dof_handler.begin_active(),
1571 endc = dof_handler.end();
1572 for (; cell != endc; ++cell)
1575 cell_owners[cell->active_cell_index()];
1576 const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
1577 local_dof_indices.resize(dofs_per_cell);
1578 cell->get_dof_indices(local_dof_indices);
1584 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1585 if (subdomain_association[local_dof_indices[i]] ==
1587 subdomain_association[local_dof_indices[i]] = subdomain_id;
1588 else if (subdomain_association[local_dof_indices[i]] > subdomain_id)
1590 subdomain_association[local_dof_indices[i]] = subdomain_id;
1594 Assert(std::find(subdomain_association.begin(),
1595 subdomain_association.end(),
1597 subdomain_association.end(),
1603 template <
typename DoFHandlerType>
1608 std::vector<types::subdomain_id> subdomain_association(
1609 dof_handler.n_dofs());
1612 return std::count(subdomain_association.begin(),
1613 subdomain_association.end(),
1619 template <
typename DoFHandlerType>
1626 Assert((dof_handler.get_triangulation().locally_owned_subdomain() ==
1629 dof_handler.get_triangulation().locally_owned_subdomain()),
1631 "For parallel::distributed::Triangulation objects and " 1632 "associated DoF handler objects, asking for any subdomain other " 1633 "than the locally owned one does not make sense."));
1635 IndexSet index_set(dof_handler.n_dofs());
1637 std::vector<types::global_dof_index> local_dof_indices;
1645 std::vector<types::global_dof_index> subdomain_indices;
1647 typename DoFHandlerType::active_cell_iterator cell =
1648 dof_handler.begin_active(),
1649 endc = dof_handler.
end();
1650 for (; cell != endc; ++cell)
1651 if ((cell->is_artificial() ==
false) &&
1652 (cell->subdomain_id() == subdomain))
1654 const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
1655 local_dof_indices.resize(dofs_per_cell);
1656 cell->get_dof_indices(local_dof_indices);
1657 subdomain_indices.insert(subdomain_indices.end(),
1658 local_dof_indices.begin(),
1659 local_dof_indices.end());
1662 std::sort(subdomain_indices.begin(), subdomain_indices.end());
1663 subdomain_indices.erase(std::unique(subdomain_indices.begin(),
1664 subdomain_indices.end()),
1665 subdomain_indices.end());
1668 index_set.add_indices(subdomain_indices.begin(), subdomain_indices.end());
1669 index_set.compress();
1676 template <
typename DoFHandlerType>
1679 const DoFHandlerType & dof_handler,
1681 std::vector<unsigned int> &n_dofs_on_subdomain)
1683 Assert(n_dofs_on_subdomain.size() == dof_handler.get_fe(0).n_components(),
1685 dof_handler.get_fe(0).n_components()));
1686 std::fill(n_dofs_on_subdomain.begin(), n_dofs_on_subdomain.end(), 0);
1694 DoFHandlerType::dimension,
1695 DoFHandlerType::space_dimension>::active_cell_iterator cell =
1696 dof_handler.get_triangulation().begin_active();
1697 cell != dof_handler.get_triangulation().end();
1699 if (cell->subdomain_id() == subdomain)
1705 ExcMessage(
"There are no cells for the given subdomain!"));
1709 std::vector<types::subdomain_id> subdomain_association(
1710 dof_handler.n_dofs());
1713 std::vector<unsigned char> component_association(dof_handler.n_dofs());
1714 internal::get_component_association(dof_handler,
1715 std::vector<bool>(),
1716 component_association);
1718 for (
unsigned int c = 0; c < dof_handler.get_fe(0).n_components(); ++c)
1721 if ((subdomain_association[i] == subdomain) &&
1722 (component_association[i] ==
static_cast<unsigned char>(c)))
1723 ++n_dofs_on_subdomain[c];
1735 template <
int dim,
int spacedim>
1738 const std::vector<unsigned char> & dofs_by_component,
1739 const std::vector<unsigned int> & target_component,
1740 const bool only_once,
1741 std::vector<types::global_dof_index> &dofs_per_component,
1742 unsigned int & component)
1753 resolve_components(base,
1761 for (
unsigned int dd = 0; dd < d; ++dd, ++component)
1762 dofs_per_component[target_component[component]] +=
1763 std::count(dofs_by_component.begin(),
1764 dofs_by_component.end(),
1771 for (
unsigned int dd = 1; dd < d; ++dd)
1772 dofs_per_component[target_component[component - d + dd]] =
1773 dofs_per_component[target_component[component - d]];
1780 template <
int dim,
int spacedim>
1783 const std::vector<unsigned char> & dofs_by_component,
1784 const std::vector<unsigned int> & target_component,
1785 const bool only_once,
1786 std::vector<types::global_dof_index> &dofs_per_component,
1787 unsigned int & component)
1792 for (
unsigned int fe = 1; fe < fe_collection.
size(); ++fe)
1797 Assert(fe_collection[fe].n_base_elements() ==
1798 fe_collection[0].n_base_elements(),
1800 for (
unsigned int b = 0;
b < fe_collection[0].n_base_elements(); ++
b)
1805 Assert(fe_collection[fe].base_element(b).n_base_elements() ==
1806 fe_collection[0].base_element(b).n_base_elements(),
1811 resolve_components(fe_collection[0],
1829 template <
int dim,
int spacedim>
1841 template <
int dim,
int spacedim>
1843 all_elements_are_primitive(
1844 const ::hp::FECollection<dim, spacedim> &fe_collection)
1846 for (
unsigned int i = 0; i < fe_collection.size(); ++i)
1847 if (fe_collection[i].is_primitive() ==
false)
1855 template <
typename DoFHandlerType>
1858 const DoFHandlerType & dof_handler,
1859 std::vector<types::global_dof_index> &dofs_per_component,
1861 std::vector<unsigned int> target_component)
1863 const unsigned int n_components = dof_handler.get_fe(0).n_components();
1865 std::fill(dofs_per_component.begin(),
1866 dofs_per_component.end(),
1871 if (target_component.size() == 0)
1875 target_component[i] = i;
1882 const unsigned int max_component =
1883 *std::max_element(target_component.begin(), target_component.end());
1884 const unsigned int n_target_components = max_component + 1;
1885 (void)n_target_components;
1893 dofs_per_component[0] = dof_handler.n_locally_owned_dofs();
1900 std::vector<unsigned char> dofs_by_component(
1901 dof_handler.n_locally_owned_dofs());
1902 internal::get_component_association(dof_handler,
1907 unsigned int component = 0;
1908 internal::resolve_components(dof_handler.get_fe_collection(),
1918 Assert((internal::all_elements_are_primitive(
1919 dof_handler.get_fe_collection()) ==
false) ||
1920 (std::accumulate(dofs_per_component.begin(),
1921 dofs_per_component.end(),
1923 dof_handler.n_locally_owned_dofs()),
1927 #ifdef DEAL_II_WITH_MPI 1928 const unsigned int dim = DoFHandlerType::dimension;
1929 const unsigned int spacedim = DoFHandlerType::space_dimension;
1933 &dof_handler.get_triangulation())))
1935 std::vector<types::global_dof_index> local_dof_count =
1938 const int ierr = MPI_Allreduce(local_dof_count.data(),
1939 dofs_per_component.data(),
1940 n_target_components,
1941 DEAL_II_DOF_INDEX_MPI_TYPE,
1943 tria->get_communicator());
1951 template <
typename DoFHandlerType>
1954 std::vector<types::global_dof_index> &dofs_per_block,
1955 const std::vector<unsigned int> & target_block_)
1957 std::vector<unsigned int> target_block = target_block_;
1959 const ::hp::FECollection<DoFHandlerType::dimension,
1960 DoFHandlerType::space_dimension>
1961 &fe_collection = dof_handler.get_fe_collection();
1964 for (
unsigned int this_fe = 0; this_fe < fe_collection.size(); ++this_fe)
1967 DoFHandlerType::space_dimension> &fe =
1968 fe_collection[this_fe];
1969 std::fill(dofs_per_block.begin(),
1970 dofs_per_block.end(),
1975 if (target_block.size() == 0)
1977 target_block.resize(fe.n_blocks());
1978 for (
unsigned int i = 0; i < fe.n_blocks(); ++i)
1979 target_block[i] = i;
1982 Assert(target_block.size() == fe.n_blocks(),
1987 const unsigned int max_block =
1988 *std::max_element(target_block.begin(), target_block.end());
1989 const unsigned int n_target_blocks = max_block + 1;
1990 (void)n_target_blocks;
1992 const unsigned int n_blocks = fe.n_blocks();
2000 dofs_per_block[0] = dof_handler.n_dofs();
2004 std::vector<unsigned char> dofs_by_block(
2005 dof_handler.n_locally_owned_dofs());
2006 internal::get_block_association(dof_handler, dofs_by_block);
2009 for (
unsigned int block = 0; block < fe.n_blocks(); ++block)
2010 dofs_per_block[target_block[block]] +=
2011 std::count(dofs_by_block.begin(), dofs_by_block.end(), block);
2013 #ifdef DEAL_II_WITH_MPI 2017 DoFHandlerType::space_dimension>
2019 DoFHandlerType::dimension,
2020 DoFHandlerType::space_dimension
> *>(
2021 &dof_handler.get_triangulation())))
2023 std::vector<types::global_dof_index> local_dof_count =
2025 const int ierr = MPI_Allreduce(local_dof_count.data(),
2026 dofs_per_block.data(),
2028 DEAL_II_DOF_INDEX_MPI_TYPE,
2030 tria->get_communicator());
2039 template <
typename DoFHandlerType>
2042 std::vector<types::global_dof_index> &mapping)
2045 mapping.insert(mapping.end(),
2046 dof_handler.n_dofs(),
2049 std::vector<types::global_dof_index> dofs_on_face;
2059 typename DoFHandlerType::active_cell_iterator cell =
2060 dof_handler.begin_active(),
2061 endc = dof_handler.end();
2062 for (; cell != endc; ++cell)
2063 for (
unsigned int f = 0;
2064 f < GeometryInfo<DoFHandlerType::dimension>::faces_per_cell;
2066 if (cell->at_boundary(f))
2068 const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
2069 dofs_on_face.resize(dofs_per_face);
2070 cell->face(f)->get_dof_indices(dofs_on_face,
2071 cell->active_fe_index());
2072 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2074 mapping[dofs_on_face[i]] = next_boundary_index++;
2082 template <
typename DoFHandlerType>
2085 const std::set<types::boundary_id> &boundary_ids,
2086 std::vector<types::global_dof_index> &mapping)
2093 mapping.insert(mapping.end(),
2094 dof_handler.n_dofs(),
2098 if (boundary_ids.size() == 0)
2101 std::vector<types::global_dof_index> dofs_on_face;
2105 typename DoFHandlerType::active_cell_iterator cell =
2106 dof_handler.begin_active(),
2107 endc = dof_handler.end();
2108 for (; cell != endc; ++cell)
2109 for (
unsigned int f = 0;
2110 f < GeometryInfo<DoFHandlerType::dimension>::faces_per_cell;
2112 if (boundary_ids.find(cell->face(f)->boundary_id()) !=
2115 const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
2116 dofs_on_face.resize(dofs_per_face);
2117 cell->face(f)->get_dof_indices(dofs_on_face,
2118 cell->active_fe_index());
2119 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2121 mapping[dofs_on_face[i]] = next_boundary_index++;
2125 dof_handler.n_boundary_dofs(boundary_ids));
2132 template <
typename DoFHandlerType>
2136 DoFHandlerType::space_dimension> &mapping,
2137 const DoFHandlerType & dof_handler,
2141 const unsigned int dim = DoFHandlerType::dimension;
2142 const unsigned int spacedim = DoFHandlerType::space_dimension;
2145 dof_handler.get_fe_collection();
2148 for (
unsigned int fe_index = 0; fe_index < fe_collection.
size();
2152 Assert(fe_collection[fe_index].has_support_points(),
2155 fe_collection[fe_index].get_unit_support_points()));
2169 typename DoFHandlerType::active_cell_iterator cell = dof_handler
2171 endc = dof_handler.end();
2173 std::vector<types::global_dof_index> local_dof_indices;
2174 for (; cell != endc; ++cell)
2176 if (cell->is_artificial() ==
false)
2178 hp_fe_values.reinit(cell);
2182 local_dof_indices.resize(cell->get_fe().dofs_per_cell);
2183 cell->get_dof_indices(local_dof_indices);
2185 const std::vector<Point<spacedim>> &points =
2187 for (
unsigned int i = 0; i < cell->get_fe().dofs_per_cell; ++i)
2189 support_points[local_dof_indices[i]] = points[i];
2194 template <
typename DoFHandlerType>
2198 DoFHandlerType::space_dimension> &mapping,
2199 const DoFHandlerType & dof_handler,
2212 Assert(x_support_points.find(i) != x_support_points.end(),
2214 support_points[i] = x_support_points[i];
2220 template <
int dim,
int spacedim>
2231 "This function can not be used with distributed triangulations." 2232 "See the documentation for more information."));
2238 internal::map_dofs_to_support_points(mapping_collection,
2244 template <
int dim,
int spacedim>
2256 "This function can not be used with distributed triangulations." 2257 "See the documentation for more information."));
2261 internal::map_dofs_to_support_points(mapping, dof_handler, support_points);
2265 template <
int dim,
int spacedim>
2272 support_points.clear();
2278 internal::map_dofs_to_support_points(mapping_collection,
2284 template <
int dim,
int spacedim>
2291 support_points.clear();
2295 internal::map_dofs_to_support_points(mapping, dof_handler, support_points);
2298 template <
int spacedim>
2306 using dof_map_t = std::map<types::global_dof_index, Point<spacedim>>;
2308 using point_map_t = std::map<Point<spacedim>,
2309 std::vector<types::global_dof_index>,
2312 point_map_t point_map;
2315 for (
typename dof_map_t::const_iterator it = support_points.begin();
2316 it != support_points.end();
2319 std::vector<types::global_dof_index> &v = point_map[it->second];
2320 v.push_back(it->first);
2324 for (
typename point_map_t::iterator it = point_map.begin();
2325 it != point_map.end();
2328 out << it->first <<
" \"";
2329 const std::vector<types::global_dof_index> &v = it->second;
2330 for (
unsigned int i = 0; i < v.size(); ++i)
2344 template <
int dim,
int spacedim>
2351 const unsigned int nb = fe.
n_blocks();
2353 tables_by_block.resize(1);
2354 tables_by_block[0].reinit(nb, nb);
2355 tables_by_block[0].fill(
none);
2363 tables_by_block[0](ib, jb) |= table(i, j);
2369 template <
int dim,
int spacedim>
2377 tables_by_block.resize(fe_collection.
size());
2379 for (
unsigned int f = 0; f < fe_collection.
size(); ++f)
2383 const unsigned int nb = fe.
n_blocks();
2384 tables_by_block[f].reinit(nb, nb);
2385 tables_by_block[f].fill(
none);
2392 tables_by_block[f](ib, jb) |= table(i, j);
2400 template <
int dim,
int spacedim>
2404 const unsigned int level,
2405 const std::vector<bool> & selected_dofs,
2408 typename DoFHandler<dim, spacedim>::level_cell_iterator cell;
2409 typename DoFHandler<dim, spacedim>::level_cell_iterator endc =
2410 dof_handler.
end(level);
2411 std::vector<types::global_dof_index> indices;
2415 for (cell = dof_handler.
begin(level); cell != endc; ++cell)
2416 if (cell->is_locally_owned_on_level())
2420 dof_handler.
get_fe().dofs_per_cell);
2422 for (cell = dof_handler.
begin(level); cell != endc; ++cell)
2423 if (cell->is_locally_owned_on_level())
2425 indices.resize(cell->
get_fe().dofs_per_cell);
2426 cell->get_mg_dof_indices(indices);
2428 if (selected_dofs.size() != 0)
2433 if (selected_dofs.size() == 0)
2434 block_list.
add(i, indices[j] - offset);
2437 if (selected_dofs[j])
2438 block_list.
add(i, indices[j] - offset);
2446 template <
typename DoFHandlerType>
2449 const DoFHandlerType &dof_handler,
2450 const unsigned int level,
2451 const bool interior_only)
2454 block_list.
reinit(1, dof_handler.n_dofs(level), dof_handler.n_dofs(level));
2455 typename DoFHandlerType::level_cell_iterator cell;
2456 typename DoFHandlerType::level_cell_iterator endc = dof_handler.end(level);
2458 std::vector<types::global_dof_index> indices;
2459 std::vector<bool> exclude;
2461 for (cell = dof_handler.begin(level); cell != endc; ++cell)
2463 indices.resize(cell->get_fe().dofs_per_cell);
2464 cell->get_mg_dof_indices(indices);
2470 std::fill(exclude.begin(), exclude.end(),
false);
2473 for (
unsigned int face = 0;
2474 face < GeometryInfo<DoFHandlerType::dimension>::faces_per_cell;
2476 if (cell->at_boundary(face) ||
2477 cell->neighbor(face)->level() != cell->level())
2478 for (
unsigned int i = 0; i < dpf; ++i)
2482 block_list.
add(0, indices[j]);
2486 for (
const auto index : indices)
2487 block_list.
add(0, index);
2493 template <
typename DoFHandlerType>
2496 const DoFHandlerType &dof_handler,
2497 const unsigned int level,
2498 const bool interior_dofs_only,
2499 const bool boundary_dofs)
2501 Assert(level > 0 && level < dof_handler.get_triangulation().n_levels(),
2502 ExcIndexRange(level, 1, dof_handler.get_triangulation().n_levels()));
2504 typename DoFHandlerType::level_cell_iterator pcell =
2505 dof_handler.begin(level - 1);
2506 typename DoFHandlerType::level_cell_iterator endc =
2507 dof_handler.end(level - 1);
2509 std::vector<types::global_dof_index> indices;
2510 std::vector<bool> exclude;
2512 for (
unsigned int block = 0; pcell != endc; ++pcell)
2514 if (!pcell->has_children())
2517 for (
unsigned int child = 0; child < pcell->n_children(); ++child)
2519 const typename DoFHandlerType::level_cell_iterator cell =
2520 pcell->child(child);
2524 dof_handler.get_fe();
2526 indices.resize(n_dofs);
2527 exclude.resize(n_dofs);
2528 std::fill(exclude.begin(), exclude.end(),
false);
2529 cell->get_mg_dof_indices(indices);
2531 if (interior_dofs_only)
2537 for (
unsigned int d = 0; d < DoFHandlerType::dimension; ++d)
2540 DoFHandlerType::dimension>::vertex_to_face[child][d];
2541 for (
unsigned int i = 0; i < dpf; ++i)
2548 for (
unsigned int face = 0;
2552 if (cell->at_boundary(face))
2553 for (
unsigned int i = 0; i < dpf; ++i)
2557 for (
unsigned int i = 0; i < n_dofs; ++i)
2559 block_list.
add(block, indices[i]);
2565 template <
typename DoFHandlerType>
2566 std::vector<unsigned int>
2568 const DoFHandlerType &dof_handler,
2569 const unsigned int level,
2570 const bool interior_only,
2571 const bool boundary_patches,
2572 const bool level_boundary_patches,
2573 const bool single_cell_patches,
2574 const bool invert_vertex_mapping)
2576 const unsigned int n_blocks = dof_handler.get_fe().n_blocks();
2581 exclude_boundary_dofs,
2583 level_boundary_patches,
2584 single_cell_patches,
2585 invert_vertex_mapping);
2588 template <
typename DoFHandlerType>
2589 std::vector<unsigned int>
2591 const DoFHandlerType &dof_handler,
2592 const unsigned int level,
2593 const BlockMask & exclude_boundary_dofs,
2594 const bool boundary_patches,
2595 const bool level_boundary_patches,
2596 const bool single_cell_patches,
2597 const bool invert_vertex_mapping)
2599 typename DoFHandlerType::level_cell_iterator cell;
2600 typename DoFHandlerType::level_cell_iterator endc = dof_handler.end(level);
2604 std::vector<unsigned int> vertex_cell_count(
2605 dof_handler.get_triangulation().n_vertices(), 0);
2608 std::vector<bool> vertex_boundary(
2609 dof_handler.get_triangulation().n_vertices(),
false);
2611 std::vector<unsigned int> vertex_mapping(
2612 dof_handler.get_triangulation().n_vertices(),
2616 std::vector<unsigned int> vertex_dof_count(
2617 dof_handler.get_triangulation().n_vertices(), 0);
2621 for (cell = dof_handler.begin(level); cell != endc; ++cell)
2622 for (
unsigned int v = 0;
2623 v < GeometryInfo<DoFHandlerType::dimension>::vertices_per_cell;
2626 const unsigned int vg = cell->vertex_index(v);
2627 vertex_dof_count[vg] += cell->get_fe().dofs_per_cell;
2628 ++vertex_cell_count[vg];
2629 for (
unsigned int d = 0; d < DoFHandlerType::dimension; ++d)
2631 const unsigned int face =
2633 if (cell->at_boundary(face))
2634 vertex_boundary[vg] =
true;
2635 else if ((!level_boundary_patches) &&
2636 (cell->neighbor(face)->level() !=
2637 static_cast<int>(level)))
2638 vertex_boundary[vg] =
true;
2644 for (
unsigned int vg = 0; vg < vertex_dof_count.size(); ++vg)
2645 if ((!single_cell_patches && vertex_cell_count[vg] < 2) ||
2646 (!boundary_patches && vertex_boundary[vg]))
2647 vertex_dof_count[vg] = 0;
2650 unsigned int n_vertex_count = 0;
2651 for (
unsigned int vg = 0; vg < vertex_mapping.size(); ++vg)
2652 if (vertex_dof_count[vg] != 0)
2653 vertex_mapping[vg] = n_vertex_count++;
2656 for (
unsigned int vg = 0; vg < vertex_mapping.size(); ++vg)
2657 if (vertex_dof_count[vg] != 0)
2658 vertex_dof_count[vertex_mapping[vg]] = vertex_dof_count[vg];
2662 vertex_dof_count.resize(n_vertex_count);
2666 block_list.
reinit(vertex_dof_count.size(),
2667 dof_handler.n_dofs(level),
2670 std::vector<types::global_dof_index> indices;
2671 std::vector<bool> exclude;
2673 for (cell = dof_handler.begin(level); cell != endc; ++cell)
2677 cell->get_mg_dof_indices(indices);
2679 for (
unsigned int v = 0;
2680 v < GeometryInfo<DoFHandlerType::dimension>::vertices_per_cell;
2683 const unsigned int vg = cell->vertex_index(v);
2684 const unsigned int block = vertex_mapping[vg];
2690 if (exclude_boundary_dofs.
size() == 0 ||
2696 std::fill(exclude.begin(), exclude.end(),
false);
2699 for (
unsigned int d = 0; d < DoFHandlerType::dimension; ++d)
2702 DoFHandlerType::dimension>::vertex_to_face[v][d];
2704 DoFHandlerType::dimension>::opposite_face[a_face];
2705 for (
unsigned int i = 0; i < dpf; ++i)
2716 for (
unsigned int j = 0; j < indices.size(); ++j)
2718 block_list.
add(block, indices[j]);
2722 for (
const auto index : indices)
2723 block_list.
add(block, index);
2728 if (invert_vertex_mapping)
2731 unsigned int n_vertex_count = 0;
2732 for (
unsigned int vg = 0; vg < vertex_mapping.size(); ++vg)
2734 vertex_mapping[n_vertex_count++] = vg;
2737 vertex_mapping.resize(n_vertex_count);
2740 return vertex_mapping;
2744 template <
typename DoFHandlerType>
2747 const std::vector<typename DoFHandlerType::active_cell_iterator> &patch)
2749 std::set<types::global_dof_index> dofs_on_patch;
2750 std::vector<types::global_dof_index> local_dof_indices;
2755 for (
unsigned int i = 0; i < patch.size(); ++i)
2757 const typename DoFHandlerType::active_cell_iterator cell = patch[i];
2758 Assert(cell->is_artificial() ==
false,
2759 ExcMessage(
"This function can not be called with cells that are " 2760 "not either locally owned or ghost cells."));
2761 local_dof_indices.resize(cell->get_fe().dofs_per_cell);
2762 cell->get_dof_indices(local_dof_indices);
2763 dofs_on_patch.insert(local_dof_indices.begin(),
2764 local_dof_indices.end());
2768 return dofs_on_patch.size();
2773 template <
typename DoFHandlerType>
2774 std::vector<types::global_dof_index>
2776 const std::vector<typename DoFHandlerType::active_cell_iterator> &patch)
2778 std::set<types::global_dof_index> dofs_on_patch;
2779 std::vector<types::global_dof_index> local_dof_indices;
2784 for (
unsigned int i = 0; i < patch.size(); ++i)
2786 const typename DoFHandlerType::active_cell_iterator cell = patch[i];
2787 Assert(cell->is_artificial() ==
false,
2788 ExcMessage(
"This function can not be called with cells that are " 2789 "not either locally owned or ghost cells."));
2790 local_dof_indices.resize(cell->get_fe().dofs_per_cell);
2791 cell->get_dof_indices(local_dof_indices);
2792 dofs_on_patch.insert(local_dof_indices.begin(),
2793 local_dof_indices.end());
2796 Assert(dofs_on_patch.size() == count_dofs_on_patch<DoFHandlerType>(patch),
2803 return std::vector<types::global_dof_index>(dofs_on_patch.begin(),
2804 dofs_on_patch.end());
2814 #include "dof_tools.inst" 2818 DEAL_II_NAMESPACE_CLOSE
unsigned int n_active_cells() const
const Triangulation< dim, spacedim > & get_triangulation() const
static const unsigned int invalid_unsigned_int
#define AssertDimension(dim1, dim2)
ElementIterator end() const
const types::subdomain_id invalid_subdomain_id
void add_index(const size_type index)
cell_iterator begin(const unsigned int level=0) const
static ::ExceptionBase & ExcIO()
const hp::FECollection< dim, spacedim > & get_fe() const
cell_iterator end() const
#define AssertIndexRange(index, range)
void add_indices(const ForwardIterator &begin, const ForwardIterator &end)
active_cell_iterator begin_active(const unsigned int level=0) const
bool represents_n_components(const unsigned int n) const
bool represents_the_all_selected_mask() const
unsigned int size() const
Transformed quadrature points.
#define AssertThrow(cond, exc)
bool is_primitive() const
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
const FiniteElement< dim, spacedim > & get_fe(const unsigned int index=0) const
unsigned int n_blocks() const
const std::vector< Point< spacedim > > & get_quadrature_points() const
unsigned int component_to_block_index(const unsigned int component) const
size_type n_constraints() const
unsigned int n_locally_owned_dofs() const
virtual void reinit(const size_type m, const size_type n, const ArrayView< const unsigned int > &row_lengths) override
static ::ExceptionBase & ExcMessage(std::string arg1)
unsigned int subdomain_id
const FEValues< dim, spacedim > & get_present_fe_values() const
#define Assert(cond, exc)
unsigned int element_multiplicity(const unsigned int index) const
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
Abstract base class for mapping classes.
const ComponentMask & get_nonzero_components(const unsigned int i) const
void add(const size_type i, const size_type j)
types::global_dof_index n_dofs() const
unsigned int size() const
virtual const FiniteElement< dim, spacedim > & base_element(const unsigned int index) const
virtual unsigned int face_to_cell_index(const unsigned int face_dof_index, const unsigned int face, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false) const
const hp::FECollection< dim, spacedim > & get_fe_collection() const
unsigned int n_mpi_processes(const MPI_Comm &mpi_communicator)
const unsigned int dofs_per_cell
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
void set_size(const size_type size)
const std::vector< std::pair< size_type, number > > * get_constraint_entries(const size_type line_n) const
unsigned int global_dof_index
const types::subdomain_id artificial_subdomain_id
std::pair< unsigned int, unsigned int > system_to_component_index(const unsigned int index) const
#define AssertThrowMPI(error_code)
unsigned int n_components() const
std::pair< unsigned int, types::global_dof_index > system_to_block_index(const unsigned int component) const
unsigned int n_selected_blocks(const unsigned int overall_number_of_blocks=numbers::invalid_unsigned_int) const
const Triangulation< dim, spacedim > & get_triangulation() const
unsigned int first_selected_component(const unsigned int overall_number_of_components=numbers::invalid_unsigned_int) const
unsigned int n_selected_components(const unsigned int overall_number_of_components=numbers::invalid_unsigned_int) const
const unsigned int dofs_per_face
types::global_dof_index n_dofs() const
static ::ExceptionBase & ExcInvalidBoundaryIndicator()
static ::ExceptionBase & ExcNotImplemented()
bool is_element(const size_type index) const
const types::boundary_id internal_face_boundary_id
const types::global_dof_index invalid_dof_index
unsigned int size() const
unsigned int n_base_elements() const
ElementIterator begin() const
void push_back(const Quadrature< dim > &new_quadrature)
static ::ExceptionBase & ExcInternalError()
Triangulation< dim, spacedim > & get_triangulation()