72 template <
int dim,
typename Number =
double>
84 double downstream_size = 0;
86 for (
unsigned int d = 0; d < dim; ++d)
88 downstream_size += (rhs[d] - lhs[d]) * weight;
91 if (downstream_size < 0)
93 else if (downstream_size > 0)
97 for (
unsigned int d = 0; d < dim; ++d)
101 return lhs[d] < rhs[d];
121 template <
int dim,
int spacedim>
122 std::vector<unsigned char>
126 std::vector<unsigned char> local_component_association(
135 local_component_association[i] =
146 const unsigned int first_comp =
151 local_component_association[i] = first_comp;
158 for (
unsigned int c = first_comp; c < fe.
n_components(); ++c)
159 if (component_mask[c] ==
true)
161 local_component_association[i] = c;
166 Assert(std::find(local_component_association.begin(),
167 local_component_association.end(),
168 static_cast<unsigned char>(-1)) ==
169 local_component_association.end(),
172 return local_component_association;
192 template <
int dim,
int spacedim>
196 std::vector<unsigned char> &dofs_by_component)
198 const ::hp::FECollection<dim, spacedim> &fe_collection =
212 std::vector<std::vector<unsigned char>> local_component_association(
213 fe_collection.size());
214 for (
unsigned int f = 0; f < fe_collection.size(); ++f)
217 local_component_association[f] =
222 std::vector<types::global_dof_index> indices;
227 const unsigned int dofs_per_cell = c->get_fe().n_dofs_per_cell();
228 indices.resize(dofs_per_cell);
229 c->get_dof_indices(indices);
230 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
233 indices[i])] = local_component_association[fe_index][i];
245 template <
int dim,
int spacedim>
248 std::vector<unsigned char> & dofs_by_block)
250 const ::hp::FECollection<dim, spacedim> &fe_collection =
264 std::vector<std::vector<unsigned char>> local_block_association(
265 fe_collection.size());
266 for (
unsigned int f = 0; f < fe_collection.size(); ++f)
270 static_cast<unsigned char>(-1));
274 Assert(std::find(local_block_association[f].begin(),
275 local_block_association[f].end(),
276 static_cast<unsigned char>(-1)) ==
277 local_block_association[f].end(),
282 std::vector<types::global_dof_index> indices;
284 if (cell->is_locally_owned())
287 const unsigned int dofs_per_cell = cell->get_fe().n_dofs_per_cell();
288 indices.resize(dofs_per_cell);
289 cell->get_dof_indices(indices);
290 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
293 indices[i])] = local_block_association[fe_index][i];
300 template <
int dim,
int spacedim,
typename Number>
305 const unsigned int component)
314 for (
unsigned int i = 0; i < fe_collection.size(); ++i)
316 Assert(fe_collection[i].is_primitive() ==
true,
323 const bool consider_components =
327 if (consider_components ==
false)
331 std::vector<unsigned char> component_dofs(
338 for (
unsigned int i = 0; i < dof_data.
size(); ++i)
339 if (component_dofs[i] ==
static_cast<unsigned char>(component))
344 std::vector<unsigned char> touch_count(dof_handler.
n_dofs(), 0);
346 std::vector<types::global_dof_index> dof_indices;
347 dof_indices.reserve(fe_collection.max_dofs_per_cell());
351 const unsigned int dofs_per_cell = cell->get_fe().n_dofs_per_cell();
352 dof_indices.resize(dofs_per_cell);
353 cell->get_dof_indices(dof_indices);
355 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
358 if (!consider_components ||
359 (cell->get_fe().system_to_component_index(i).first == component))
362 dof_data(dof_indices[i]) += cell_data(cell->active_cell_index());
365 ++touch_count[dof_indices[i]];
375 Assert(consider_components || (touch_count[i] != 0),
377 if (touch_count[i] != 0)
378 dof_data(i) /= touch_count[i];
384 template <
int dim,
int spacedim>
392 "The given component mask is not sized correctly to represent the "
393 "components of the given finite element."));
411 std::vector<types::global_dof_index> selected_dofs;
414 if (component_mask[dofs_by_component[i]] ==
true)
419 result.
add_indices(selected_dofs.begin(), selected_dofs.end());
425 template <
int dim,
int spacedim>
431 return extract_dofs<dim, spacedim>(
437 template <
int dim,
int spacedim>
438 std::vector<IndexSet>
445 "The given component mask is not sized correctly to represent the "
446 "components of the given finite element."));
455 std::vector<IndexSet> index_per_comp(n_comps,
IndexSet(dof.
n_dofs()));
459 const auto &comp_i = dofs_by_component[i];
460 if (component_mask[comp_i])
461 index_per_comp[comp_i].add_index(
462 locally_owned_dofs.nth_index_in_set(i));
464 for (
auto &c : index_per_comp)
466 return index_per_comp;
471 template <
int dim,
int spacedim>
476 std::vector<bool> & selected_dofs)
483 "The given component mask is not sized correctly to represent the "
484 "components of the given finite element."));
493 std::fill_n(selected_dofs.begin(), dof.
n_dofs(
level),
false);
500 std::fill_n(selected_dofs.begin(), dof.
n_dofs(
level),
true);
505 std::fill_n(selected_dofs.begin(), dof.
n_dofs(
level),
false);
509 std::vector<unsigned char> local_component_association =
513 local_selected_dofs[i] = component_mask[local_component_association[i]];
519 cell->get_mg_dof_indices(indices);
521 selected_dofs[indices[i]] = local_selected_dofs[i];
527 template <
int dim,
int spacedim>
532 std::vector<bool> & selected_dofs)
543 template <
int dim,
int spacedim>
547 std::vector<bool> & selected_dofs,
548 const std::set<types::boundary_id> &boundary_ids)
554 "This function can not be used with distributed triangulations. "
555 "See the documentation for more information."));
561 selected_dofs.clear();
562 selected_dofs.resize(dof_handler.
n_dofs(),
false);
570 template <
int dim,
int spacedim>
575 const std::set<types::boundary_id> &boundary_ids)
584 template <
int dim,
int spacedim>
588 const std::set<types::boundary_id> &boundary_ids)
592 ExcMessage(
"Component mask has invalid size."));
601 const bool check_boundary_id = (boundary_ids.size() != 0);
605 const bool check_vector_component =
611 std::vector<types::global_dof_index> face_dof_indices;
612 face_dof_indices.reserve(
624 if (cell->is_artificial() ==
false)
625 for (
const unsigned int face : cell->face_indices())
626 if (cell->at_boundary(face))
627 if (!check_boundary_id ||
628 (boundary_ids.find(cell->face(face)->boundary_id()) !=
633 const auto reference_cell = cell->reference_cell();
635 const unsigned int n_vertices_per_cell =
636 reference_cell.n_vertices();
637 const unsigned int n_lines_per_cell = reference_cell.n_lines();
638 const unsigned int n_vertices_per_face =
639 reference_cell.face_reference_cell(face).n_vertices();
640 const unsigned int n_lines_per_face =
641 reference_cell.face_reference_cell(face).n_lines();
644 face_dof_indices.resize(dofs_per_face);
645 cell->face(face)->get_dof_indices(face_dof_indices,
646 cell->active_fe_index());
649 if (!check_vector_component)
650 selected_dofs.
add_index(face_dof_indices[i]);
665 (dim == 3 ? (i < n_vertices_per_face *
668 (i < n_vertices_per_face *
672 (i - n_vertices_per_face *
674 n_vertices_per_cell *
677 n_vertices_per_face *
681 n_vertices_per_cell *
691 selected_dofs.
add_index(face_dof_indices[i]);
695 const unsigned int first_nonzero_comp =
701 if (component_mask[first_nonzero_comp] ==
true)
702 selected_dofs.
add_index(face_dof_indices[i]);
707 return selected_dofs;
712 template <
int dim,
int spacedim>
717 std::vector<bool> & selected_dofs,
718 const std::set<types::boundary_id> &boundary_ids)
722 ExcMessage(
"This component mask has the wrong size."));
729 const bool check_boundary_id = (boundary_ids.size() != 0);
733 const bool check_vector_component =
737 selected_dofs.clear();
738 selected_dofs.resize(dof_handler.
n_dofs(),
false);
739 std::vector<types::global_dof_index> cell_dof_indices;
740 cell_dof_indices.reserve(
750 for (
const unsigned int face : cell->face_indices())
751 if (cell->at_boundary(face))
752 if (!check_boundary_id ||
753 (boundary_ids.find(cell->face(face)->boundary_id()) !=
759 cell_dof_indices.resize(dofs_per_cell);
760 cell->get_dof_indices(cell_dof_indices);
765 if (!check_vector_component)
766 selected_dofs[cell_dof_indices[i]] =
true;
773 selected_dofs[cell_dof_indices[i]] =
778 const unsigned int first_nonzero_comp =
784 selected_dofs[cell_dof_indices[i]] =
785 (component_mask[first_nonzero_comp] ==
true);
794 template <
int dim,
int spacedim,
typename number>
803 const std::function<
bool(
808 ->
bool {
return cell->is_locally_owned() && predicate(cell); };
810 std::vector<types::global_dof_index> local_dof_indices;
811 local_dof_indices.reserve(
815 std::set<types::global_dof_index> predicate_dofs;
818 if (!cell->is_artificial() && predicate(cell))
820 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
821 cell->get_dof_indices(local_dof_indices);
822 predicate_dofs.insert(local_dof_indices.begin(),
823 local_dof_indices.end());
827 std::set<types::global_dof_index> dofs_with_support_on_halo_cells;
829 const std::vector<typename DoFHandler<dim, spacedim>::active_cell_iterator>
833 active_cell_iterator>::const_iterator it =
835 it != halo_cells.end();
847 const unsigned int dofs_per_cell = (*it)->get_fe().n_dofs_per_cell();
848 local_dof_indices.resize(dofs_per_cell);
849 (*it)->get_dof_indices(local_dof_indices);
850 dofs_with_support_on_halo_cells.insert(local_dof_indices.begin(),
851 local_dof_indices.end());
863 std::set<types::global_dof_index> extra_halo;
864 for (
const auto dof : dofs_with_support_on_halo_cells)
870 const unsigned int line_size = line_ptr->size();
871 for (
unsigned int j = 0; j < line_size; ++j)
872 extra_halo.insert((*line_ptr)[j].first);
875 dofs_with_support_on_halo_cells.insert(extra_halo.begin(),
882 support_set.
add_indices(predicate_dofs.begin(), predicate_dofs.end());
886 halo_set.
add_indices(dofs_with_support_on_halo_cells.begin(),
887 dofs_with_support_on_halo_cells.end());
902 template <
int spacedim>
911 template <
int spacedim>
915 const unsigned int dim = 2;
923 for (
const auto &cell : dof_handler.active_cell_iterators())
924 if (!cell->is_artificial())
926 for (
const unsigned int face : cell->face_indices())
927 if (cell->face(face)->has_children())
930 line = cell->face(face);
934 selected_dofs.add_index(
935 line->child(0)->vertex_dof_index(1, dof));
937 for (
unsigned int child = 0; child < 2; ++child)
939 if (cell->neighbor_child_on_subface(face, child)
944 selected_dofs.add_index(
945 line->child(child)->dof_index(dof));
950 selected_dofs.compress();
951 return selected_dofs;
955 template <
int spacedim>
959 const unsigned int dim = 3;
966 for (
const auto &cell : dof_handler.active_cell_iterators())
967 if (!cell->is_artificial())
968 for (auto f : cell->face_indices())
972 if (cell->face(f)->has_children())
974 for (
unsigned int child = 0; child < 4; ++child)
975 if (!cell->neighbor_child_on_subface(f, child)
979 std::vector<types::global_dof_index> ldi(
981 face->child(child)->get_dof_indices(ldi);
982 selected_dofs.add_indices(ldi.begin(), ldi.end());
987 for (
unsigned int vertex = 0; vertex < 4; ++vertex)
990 unconstrained_dofs.add_index(
991 face->vertex_dof_index(vertex, dof));
994 selected_dofs.subtract_set(unconstrained_dofs);
995 return selected_dofs;
1002 template <
int dim,
int spacedim>
1006 return internal::extract_hanging_node_dofs(dof_handler);
1011 template <
int dim,
int spacedim>
1015 std::vector<bool> & selected_dofs)
1021 std::fill_n(selected_dofs.begin(), dof_handler.
n_dofs(),
false);
1023 std::vector<types::global_dof_index> local_dof_indices;
1024 local_dof_indices.reserve(
1030 if (cell->subdomain_id() == subdomain_id)
1032 const unsigned int dofs_per_cell = cell->get_fe().n_dofs_per_cell();
1033 local_dof_indices.resize(dofs_per_cell);
1034 cell->get_dof_indices(local_dof_indices);
1035 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1036 selected_dofs[local_dof_indices[i]] =
true;
1042 template <
int dim,
int spacedim>
1052 std::vector<types::global_dof_index> dof_indices;
1053 std::set<types::global_dof_index> global_dof_indices;
1058 dof_indices.resize(cell->get_fe().n_dofs_per_cell());
1059 cell->get_dof_indices(dof_indices);
1063 global_dof_indices.insert(dof_index);
1066 dof_set.
add_indices(global_dof_indices.begin(), global_dof_indices.end());
1075 template <
int dim,
int spacedim>
1085 template <
int dim,
int spacedim>
1089 const unsigned int level)
1097 std::vector<types::global_dof_index> dof_indices;
1098 std::set<types::global_dof_index> global_dof_indices;
1100 const auto filtered_iterators_range =
1103 for (
const auto &cell : filtered_iterators_range)
1105 dof_indices.resize(cell->get_fe().n_dofs_per_cell());
1106 cell->get_mg_dof_indices(dof_indices);
1110 global_dof_indices.insert(dof_index);
1113 dof_set.
add_indices(global_dof_indices.begin(), global_dof_indices.end());
1122 template <
int dim,
int spacedim>
1127 const unsigned int level)
1134 template <
int dim,
int spacedim>
1149 std::vector<types::global_dof_index> dof_indices;
1150 std::vector<types::global_dof_index> dofs_on_ghosts;
1153 if (cell->is_ghost())
1155 dof_indices.resize(cell->get_fe().n_dofs_per_cell());
1156 cell->get_dof_indices(dof_indices);
1157 for (
const auto dof_index : dof_indices)
1159 dofs_on_ghosts.push_back(dof_index);
1163 std::sort(dofs_on_ghosts.begin(), dofs_on_ghosts.end());
1165 std::unique(dofs_on_ghosts.begin(),
1166 dofs_on_ghosts.end()));
1174 template <
int dim,
int spacedim>
1184 template <
int dim,
int spacedim>
1188 const unsigned int level)
1201 std::vector<types::global_dof_index> dof_indices;
1202 std::vector<types::global_dof_index> dofs_on_ghosts;
1213 dof_indices.resize(cell->get_fe().n_dofs_per_cell());
1214 cell->get_mg_dof_indices(dof_indices);
1215 for (
const auto dof_index : dof_indices)
1217 dofs_on_ghosts.push_back(dof_index);
1221 std::sort(dofs_on_ghosts.begin(), dofs_on_ghosts.end());
1223 std::unique(dofs_on_ghosts.begin(),
1224 dofs_on_ghosts.end()));
1233 template <
int dim,
int spacedim>
1237 const unsigned int level,
1245 template <
int dim,
int spacedim>
1249 std::vector<std::vector<bool>> & constant_modes)
1255 constant_modes = std::vector<std::vector<bool>>(0);
1263 std::vector<unsigned char> dofs_by_component(
1268 unsigned int n_selected_dofs = 0;
1269 for (
unsigned int i = 0; i < n_components; ++i)
1270 if (component_mask[i] ==
true)
1272 std::count(dofs_by_component.begin(), dofs_by_component.end(), i);
1276 std::vector<unsigned int> component_numbering(
1278 for (
unsigned int i = 0, count = 0; i < locally_owned_dofs.
n_elements();
1280 if (component_mask[dofs_by_component[i]])
1281 component_numbering[i] = count++;
1288 const ::hp::FECollection<dim, spacedim> &fe_collection =
1290 std::vector<Table<2, bool>> element_constant_modes;
1291 std::vector<std::vector<std::pair<unsigned int, unsigned int>>>
1292 constant_mode_to_component_translation(n_components);
1294 unsigned int n_constant_modes = 0;
1295 int first_non_empty_constant_mode = -1;
1296 for (
unsigned int f = 0; f < fe_collection.size(); ++f)
1298 std::pair<Table<2, bool>, std::vector<unsigned int>> data =
1299 fe_collection[f].get_constant_modes();
1303 if (first_non_empty_constant_mode < 0 && data.first.n_rows() > 0)
1305 first_non_empty_constant_mode = f;
1309 for (
unsigned int i = 0; i < data.second.size(); ++i)
1310 if (component_mask[data.second[i]])
1311 constant_mode_to_component_translation[data.second[i]]
1312 .emplace_back(n_constant_modes++, i);
1318 element_constant_modes.push_back(data.first);
1320 element_constant_modes.back().n_rows() == 0 ||
1321 element_constant_modes.back().n_rows() ==
1322 element_constant_modes[first_non_empty_constant_mode].n_rows(),
1329 constant_modes.clear();
1330 constant_modes.resize(n_constant_modes,
1331 std::vector<bool>(n_selected_dofs,
false));
1335 std::vector<types::global_dof_index> dof_indices;
1339 dof_indices.resize(cell->get_fe().n_dofs_per_cell());
1340 cell->get_dof_indices(dof_indices);
1342 for (
unsigned int i = 0; i < dof_indices.size(); ++i)
1343 if (locally_owned_dofs.
is_element(dof_indices[i]))
1345 const unsigned int loc_index =
1347 const unsigned int comp = dofs_by_component[loc_index];
1348 if (component_mask[comp])
1349 for (
auto &indices :
1350 constant_mode_to_component_translation[comp])
1351 constant_modes[indices
1352 .
first][component_numbering[loc_index]] =
1353 element_constant_modes[cell->active_fe_index()](
1361 template <
int dim,
int spacedim>
1364 std::vector<unsigned int> & active_fe_indices)
1371 active_fe_indices.assign(indices.begin(), indices.end());
1374 template <
int dim,
int spacedim>
1375 std::vector<IndexSet>
1379 ExcMessage(
"The given DoFHandler has no DoFs."));
1387 "For parallel::distributed::Triangulation objects and "
1388 "associated DoF handler objects, asking for any information "
1389 "related to a subdomain other than the locally owned one does "
1390 "not make sense."));
1394 std::vector<::types::subdomain_id> subdomain_association(
1397 subdomain_association);
1411 const unsigned int n_subdomains =
1415 unsigned int max_subdomain_id = 0;
1418 std::max(max_subdomain_id, cell->subdomain_id());
1419 return max_subdomain_id + 1;
1425 Assert(n_subdomains > *std::max_element(subdomain_association.begin(),
1426 subdomain_association.end()),
1429 std::vector<::IndexSet> index_sets(
1438 index < subdomain_association.size();
1442 if (subdomain_association[index] != this_subdomain)
1444 index_sets[this_subdomain].add_range(i_min, index);
1446 this_subdomain = subdomain_association[index];
1451 if (i_min == subdomain_association.size() - 1)
1453 index_sets[this_subdomain].add_index(i_min);
1459 index_sets[this_subdomain].add_range(i_min,
1460 subdomain_association.size());
1463 for (
unsigned int i = 0; i < n_subdomains; ++i)
1464 index_sets[i].compress();
1469 template <
int dim,
int spacedim>
1470 std::vector<IndexSet>
1480 "For parallel::distributed::Triangulation objects and "
1481 "associated DoF handler objects, asking for any information "
1482 "related to a subdomain other than the locally owned one does "
1483 "not make sense."));
1491 std::vector<IndexSet> dof_set =
1493 const ::types::subdomain_id n_subdomains = dof_set.size();
1499 subdomain_id < n_subdomains;
1512 std::vector<types::global_dof_index> local_dof_indices;
1513 std::set<types::global_dof_index> subdomain_halo_global_dof_indices;
1514 for (
typename std::vector<
1516 const_iterator it_cell = active_halo_layer.begin();
1517 it_cell != active_halo_layer.end();
1523 cell->subdomain_id() != subdomain_id,
1525 "The subdomain ID of the halo cell should not match that of the vector entry."));
1528 cell->get_dof_indices(local_dof_indices);
1532 subdomain_halo_global_dof_indices.insert(local_dof_index);
1535 dof_set[subdomain_id].add_indices(
1536 subdomain_halo_global_dof_indices.begin(),
1537 subdomain_halo_global_dof_indices.end());
1539 dof_set[subdomain_id].compress();
1545 template <
int dim,
int spacedim>
1549 std::vector<types::subdomain_id> &subdomain_association)
1557 "For parallel::distributed::Triangulation objects and "
1558 "associated DoF handler objects, asking for any subdomain other "
1559 "than the locally owned one does not make sense."));
1561 Assert(subdomain_association.size() == dof_handler.
n_dofs(),
1575 std::vector<types::subdomain_id> cell_owners(
1581 cell_owners = tr->get_true_subdomain_ids_of_cells();
1582 Assert(tr->get_true_subdomain_ids_of_cells().size() ==
1583 tr->n_active_cells(),
1590 cell_owners[cell->active_cell_index()] = cell->subdomain_id();
1594 std::fill_n(subdomain_association.begin(),
1598 std::vector<types::global_dof_index> local_dof_indices;
1599 local_dof_indices.reserve(
1607 cell_owners[cell->active_cell_index()];
1608 const unsigned int dofs_per_cell = cell->get_fe().n_dofs_per_cell();
1609 local_dof_indices.resize(dofs_per_cell);
1610 cell->get_dof_indices(local_dof_indices);
1616 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1617 if (subdomain_association[local_dof_indices[i]] ==
1619 subdomain_association[local_dof_indices[i]] = subdomain_id;
1620 else if (subdomain_association[local_dof_indices[i]] > subdomain_id)
1622 subdomain_association[local_dof_indices[i]] = subdomain_id;
1626 Assert(std::find(subdomain_association.begin(),
1627 subdomain_association.end(),
1629 subdomain_association.end(),
1635 template <
int dim,
int spacedim>
1641 std::vector<types::subdomain_id> subdomain_association(
1645 return std::count(subdomain_association.begin(),
1646 subdomain_association.end(),
1652 template <
int dim,
int spacedim>
1665 "For parallel::distributed::Triangulation objects and "
1666 "associated DoF handler objects, asking for any subdomain other "
1667 "than the locally owned one does not make sense."));
1671 std::vector<types::global_dof_index> local_dof_indices;
1672 local_dof_indices.reserve(
1680 std::vector<types::global_dof_index> subdomain_indices;
1683 if ((cell->is_artificial() ==
false) &&
1684 (cell->subdomain_id() == subdomain))
1686 const unsigned int dofs_per_cell = cell->get_fe().n_dofs_per_cell();
1687 local_dof_indices.resize(dofs_per_cell);
1688 cell->get_dof_indices(local_dof_indices);
1689 subdomain_indices.insert(subdomain_indices.end(),
1690 local_dof_indices.begin(),
1691 local_dof_indices.end());
1694 std::sort(subdomain_indices.begin(), subdomain_indices.end());
1695 subdomain_indices.erase(std::unique(subdomain_indices.begin(),
1696 subdomain_indices.end()),
1697 subdomain_indices.end());
1700 index_set.
add_indices(subdomain_indices.begin(), subdomain_indices.end());
1708 template <
int dim,
int spacedim>
1713 std::vector<unsigned int> & n_dofs_on_subdomain)
1718 std::fill(n_dofs_on_subdomain.begin(), n_dofs_on_subdomain.end(), 0);
1727 return cell.subdomain_id() == subdomain;
1729 ExcMessage(
"There are no cells for the given subdomain!"));
1731 std::vector<types::subdomain_id> subdomain_association(
1735 std::vector<unsigned char> component_association(dof_handler.
n_dofs());
1737 std::vector<bool>(),
1738 component_association);
1740 for (
unsigned int c = 0; c < dof_handler.
get_fe(0).n_components(); ++c)
1743 if ((subdomain_association[i] == subdomain) &&
1744 (component_association[i] ==
static_cast<unsigned char>(c)))
1745 ++n_dofs_on_subdomain[c];
1757 template <
int dim,
int spacedim>
1760 const std::vector<unsigned char> & dofs_by_component,
1761 const std::vector<unsigned int> & target_component,
1762 const bool only_once,
1763 std::vector<types::global_dof_index> &dofs_per_component,
1764 unsigned int & component)
1783 for (
unsigned int dd = 0; dd < d; ++dd, ++component)
1784 dofs_per_component[target_component[component]] +=
1785 std::count(dofs_by_component.begin(),
1786 dofs_by_component.end(),
1793 for (
unsigned int dd = 1; dd < d; ++dd)
1794 dofs_per_component[target_component[component - d + dd]] =
1795 dofs_per_component[target_component[component - d]];
1802 template <
int dim,
int spacedim>
1805 const std::vector<unsigned char> & dofs_by_component,
1806 const std::vector<unsigned int> & target_component,
1807 const bool only_once,
1808 std::vector<types::global_dof_index> &dofs_per_component,
1809 unsigned int & component)
1814 for (
unsigned int fe = 1; fe < fe_collection.
size(); ++fe)
1816 Assert(fe_collection[fe].n_components() ==
1817 fe_collection[0].n_components(),
1819 Assert(fe_collection[fe].n_base_elements() ==
1820 fe_collection[0].n_base_elements(),
1822 for (
unsigned int b = 0; b < fe_collection[0].n_base_elements(); ++b)
1824 Assert(fe_collection[fe].base_element(b).n_components() ==
1825 fe_collection[0].base_element(b).n_components(),
1827 Assert(fe_collection[fe].base_element(b).n_base_elements() ==
1828 fe_collection[0].base_element(b).n_base_elements(),
1851 template <
int dim,
int spacedim>
1863 template <
int dim,
int spacedim>
1865 all_elements_are_primitive(
1866 const ::hp::FECollection<dim, spacedim> &fe_collection)
1868 for (
unsigned int i = 0; i < fe_collection.size(); ++i)
1869 if (fe_collection[i].is_primitive() ==
false)
1879 template <
int dim,
int spacedim>
1880 std::vector<types::global_dof_index>
1883 const bool only_once,
1884 const std::vector<unsigned int> &target_component_)
1890 std::vector<unsigned int> target_component = target_component_;
1891 if (target_component.size() == 0)
1893 target_component.resize(n_components);
1894 for (
unsigned int i = 0; i < n_components; ++i)
1895 target_component[i] = i;
1898 Assert(target_component.size() == n_components,
1902 const unsigned int max_component =
1903 *std::max_element(target_component.begin(), target_component.end());
1904 const unsigned int n_target_components = max_component + 1;
1906 std::vector<types::global_dof_index> dofs_per_component(
1911 if (n_components == 1)
1914 return dofs_per_component;
1920 std::vector<unsigned char> dofs_by_component(
1927 unsigned int component = 0;
1938 Assert((internal::all_elements_are_primitive(
1940 (std::accumulate(dofs_per_component.begin(),
1941 dofs_per_component.end(),
1947#ifdef DEAL_II_WITH_MPI
1953 std::vector<types::global_dof_index> local_dof_count =
1956 const int ierr = MPI_Allreduce(local_dof_count.data(),
1957 dofs_per_component.data(),
1958 n_target_components,
1966 return dofs_per_component;
1971 template <
int dim,
int spacedim>
1972 std::vector<types::global_dof_index>
1974 const std::vector<unsigned int> &target_block_)
1976 const ::hp::FECollection<dim, spacedim> &fe_collection =
1985 const unsigned int n_blocks = fe_collection[0].n_blocks();
1987 std::vector<unsigned int> target_block = target_block_;
1988 if (target_block.size() == 0)
1990 target_block.resize(fe_collection[0].n_blocks());
1991 for (
unsigned int i = 0; i < n_blocks; ++i)
1992 target_block[i] = i;
1995 Assert(target_block.size() == n_blocks,
1997 for (
unsigned int f = 1; f < fe_collection.size(); ++f)
1998 Assert(fe_collection[0].n_blocks() == fe_collection[f].n_blocks(),
1999 ExcMessage(
"This function can only work if all elements in a "
2000 "collection have the same number of blocks."));
2006 std::vector<types::global_dof_index> dofs_per_block(1);
2007 dofs_per_block[0] = dof_handler.
n_dofs();
2008 return dofs_per_block;
2012 const unsigned int max_block =
2013 *std::max_element(target_block.begin(), target_block.end());
2014 const unsigned int n_target_blocks = max_block + 1;
2016 std::vector<types::global_dof_index> dofs_per_block(n_target_blocks);
2020 for (
unsigned int this_fe = fe_collection.size() - 1;
2021 this_fe < fe_collection.size();
2026 std::vector<unsigned char> dofs_by_block(
2031 for (
unsigned int block = 0; block < fe.
n_blocks(); ++block)
2032 dofs_per_block[target_block[block]] +=
2033 std::count(dofs_by_block.begin(), dofs_by_block.end(), block);
2035#ifdef DEAL_II_WITH_MPI
2042 std::vector<types::global_dof_index> local_dof_count =
2044 const int ierr = MPI_Allreduce(local_dof_count.data(),
2045 dofs_per_block.data(),
2055 return dofs_per_block;
2060 template <
int dim,
int spacedim>
2063 std::vector<types::global_dof_index> &mapping)
2066 mapping.insert(mapping.end(),
2070 std::vector<types::global_dof_index> dofs_on_face;
2081 for (
const unsigned int f : cell->face_indices())
2082 if (cell->at_boundary(f))
2084 const unsigned int dofs_per_face =
2085 cell->get_fe().n_dofs_per_face(f);
2086 dofs_on_face.resize(dofs_per_face);
2087 cell->face(f)->get_dof_indices(dofs_on_face,
2088 cell->active_fe_index());
2089 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2091 mapping[dofs_on_face[i]] = next_boundary_index++;
2099 template <
int dim,
int spacedim>
2102 const std::set<types::boundary_id> &boundary_ids,
2103 std::vector<types::global_dof_index> &mapping)
2110 mapping.insert(mapping.end(),
2115 if (boundary_ids.size() == 0)
2118 std::vector<types::global_dof_index> dofs_on_face;
2123 for (
const unsigned int f : cell->face_indices())
2124 if (boundary_ids.find(cell->face(f)->boundary_id()) !=
2127 const unsigned int dofs_per_face =
2128 cell->get_fe().n_dofs_per_face(f);
2129 dofs_on_face.resize(dofs_per_face);
2130 cell->face(f)->get_dof_indices(dofs_on_face,
2131 cell->active_fe_index());
2132 for (
unsigned int i = 0; i < dofs_per_face; ++i)
2134 mapping[dofs_on_face[i]] = next_boundary_index++;
2145 template <
int dim,
int spacedim>
2146 std::map<types::global_dof_index, Point<spacedim>>
2152 std::map<types::global_dof_index, Point<spacedim>> support_points;
2158 for (
unsigned int fe_index = 0; fe_index < fe_collection.
size();
2162 Assert((fe_collection[fe_index].n_dofs_per_cell() == 0) ||
2163 (fe_collection[fe_index].has_support_points()),
2166 fe_collection[fe_index].get_unit_support_points()));
2171 (in_mask.
size() == 0 ?
2187 std::vector<types::global_dof_index> local_dof_indices;
2188 for (
const auto &cell : dof_handler.active_cell_iterators())
2190 if (cell->is_artificial() == false)
2192 hp_fe_values.reinit(cell);
2196 local_dof_indices.resize(cell->get_fe().n_dofs_per_cell());
2197 cell->get_dof_indices(local_dof_indices);
2199 const std::vector<Point<spacedim>> &points =
2201 for (
unsigned int i = 0; i < cell->get_fe().n_dofs_per_cell();
2204 const unsigned int dof_comp =
2205 cell->get_fe().system_to_component_index(i).first;
2209 support_points[local_dof_indices[i]] = points[i];
2213 return support_points;
2217 template <
int dim,
int spacedim>
2218 std::vector<Point<spacedim>>
2219 map_dofs_to_support_points_vector(
2224 std::vector<Point<spacedim>> support_points(dof_handler.
n_dofs());
2227 const std::map<types::global_dof_index, Point<spacedim>>
2235 Assert(x_support_points.find(i) != x_support_points.end(),
2238 support_points[i] = x_support_points.find(i)->second;
2241 return support_points;
2247 template <
int dim,
int spacedim>
2259 "This function can not be used with distributed triangulations. "
2260 "See the documentation for more information."));
2267 internal::map_dofs_to_support_points_vector(mapping_collection,
2273 template <
int dim,
int spacedim>
2286 "This function can not be used with distributed triangulations. "
2287 "See the documentation for more information."));
2292 internal::map_dofs_to_support_points_vector(mapping, dof_handler, mask);
2297 template <
int dim,
int spacedim>
2298 DEAL_II_DEPRECATED_EARLY
void
2305 support_points.clear();
2311 support_points = internal::map_dofs_to_support_points(mapping_collection,
2318 template <
int dim,
int spacedim>
2319 DEAL_II_DEPRECATED_EARLY
void
2326 support_points.clear();
2331 internal::map_dofs_to_support_points(mapping, dof_handler, mask);
2335 template <
int dim,
int spacedim>
2336 std::map<types::global_dof_index, Point<spacedim>>
2345 return internal::map_dofs_to_support_points(mapping_collection,
2351 template <
int dim,
int spacedim>
2352 std::map<types::global_dof_index, Point<spacedim>>
2358 return internal::map_dofs_to_support_points(mapping, dof_handler, mask);
2362 template <
int spacedim>
2370 std::map<Point<spacedim>,
2371 std::vector<types::global_dof_index>,
2376 for (
const auto &it : support_points)
2378 std::vector<types::global_dof_index> &v = point_map[it.second];
2379 v.push_back(it.first);
2383 for (
const auto &it : point_map)
2385 out << it.first <<
" \"";
2386 const std::vector<types::global_dof_index> &v = it.second;
2387 for (
unsigned int i = 0; i < v.size(); ++i)
2401 template <
int dim,
int spacedim>
2410 const unsigned int nb = fe.
n_blocks();
2412 tables_by_block.resize(1);
2413 tables_by_block[0].reinit(nb, nb);
2414 tables_by_block[0].fill(
none);
2422 tables_by_block[0](ib, jb) |= table(i, j);
2430 tables_by_block.resize(fe_collection.
size());
2432 for (
unsigned int f = 0; f < fe_collection.
size(); ++f)
2436 const unsigned int nb = fe.
n_blocks();
2437 tables_by_block[f].reinit(nb, nb);
2438 tables_by_block[f].fill(
none);
2445 tables_by_block[f](ib, jb) |= table(i, j);
2454 template <
int dim,
int spacedim>
2458 const unsigned int level,
2459 const std::vector<bool> & selected_dofs,
2462 std::vector<types::global_dof_index> indices;
2467 if (cell->is_locally_owned_on_level())
2474 if (cell->is_locally_owned_on_level())
2476 indices.resize(cell->get_fe().n_dofs_per_cell());
2477 cell->get_mg_dof_indices(indices);
2479 if (selected_dofs.size() != 0)
2484 if (selected_dofs.size() == 0)
2485 block_list.
add(i, indices[j] - offset);
2488 if (selected_dofs[j])
2489 block_list.
add(i, indices[j] - offset);
2497 template <
int dim,
int spacedim>
2501 const unsigned int level,
2502 const bool interior_only)
2507 std::vector<types::global_dof_index> indices;
2508 std::vector<bool> exclude;
2512 indices.resize(cell->get_fe().n_dofs_per_cell());
2513 cell->get_mg_dof_indices(indices);
2519 std::fill(exclude.begin(), exclude.end(),
false);
2521 for (
const unsigned int face : cell->face_indices())
2522 if (cell->at_boundary(face) ||
2523 cell->neighbor(face)->level() != cell->level())
2528 block_list.
add(0, indices[j]);
2532 for (
const auto index : indices)
2533 block_list.
add(0, index);
2539 template <
int dim,
int spacedim>
2543 const unsigned int level,
2544 const bool interior_dofs_only,
2545 const bool boundary_dofs)
2550 std::vector<types::global_dof_index> indices;
2551 std::vector<bool> exclude;
2553 unsigned int block = 0;
2556 if (pcell->is_active())
2559 for (
unsigned int child = 0; child < pcell->n_children(); ++child)
2561 const auto cell = pcell->child(child);
2566 indices.resize(n_dofs);
2567 exclude.resize(n_dofs);
2568 std::fill(exclude.begin(), exclude.end(),
false);
2569 cell->get_mg_dof_indices(indices);
2571 if (interior_dofs_only)
2575 for (
unsigned int d = 0; d < dim; ++d)
2577 const unsigned int face =
2586 for (
const unsigned int face :
2588 if (cell->at_boundary(face))
2594 for (
unsigned int i = 0; i < n_dofs; ++i)
2596 block_list.
add(block, indices[i]);
2602 template <
int dim,
int spacedim>
2603 std::vector<unsigned int>
2606 const unsigned int level,
2607 const bool interior_only,
2608 const bool boundary_patches,
2609 const bool level_boundary_patches,
2610 const bool single_cell_patches,
2611 const bool invert_vertex_mapping)
2618 exclude_boundary_dofs,
2620 level_boundary_patches,
2621 single_cell_patches,
2622 invert_vertex_mapping);
2625 template <
int dim,
int spacedim>
2626 std::vector<unsigned int>
2629 const unsigned int level,
2630 const BlockMask & exclude_boundary_dofs,
2631 const bool boundary_patches,
2632 const bool level_boundary_patches,
2633 const bool single_cell_patches,
2634 const bool invert_vertex_mapping)
2638 std::vector<unsigned int> vertex_cell_count(
2642 std::vector<bool> vertex_boundary(
2645 std::vector<unsigned int> vertex_mapping(
2650 std::vector<unsigned int> vertex_dof_count(
2656 for (
const unsigned int v : cell->vertex_indices())
2658 const unsigned int vg = cell->vertex_index(v);
2659 vertex_dof_count[vg] += cell->get_fe().n_dofs_per_cell();
2660 ++vertex_cell_count[vg];
2661 for (
unsigned int d = 0; d < dim; ++d)
2664 if (cell->at_boundary(face))
2665 vertex_boundary[vg] =
true;
2666 else if ((!level_boundary_patches) &&
2667 (cell->neighbor(face)->level() !=
2668 static_cast<int>(
level)))
2669 vertex_boundary[vg] =
true;
2675 for (
unsigned int vg = 0; vg < vertex_dof_count.size(); ++vg)
2676 if ((!single_cell_patches && vertex_cell_count[vg] < 2) ||
2677 (!boundary_patches && vertex_boundary[vg]))
2678 vertex_dof_count[vg] = 0;
2681 unsigned int n_vertex_count = 0;
2682 for (
unsigned int vg = 0; vg < vertex_mapping.size(); ++vg)
2683 if (vertex_dof_count[vg] != 0)
2684 vertex_mapping[vg] = n_vertex_count++;
2687 for (
unsigned int vg = 0; vg < vertex_mapping.size(); ++vg)
2688 if (vertex_dof_count[vg] != 0)
2689 vertex_dof_count[vertex_mapping[vg]] = vertex_dof_count[vg];
2693 vertex_dof_count.resize(n_vertex_count);
2697 block_list.
reinit(vertex_dof_count.size(),
2701 std::vector<types::global_dof_index> indices;
2702 std::vector<bool> exclude;
2708 cell->get_mg_dof_indices(indices);
2710 for (
const unsigned int v : cell->vertex_indices())
2712 const unsigned int vg = cell->vertex_index(v);
2713 const unsigned int block = vertex_mapping[vg];
2719 if (exclude_boundary_dofs.
size() == 0 ||
2725 std::fill(exclude.begin(), exclude.end(),
false);
2727 for (
unsigned int d = 0; d < dim; ++d)
2729 const unsigned int a_face =
2731 const unsigned int face =
2744 for (
unsigned int j = 0; j < indices.size(); ++j)
2746 block_list.
add(block, indices[j]);
2750 for (
const auto index : indices)
2751 block_list.
add(block, index);
2756 if (invert_vertex_mapping)
2759 unsigned int n_vertex_count = 0;
2760 for (
unsigned int vg = 0; vg < vertex_mapping.size(); ++vg)
2762 vertex_mapping[n_vertex_count++] = vg;
2765 vertex_mapping.resize(n_vertex_count);
2768 return vertex_mapping;
2772 template <
int dim,
int spacedim>
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)
2788 Assert(cell->is_artificial() ==
false,
2789 ExcMessage(
"This function can not be called with cells that are "
2790 "not either locally owned or ghost cells."));
2792 cell->get_dof_indices(local_dof_indices);
2793 dofs_on_patch.insert(local_dof_indices.begin(),
2794 local_dof_indices.end());
2798 return dofs_on_patch.size();
2803 template <
int dim,
int spacedim>
2804 std::vector<types::global_dof_index>
2809 std::set<types::global_dof_index> dofs_on_patch;
2810 std::vector<types::global_dof_index> local_dof_indices;
2815 for (
unsigned int i = 0; i < patch.size(); ++i)
2819 Assert(cell->is_artificial() ==
false,
2820 ExcMessage(
"This function can not be called with cells that are "
2821 "not either locally owned or ghost cells."));
2823 cell->get_dof_indices(local_dof_indices);
2824 dofs_on_patch.insert(local_dof_indices.begin(),
2825 local_dof_indices.end());
2828 Assert((dofs_on_patch.size() == count_dofs_on_patch<dim, spacedim>(patch)),
2835 return std::vector<types::global_dof_index>(dofs_on_patch.begin(),
2836 dofs_on_patch.end());
2846#include "dof_tools.inst"
const std::vector< std::pair< size_type, number > > * get_constraint_entries(const size_type line_n) const
size_type n_constraints() const
unsigned int size() const
unsigned int n_selected_blocks(const unsigned int overall_number_of_blocks=numbers::invalid_unsigned_int) const
bool represents_n_components(const unsigned int n) const
bool represents_the_all_selected_mask() const
unsigned int size() const
unsigned int n_selected_components(const unsigned int overall_number_of_components=numbers::invalid_unsigned_int) const
unsigned int first_selected_component(const unsigned int overall_number_of_components=numbers::invalid_unsigned_int) const
const hp::FECollection< dim, spacedim > & get_fe_collection() const
const FiniteElement< dim, spacedim > & get_fe(const types::fe_index index=0) const
const IndexSet & locally_owned_mg_dofs(const unsigned int level) const
types::global_dof_index n_boundary_dofs() const
const Triangulation< dim, spacedim > & get_triangulation() const
const IndexSet & locally_owned_dofs() const
active_cell_iterator begin_active(const unsigned int level=0) const
std::vector< types::fe_index > get_active_fe_indices() const
bool has_hp_capabilities() const
types::global_dof_index n_dofs() const
types::global_dof_index n_locally_owned_dofs() const
const std::vector< Point< spacedim > > & get_quadrature_points() const
const FEValues< dim, spacedim > & get_present_fe_values() const
unsigned int n_dofs_per_vertex() const
unsigned int n_dofs_per_cell() const
unsigned int n_dofs_per_line() const
unsigned int n_dofs_per_face(unsigned int face_no=0, unsigned int child=0) const
unsigned int n_blocks() const
unsigned int n_components() const
std::pair< unsigned int, types::global_dof_index > system_to_block_index(const unsigned int component) const
const ComponentMask & get_nonzero_components(const unsigned int i) const
virtual const FiniteElement< dim, spacedim > & base_element(const unsigned int index) const
ComponentMask component_mask(const FEValuesExtractors::Scalar &scalar) const
bool is_primitive() const
virtual bool has_support_on_face(const unsigned int shape_index, const unsigned int face_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
unsigned int component_to_block_index(const unsigned int component) const
std::pair< unsigned int, unsigned int > system_to_component_index(const unsigned int index) const
unsigned int element_multiplicity(const unsigned int index) const
unsigned int n_base_elements() const
std::pair< unsigned int, unsigned int > face_system_to_component_index(const unsigned int index, const unsigned int face_no=0) const
size_type index_within_set(const size_type global_index) const
size_type n_elements() const
bool is_element(const size_type index) const
void add_index(const size_type index)
void fill_binary_vector(VectorType &vector) const
void subtract_set(const IndexSet &other)
size_type nth_index_in_set(const size_type local_index) const
void add_indices(const ForwardIterator &begin, const ForwardIterator &end)
Abstract base class for mapping classes.
void reinit(const size_type m, const size_type n, const ArrayView< const unsigned int > &row_lengths)
void add(const size_type i, const size_type j)
virtual MPI_Comm get_communicator() const
virtual types::subdomain_id locally_owned_subdomain() const
unsigned int n_active_cells() const
unsigned int n_levels() const
unsigned int n_vertices() const
unsigned int size() const
unsigned int max_dofs_per_face() const
ComponentMask component_mask(const FEValuesExtractors::Scalar &scalar) const
unsigned int n_components() const
unsigned int max_dofs_per_cell() const
void push_back(const Quadrature< dim_in > &new_quadrature)
virtual MPI_Comm get_communicator() const override
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
IteratorRange< active_cell_iterator > active_cell_iterators() const
IteratorRange< FilteredIterator< BaseIterator > > filter_iterators(IteratorRange< BaseIterator > i, const Predicate &p)
IteratorRange< cell_iterator > cell_iterators_on_level(const unsigned int level) const
static ::ExceptionBase & ExcIO()
static ::ExceptionBase & ExcInvalidBoundaryIndicator()
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertThrowMPI(error_code)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcIndexRange(std::size_t arg1, std::size_t arg2, std::size_t arg3)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
typename ActiveSelector::line_iterator line_iterator
typename ActiveSelector::face_iterator face_iterator
typename ActiveSelector::active_cell_iterator active_cell_iterator
typename ActiveSelector::CellAccessor cell_accessor
@ update_quadrature_points
Transformed quadrature points.
unsigned int n_mpi_processes(const MPI_Comm mpi_communicator)
const types::boundary_id internal_face_boundary_id
const types::subdomain_id artificial_subdomain_id
const types::subdomain_id invalid_subdomain_id
static const unsigned int invalid_unsigned_int
const types::global_dof_index invalid_dof_index
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
unsigned short int fe_index
static std_cxx20::ranges::iota_view< unsigned int, unsigned int > face_indices()
const ::Triangulation< dim, spacedim > & tria
#define DEAL_II_DOF_INDEX_MPI_TYPE